Skip to content

fix: repair invalid action.yml and harden the action - #2

Merged
SafeEval merged 2 commits into
mainfrom
agent/fix-and-harden
Jul 30, 2026
Merged

fix: repair invalid action.yml and harden the action#2
SafeEval merged 2 commits into
mainfrom
agent/fix-and-harden

Conversation

@SafeEval

Copy link
Copy Markdown
Member

The action is broken on every ref, including v1.0.0 and v1

action.yml is not valid YAML. The Lint PR commits step embedded a Python script at column 0 inside an 8-space run: | block scalar:

      run: |
        done < <(curl ... |
                 python3 -c 'import json,sys,base64
for c in json.load(sys.stdin):          # <- column 0 ends the block scalar
    if msg.startswith("Merge "): continue   # <- YAML reads ": " as a mapping

The dedent terminates the scalar, so YAML parses the Python as a mapping key and fails at line 81. GitHub cannot load this action at all — it fails for every consumer, on the published tags.

Fix: delete the script rather than re-indent it

commitlint already has --range, which reads the PR's commits from git and skips merge commits itself. Using it removes the API call, the token, the base64 round-trip, and the pagination — and with them, three more defects:

Defect Status
per_page=250 silently capped at 100 by the API — PRs over 100 commits were partially linted with no warning gone (no API)
|| status=1 unreachable in warn mode (verified: --mode warn exits 0) gone
ALLOW_REVERT_PREFIX comment described merge commits, but that flag only accepts Revert "..." subjects (verified both ways) gone

The remaining git handling carries over the two lessons from the sibling repo's CI: shallow checkouts don't contain the PR base, and HEAD on a pull_request event is GitHub's synthetic merge commit. Both endpoints are fetched and the range ends at the real branch tip. Verified end-to-end against an actual --depth 1 clone.

A missing checkout now produces an actionable ::error:: instead of a bare git failure.

SHA pinning

actions/setup-go@v5@40f1582… (v5.6.0). The README recommended SHA pinning while the action itself used a mutable tag.

I also caught myself here: I first pinned actionlint to a Docker digest I had invented. It matched no real tag — checked against the registry. Replaced with a source install at a pinned version, which also fits this repo's "no third-party actions" stance better than a container.

LICENSE

MIT, Copyright (c) 2026 DivergentCodes. The repo had none, which left it legally unusable by anyone — a problem for something meant to be consumed.

CI

The check that would have prevented this entire PR:

  • action.yml parses — confirmed to catch the original defect at line 81
  • actionlint — also catches it, at the same line
  • pin guard — fails on any unpinned uses:
  • self-test — runs the action against its own PR, both with commits-mode on and off, in warn so contributor commit style never gates this repo's CI

Static checks alone wouldn't have caught a composite action that parses but doesn't run, hence the self-test.

README

Corrected claims that are no longer true: removed the github-token input, changed permissions: pull-requests: readcontents: read, dropped the python3/base64 runner requirements, and added the now-required actions/checkout step to the example. Verified the input table matches action.yml exactly — no documented-but-nonexistent inputs, none undocumented.

After merge

v1.0.0 and v1 both point at broken code. They should be re-cut: tag v1.0.1 from main and move v1 to it, so anyone following the README's @v1 guidance gets something that loads.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VSrrciEDBTuFNMtKocScML

action.yml was not valid YAML on any ref, including the published v1.0.0
and v1 tags: the `Lint PR commits` step embedded a Python script at column
0 inside an 8-space block scalar, so the dedent ended the scalar and YAML
read `if msg.startswith("Merge "): continue` as a mapping. GitHub could not
load the action at all — it was broken for every consumer.

Rather than re-indent the heredoc, drop it. commitlint already has
`--range`, which reads the PR's commits from git and skips merge commits
itself, so the API call, the token, the base64 round-trip, and the
pagination all disappear. That removes the construct that broke the parse
and three defects with it:

  - per_page=250 was silently capped at 100 by the API, so PRs with more
    than 100 commits were partially linted with no warning
  - `|| status=1` was unreachable in warn mode, since --mode warn exits 0
  - the ALLOW_REVERT_PREFIX comment described merge commits, but that flag
    only accepts `Revert "..."` subjects

Shallow checkouts do not contain the PR base, and HEAD on a pull_request
event is GitHub's synthetic merge commit, so fetch both endpoints and lint
to the branch tip. Guard for a missing checkout with an actionable error
rather than a bare git failure.

Pin actions/setup-go to a commit SHA. The README recommended SHA pinning
while the action itself used a mutable tag.

Add MIT LICENSE (the repo had none, leaving it legally unusable) and CI:
action.yml is parsed, actionlint runs, unpinned `uses:` fail the build, and
a self-test job runs the action against its own PR. The parse check and
actionlint were both confirmed to catch the original defect at line 81.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VSrrciEDBTuFNMtKocScML
@SafeEval
SafeEval marked this pull request as ready for review July 30, 2026 17:54
CI caught two problems with its own new checks.

The pin guard flagged `uses: ./`. A local path refers to the commit already
checked out, so there is no external ref to pin; exclude `./`-prefixed uses
rather than weaken the SHA pattern.

The self-test could not run the action: it installs the linter with
`go install`, and DivergentCodes/commitlint is still private, so the module
proxy returns 404 on a hosted runner. Confirmed by fetching both the repo
and proxy.golang.org unauthenticated. Gate the job on a COMMITLINT_PUBLIC
repo variable so it is skipped for a known reason instead of failing for
one unrelated to this code; drop the condition once commitlint is public.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VSrrciEDBTuFNMtKocScML
@SafeEval

Copy link
Copy Markdown
Member Author

CI is green. It also caught two problems in its own new checks, both now fixed:

  1. Pin guard flagged uses: ./ — a local path refers to the commit already checked out, so there's nothing external to pin. Excluded ./-prefixed uses rather than weakening the SHA pattern.

  2. The self-test couldn't run the action — and this one matters beyond CI.

Ordering constraint for going public

The action installs the linter with go install github.com/DivergentCodes/commitlint@.... commitlint is still private, so on a hosted runner the module proxy returns 404 and the install fails:

fatal: could not read Username for 'https://github.com': terminal prompts disabled

Confirmed by fetching both unauthenticated — github.com/DivergentCodes/commitlint404, proxy.golang.org/.../commitlint/@latest404.

So this action cannot work for anyone, including this repo's own CI, until commitlint is public. Making commitlint-action public first would ship something that fails on first use.

Correct order: make commitlint public → then commitlint-action → then set COMMITLINT_PUBLIC=true (repo variable) to enable the self-test job → then re-cut tags.

The self-test is gated on that variable so it skips for a known, documented reason rather than failing for one unrelated to the code under review. Once commitlint is public, delete the if: and the job runs unconditionally.

Still outstanding after merge

v1.0.0 and v1 both point at code that cannot load. Re-cut v1.0.1 from main and move v1 to it, so the README's @v1 guidance resolves to something that works.

@SafeEval
SafeEval merged commit ad493c6 into main Jul 30, 2026
2 checks passed
@SafeEval
SafeEval deleted the agent/fix-and-harden branch July 30, 2026 18:05
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