Skip to content

ci: resolve shellcheck-glob from .shellcheck-scope in pr-validation - #349

Open
Danathar wants to merge 2 commits into
projectbluefin:mainfrom
Danathar:ci/shellcheck-scope-pr-validation
Open

Danathar wants to merge 2 commits into
projectbluefin:mainfrom
Danathar:ci/shellcheck-scope-pr-validation

Conversation

@Danathar

Copy link
Copy Markdown

Summary

Wires .github/workflows/pr-validation.yml to dynamically resolve the .shellcheck-scope manifest into the shellcheck-glob input of bootc-build/validate-pr. This completes the CI half of #324 that was left unapplied when #326 landed (due to the hive GitHub App lacking workflows permissions).

Changes

  1. .github/workflows/pr-validation.yml:
    • Adds step Resolve shell lint scope (id: shell-scope) that reads .shellcheck-scope (stripping comments and blank lines) and emits glob into $GITHUB_OUTPUT.
    • Passes ${{ steps.shell-scope.outputs.glob }} to validate-pr's shellcheck-glob input.
  2. .shellcheck-scope:
    • Updates the header comment to document that .github/workflows/pr-validation.yml resolves this file.
  3. tests/unit/shellcheck-scope_test.bats:
    • Replaces test 6 ("documents the open gap") with the assertion verifying that shellcheck-glob: in pr-validation.yml resolves from steps.shell-scope.outputs.glob.

Verification

  • bats tests/unit/shellcheck-scope_test.bats passes (7/7 tests green).
  • actionlint .github/workflows/pr-validation.yml passes cleanly.
  • python3 -c "import yaml; yaml.safe_load(open('.github/workflows/pr-validation.yml'))" passes cleanly.
  • just check passes cleanly.
  • Shellcheck verified passing on .github/actions/check-token-health/check_token_health.sh and build/*.sh.

Fixes #324

— hive: backend=agy

Wires pr-validation.yml to dynamically resolve the .shellcheck-scope manifest
into the shellcheck-glob input of bootc-build/validate-pr, completing the CI
half of projectbluefin#324 that was left unapplied in projectbluefin#326.

This ensures that CI shellchecks all scripts declared in .shellcheck-scope,
including .github/actions/check-token-health/check_token_health.sh, aligning
CI linting with local `just lint`.

Also updates:
- .shellcheck-scope comments documenting that pr-validation.yml resolves it
- tests/unit/shellcheck-scope_test.bats test 6 assertion to verify the wiring

Fixes projectbluefin#324

Signed-off-by: Danathar <Danathar@users.noreply.github.com>

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change does what it says — but a CI change that CI has never run is not verifiable

What I confirmed

The resolver produces the right string. Running your sed pipeline against this branch's .shellcheck-scope:

$ sed 's/#.*//' .shellcheck-scope | tr -d '[:blank:]' | grep -v '^$' | tr '\n' ' ' | sed 's/[[:space:]]*$//'
build/*.sh .github/actions/**/*.sh

And the scope genuinely is wider than the hardcoded build/*.sh it replaces — just lint on this branch lints six files, one of which CI has never seen:

Shellchecking 6 scripts:
  build/00-image-info.sh
  build/10-build.sh
  build/clean-stage.sh
  build/copr-helpers.sh
  build/validate-brewfiles.sh
  .github/actions/check-token-health/check_token_health.sh   <-- previously unlinted in CI

All six pass (just lint exit 0), so widening the scope will not immediately turn CI red. Gates on this branch merged into origin/main @ 1db684b: bats tests/unit 180/180, just lint 0, just check 0 — matching the baseline on unmodified main.

The replacement test is also non-vacuous: it greps pr-validation.yml for steps.shell-scope.outputs.glob and fails if absent, so deleting the workflow wiring breaks it. Good — the old test pinned the gap, the new one pins the fix.

The blocker

No CI has executed on this PR. get_check_runs returns total_count: 0. The underlying run:

Unit Tests, run_number 54, head_sha 62eadc8
  event: pull_request, status: completed, conclusion: action_required

action_required = created with zero jobs, waiting on maintainer approval of fork workflow runs. For most PRs that is an inconvenience. For this one it is disqualifying on its own terms: the entire content of this PR is a change to what CI does, and no one has observed CI doing it. My just lint run is a local approximation of a different code path — the real question is what projectbluefin/actions/bootc-build/validate-pr does when handed this string, and that has not happened once.

Please get the fork run approved and confirm validate is green before merging.

The thing I would actually check when that run happens

.github/actions/**/*.sh relies on globstar. Whether ** crosses directories depends entirely on how validate-pr consumes shellcheck-glob — if it word-splits the input and expands it in a shell without shopt -s globstar, then ** degrades to a single * and the pattern silently becomes .github/actions/*/*.sh.

Today that happens to still match the one file you care about (check-token-health/check_token_health.sh is exactly one level deep), so it will look like it works. It will stop working the first time someone adds .github/actions/foo/bar/baz.sh, and it will fail silently — by linting less, which is the precise failure this manifest exists to prevent.

.shellcheck-scope is explicitly documented as being expanded "with shopt -s globstar nullglob", and the Justfile:shell-sources recipe does set both. The workflow half now bypasses that recipe entirely. Two options:

  • Have the workflow step call just shell-sources and join its output, so both consumers share one expansion implementation; or
  • Keep the sed pipeline but add a test asserting the CI-resolved list equals the just shell-sources list, so drift between the two is caught.

Relatedly, nullglob matters too: if a declared pattern ever matches nothing, an unexpanded glob gets passed to shellcheck as a literal filename and the step fails with a confusing "No such file". shell-sources handles this ([[ -f "$f" ]]); the workflow path does not.

Not blocking — the current scope works — but the whole point of #324 is one source of truth, and this lands two parsers for one manifest.


Generated by Claude Code

hanthor's review on projectbluefin#349 confirmed the workflow's sed-based resolver
produces the right glob string today, but pointed out it is a second,
independent reimplementation of what `just shell-sources` already
does -- and that the two could silently diverge (e.g. a `**` pattern
degrading if one side's shell lacks globstar/nullglob), defeating the
point of projectbluefin#324's single-source-of-truth manifest.

Install `just` (same pinned/verified pattern already used in
unit-tests.yml) and call `just shell-sources` directly, joining its
expanded file list for the shellcheck-glob input instead of deriving
a glob string by hand. Verified this produces the same six files
locally, that `shellcheck` accepts the pre-expanded list identically
to how projectbluefin/actions/bootc-build/validate-pr's own
`shopt -s globstar nullglob; shellcheck ${SHELLCHECK_GLOB}` step
would expand the old glob string, and that `just lint`, `just check`,
and the full 180-test bats suite still pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LNgJ8VMdoqzGequbxsP2Kc
@Danathar

Copy link
Copy Markdown
Author

@hanthor — pushed in 9263a24: the workflow now installs just (same pinned/verified pattern already used in unit-tests.yml) and calls just shell-sources directly instead of re-deriving the glob with its own sed pipeline — one expansion implementation for both just lint and CI, per your suggestion.

Verified: the pre-expanded file list is accepted identically by validate-pr's own shopt -s globstar nullglob; shellcheck ${SHELLCHECK_GLOB} step (checked the actual action source — that input already sets globstar/nullglob itself, so the degrade-to-*-without-globstar risk doesn't apply to this particular input either way, but the dedup is still the right call). just lint, just check, and the full 180-test suite all still pass.

@kubestellar-hive kubestellar-hive Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — no findings from this perspective.

— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.78

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants