refactor(govulncheck): convert reusable workflow to composite action#109
Merged
sydorovdmytro merged 1 commit intomainfrom Apr 15, 2026
Merged
Conversation
The reusable workflow couldn't resolve its own ref at call time: `github.workflow_ref` and `github.workflow_sha` both leak the caller's context under `workflow_call`, so the sparse-checkout of `loft-sh/github-actions` for the scripts failed with `fatal: couldn't find remote ref refs/pull/N/merge` on any PR-triggered call (observed in loft-enterprise#6676). `github.job_workflow_sha` is documented but only populated as an OIDC claim, not in the expression context (actions/runner#2417). Converting to a composite action sidesteps the problem entirely: composite actions are checked out to `github.action_path` at the correct ref automatically, no ref resolution needed. Same pattern already used by `ci-test-notify`, `release-notification`, `linear-release-sync`, `semver-validation`. Caller contract change (v1, breaking): - `runs-on` input removed; caller sets it on their job - `timeout-minutes` input removed; composite steps can't timeout, caller sets job-level `timeout-minutes` - `secrets:` (`gh-access-token`, `slack-webhook-url`) → inputs; actions can't declare `secrets:` — caller interpolates `${{ secrets.* }}` - Caller supplies their own `actions/checkout` step + fork guard Since no caller currently uses `govulncheck/v1`, the tag can be moved forward to this commit without migration fallout. - Move `.github/scripts/govulncheck/` → `.github/actions/govulncheck/` - Delete `.github/workflows/govulncheck.yaml` - Update `test-govulncheck.yaml` path filter + test target - Extend renovate customManager to scan `action.yml` inputs - Rewrite README section for the composite-action contract Refs DEVOPS-772
f8890e0 to
8318e89
Compare
sydorovdmytro
added a commit
that referenced
this pull request
Apr 15, 2026
Reusable workflows can't resolve their own ref from the `github` context: both `github.workflow_ref` and `github.workflow_sha` leak the caller under `workflow_call`, so the sparse-checkout of `loft-sh/github-actions` for the scripts fails on any PR-triggered call (observed in loft-enterprise#6676 for the sibling govulncheck workflow). `github.job_workflow_sha` is documented but only exposed as an OIDC claim (actions/runner#2417). Ship this as a composite action from the start — the same pattern already used by ci-test-notify, release-notification, linear-release-sync, semver-validation, and (post-#109) govulncheck: composite actions get `github.action_path` and the repo is auto-checked-out at the correct ref, so no ref resolution needed. One action with a `mode: check|report` input instead of two: both flows share the same setup (setup-go, install go-licenses, private- repo git auth) — only the trailing steps differ (`go-licenses check` vs `go-licenses report` + peter-evans/create-pull-request). The same `run.sh` with check/report subcommands ports unchanged, keeping all 17 bats tests valid. Caller contract (each caller provides their own checkout + fork guard + timeout-minutes at job level): jobs: check: runs-on: ubuntu-latest if: github.repository_owner == 'loft-sh' permissions: contents: read timeout-minutes: 15 steps: - uses: actions/checkout@... with: {persist-credentials: false} - uses: loft-sh/github-actions/.github/actions/go-licenses@go-licenses/v1 with: mode: check # or: report ... - `.github/actions/go-licenses/action.yml` — composite action - `.github/actions/go-licenses/run.sh` — moved from `.github/scripts/` - `.github/actions/go-licenses/test/run.bats` — moved, 17/17 pass - `.github/actions/go-licenses/README.md` — usage + inputs - `.github/workflows/go-licenses-check.yaml` — deleted - `.github/workflows/go-licenses-report.yaml` — deleted - `test-go-licenses.yaml` + `Makefile` — retargeted at the new path Refs DEVOPS-772
6 tasks
sydorovdmytro
added a commit
that referenced
this pull request
Apr 15, 2026
Reusable workflows can't resolve their own ref from the `github` context: both `github.workflow_ref` and `github.workflow_sha` leak the caller under `workflow_call`, so the sparse-checkout of `loft-sh/github-actions` for the scripts fails on any PR-triggered call (observed in loft-enterprise#6676 for the sibling govulncheck workflow). `github.job_workflow_sha` is documented but only exposed as an OIDC claim (actions/runner#2417). Ship this as a composite action from the start — the same pattern already used by ci-test-notify, release-notification, linear-release-sync, semver-validation, and (post-#109) govulncheck: composite actions get `github.action_path` and the repo is auto-checked-out at the correct ref, so no ref resolution needed. One action with a `mode: check|report` input instead of two: both flows share the same setup (setup-go, install go-licenses, private- repo git auth) — only the trailing steps differ (`go-licenses check` vs `go-licenses report` + peter-evans/create-pull-request). The same `run.sh` with check/report subcommands ports unchanged, keeping all 17 bats tests valid. Caller contract (each caller provides their own checkout + fork guard + timeout-minutes at job level): jobs: check: runs-on: ubuntu-latest if: github.repository_owner == 'loft-sh' permissions: contents: read timeout-minutes: 15 steps: - uses: actions/checkout@... with: {persist-credentials: false} - uses: loft-sh/github-actions/.github/actions/go-licenses@go-licenses/v1 with: mode: check # or: report ... - `.github/actions/go-licenses/action.yml` — composite action - `.github/actions/go-licenses/run.sh` — moved from `.github/scripts/` - `.github/actions/go-licenses/test/run.bats` — moved, 17/17 pass - `.github/actions/go-licenses/README.md` — usage + inputs - `.github/workflows/go-licenses-check.yaml` — deleted - `.github/workflows/go-licenses-report.yaml` — deleted - `test-go-licenses.yaml` + `Makefile` — retargeted at the new path Refs DEVOPS-772
sydorovdmytro
added a commit
that referenced
this pull request
Apr 15, 2026
…action The reusable workflow couldn't resolve its own ref at call time. `github.workflow_ref` and `github.workflow_sha` both leak the caller's context under `workflow_call` — the sparse-checkout of `loft-sh/github-actions` for the scripts used the parsed workflow_ref (`refs/heads/main` for push events, `refs/tags/vX` for releases), which: - On push-to-main: happened to resolve because main/main lined up, but silently pulled scripts from `main` rather than the pinned `@publish-helm-chart/v1` — tag pinning was a lie. - On release events: the caller's `refs/tags/v4.6.0` doesn't exist in `loft-sh/github-actions`, so the first release-triggered caller (pending loft-enterprise release-chart migration) would fail with `fatal: couldn't find remote ref`. Converting to a composite action sidesteps both — `github.action_path` is correct automatically, tag pinning is real, no release-event breakage. Same pattern already used by ci-test-notify, release-notification, linear-release-sync, semver-validation, govulncheck (#109), and go-licenses (#100). Caller contract change (v2, breaking): - `ref` input removed — caller checks out the desired ref themselves - `runs-on` / `timeout-minutes` / `permissions` set by caller - `secrets: chart-museum-*` → regular inputs (actions can't declare secrets; caller interpolates `${{ secrets.* }}`) - Caller supplies `actions/checkout` before the action Only caller today is loft-enterprise push-head-images.yaml (merged via #6673 yesterday) — one migration PR follows. - `.github/scripts/publish-helm-chart/` → `.github/actions/publish-helm-chart/` - Delete `.github/workflows/publish-helm-chart.yaml` - Retarget `test-publish-helm-chart.yaml` path filter + test target - Rewrite README section for the composite-action contract Refs DEVOPS-772
6 tasks
sydorovdmytro
added a commit
that referenced
this pull request
Apr 15, 2026
…action (#115) The reusable workflow couldn't resolve its own ref at call time. `github.workflow_ref` and `github.workflow_sha` both leak the caller's context under `workflow_call` — the sparse-checkout of `loft-sh/github-actions` for the scripts used the parsed workflow_ref (`refs/heads/main` for push events, `refs/tags/vX` for releases), which: - On push-to-main: happened to resolve because main/main lined up, but silently pulled scripts from `main` rather than the pinned `@publish-helm-chart/v1` — tag pinning was a lie. - On release events: the caller's `refs/tags/v4.6.0` doesn't exist in `loft-sh/github-actions`, so the first release-triggered caller (pending loft-enterprise release-chart migration) would fail with `fatal: couldn't find remote ref`. Converting to a composite action sidesteps both — `github.action_path` is correct automatically, tag pinning is real, no release-event breakage. Same pattern already used by ci-test-notify, release-notification, linear-release-sync, semver-validation, govulncheck (#109), and go-licenses (#100). Caller contract change (v2, breaking): - `ref` input removed — caller checks out the desired ref themselves - `runs-on` / `timeout-minutes` / `permissions` set by caller - `secrets: chart-museum-*` → regular inputs (actions can't declare secrets; caller interpolates `${{ secrets.* }}`) - Caller supplies `actions/checkout` before the action Only caller today is loft-enterprise push-head-images.yaml (merged via #6673 yesterday) — one migration PR follows. - `.github/scripts/publish-helm-chart/` → `.github/actions/publish-helm-chart/` - Delete `.github/workflows/publish-helm-chart.yaml` - Retarget `test-publish-helm-chart.yaml` path filter + test target - Rewrite README section for the composite-action contract Refs DEVOPS-772
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The reusable workflow couldn't resolve its own ref at call time. Both
github.workflow_refandgithub.workflow_shaleak the caller's context underworkflow_call, so the sparse-checkout ofloft-sh/github-actions(to getrun.sh) failed with:on any PR-triggered call — observed in loft-enterprise#6676.
github.job_workflow_shais documented but only populated as an OIDC claim, not in the expression context (actions/runner#2417).Converting to a composite action sidesteps the problem entirely: composite actions are checked out to
github.action_pathat the correct ref automatically, no ref resolution needed. This is already the pattern used byci-test-notify,release-notification,linear-release-sync, andsemver-validation.What changed
.github/scripts/govulncheck/→.github/actions/govulncheck/(code + bats tests moved, unchanged).github/actions/govulncheck/action.yml— new composite action.github/workflows/govulncheck.yaml— deleted (the broken reusable workflow).github/workflows/test-govulncheck.yaml— path filter + test target updatedMakefile,README.md,renovate.json— updated to reflect the new locationCaller contract change (breaking, but no callers yet)
uses:at job leveluses:at step levelruns-oninputtimeout-minutesinputsecrets: gh-access-token, slack-webhook-urlsecrets:block)if: github.repository_owner == 'loft-sh'actions/checkoutfirstSince no caller currently uses
govulncheck/v1, the tag can be moved forward to this commit after merge without migration fallout. loft-enterprise#6676 will be updated to call the composite action.Test plan
make test-govulncheck— 11/11 bats tests passmake lint— actionlint + zizmor cleantest-govulncheck.yamlCI job green on this PRgovulncheck/v1tag; update loft-enterprise#6676 callerRefs DEVOPS-772