From 978a1ad9a99898d45723d800be25092ad5fda2b8 Mon Sep 17 00:00:00 2001 From: Jason Garber Date: Fri, 1 Mar 2024 18:49:45 +0000 Subject: [PATCH] Refactor actionlint feature --- src/actionlint/README.md | 2 +- src/actionlint/devcontainer-feature.json | 2 +- src/actionlint/install.sh | 59 ++++++++--- src/actionlint/shared.lib.sh | 100 ++++++++++++++++++ test/actionlint/actionlint-install-path.sh | 17 --- test/actionlint/actionlint-version.sh | 17 --- .../install-bookworm-with-settings.sh | 14 +++ test/actionlint/install-bookworm.sh | 14 +++ .../actionlint/install-jammy-with-settings.sh | 14 +++ test/actionlint/install-jammy.sh | 14 +++ test/actionlint/scenarios.json | 30 +++++- test/actionlint/test.sh | 35 +----- 12 files changed, 227 insertions(+), 91 deletions(-) create mode 100755 src/actionlint/shared.lib.sh delete mode 100755 test/actionlint/actionlint-install-path.sh delete mode 100755 test/actionlint/actionlint-version.sh create mode 100755 test/actionlint/install-bookworm-with-settings.sh create mode 100755 test/actionlint/install-bookworm.sh create mode 100755 test/actionlint/install-jammy-with-settings.sh create mode 100755 test/actionlint/install-jammy.sh diff --git a/src/actionlint/README.md b/src/actionlint/README.md index 3024ade..8435107 100644 --- a/src/actionlint/README.md +++ b/src/actionlint/README.md @@ -19,6 +19,6 @@ Install [actionlint](https://github.com/rhysd/actionlint), a static checker for ## OS Support -This Feature should work on recent versions of Debian/Ubuntu and Linux distributions using the [apt](https://wiki.debian.org/AptCLI) management tool. +This Feature should work on recent versions of Debian/Ubuntu, RedHat Enterprise Linux, Fedora, Alma, and RockyLinux distributions with the `apt`, `yum`, `dnf`, or `microdnf` package manager installed. `bash` is required to execute the `install.sh` script. diff --git a/src/actionlint/devcontainer-feature.json b/src/actionlint/devcontainer-feature.json index 830414e..3c1cf52 100644 --- a/src/actionlint/devcontainer-feature.json +++ b/src/actionlint/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "actionlint", "id": "actionlint", - "version": "1.0.0", + "version": "1.1.0", "description": "Install actionlint, a static checker for GitHub Actions workflow files.", "options": { "version": { diff --git a/src/actionlint/install.sh b/src/actionlint/install.sh index 737914a..d2406ea 100755 --- a/src/actionlint/install.sh +++ b/src/actionlint/install.sh @@ -1,27 +1,54 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash set -e ACTIONLINT_VERSION="${VERSION:-"latest"}" -INSTALL_PATH="${INSTALLPATH:-"/usr/local/bin"}" +ACTIONLINT_INSTALL_PATH="${INSTALLPATH:-"/usr/local/bin"}" +ACTIONLINT_REPOSITORY="https://github.com/rhysd/actionlint" -if [ "$(id -u)" -ne 0 ]; then - printf 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' - exit 1 -fi - -curl_installed="" +DIRNAME=$(dirname -- "${0}") +SCRIPT_DIR=$(cd -- "${DIRNAME}" > /dev/null 2>&1 && pwd) -if ! type curl >/dev/null 2>&1; then - apt update --yes - apt install --no-install-recommends --yes curl ca-certificates +# shellcheck source=./src/actionlint/shared.lib.sh +. "${SCRIPT_DIR}"/shared.lib.sh - curl_installed="true" +if type actionlint > /dev/null 2>&1; then + echo "Detected existing system install: $(actionlint --version)" + clean_up + exit 0 fi -curl -sSL https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash | \ - /bin/bash -s -- "${ACTIONLINT_VERSION}" "${INSTALL_PATH}" +check_packages curl ca-certificates -if ! [ -z $curl_installed ]; then - apt purge curl --autoremove --yes +if [[ "${ACTIONLINT_VERSION}" = "latest" ]]; then + ACTIONLINT_VERSION=$(latest_release_version "${ACTIONLINT_REPOSITORY}") fi + +machine="$(uname -m)" +case "${machine}" in + x86_64) + arch="amd64" + ;; + i?86) + arch="386" + ;; + aarch64|arm64) + arch="arm64" + ;; + arm*) + arch="armv6" + ;; + *) + echo "Could not determine arch from machine hardware name '${machine}'" >&2 + exit 1 + ;; +esac + +# https://github.com/rhysd/actionlint/releases/download/v1.0.0/actionlint_1.0.0_linux_386.tar.gz +url="${ACTIONLINT_REPOSITORY}/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_${arch}.tar.gz" + +echo "Downloading ${url} with curl..." + +curl -L "${url}" | tar xvz -C "${ACTIONLINT_INSTALL_PATH}" actionlint + +echo "Done!" diff --git a/src/actionlint/shared.lib.sh b/src/actionlint/shared.lib.sh new file mode 100755 index 0000000..178e005 --- /dev/null +++ b/src/actionlint/shared.lib.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +if [[ "$(id -u)" -ne 0 ]]; then + printf 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +# Bring in ID, ID_LIKE, VERSION_ID, VERSION_CODENAME +. /etc/os-release +# Get an adjusted ID independent of distro variants +# shellcheck disable=SC2154 +if [[ "${ID}" = "debian" ]] || [[ "${ID_LIKE}" = "debian" ]]; then + ADJUSTED_ID="debian" +elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID}" = "mariner" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* || "${ID_LIKE}" = *"mariner"* ]]; then + ADJUSTED_ID="rhel" + # shellcheck disable=SC2034 + VERSION_CODENAME="${ID}${VERSION_ID}" +else + echo "Linux distro ${ID} not supported." + exit 1 +fi + +if type apt-get > /dev/null 2>&1; then + INSTALL_CMD="apt-get" +elif type microdnf > /dev/null 2>&1; then + INSTALL_CMD="microdnf" +elif type dnf > /dev/null 2>&1; then + INSTALL_CMD="dnf" +elif type yum > /dev/null 2>&1; then + INSTALL_CMD="yum" +else + echo "Unable to find a supported package manager." + exit 1 +fi + +clean_up() { + case ${ADJUSTED_ID} in + debian) + rm -rf /var/lib/apt/lists/* + ;; + rhel) + rm -rf /var/cache/dnf/* + rm -rf /var/cache/yum/* + ;; + *) + ;; + esac +} + +pkg_mgr_update() { + if [[ "${INSTALL_CMD}" = "apt-get" ]]; then + if [[ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]]; then + echo "Running apt-get update..." + ${INSTALL_CMD} update -y + fi + elif [[ ${INSTALL_CMD} = "dnf" ]] || [[ ${INSTALL_CMD} = "yum" ]]; then + if [[ "$(find /var/cache/"${INSTALL_CMD}"/* | wc -l)" = "0" ]]; then + echo "Running ${INSTALL_CMD} check-update..." + ${INSTALL_CMD} check-update + fi + fi +} + +check_packages() { + if [[ "${INSTALL_CMD}" = "apt-get" ]]; then + if ! dpkg -s "$@" > /dev/null 2>&1; then + pkg_mgr_update + ${INSTALL_CMD} -y install --no-install-recommends "$@" + fi + elif [[ "${INSTALL_CMD}" = "dnf" ]] || [[ "${INSTALL_CMD}" = "yum" ]]; then + _num_pkgs=$(echo "$@" | tr ' ' \\012 | wc -l) + _num_installed=$(${INSTALL_CMD} -C list installed "$@" | sed '1,/^Installed/d' | wc -l) + if [[ "${_num_pkgs}" != "${_num_installed}" ]]; then + pkg_mgr_update + ${INSTALL_CMD} -y install "$@" + fi + elif [[ "${INSTALL_CMD}" = "microdnf" ]]; then + ${INSTALL_CMD} -y install \ + --refresh \ + --best \ + --nodocs \ + --noplugins \ + --setopt=install_weak_deps=0 \ + "$@" + else + echo "Linux distro ${ID} not supported." + exit 1 + fi +} + +latest_release_version() { + if [[ $# -eq 0 ]]; then + echo "No repository URL provided." + exit 1 + fi + + curl -s --head "${1}"/releases/latest | sed -nr 's/location:.*\/v(.+)/\1/ip' | tr -d '\r' +} + +export DEBIAN_FRONTEND="noninteractive" diff --git a/test/actionlint/actionlint-install-path.sh b/test/actionlint/actionlint-install-path.sh deleted file mode 100755 index 0147da6..0000000 --- a/test/actionlint/actionlint-install-path.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -set -e - -# Optional: Import test library bundled with the devcontainer CLI -# See https://github.com/devcontainers/cli/blob/HEAD/docs/features/test.md#dev-container-features-test-lib -# Provides the 'check' and 'reportResults' commands. -source dev-container-features-test-lib - -# Feature-specific tests -# The 'check' command comes from the dev-container-features-test-lib. Syntax is... -# check