Skip to content

chore(github-actions): update ppat/github-workflows (v4.4.0 -> v5.0.1) - #877

Merged
ppat merged 2 commits into
mainfrom
lint-uplift/coder-gw-v5
Aug 20, 2026
Merged

chore(github-actions): update ppat/github-workflows (v4.4.0 -> v5.0.1)#877
ppat merged 2 commits into
mainfrom
lint-uplift/coder-gw-v5

Conversation

@ppat

@ppat ppat commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Summary

Bumps every ppat/github-workflows ref from v4.4.0 to v5.0.1
(667d20d10c8756b11feeab1ee691825ccea8f991, verified to resolve to the
v5.0.1 tag) and fixes what v5 breaks in this repo, minimally.

Supersedes #876 (chore(github-actions): update ppat/github-workflows (v4.4.0 -> v5.0.0)) — left open/untouched per instructions; please close
it manually once this merges.

Per standing instruction for this batch: this PR does not touch
commitlint.config.js/scope-enum and does not bump the
renovate-presets pin (stays v0.2.1).

Refs bumped (14 occurrences, all confirmed gone from the old pin)

1e8ca1b00b6e69bdf5aef8b33111c594c051ff65 # v4.4.0667d20d10c8756b11feeab1ee691825ccea8f991 # v5.0.1

  • .github/workflows/renovate.yaml — 1x (renovate.yaml)
  • .github/workflows/lint.yaml — 11x (detect-changed-files.yaml,
    lint-commit-messages.yaml, lint-github-actions.yaml,
    lint-markdown.yaml, lint-hadolint.yaml, lint-pre-commit.yaml,
    lint-renovate-config-check.yaml, lint-shellcheck.yaml,
    lint-terraform.yaml, lint-yaml.yaml, lint-zizmor.yaml)
  • .github/workflows/release.yaml — 2x (release-semantic.yaml,
    build-docker-image.yaml)

workflow_call.inputs for every called workflow was diffed v4.4.0→v5.0.1:
no renames or removals affect any call site here. lint-zizmor.yaml
gained four new optional inputs (advisory_only, min_confidence,
min_severity, persona), all defaulting to current behavior — not
adopted, since this batch is scoped to "make v5 work," not "adopt every
new knob."

Why anything needed fixing: actionlint's shellcheck integration

v5's lint-github-actions.yaml bumps actionlint v1.7.4 → v1.7.12,
which turns on actionlint -shellcheck's integration — previously inert
because set -x style debug output made it look like it ran, but
actionlint never actually invoked shellcheck under v4. This is the
first real shellcheck pass over this repo's own workflow run: blocks
(the reusable workflows in ppat/github-workflows were already fixed
upstream). actionlint appends --norc, so this repo's
.shellcheckrc does not filter these findings
— every finding had to
be triaged inline.

