From 596bf486b8c334096c9ce7af875bdc5c2e33fc54 Mon Sep 17 00:00:00 2001 From: Justus-at-Tazama Date: Wed, 8 Apr 2026 23:35:05 +0200 Subject: [PATCH] fix(workflows): sync workflow audit fixes from tazama-lf/workflows Applies all changes from tazama-lf/workflows PR #76 (workflow audit fixes - batch 1) to frmscoe/workflows. Changes are synced verbatim from the canonical source. - fix(njsscan): fix SARIF upload guard, category, upgrade upload-sarif v4 (#68) - fix(gpg-verify): make curl error handler reachable under bash -e (#69) - fix(dco-check, gpg-verify): replace mutable branch refs with immutable SHAs (#70) - fix(package-rule): add ref guard to prevent push from non-canonical branches (#71) - fix(gpg-verify): rename workflow to Signature Verify, update header comment (#72) - fix(package-rule): pass GH_TOKEN to docker build via BuildKit secret (#73) - fix(sbom): pass GH_TOKEN to docker build via BuildKit secret (#74) - fix(dockerfile-linter): skip hadolint and upload when no Dockerfile present (#75) - fix(dockerfile-linter, sbom): address CodeRabbit review findings Signed-off-by: Justus-at-Tazama --- .github/workflows/codacy.yml | 3 +- .github/workflows/dco-check.yml | 14 +++---- .github/workflows/dockerfile-linter.yml | 55 +++++++++++++++++++++++++ .github/workflows/gpg-verify.yml | 26 ++++++------ .github/workflows/njsscan.yml | 5 ++- .github/workflows/package-rule-rc.yml | 11 ++++- .github/workflows/package-rule.yml | 11 ++++- .github/workflows/sbom.yml | 4 +- 8 files changed, 100 insertions(+), 29 deletions(-) create mode 100644 .github/workflows/dockerfile-linter.yml diff --git a/.github/workflows/codacy.yml b/.github/workflows/codacy.yml index 0591e76..6f3b35e 100644 --- a/.github/workflows/codacy.yml +++ b/.github/workflows/codacy.yml @@ -59,6 +59,7 @@ jobs: # Upload the SARIF file generated in the previous step - name: Upload SARIF results file - uses: github/codeql-action/upload-sarif@5c8a8a642e79153f5d047b10ec1cba1d1cc65699 # v3 + uses: github/codeql-action/upload-sarif@60168ffe96596fce55ee3851b6bb7b2e1ea8dbb0 # v4.35.1 with: sarif_file: results.sarif + category: codacy diff --git a/.github/workflows/dco-check.yml b/.github/workflows/dco-check.yml index c5c04ff..316a7b5 100644 --- a/.github/workflows/dco-check.yml +++ b/.github/workflows/dco-check.yml @@ -26,21 +26,17 @@ jobs: - name: Set up environment variables env: - PR_BASE_REF: ${{ github.event.pull_request.base.ref }} - PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} + PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} + PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: | - printf 'BASE_BRANCH=%s\n' "$PR_BASE_REF" >> "$GITHUB_ENV" - printf 'HEAD_BRANCH=%s\n' "$PR_HEAD_REF" >> "$GITHUB_ENV" + printf 'BASE_SHA=%s\n' "$PR_BASE_SHA" >> "$GITHUB_ENV" + printf 'HEAD_SHA=%s\n' "$PR_HEAD_SHA" >> "$GITHUB_ENV" # Step to check each commit in the pull request for a Signed-off-by line - name: Check for DCO Sign-off run: | - # Get the base branch and head branch of the pull request - base_branch=$BASE_BRANCH - head_branch=$HEAD_BRANCH - # Get the list of commit hashes introduced by this PR (head commits not yet in base) - commits=$(git log --pretty=format:%H origin/${base_branch}..origin/${head_branch}) + commits=$(git log --pretty=format:%H "$BASE_SHA..$HEAD_SHA") non_compliant_commits="" # Loop through each commit and check for the Signed-off-by line diff --git a/.github/workflows/dockerfile-linter.yml b/.github/workflows/dockerfile-linter.yml new file mode 100644 index 0000000..ed463b8 --- /dev/null +++ b/.github/workflows/dockerfile-linter.yml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# hadoint is a Dockerfile linter written in Haskell +# that helps you build best practice Docker images. +# More details at https://github.com/hadolint/hadolint + +# Please do not attempt to edit this flow without the direct consent from the DevOps team. This file is managed centrally. + +name: Hadolint + +on: + push: + branches: [ "dev", "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "dev" ] + schedule: + - cron: '17 13 * * 0' + +permissions: + contents: read + +jobs: + hadolint: + if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' + name: Run hadolint scanning + runs-on: ubuntu-latest + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Run hadolint + id: hadolint + if: hashFiles('Dockerfile') != '' + uses: hadolint/hadolint-action@f988afea3da57ee48710a9795b6bb677cc901183 + with: + dockerfile: ./Dockerfile + format: sarif + output-file: hadolint-results.sarif + no-fail: true + + - name: Upload analysis results to GitHub + if: steps.hadolint.outcome == 'success' + uses: github/codeql-action/upload-sarif@5c8a8a642e79153f5d047b10ec1cba1d1cc65699 # v3 + with: + sarif_file: hadolint-results.sarif + wait-for-processing: true \ No newline at end of file diff --git a/.github/workflows/gpg-verify.yml b/.github/workflows/gpg-verify.yml index 79e78d2..d228bf8 100644 --- a/.github/workflows/gpg-verify.yml +++ b/.github/workflows/gpg-verify.yml @@ -1,10 +1,10 @@ # SPDX-License-Identifier: Apache-2.0 -# This GitHub Actions workflow checks that all commits in a pull request (PR) have been verified with GPG signatures. +# This GitHub Actions workflow checks that all commits in a pull request (PR) have a verified cryptographic signature (GPG, SSH, or S/MIME). # Please do not attempt to edit this flow without the direct consent from the DevOps team. This file is managed centrally. -name: GPG Verify +name: Signature Verify on: [pull_request] # Trigger this workflow on pull request events @@ -22,20 +22,20 @@ jobs: - name: Set up environment variables env: - PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} - PR_BASE_REF: ${{ github.event.pull_request.base.ref }} + PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} + PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_REPO: ${{ github.repository }} run: | - printf 'PR_HEAD_REF=%s\n' "$PR_HEAD_REF" >> "$GITHUB_ENV" - printf 'PR_BASE_REF=%s\n' "$PR_BASE_REF" >> "$GITHUB_ENV" + printf 'PR_HEAD_SHA=%s\n' "$PR_HEAD_SHA" >> "$GITHUB_ENV" + printf 'PR_BASE_SHA=%s\n' "$PR_BASE_SHA" >> "$GITHUB_ENV" printf 'GITHUB_TOKEN=%s\n' "$GH_TOKEN" >> "$GITHUB_ENV" printf 'GITHUB_REPOSITORY=%s\n' "$GH_REPO" >> "$GITHUB_ENV" - name: Check GPG verification status # Step to check each commit for GPG signature verification run: | # Get the list of commits in the pull request (head commits not yet in base) - commits=$(git log --pretty=format:%H origin/${PR_BASE_REF}..origin/${PR_HEAD_REF}) + commits=$(git log --pretty=format:%H "$PR_BASE_SHA..$PR_HEAD_SHA") if [[ -z "$commits" ]]; then echo "No commits to verify." @@ -44,16 +44,14 @@ jobs: # Check the GPG verification status of each commit via the GitHub commit API for commit in $commits; do - response=$(curl -s --max-time 10 --fail \ + response=$(curl -sS --max-time 10 --fail \ -H "Authorization: token $GITHUB_TOKEN" \ -H "Accept: application/vnd.github+json" \ - https://api.github.com/repos/$GITHUB_REPOSITORY/commits/$commit) - curl_exit=$? - - if [[ $curl_exit -ne 0 ]]; then + "https://api.github.com/repos/$GITHUB_REPOSITORY/commits/$commit") || { + curl_exit=$? echo "GitHub API request failed for commit $commit (curl exit $curl_exit). Check network or API availability." - exit 1 - fi + exit "$curl_exit" + } verified=$(echo "$response" | jq -r '.commit.verification.verified') diff --git a/.github/workflows/njsscan.yml b/.github/workflows/njsscan.yml index 8c6584b..8714def 100644 --- a/.github/workflows/njsscan.yml +++ b/.github/workflows/njsscan.yml @@ -43,7 +43,8 @@ jobs: with: args: '. --sarif --output results.sarif' - name: Upload njsscan report - uses: github/codeql-action/upload-sarif@5c8a8a642e79153f5d047b10ec1cba1d1cc65699 # v3 - if: hashFiles('results.sarif') != '' + uses: github/codeql-action/upload-sarif@60168ffe96596fce55ee3851b6bb7b2e1ea8dbb0 # v4.35.1 + if: steps.njsscan.outcome == 'success' with: sarif_file: results.sarif + category: njsscan diff --git a/.github/workflows/package-rule-rc.yml b/.github/workflows/package-rule-rc.yml index 07234a3..fd0a46a 100644 --- a/.github/workflows/package-rule-rc.yml +++ b/.github/workflows/package-rule-rc.yml @@ -155,9 +155,15 @@ jobs: - name: Build and push RC Docker image env: + GH_TOKEN: ${{ secrets.GH_TOKEN_LIB }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} run: | + if [[ "$GITHUB_REF" != "refs/heads/dev" ]]; then + echo "::error::RC images must be published from dev. Refusing to push from $GITHUB_REF." + exit 1 + fi + VERSION="${{ steps.rule_version.outputs.VERSION }}" RULE_NUM="${{ inputs.rule_number }}" IMAGE="tazamaorg/rule-${RULE_NUM}" @@ -165,7 +171,10 @@ jobs: echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin # Build once, tag with versioned prerelease and moving :rc pointer - docker build -t "${IMAGE}:${VERSION}" -t "${IMAGE}:rc" "rule-executer-${RULE_NUM}" + docker build \ + --secret id=GH_TOKEN,env=GH_TOKEN \ + -t "${IMAGE}:${VERSION}" -t "${IMAGE}:rc" \ + "rule-executer-${RULE_NUM}" docker push "${IMAGE}:${VERSION}" docker push "${IMAGE}:rc" diff --git a/.github/workflows/package-rule.yml b/.github/workflows/package-rule.yml index 344e798..e8076c7 100644 --- a/.github/workflows/package-rule.yml +++ b/.github/workflows/package-rule.yml @@ -155,9 +155,15 @@ jobs: - name: Build and push stable Docker image env: + GH_TOKEN: ${{ secrets.GH_TOKEN_LIB }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} run: | + if [[ "$GITHUB_REF" != "refs/heads/main" ]]; then + echo "::error::Stable images must be published from main. Refusing to push from $GITHUB_REF." + exit 1 + fi + VERSION="${{ steps.rule_version.outputs.VERSION }}" RULE_NUM="${{ inputs.rule_number }}" IMAGE="tazamaorg/rule-${RULE_NUM}" @@ -165,7 +171,10 @@ jobs: echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin # Build once, tag with versioned and :latest moving pointer - docker build -t "${IMAGE}:${VERSION}" -t "${IMAGE}:latest" "rule-executer-${RULE_NUM}" + docker build \ + --secret id=GH_TOKEN,env=GH_TOKEN \ + -t "${IMAGE}:${VERSION}" -t "${IMAGE}:latest" \ + "rule-executer-${RULE_NUM}" docker push "${IMAGE}:${VERSION}" docker push "${IMAGE}:latest" diff --git a/.github/workflows/sbom.yml b/.github/workflows/sbom.yml index 3a184e6..445721f 100644 --- a/.github/workflows/sbom.yml +++ b/.github/workflows/sbom.yml @@ -36,7 +36,9 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Build the Docker image if: hashFiles('Dockerfile') != '' - run: docker build . --file Dockerfile --tag localbuild/testimage:latest + env: + GH_TOKEN: ${{ secrets.GH_TOKEN_LIB }} + run: docker build --secret id=GH_TOKEN,env=GH_TOKEN --file Dockerfile --tag localbuild/testimage:latest . - name: Scan the image and upload dependency results if: hashFiles('Dockerfile') != '' uses: anchore/sbom-action@bb716408e75840bbb01e839347cd213767269d4a