Repository navigation
fix: use single quotes in a workflow expression, and lint for it - #67
Merged
Merged
Conversation
The first deploy after the workflow_run migration failed before any job started — no
logs, no annotations, no failing step, because GitHub rejected the workflow file itself:
publish-gh-pages.yml:146: got unexpected character '"' while lexing expression ...
only single quotes are available for string delimiter
`${{ github.event.workflow_run.html_url || "manual dispatch" }}`, in the context-logging
step. Expressions take single-quoted string literals only, and a single-quoted literal
cannot be nested inside the single-quoted shell word it was written in.
Fixed by taking every context value through `env:` instead of interpolating it into the
script — which is the right shape anyway, since it also keeps arbitrary values out of
the shell.
The reason this reached main is worth more than the fix. Workflow expressions are
validated only by GitHub: this passed YAML parsing, passed `bash -n` on every embedded
script, and passed the workflow harness (which substitutes `${{ }}` away before running
anything). Nothing local could see it, and the failure mode gives you no logs to read.
So _lint.yml now runs actionlint, which reports this exact error and pinpoints the
column. It was previously rejected for false-flagging job.workflow_repository /
job.workflow_sha — its `job` context schema is stale, while those properties are real and
publish-gh-pages.yml depends on them. Those two are suppressed by an -ignore pattern
narrow enough to not hide anything else; with them suppressed the repo lints clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The CI runner has shellcheck installed, so actionlint runs it over every embedded script — which my local run had disabled, so I missed both. SC2002: `$(cat file | head -1)` is a pointless subprocess; `head -1 file`. SC2015: `[ -n "$stable_src" ] && ln -s … || true` is not if-then-else. It swallows a FAILED symlink as well as the intended empty-stable_src case, and a missing stable/ alias is silent damage — the root redirect targets that constant URL, and cross-project intersphinx points at it. Now an explicit `if`, so a real `ln` failure fails the deploy. This one predates the migration; actionlint found it on its first run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
The first deploy after #66 failed before any job started — no logs, no annotations, no failing step, because GitHub rejected the workflow file itself:
${{ github.event.workflow_run.html_url || "manual dispatch" }}, in the context-logging step I added in #66. Expressions take single-quoted string literals only — and a single-quoted literal can't be nested inside the single-quoted shell word it was written in.Fixed by taking every context value through
env:rather than interpolating into the script, which is the right shape regardless: it keeps arbitrary values out of the shell too.The gap matters more than the bug
Workflow expressions are validated only by GitHub. This passed:
bash -non every embedded script${{ }}away before running anything…and the failure mode hands you nothing to read.
gh run view --logreturns log not found; the jobs array is empty. I only isolated it by dispatching the workflow manually, where the error surfaced on stderr.So
_lint.ymlnow runs actionlint, which reports this exact error with the column. Verified against a copy with the bug reintroduced.It was previously rejected for false-flagging
job.workflow_repository/job.workflow_sha— itsjobcontext schema is stale, while those properties are real andpublish-gh-pages.ymldepends on them to version-matchassemble.mjs. Those two are suppressed with an-ignorepattern narrow enough not to hide anything else; with them suppressed the repo lints clean.State
main's deploy is currently broken — this restores it. Thev0.25.0tag waits until a deploy frommainis verified green.🤖 Generated with Claude Code