From cd5adb6e21fbd55f7602e86f71e59229981796e6 Mon Sep 17 00:00:00 2001 From: "Michael Peters Jr." Date: Tue, 1 Sep 2026 11:50:04 -0700 Subject: [PATCH] fix: harden Go workflow templates per zizmor findings Applies zizmor --fix=all across the 5 Go workflow templates (go_app/go_lib pull_requests/push_main, go_app_release), clearing 111 of 115 findings: - unpinned-uses: pin every action to a commit SHA (with the resolved version kept as a trailing comment) - artipacked: set persist-credentials: false on checkout steps that don't need to push back to the repo - template-injection: move ${{ inputs.* }} / ${{ matrix.* }} values out of run: blocks and into env:, so they're passed as data instead of interpolated into shell commands - ref-confusion: resolved as a side effect of pinning to a SHA - cache-poisoning: disable setup-go's default caching in go_app_release.yml, where the same job publishes a Docker image The remaining 4 (adhoc-packages, ad-hoc npm install for commitlint / conventional-changelog tooling) don't have a clean automated fix: the tooling installs into whatever the *caller* repo has checked out, so zizmor's recommended remediation (commit a lockfile) would need to live in every consumer repo, defeating the point of a shared template. Pinned both packages to exact matching versions instead (also fixes a latent bug: commitlint's cli was floating to whatever was current at CI-run time while config-conventional was pinned to a stale v18, an unsupported cli/config version mismatch) and suppressed with a documented `zizmor: ignore[adhoc-packages]`. Also fixes 20 shellcheck SC2086 warnings (unquoted expansions) introduced by the env: extraction above by quoting the new variables where safe. The two *_TAGS variables are deliberately left unquoted with an explanatory comment, since they default to/can be empty and quoting would pass a stray "" argument to `go test` instead of nothing. Part of #76. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/go_app_pull_requests.yml | 72 ++++++++++++++-------- .github/workflows/go_app_push_main.yml | 54 +++++++++++----- .github/workflows/go_app_release.yml | 17 ++--- .github/workflows/go_lib_pull_requests.yml | 61 ++++++++++++------ .github/workflows/go_lib_push_main.yml | 54 +++++++++++----- 5 files changed, 172 insertions(+), 86 deletions(-) diff --git a/.github/workflows/go_app_pull_requests.yml b/.github/workflows/go_app_pull_requests.yml index 5fb9ee8..d8a231b 100644 --- a/.github/workflows/go_app_pull_requests.yml +++ b/.github/workflows/go_app_pull_requests.yml @@ -50,7 +50,9 @@ jobs: outputs: modules: ${{ steps.set-modules.outputs.modules }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false - name: Find Go modules id: set-modules run: | @@ -63,15 +65,16 @@ jobs: runs-on: ubuntu-latest steps: # checkout the commits to lint. - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 with: fetch-depth: 0 + persist-credentials: false # setup node, needed to lint commits. - - uses: actions/setup-node@v1 + - uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e # v1.4.6 with: node-version: 18 # Install needed libraries to lint commits. - - run: npm install --save-dev @commitlint/{config-conventional@v18.6.0,cli} + - run: npm install --save-dev @commitlint/config-conventional@21.2.2 @commitlint/cli@21.2.2 # zizmor: ignore[adhoc-packages] tooling installed into the caller's ephemeral checkout; a committed lockfile would need to live in every consumer repo, defeating the point of a shared template # Lint the commits. - run: npx commitlint --from=${{ github.event.pull_request.base.sha }} lint: @@ -82,12 +85,13 @@ jobs: steps: # Checkout code to build (fetch-depth: 0 needed for only-new-issues diff). - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 with: fetch-depth: 0 + persist-credentials: false # Setup Go. - name: Setup Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version: 'stable' # Use auth to get access to private Git repos for Go code dependencies. @@ -98,7 +102,7 @@ jobs: run: git config --global url."https://${GITHUB_USERNAME}:${TOKEN}@github.com".insteadOf "https://github.com" - name: Run golangci-lint - uses: golangci/golangci-lint-action@v9 + uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0 with: version: latest only-new-issues: true @@ -115,10 +119,12 @@ jobs: steps: # Checkout go code to test. - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 + with: + persist-credentials: false # Setup Go. - name: Setup Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version: 'stable' # Login to Artifact Registry if configured. @@ -126,7 +132,7 @@ jobs: env: ARTIFACT_REGISTRY_JSON_KEY: ${{ secrets.ARTIFACT_REGISTRY_JSON_KEY }} if: ${{ env.ARTIFACT_REGISTRY_JSON_KEY }} - uses: docker/login-action@v2 + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0 with: registry: ${{ secrets.ARTIFACT_REGISTRY }} username: _json_key @@ -152,27 +158,35 @@ jobs: # Build coverage output directories. - name: build coverage output directories run: | - mkdir -p ${{ matrix.module }}/coverage/unit - mkdir -p ${{ matrix.module }}/coverage/int + mkdir -p "${MATRIX_MODULE}/coverage/unit" + mkdir -p "${MATRIX_MODULE}/coverage/int" + env: + MATRIX_MODULE: ${{ matrix.module }} # Run unit tests for the module. - name: go test working-directory: ${{ matrix.module }} run: | - go test -cover --race -v ${{ inputs.GO_TEST_UNIT_TAGS }} ./... \ - -args -test.gocoverdir="${{ github.workspace }}/${{ matrix.module }}/coverage/unit" \ + # GO_TEST_UNIT_TAGS may be empty by default; leave unquoted so an + # empty value disappears instead of being passed as a stray "" arg. + # shellcheck disable=SC2086 + go test -cover --race -v ${INPUTS_GO_TEST_UNIT_TAGS} ./... \ + -args -test.gocoverdir="${{ github.workspace }}/${MATRIX_MODULE}/coverage/unit" \ 2>&1 | tee unit_test_output.txt + env: + INPUTS_GO_TEST_UNIT_TAGS: ${{ inputs.GO_TEST_UNIT_TAGS }} + MATRIX_MODULE: ${{ matrix.module }} - name: Build Unit Test Junit report working-directory: ${{ matrix.module }} run: go-junit-report -in unit_test_output.txt -set-exit-code > junit_report.xml || true - name: Unit Test Report - uses: dorny/test-reporter@v1 + uses: dorny/test-reporter@d61b558e8df85cb60d09ca3e5b09653b4477cea7 # v1 if: success() || failure() with: name: Unit Test Report (${{ matrix.module }}) path: ${{ matrix.module }}/junit_report.xml reporter: java-junit - name: Upload unit test coverage results to Codecov - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: fail_ci_if_error: true # optional (default = false) report_type: test_results @@ -184,14 +198,20 @@ jobs: if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} working-directory: ${{ matrix.module }} run: | - go test -v ${{ inputs.GO_TEST_INTEGRATION_TAGS }} -timeout ${{ inputs.GO_TEST_INTEGRATION_TIMEOUT }} ./... \ + # GO_TEST_INTEGRATION_TAGS may be empty; leave unquoted so an empty + # value disappears instead of being passed as a stray "" arg. + # shellcheck disable=SC2086 + go test -v ${INPUTS_GO_TEST_INTEGRATION_TAGS} -timeout "${INPUTS_GO_TEST_INTEGRATION_TIMEOUT}" ./... \ | tee integration_test_output.txt + env: + INPUTS_GO_TEST_INTEGRATION_TAGS: ${{ inputs.GO_TEST_INTEGRATION_TAGS }} + INPUTS_GO_TEST_INTEGRATION_TIMEOUT: ${{ inputs.GO_TEST_INTEGRATION_TIMEOUT }} - name: Build Integration Test Junit report if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} working-directory: ${{ matrix.module }} run: go-junit-report -in integration_test_output.txt -set-exit-code > junit_integration_report.xml || true - name: Integration Test Report - uses: dorny/test-reporter@v1 + uses: dorny/test-reporter@d61b558e8df85cb60d09ca3e5b09653b4477cea7 # v1 if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} with: name: Integration Test Report (${{ matrix.module }}) @@ -199,7 +219,7 @@ jobs: reporter: java-junit - name: Upload integration test results to Codecov if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: fail_ci_if_error: true # optional (default = false) report_type: test_results @@ -216,7 +236,7 @@ jobs: go tool covdata textfmt -i=./coverage/unit -o coverage.txt fi - name: Upload test coverage results to Codecov - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} report_type: coverage @@ -232,10 +252,12 @@ jobs: steps: # Checkout code to build. - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 + with: + persist-credentials: false # Setup Go. - name: Setup Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version: 'stable' # Use auth to get access to private Git repos for Go code dependencies. @@ -251,7 +273,7 @@ jobs: # Setup docker build arguments. - name: Docker release meta id: release - uses: docker/metadata-action@v4 + uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v4.6.0 with: images: | ${{ github.repository }} @@ -260,10 +282,10 @@ jobs: # Setup Docker builder to do build. - name: Setup Docker Buildx id: buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 # v2.10.0 # Build the app. - name: Build - uses: docker/build-push-action@v3 + uses: docker/build-push-action@1104d471370f9806843c095c1db02b5a90c5f8b6 # v3.3.1 with: push: false provenance: false diff --git a/.github/workflows/go_app_push_main.yml b/.github/workflows/go_app_push_main.yml index 1cc7d57..6df5f31 100644 --- a/.github/workflows/go_app_push_main.yml +++ b/.github/workflows/go_app_push_main.yml @@ -51,7 +51,9 @@ jobs: outputs: modules: ${{ steps.set-modules.outputs.modules }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false - name: Find Go modules id: set-modules run: | @@ -69,10 +71,12 @@ jobs: steps: # Checkout go code to test. - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 + with: + persist-credentials: false # Setup Go. - name: Setup Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version: 'stable' # Login to Artifact Registry if configured. @@ -80,7 +84,7 @@ jobs: env: ARTIFACT_REGISTRY_JSON_KEY: ${{ secrets.ARTIFACT_REGISTRY_JSON_KEY }} if: ${{ env.ARTIFACT_REGISTRY_JSON_KEY }} - uses: docker/login-action@v2 + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0 with: registry: ${{ secrets.ARTIFACT_REGISTRY }} username: _json_key @@ -105,27 +109,35 @@ jobs: # Build coverage output directories. - name: build coverage output directories run: | - mkdir -p ${{ matrix.module }}/coverage/unit - mkdir -p ${{ matrix.module }}/coverage/int + mkdir -p "${MATRIX_MODULE}/coverage/unit" + mkdir -p "${MATRIX_MODULE}/coverage/int" + env: + MATRIX_MODULE: ${{ matrix.module }} # Run unit tests for the module. - name: go test working-directory: ${{ matrix.module }} run: | - go test -cover --race -v ${{ inputs.GO_TEST_UNIT_TAGS }} ./... \ - -args -test.gocoverdir="${{ github.workspace }}/${{ matrix.module }}/coverage/unit" \ + # GO_TEST_UNIT_TAGS may be empty by default; leave unquoted so an + # empty value disappears instead of being passed as a stray "" arg. + # shellcheck disable=SC2086 + go test -cover --race -v ${INPUTS_GO_TEST_UNIT_TAGS} ./... \ + -args -test.gocoverdir="${{ github.workspace }}/${MATRIX_MODULE}/coverage/unit" \ 2>&1 | tee unit_test_output.txt + env: + INPUTS_GO_TEST_UNIT_TAGS: ${{ inputs.GO_TEST_UNIT_TAGS }} + MATRIX_MODULE: ${{ matrix.module }} - name: Build Unit Test Junit report working-directory: ${{ matrix.module }} run: go-junit-report -in unit_test_output.txt -set-exit-code > junit_report.xml || true - name: Unit Test Report - uses: dorny/test-reporter@v1 + uses: dorny/test-reporter@d61b558e8df85cb60d09ca3e5b09653b4477cea7 # v1 if: success() || failure() with: name: Unit Test Report (${{ matrix.module }}) path: ${{ matrix.module }}/junit_report.xml reporter: java-junit - name: Upload unit test results to Codecov - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: fail_ci_if_error: true # optional (default = false) report_type: test_results @@ -137,14 +149,20 @@ jobs: if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} working-directory: ${{ matrix.module }} run: | - go test -v ${{ inputs.GO_TEST_INTEGRATION_TAGS }} -timeout ${{ inputs.GO_TEST_INTEGRATION_TIMEOUT }} ./... \ + # GO_TEST_INTEGRATION_TAGS may be empty; leave unquoted so an empty + # value disappears instead of being passed as a stray "" arg. + # shellcheck disable=SC2086 + go test -v ${INPUTS_GO_TEST_INTEGRATION_TAGS} -timeout "${INPUTS_GO_TEST_INTEGRATION_TIMEOUT}" ./... \ | tee integration_test_output.txt + env: + INPUTS_GO_TEST_INTEGRATION_TAGS: ${{ inputs.GO_TEST_INTEGRATION_TAGS }} + INPUTS_GO_TEST_INTEGRATION_TIMEOUT: ${{ inputs.GO_TEST_INTEGRATION_TIMEOUT }} - name: Build Integration Test Junit report if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} working-directory: ${{ matrix.module }} run: go-junit-report -in integration_test_output.txt -set-exit-code > junit_integration_report.xml || true - name: Integration Test Report - uses: dorny/test-reporter@v1 + uses: dorny/test-reporter@d61b558e8df85cb60d09ca3e5b09653b4477cea7 # v1 if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} with: name: Integration Test Report (${{ matrix.module }}) @@ -152,7 +170,7 @@ jobs: reporter: java-junit - name: Upload integration test results to Codecov if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: fail_ci_if_error: true # optional (default = false) report_type: test_results @@ -169,7 +187,7 @@ jobs: go tool covdata textfmt -i=./coverage/unit -o coverage.txt fi - name: Upload test coverage results to Codecov - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} files: ${{ matrix.module }}/coverage.txt @@ -185,15 +203,17 @@ jobs: steps: # Checkout code to release. - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false # Setup Node needed to create release. - name: Setup Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e # v1.4.6 with: node-version: 18 # Add plugin to make the changelog for the release. - name: Add plugin for conventional commits - run: npm install conventional-changelog-conventionalcommits@6 + run: npm install conventional-changelog-conventionalcommits@6.1.0 # zizmor: ignore[adhoc-packages] tooling installed into the caller's ephemeral checkout; a committed lockfile would need to live in every consumer repo, defeating the point of a shared template working-directory: ./.github/workflows # Create the release. - name: Release to GitHub diff --git a/.github/workflows/go_app_release.yml b/.github/workflows/go_app_release.yml index f5a2d0c..d77fb60 100644 --- a/.github/workflows/go_app_release.yml +++ b/.github/workflows/go_app_release.yml @@ -53,12 +53,15 @@ jobs: runs-on: ubuntu-latest steps: # Checkout code needed to build docker image. - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 + with: + persist-credentials: false # Setup Go. - name: Setup Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version: 'stable' + cache: false # Reclaim disk from preinstalled toolchains so large builds have headroom. - name: Free up runner disk space if: ${{ inputs.FREE_DISK_SPACE }} @@ -91,7 +94,7 @@ jobs: # Create docker image meta data. Docker tags include the Git tag itself and the sematic version parsing of that tag if possible. - name: Docker release meta id: release - uses: docker/metadata-action@v4 + uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v4.6.0 with: images: | ${{ env.ARTIFACT_REGISTRY_IMAGE_NAME }} @@ -105,21 +108,21 @@ jobs: env: ARTIFACT_REGISTRY_JSON_KEY: ${{ secrets.ARTIFACT_REGISTRY_JSON_KEY }} if: ${{ env.ARTIFACT_REGISTRY_JSON_KEY }} - uses: docker/login-action@v2 + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0 with: registry: ${{ secrets.ARTIFACT_REGISTRY }} username: _json_key password: ${{ secrets.ARTIFACT_REGISTRY_JSON_KEY }} # Setup QEMU needed to build arm64 images. - name: Setup QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0 # Setup Docker builder needed to build multi-architectural images. - name: Setup Docker Buildx id: buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 # v2.10.0 # Build and push the image. - name: Build and Push to Artifact Registry - uses: docker/build-push-action@v3 + uses: docker/build-push-action@1104d471370f9806843c095c1db02b5a90c5f8b6 # v3.3.1 with: outputs: type=registry,oci-mediatypes=${{ inputs.LEGACY_DOCKER_MEDIATYPES && 'false' || 'true' }} provenance: false diff --git a/.github/workflows/go_lib_pull_requests.yml b/.github/workflows/go_lib_pull_requests.yml index 27b5990..f6ccfde 100644 --- a/.github/workflows/go_lib_pull_requests.yml +++ b/.github/workflows/go_lib_pull_requests.yml @@ -54,7 +54,9 @@ jobs: outputs: modules: ${{ steps.set-modules.outputs.modules }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false - name: Find Go modules id: set-modules run: | @@ -67,15 +69,16 @@ jobs: runs-on: ubuntu-latest steps: # checkout the commits to lint. - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 with: fetch-depth: 0 + persist-credentials: false # setup node, needed to lint commits. - - uses: actions/setup-node@v1 + - uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e # v1.4.6 with: node-version: 18 # Install needed libraries to lint commits. - - run: npm install --save-dev @commitlint/{config-conventional@v18.6.0,cli} + - run: npm install --save-dev @commitlint/config-conventional@21.2.2 @commitlint/cli@21.2.2 # zizmor: ignore[adhoc-packages] tooling installed into the caller's ephemeral checkout; a committed lockfile would need to live in every consumer repo, defeating the point of a shared template # Lint the commits. - run: npx commitlint --from=${{ github.event.pull_request.base.sha }} lint: @@ -87,10 +90,12 @@ jobs: steps: # Checkout code to build. - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 + with: + persist-credentials: false # Setup Go. - name: Setup Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version: 'stable' # Use auth to get access to private Git repos for Go code dependencies. @@ -102,7 +107,7 @@ jobs: git config --global url."https://${GITHUB_USERNAME}:${TOKEN}@github.com".insteadOf "https://github.com" - name: Run golangci-lint - uses: golangci/golangci-lint-action@v9 + uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0 with: version: latest args: --timeout=5m --enable=bodyclose @@ -118,10 +123,12 @@ jobs: steps: # Checkout go code to test. - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 + with: + persist-credentials: false # Setup Go. - name: Setup Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version: 'stable' # Login to Artifact Registry if configured. @@ -129,7 +136,7 @@ jobs: env: ARTIFACT_REGISTRY_JSON_KEY: ${{ secrets.ARTIFACT_REGISTRY_JSON_KEY }} if: ${{ env.ARTIFACT_REGISTRY_JSON_KEY }} - uses: docker/login-action@v2 + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0 with: registry: ${{ secrets.ARTIFACT_REGISTRY }} username: _json_key @@ -155,27 +162,35 @@ jobs: # Build coverage output directories. - name: build coverage output directories run: | - mkdir -p ${{ matrix.module }}/coverage/unit - mkdir -p ${{ matrix.module }}/coverage/int + mkdir -p "${MATRIX_MODULE}/coverage/unit" + mkdir -p "${MATRIX_MODULE}/coverage/int" + env: + MATRIX_MODULE: ${{ matrix.module }} # Run unit tests for the module. - name: go test working-directory: ${{ matrix.module }} run: | - go test -cover --race -v ${{ inputs.GO_TEST_UNIT_TAGS }} ./... \ - -args -test.gocoverdir="${{ github.workspace }}/${{ matrix.module }}/coverage/unit" \ + # GO_TEST_UNIT_TAGS may be empty by default; leave unquoted so an + # empty value disappears instead of being passed as a stray "" arg. + # shellcheck disable=SC2086 + go test -cover --race -v ${INPUTS_GO_TEST_UNIT_TAGS} ./... \ + -args -test.gocoverdir="${{ github.workspace }}/${MATRIX_MODULE}/coverage/unit" \ 2>&1 | tee unit_test_output.txt + env: + INPUTS_GO_TEST_UNIT_TAGS: ${{ inputs.GO_TEST_UNIT_TAGS }} + MATRIX_MODULE: ${{ matrix.module }} - name: Build Unit Test Junit report working-directory: ${{ matrix.module }} run: go-junit-report -in unit_test_output.txt -set-exit-code > junit_report.xml || true - name: Unit Test Report - uses: dorny/test-reporter@v1 + uses: dorny/test-reporter@d61b558e8df85cb60d09ca3e5b09653b4477cea7 # v1 if: success() || failure() with: name: Unit Test Report (${{ matrix.module }}) path: ${{ matrix.module }}/junit_report.xml reporter: java-junit - name: Upload unit test coverage results to Codecov - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: fail_ci_if_error: true # optional (default = false) report_type: test_results @@ -187,14 +202,20 @@ jobs: if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} working-directory: ${{ matrix.module }} run: | - go test -v ${{ inputs.GO_TEST_INTEGRATION_TAGS }} -timeout ${{ inputs.GO_TEST_INTEGRATION_TIMEOUT }} ./... \ + # GO_TEST_INTEGRATION_TAGS may be empty; leave unquoted so an empty + # value disappears instead of being passed as a stray "" arg. + # shellcheck disable=SC2086 + go test -v ${INPUTS_GO_TEST_INTEGRATION_TAGS} -timeout "${INPUTS_GO_TEST_INTEGRATION_TIMEOUT}" ./... \ | tee integration_test_output.txt + env: + INPUTS_GO_TEST_INTEGRATION_TAGS: ${{ inputs.GO_TEST_INTEGRATION_TAGS }} + INPUTS_GO_TEST_INTEGRATION_TIMEOUT: ${{ inputs.GO_TEST_INTEGRATION_TIMEOUT }} - name: Build Integration Test Junit report if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} working-directory: ${{ matrix.module }} run: go-junit-report -in integration_test_output.txt -set-exit-code > junit_integration_report.xml || true - name: Integration Test Report - uses: dorny/test-reporter@v1 + uses: dorny/test-reporter@d61b558e8df85cb60d09ca3e5b09653b4477cea7 # v1 if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} with: name: Integration Test Report (${{ matrix.module }}) @@ -202,7 +223,7 @@ jobs: reporter: java-junit - name: Upload integration test coverage results to Codecov if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: fail_ci_if_error: true # optional (default = false) report_type: test_results @@ -219,7 +240,7 @@ jobs: go tool covdata textfmt -i=./coverage/unit -o coverage.txt fi - name: Upload test coverage results to Codecov - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} report_type: coverage diff --git a/.github/workflows/go_lib_push_main.yml b/.github/workflows/go_lib_push_main.yml index ee80f2f..900b705 100644 --- a/.github/workflows/go_lib_push_main.yml +++ b/.github/workflows/go_lib_push_main.yml @@ -55,7 +55,9 @@ jobs: outputs: modules: ${{ steps.set-modules.outputs.modules }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false - name: Find Go modules id: set-modules run: | @@ -73,10 +75,12 @@ jobs: steps: # Checkout go code to test. - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 + with: + persist-credentials: false # Setup Go. - name: Setup Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version: 'stable' # Login to Artifact Registry if configured. @@ -84,7 +88,7 @@ jobs: env: ARTIFACT_REGISTRY_JSON_KEY: ${{ secrets.ARTIFACT_REGISTRY_JSON_KEY }} if: ${{ env.ARTIFACT_REGISTRY_JSON_KEY }} - uses: docker/login-action@v2 + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0 with: registry: ${{ secrets.ARTIFACT_REGISTRY }} username: _json_key @@ -110,27 +114,35 @@ jobs: # Build coverage output directories. - name: build coverage output directories run: | - mkdir -p ${{ matrix.module }}/coverage/unit - mkdir -p ${{ matrix.module }}/coverage/int + mkdir -p "${MATRIX_MODULE}/coverage/unit" + mkdir -p "${MATRIX_MODULE}/coverage/int" + env: + MATRIX_MODULE: ${{ matrix.module }} # Run unit tests for the module. - name: go test working-directory: ${{ matrix.module }} run: | - go test -cover --race -v ${{ inputs.GO_TEST_UNIT_TAGS }} ./... \ - -args -test.gocoverdir="${{ github.workspace }}/${{ matrix.module }}/coverage/unit" \ + # GO_TEST_UNIT_TAGS may be empty by default; leave unquoted so an + # empty value disappears instead of being passed as a stray "" arg. + # shellcheck disable=SC2086 + go test -cover --race -v ${INPUTS_GO_TEST_UNIT_TAGS} ./... \ + -args -test.gocoverdir="${{ github.workspace }}/${MATRIX_MODULE}/coverage/unit" \ 2>&1 | tee unit_test_output.txt + env: + INPUTS_GO_TEST_UNIT_TAGS: ${{ inputs.GO_TEST_UNIT_TAGS }} + MATRIX_MODULE: ${{ matrix.module }} - name: Build Unit Test Junit report working-directory: ${{ matrix.module }} run: go-junit-report -in unit_test_output.txt -set-exit-code > junit_report.xml || true - name: Unit Test Report - uses: dorny/test-reporter@v1 + uses: dorny/test-reporter@d61b558e8df85cb60d09ca3e5b09653b4477cea7 # v1 if: success() || failure() with: name: Unit Test Report (${{ matrix.module }}) path: ${{ matrix.module }}/junit_report.xml reporter: java-junit - name: Upload unit test coverage results to Codecov - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: fail_ci_if_error: true # optional (default = false) report_type: test_results @@ -142,14 +154,20 @@ jobs: if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} working-directory: ${{ matrix.module }} run: | - go test -v ${{ inputs.GO_TEST_INTEGRATION_TAGS }} -timeout ${{ inputs.GO_TEST_INTEGRATION_TIMEOUT }} ./... \ + # GO_TEST_INTEGRATION_TAGS may be empty; leave unquoted so an empty + # value disappears instead of being passed as a stray "" arg. + # shellcheck disable=SC2086 + go test -v ${INPUTS_GO_TEST_INTEGRATION_TAGS} -timeout "${INPUTS_GO_TEST_INTEGRATION_TIMEOUT}" ./... \ | tee integration_test_output.txt + env: + INPUTS_GO_TEST_INTEGRATION_TAGS: ${{ inputs.GO_TEST_INTEGRATION_TAGS }} + INPUTS_GO_TEST_INTEGRATION_TIMEOUT: ${{ inputs.GO_TEST_INTEGRATION_TIMEOUT }} - name: Build Integration Test Junit report if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} working-directory: ${{ matrix.module }} run: go-junit-report -in integration_test_output.txt -set-exit-code > junit_integration_report.xml || true - name: Integration Test Report - uses: dorny/test-reporter@v1 + uses: dorny/test-reporter@d61b558e8df85cb60d09ca3e5b09653b4477cea7 # v1 if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} with: name: Integration Test Report (${{ matrix.module }}) @@ -157,7 +175,7 @@ jobs: reporter: java-junit - name: Upload integration test coverage results to Codecov if: ${{ inputs.GO_TEST_INTEGRATION_ENABLED }} - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: fail_ci_if_error: true # optional (default = false) report_type: test_results @@ -174,7 +192,7 @@ jobs: go tool covdata textfmt -i=./coverage/unit -o coverage.txt fi - name: Upload test coverage results to Codecov - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} report_type: coverage @@ -191,15 +209,17 @@ jobs: steps: # Checkout code to release. - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false # Setup Node needed to create release. - name: Setup Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e # v1.4.6 with: node-version: 18 # Add plugin to make the changelog for the release. - name: Add plugin for conventional commits - run: npm install conventional-changelog-conventionalcommits@6 + run: npm install conventional-changelog-conventionalcommits@6.1.0 # zizmor: ignore[adhoc-packages] tooling installed into the caller's ephemeral checkout; a committed lockfile would need to live in every consumer repo, defeating the point of a shared template working-directory: ./.github/workflows # Create the release. - name: Release to GitHub