From d1efa5c3970e0b7c200649275e77c0ac4f0231ab Mon Sep 17 00:00:00 2001 From: George Adams Date: Mon, 5 Aug 2024 13:13:57 +0100 Subject: [PATCH] add super linter --- .github/workflows/linter.yml | 72 +++++++++++++++++++ .test/config.sh | 1 + .../tests/java-ca-certificates-update/run.sh | 43 +++++------ dockerhub_doc_config_update.sh | 51 +++++++------ 4 files changed, 120 insertions(+), 47 deletions(-) create mode 100644 .github/workflows/linter.yml diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml new file mode 100644 index 000000000..bf2472585 --- /dev/null +++ b/.github/workflows/linter.yml @@ -0,0 +1,72 @@ +# ******************************************************************************** +# Copyright (c) 2020 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made +# available under the terms of the Apache Software License 2.0 +# which is available at https://www.apache.org/licenses/LICENSE-2.0. +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************** + +--- + ########################### + ########################### + ## Linter GitHub Actions ## + ########################### + ########################### + name: Linter + + # + # Documentation: + # https://help.github.com/en/articles/workflow-syntax-for-github-actions + # + + ############################# + # Start the job on all push # + ############################# + on: + pull_request: + branches: [ main ] + + ############### + # Set the Job # + ############### + permissions: + contents: read + + jobs: + linter: + permissions: + contents: read # for actions/checkout to fetch code + statuses: write # for github/super-linter to mark status of each linter run + # Name the Job + name: Lint Code Base + # Set the agent to run on + runs-on: ubuntu-latest + + ################## + # Load all steps # + ################## + steps: + ########################## + # Checkout the code base # + ########################## + - name: Checkout Code + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + # Full git history is needed to get a proper list of changed files within `super-linter` + fetch-depth: 0 + + ################################ + # Run Linter against code base # + ################################ + - name: Lint Code Base + uses: github/super-linter@45fc0d88288beee4701c62761281edfee85655d7 # v5.0.0 + env: + VALIDATE_ALL_CODEBASE: true + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Markdown lint complains about the issue templates + FILTER_REGEX_EXCLUDE: .github/ISSUE_TEMPLATE/* diff --git a/.test/config.sh b/.test/config.sh index f52df2cc4..355854f73 100644 --- a/.test/config.sh +++ b/.test/config.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash +# shellcheck disable=SC2154 imageTests[openjdk]+=' java-ca-certificates-update ' diff --git a/.test/tests/java-ca-certificates-update/run.sh b/.test/tests/java-ca-certificates-update/run.sh index ca7f72d87..9dbdf9dc3 100755 --- a/.test/tests/java-ca-certificates-update/run.sh +++ b/.test/tests/java-ca-certificates-update/run.sh @@ -2,11 +2,12 @@ set -o pipefail +# shellcheck disable=SC2128 testDir="$(readlink -f "$(dirname "$BASH_SOURCE")")" runDir="$(dirname "$(readlink -f "$BASH_SOURCE")")" # CMD1 in each run is just a `date` to make sure nothing is broken with or without the entrypoint -CMD1=date +CMD1=$(date) # CMD2 in each run is to check for the `dockerbuilder` certificate in the Java keystore. Entrypoint export $CACERT to # point to the Java keystore. @@ -36,43 +37,43 @@ EOF # # Test run 1: No added certificates and environment variable is not set. We expect CMD1 to succeed and CMD2 to fail. -docker run --rm "$1" $CMD1 >&/dev/null +docker run --rm "$1" "$CMD1" >&/dev/null echo -n $? docker run --rm "$1" "${CMD2[@]}" >&/dev/null echo -n $? # Test run 2: No added certificates, but the environment variable is set. Since there are no certificates, we still # expect CMD1 to succeed and CMD2 to fail. -docker run --rm -e USE_SYSTEM_CA_CERTS=1 "$1" $CMD1 >&/dev/null +docker run --rm -e USE_SYSTEM_CA_CERTS=1 "$1" "$CMD1" >&/dev/null echo -n $? docker run --rm -e USE_SYSTEM_CA_CERTS=1 "$1" "${CMD2[@]}" >&/dev/null echo -n $? # Test run 3: Certificates are mounted, but the environment variable is not set, i.e. certificate importing should not # be activated. We expect CMD1 to succeed and CMD2 to fail. -docker run --rm --volume=$testDir/certs:/certificates "$1" $CMD1 >&/dev/null +docker run --rm --volume="$testDir/certs:/certificates" "$1" "$CMD1" >&/dev/null echo -n $? -docker run --rm --volume=$testDir/certs:/certificates "$1" "${CMD2[@]}" >&/dev/null +docker run --rm --volume="$testDir/certs:/certificates" "$1" "${CMD2[@]}" >&/dev/null echo -n $? # Test run 4: Certificates are mounted and the environment variable is set. We expect both CMD1 and CMD2 to succeed. -docker run --rm -e USE_SYSTEM_CA_CERTS=1 --volume=$testDir/certs:/certificates "$1" $CMD1 >&/dev/null +docker run --rm -e USE_SYSTEM_CA_CERTS=1 --volume="$testDir/certs:/certificates" "$1" "$CMD1" >&/dev/null echo -n $? -docker run --rm -e USE_SYSTEM_CA_CERTS=1 --volume=$testDir/certs:/certificates "$1" "${CMD2[@]}" >&/dev/null +docker run --rm -e USE_SYSTEM_CA_CERTS=1 --volume="$testDir/certs:/certificates" "$1" "${CMD2[@]}" >&/dev/null echo -n $? # Test run 5: Certificates are mounted and are symlinks (e.g. in Kubernetes as `Secret`s or `ConfigMap`s) and the # environment variable is set. We expect both CMD1 and CMD2 to succeed. -docker run --rm -e USE_SYSTEM_CA_CERTS=1 --volume=$testDir/certs_symlink:/certificates "$1" $CMD1 >&/dev/null +docker run --rm -e USE_SYSTEM_CA_CERTS=1 --volume="$testDir/certs_symlink:/certificates" "$1" "$CMD1" >&/dev/null echo -n $? -docker run --rm -e USE_SYSTEM_CA_CERTS=1 --volume=$testDir/certs_symlink:/certificates "$1" "${CMD2[@]}" >&/dev/null +docker run --rm -e USE_SYSTEM_CA_CERTS=1 --volume="$testDir/certs_symlink:/certificates" "$1" "${CMD2[@]}" >&/dev/null echo -n $? # Test run 6: Certificates are mounted and the environment variable is set, but the entrypoint is overridden. We expect # CMD1 to succeed and CMD2 to fail. -docker run --rm -e USE_SYSTEM_CA_CERTS=1 --volume=$testDir/certs:/certificates "$TESTIMAGE" $CMD1 >&/dev/null +docker run --rm -e USE_SYSTEM_CA_CERTS=1 --volume="$testDir/certs:/certificates" "$TESTIMAGE" "$CMD1" >&/dev/null echo -n $? -docker run --rm -e USE_SYSTEM_CA_CERTS=1 --volume=$testDir/certs:/certificates "$TESTIMAGE" "${CMD2[@]}" >&/dev/null +docker run --rm -e USE_SYSTEM_CA_CERTS=1 --volume="$testDir/certs:/certificates" "$TESTIMAGE" "${CMD2[@]}" >&/dev/null echo -n $? # @@ -80,42 +81,42 @@ echo -n $? # # Test run 1: No added certificates and environment variable is not set. We expect CMD1 to succeed and CMD2 to fail. -docker run --read-only --user 1000:1000 --rm "$1" $CMD1 >&/dev/null +docker run --read-only --user 1000:1000 --rm "$1" "$CMD1" >&/dev/null echo -n $? docker run --read-only --user 1000:1000 --rm "$1" "${CMD2[@]}" >&/dev/null echo -n $? # Test run 2: No added certificates, but the environment variable is set. Since there are no certificates, we still # expect CMD1 to succeed and CMD2 to fail. -docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 "$1" $CMD1 >&/dev/null +docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 "$1" "$CMD1" >&/dev/null echo -n $? docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 "$1" "${CMD2[@]}" >&/dev/null echo -n $? # Test run 3: Certificates are mounted, but the environment variable is not set, i.e. certificate importing should not # be activated. We expect CMD1 to succeed and CMD2 to fail. -docker run --read-only --user 1000:1000 --rm --volume=$testDir/certs:/certificates "$1" $CMD1 >&/dev/null +docker run --read-only --user 1000:1000 --rm --volume="$testDir/certs:/certificates" "$1" "$CMD1" >&/dev/null echo -n $? -docker run --read-only --user 1000:1000 --rm --volume=$testDir/certs:/certificates "$1" "${CMD2[@]}" >&/dev/null +docker run --read-only --user 1000:1000 --rm --volume="$testDir/certs:/certificates" "$1" "${CMD2[@]}" >&/dev/null echo -n $? # Test run 4: Certificates are mounted and the environment variable is set. We expect both CMD1 and CMD2 to succeed. -docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 --volume=$testDir/certs:/certificates "$1" $CMD1 >&/dev/null +docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 --volume="$testDir/certs:/certificates" "$1" "$CMD1" >&/dev/null echo -n $? -docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 --volume=$testDir/certs:/certificates "$1" "${CMD2[@]}" >&/dev/null +docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 --volume="$testDir/certs:/certificates" "$1" "${CMD2[@]}" >&/dev/null echo -n $? # Test run 5: Certificates are mounted and are symlinks (e.g. in Kubernetes as `Secret`s or `ConfigMap`s) and the # environment variable is set. We expect both CMD1 and CMD2 to succeed. -docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 --volume=$testDir/certs_symlink:/certificates "$1" $CMD1 >&/dev/null +docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 --volume="$testDir/certs_symlink:/certificates" "$1" "$CMD1" >&/dev/null echo -n $? -docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 --volume=$testDir/certs_symlink:/certificates "$1" "${CMD2[@]}" >&/dev/null +docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 --volume="$testDir/certs_symlink:/certificates" "$1" "${CMD2[@]}" >&/dev/null echo -n $? # Test run 6: Certificates are mounted and the environment variable is set, but the entrypoint is overridden. We expect # CMD1 to succeed and CMD2 to fail. # -docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 --volume=$testDir/certs:/certificates "$TESTIMAGE" $CMD1 >&/dev/null +docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 --volume="$testDir/certs:/certificates" "$TESTIMAGE" "$CMD1" >&/dev/null echo -n $? -docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 --volume=$testDir/certs:/certificates "$TESTIMAGE" "${CMD2[@]}" >&/dev/null +docker run --read-only --user 1000:1000 -v /tmp --rm -e USE_SYSTEM_CA_CERTS=1 --volume="$testDir/certs:/certificates" "$TESTIMAGE" "${CMD2[@]}" >&/dev/null echo -n $? diff --git a/dockerhub_doc_config_update.sh b/dockerhub_doc_config_update.sh index 1f63a91e0..2427dc533 100755 --- a/dockerhub_doc_config_update.sh +++ b/dockerhub_doc_config_update.sh @@ -48,7 +48,7 @@ git_repo="https://github.com/adoptium/containers/blob/master" gitcommit=$(git log | head -1 | awk '{ print $2 }') print_official_text() { - echo "$*" >> ${official_docker_image_file} + echo "$*" >> "${official_docker_image_file}" } print_official_header() { @@ -71,9 +71,9 @@ function generate_official_image_tags() { ojdk_version=${ojdk_version//+/_} case $os in - "ubuntu") distro=$(echo $dfdir | awk -F '/' '{ print $4 }' ) ;; - "ubi") distro=$(echo $dfdir | awk -F '/' '{ print $4 }' ) ;; - "windows") distro=$(echo $dfdir | awk -F '/' '{ print $4 }' ) ;; + "ubuntu") distro=$(echo "$dfdir" | awk -F '/' '{ print $4 }' ) ;; + "ubi") distro=$(echo "$dfdir" | awk -F '/' '{ print $4 }' ) ;; + "windows") distro=$(echo "$dfdir" | awk -F '/' '{ print $4 }' ) ;; *) distro=$os;; esac @@ -94,7 +94,6 @@ function generate_official_image_tags() { jdk_tag="${ver}-${distro}" all_tags="${all_tags}, ${jdk_tag}" # make "eclipse-temurin:latest" point to newest supported JDK - # shellcheck disable=SC2154 if [ "${ver}" == "${latest_version}" ]; then if [ "${vm}" == "hotspot" ]; then extra_shared_tags=", latest" @@ -104,9 +103,9 @@ function generate_official_image_tags() { unset windows_shared_tags shared_tags=$(echo ${all_tags} | sed "s/-$distro//g") - if [ $os == "windows" ]; then - windows_version=$(echo $distro | awk -F '-' '{ print $1 }' ) - windows_version_number=$(echo $distro | awk -F '-' '{ print $2 }' ) + if [ "$os" == "windows" ]; then + windows_version=$(echo "$distro" | awk -F '-' '{ print $1 }' ) + windows_version_number=$(echo "$distro" | awk -F '-' '{ print $2 }' ) windows_shared_tags=$(echo ${all_tags} | sed "s/$distro/$windows_version/g") case $distro in nanoserver*) @@ -125,22 +124,22 @@ function generate_official_image_tags() { function generate_official_image_arches() { # Generate the supported arches for the above tags. - # Official images supports amd64, arm64vX, s390x, ppc64le amd windows-amd64 - if [ $os == "windows" ]; then + # Official images support amd64, arm64vX, s390x, ppc64le, and windows-amd64 + if [ "$os" == "windows" ]; then arches="windows-amd64" else - # shellcheck disable=SC2046,SC2005,SC1003,SC2086,SC2063 - arches=$(echo $(grep ') \\' ${file} | grep -v "*" | sed 's/) \\//g; s/|//g')) - arches=$(echo ${arches} | sed 's/x86_64/amd64/g') # replace x86_64 with amd64 - arches=$(echo ${arches} | sed 's/ppc64el/ppc64le/g') # replace ppc64el with ppc64le - arches=$(echo ${arches} | sed 's/arm64/arm64v8/g') # replace arm64 with arm64v8 - arches=$(echo ${arches} | sed 's/aarch64/arm64v8/g') # replace aarch64 with arm64v8 - arches=$(echo ${arches} | sed 's/armhf/arm32v7/g') # replace armhf with arm32v7 + arches=$(echo $(grep ') \\' "${file}" | grep -v "*" | sed 's/) \\//g; s/|//g')) + arches="${arches//x86_64/amd64}" # replace x86_64 with amd64 + arches="${arches//ppc64el/ppc64le}" # replace ppc64el with ppc64le + arches="${arches//arm64/arm64v8}" # replace arm64 with arm64v8 + arches="${arches//aarch64/arm64v8}" # replace aarch64 with arm64v8 + arches="${arches//armhf/arm32v7}" # replace armhf with arm32v7 # sort arches alphabetically - arches=$(echo ${arches} | tr ' ' '\n' | sort | tr '\n' ' ' | sed 's/ /, /g' | sed 's/, $//') + arches=$(echo "${arches}" | tr ' ' '\n' | sort | tr '\n' ' ' | sed 's/ /, /g' | sed 's/, $//') fi } + function print_official_image_file() { # Retrieve the latest manifest block official_manifest=$(sed -n "/${all_tags}/,/^$/p" official-eclipse-temurin) @@ -148,11 +147,11 @@ function print_official_image_file() { # Retrieve the git commit sha from the official manifest official_gitcommit=$(echo "${official_manifest}" | grep 'GitCommit: ' | awk '{print $2}') # See if there are any changes between the two commit sha's - if git diff "$gitcommit:$dfdir/$dfname" "$official_gitcommit:$dfdir/$dfname" >/dev/null 2>&1; then - diff_count=$(git diff "$gitcommit:$dfdir/$dfname" "$official_gitcommit:$dfdir/$dfname" | wc -l) + if git diff "$gitcommit:"$dfdir"/$dfname" "$official_gitcommit:"$dfdir"/$dfname" >/dev/null 2>&1; then + diff_count=$(git diff "$gitcommit:"$dfdir"/$dfname" "$official_gitcommit:"$dfdir"/$dfname" | wc -l) # check for diff in the entrypoint.sh file - if [ -f "$dfdir/entrypoint.sh" ]; then - diff_count=$((diff_count + $(git diff "$gitcommit:$dfdir/entrypoint.sh" "$official_gitcommit:$dfdir/entrypoint.sh" | wc -l))) + if [ -f ""$dfdir"/entrypoint.sh" ]; then + diff_count=$((diff_count + $(git diff "$gitcommit:"$dfdir"/entrypoint.sh" "$official_gitcommit:"$dfdir"/entrypoint.sh" | wc -l))) fi else # Forcefully sets a diff if the file doesn't exist @@ -178,15 +177,15 @@ function print_official_image_file() { echo "Architectures: ${arches}" echo "GitCommit: ${commit}" echo "Directory: ${dfdir}" - if [ $os == "windows" ]; then + if [ "$os" == "windows" ]; then echo "Builder: classic" echo "Constraints: ${constraints}" fi echo "" - } >> ${official_docker_image_file} + } >> "${official_docker_image_file}" } -rm -f ${official_docker_image_file} +rm -f "${official_docker_image_file}" print_official_header official_os_ignore_array=(clefos debian debianslim leap tumbleweed) @@ -201,7 +200,7 @@ function generate_official_image_info() { fi done if [ "${os}" == "windows" ]; then - distro=$(echo $dfdir | awk -F '/' '{ print $4 }' ) + distro=$(echo "$dfdir" | awk -F '/' '{ print $4 }' ) # 20h2 and 1909 is not supported upstream if [[ "${distro}" == "windowsservercore-20h2" ]] || [[ "${distro}" == "windowsservercore-1909" ]] || [[ "${distro}" == "windowsservercore-ltsc2019" ]] ; then return;