Reproduced locally exactly as v5's lint-github-actions.yaml runs it:
actionlint -shellcheck shellcheck (mise-pinned to the exact versions
v5 pins: actionlint v1.7.12, shellcheck v0.11.0), over this repo's
.github/workflows/*.yaml.

Findings (18 total) — all fixed, none suppressed

File / job Finding Fix Why safe
lint.yamlterraform-dirs (pre-existing) SC2086 on >> $GITHUB_OUTPUT Quoted: >> "$GITHUB_OUTPUT" Redirection target, not argv — bash never word-splits it.
release.yaml — Login to Coder 4x SC2086 on ${CODER_URL} (curl ×3, coder login) Quoted each CODER_URL is a single secret URL, never a list — quoting a scalar can't change argv count.
release.yaml — Login to Coder 2x SC2155 on export CODER_SESSION_TOKEN=$(curl ...), export CODER_VERSION=$(curl ...) Split into export VAR + VAR=$(...) Declare/assign-separation only changes behavior if the caller checks the subshell's exit status via the export line — nothing here does (no set -e, no $? check).
release.yaml — Publish template 8x SC2086 on ${TEMPLATE_DIR}, ${TEMPLATE_VERSION}, ${TEMPLATE_NAME}, ${WORKSPACE_IMAGE} (in coder template push args, the if echo $TEMPLATE_VERSION check, and inside a jq filter string) Quoted each All scalars (a path, a semver/sha, an image ref) — none are ever space-separated lists.
release.yaml — Publish template 3x SC2155 on export TEMPLATE_NAME=... (×2), export SELECTED_TEMPLATE=$(...) Split into declare + assign Same reasoning as above.

Not touched: --var test_mode=${TEST_MODE} was left unquoted.
Shellcheck does not flag it — TEST_MODE is only ever assigned the
literal true/false, so shellcheck's flow analysis already proves it
safe — and quoting it would be an unrequested change with no finding
behind it.

No # shellcheck disable= was needed anywhere. The word-splitting
carve-out (SC2086/SC2046/SC2016/SC2154 left alone when a variable
deliberately holds a space-separated list that must expand to N argv
elements — see upstream's ${ACTIONS_FILES}/${SHELLSCRIPT_FILES}/
${DOCKER_FILES} handling) doesn't apply to any finding here: none of
this repo's local run: blocks build an argv list from a
space-separated variable.

Argv-equivalence proof

Ran a stub (coder/curl/jq replaced with argv-echoing functions)
against representative values for every quoted variable — before vs.
after produced byte-identical argv, for both the coder template push \ --directory ... --var ... --name ... "${TEMPLATE_NAME}" line and
the curl/coder login/jq calls in the Login step. Also demonstrated
the pathological case (a value containing a space) to show the fix is
strictly safer, not merely equivalent, without changing token count
for any real-world input:

BEFORE (unquoted): --var workspace_image=registry.example.com/path/coder workspace:1.2.3
  → ARGC=5: ... --var  workspace_image=registry.example.com/path/coder  workspace:1.2.3   (silently split into 2 args)
AFTER (quoted):    --var "workspace_image=registry.example.com/path/coder workspace:1.2.3"
  → ARGC=4: ... --var  workspace_image=registry.example.com/path/coder\ workspace:1.2.3   (stays 1 arg)

For normal (space-free) values, ARGC/ARGV[] are identical in both
forms — confirmed for coder template push (14 argv elements, byte
match) and all three curl calls.

Also verified

  • actionlint -shellcheck shellcheck over all .github/workflows/*.yaml: 0 findings, exit 0 (was 18 findings, exit 1, before the fix commit).
  • yamllint -c .yamllint --strict (pinned 1.38.0, matches v5's pin) on the changed files: clean.
  • zizmor --format=github --min-severity=medium --min-confidence=high --persona=regular . (pinned v1.29.0, matches v5's pin): 0 findings.
  • pre-commit hooks (as configured in this repo) passed on both commits.

Other v5 changes not applicable / not adopted here

  • lint-shellcheck.yaml's file-selection change (executable-bit only →
    executable and shebang/extension-filtered): simulated both
    selectors against this repo's files. Only 2 files carry the
    executable bit (script-memory-watchdog-test.sh,
    script-prepare-workspace.sh), and both already end in .sh, so the
    linted file set is identical before and after — no coverage
    change, no explanation needed beyond that. (This job is path-gated
    out of this PR since no .sh files changed — see CI section below.)
  • lint-shellcheck.yaml's new PASS/FAIL-per-file output and
    renovate-config-validator bump (44.14.12 → 44.30.4): internal to the
    reusable workflow, nothing in this repo needed to change.
  • lint-zizmor.yaml's four new optional inputs: not adopted (all
    default to current behavior; out of scope for "just the bump").

CI status

Job naming and which run verified what:

(filled in after push — see follow-up comment)

ppat added 2 commits August 20, 2026 06:40
Bumps every ppat/github-workflows ref (renovate.yaml, lint.yaml x11,
release.yaml x2) to the v5.0.1 tag. No workflow_call.inputs used by this
repo were renamed or removed between v4.4.0 and v5.0.1.

Supersedes #876 (the Renovate PR proposing v4.4.0 -> v5.0.0), which is
left untouched.
…hellcheck

v5's lint-github-actions.yaml turns on actionlint's shellcheck integration
(actionlint v1.7.4 -> v1.7.12), which was previously inert. That surfaces
the first real shellcheck pass over this repo's own workflow `run:`
blocks (lint.yaml, release.yaml) - actionlint appends --norc, so
.shellcheckrc does not filter these.

18 findings total, all fixed by quoting or declare/assign-separation,
never by changing what arguments a command receives:

- lint.yaml (terraform-dirs job): 1x SC2086 on `>> $GITHUB_OUTPUT`. This
  is a redirection target, not argv, so bash never word-splits it -
  quoting is behavior-preserving.
- release.yaml (Login to Coder step): 4x SC2086 on `${CODER_URL}`
  (curl/coder login args) + 2x SC2155 on `export VAR=$(curl ...)`.
  CODER_URL is a single secret URL, never a list, so quoting cannot
  change argv count; declare/assign-separation only changes when the
  subshell's exit status would be masked, and nothing here checks it.
- release.yaml (Publish template step): 8x SC2086 on
  ${TEMPLATE_DIR}/${TEMPLATE_VERSION}/${TEMPLATE_NAME}/${WORKSPACE_IMAGE}
  (all scalars, never space-separated lists) + 3x SC2155 on `export
  VAR=$(...)`. Verified with an argv-echoing stub that `coder template
  push` and the `curl`/jq calls receive byte-identical argv before and
  after, for representative values.

`--var test_mode=${TEST_MODE}` was left unquoted deliberately: shellcheck
does not flag it (TEST_MODE is only ever assigned the literal `true` or
`false`), and quoting it would be an unrequested change with no finding
behind it.

No inline `# shellcheck disable=` was needed: none of this repo's local
run: blocks build an argv list from a space-separated variable the way
upstream's ${ACTIONS_FILES}/${SHELLSCRIPT_FILES}-style callers do, so
none of the findings fall under the word-splitting-is-intentional
carve-out.
@ppat

ppat commented Aug 20, 2026

Copy link
Copy Markdown
Owner Author

CI status

PR event run (https://github.com/ppat/coder/actions/runs/32340670273 + the paired release workflow run https://github.com/ppat/coder/actions/runs/32340670286) — all jobs that this diff's path-gating enables ran for real and passed:

Job Result What it verifies
github-actions (lint-github-actions.yaml) pass (12s) The actionlint v1.7.12 + shellcheck v0.11.0 gate itself — 0 findings against the fixed lint.yaml/release.yaml
zizmor pass (15s) lint-zizmor.yaml v5.0.1, 0 findings
yaml / yamllint pass (15s) yamllint 1.38.0 against the changed workflow files
terraform-dirs pass (3s) The fixed >> "$GITHUB_OUTPUT" line runs for real
commit-messages pass (16s) Both commit messages pass commitlint (no scope-enum changes)
pre-commit pass (28s) Full .pre-commit-config.yaml suite
detect-changes pass (7s) Path-detection itself
renovate (repo-local workflow) pass (39s) renovate.yaml bump to v5.0.1
create-release / semantic-release pass (21s) release-semantic.yaml bump to v5.0.1
publish-image / build-image pass (6m42s) build-docker-image.yaml bump to v5.0.1
publish-template pass (2m17s) Real execution of every fixed line in the "Login to Coder" and "Publish template" steps — curl "${CODER_URL}"/coder login --use-token-as-session "${CODER_URL}", export CODER_SESSION_TOKEN/export CODER_VERSION split-declare, coder template push --directory "${TEMPLATE_DIR}" --var "workspace_image=${WORKSPACE_IMAGE}" ... "${TEMPLATE_NAME}", and the quoted jq filter all ran against the real Coder deployment and succeeded, in test-publish mode. This is the strongest confirmation available: not just an argv stub, but the actual command with real values.

Path-gated out of the PR event (no .sh/Terraform/Dockerfile/markdown/renovate-config files changed): shellcheck, terraform, docker-files, markdown, renovate-config-check.

Dispatched run (workflow_dispatch on this branch, files=ALL): https://github.com/ppat/coder/actions/runs/32341386012 — exercised every gated-out job for real:

Job Result Notes
shellcheck pass shellcheck: 2 file(s) checked, 0 failed — confirms the before/after linted file set claim: script-memory-watchdog-test.sh and script-prepare-workspace.sh, identical under both the old executable-only selector and the new executable+shebang/extension selector, since both already carry the executable bit and the .sh extension. No coverage change.
terraform (terraform-fmt, terraform-lint, terraform-validate) pass (all 3) lint-terraform.yaml v5.0.1 (unchanged between v4.4.0 and v5.0.1) against templates/kubernetes/homelab-workspace
docker-files / hadolint pass lint-hadolint.yaml v5.0.1 against images/homelab-workspace/Dockerfile
markdown / markdownlint pass lint-markdown.yaml v5.0.1
renovate-config-check pass lint-renovate-config-check.yaml v5.0.1 (renovate-config-validator 44.30.4) against .github/renovate.json + .github/renovate/*.json — no changes needed, renovate-presets pin untouched at v0.2.1
github-actions pass Re-confirms 0 shellcheck findings in ALL-files mode too
commit-messages skipped Expected — that job is if: github.event_name == 'pull_request'; already verified pass on the PR event above

Every job this repo's lint.yaml/release.yaml/renovate.yaml can run has now gone green under v5.0.1, either on the PR event or the dispatched run. Not merging — leaving open for review per instructions.

@ppat
ppat merged commit 68cd8e7 into main Aug 20, 2026
30 checks passed
@ppat
ppat deleted the lint-uplift/coder-gw-v5 branch August 20, 2026 07:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant