Skip to content

ci: make the inherited workflows runnable in this fork - #4

Merged
blotus merged 2 commits into
mainfrom
ci/run-tests
Aug 21, 2026
Merged

ci: make the inherited workflows runnable in this fork#4
blotus merged 2 commits into
mainfrom
ci/run-tests

Conversation

@blotus

@blotus blotus commented Aug 21, 2026

Copy link
Copy Markdown
Member

Three workflows came across with the fork. None of them had ever run — the repository had zero workflow runs before this PR.

1. tests.yml could not have passed

It was pinned to actions/checkout v3.6.0 and actions/setup-go v4.3.0. Both run on a Node runtime GitHub has since removed from its hosted runners, so the job fails at the first step whatever the code under test does.

Moved to checkout v7.0.1 and setup-go v7.0.0.

2. benchmark.yml targets a runner that does not exist here

runs-on:
  group: ARM LINUX SHARED
  labels: arm-8core-linux

That is DataDog's self-hosted pool. In this fork both jobs queue until they time out. actionlint flags the label as unknown:

benchmark.yml:21:15: label "arm-8core-linux" is unknown ... [runner-label]
benchmark.yml:91:15: label "arm-8core-linux" is unknown ... [runner-label]

Moved to ubuntu-latest, and added workflow_dispatch so it can be run deliberately.

One caveat recorded in the file rather than left implicit: GitHub-hosted runners are shared and noisy. Benchmarking this repo's lexer on one, comparing the base branch against itself, swings −4.9% to +5.3% run to run. A benchstat delta from this workflow is a hint; anything that matters should be confirmed on a quiet machine.

3. The benchmark job cost 47 minutes

Once the runner was fixed the job passed — in 46m54s, against ~3 minutes for the tests. Upstream ran it on an 8-core ARM pool; a shared 2-core runner is an order of magnitude slower, and that was being paid on every push to every branch.

The output does not justify it. Benchmarking this repo on a GitHub-hosted runner, base branch against itself, swings −4.9% to +5.3% between runs — wider than most regressions worth catching. Run automatically it reports noise for 47 minutes a PR.

So it is now workflow_dispatch only. Dispatch from a branch to compare against main, from main to refresh the cached baseline. Run it deliberately when a change is meant to move performance, and confirm anything that matters on a quiet machine.

Hardening added to tests.yml

None of this was upstream:

why
permissions: contents: read without the block the job inherits the repository default, which is not necessarily read-only
persist-credentials: false no token left behind in .git/config for a later step to find
concurrency (workflow + ref) a second push supersedes the first instead of running both
timeout-minutes: 20 a wedged run cannot burn the full six-hour default
fail-fast: false see every Go version that breaks, not just the first
gofmt + go vet nothing checked either before
-run '^$' on fuzz steps spend the 60s budget fuzzing, not re-running the suite from two steps earlier

Pinning

Every uses: across all three workflows is now a 40-character commit SHA with the tag in a trailing comment — a tag can be moved to point at different code, a SHA cannot, and the comment keeps the next bump legible. No tag-only references remain. One pre-existing pin had no comment at all (setup-go@0aaccfd…, which is v5.4.0); it is labelled now.

Worth considering separately: Settings → Actions → require SHA pinning is currently off (sha_pinning_required: false). Turning it on makes the rule enforced rather than a convention.

Verification

This PR is the first thing in this repository CI has ever checked, and it checks itself:

test (1.25)          pass    3m15s
test (1.25.7)        pass    2m56s
lint                 pass       38s
benchmark (1.25.7)   pass   46m54s   <- why it is now opt-in

actionlint is clean on all three files. Every step was also run locally first — gofmt, go vet, go build, go test, go test -race, and both fuzz targets pass.

Correction

An earlier revision of this description claimed Actions still needed enabling on the fork, inferred from the zero run count. That was wrong — Actions was already enabled, and the checks fired as soon as the PR opened. The zero runs were caused by the two faults above: a tests.yml that failed at its first step on a removed Node runtime, and a benchmark.yml queued against a runner that does not exist here. Neither leaves a run you would notice.

Note on #3

That PR adds tests that have only ever run locally. It branched before this, so it will not pick these workflows up until main is merged into it.

🤖 Generated with Claude Code

blotus and others added 2 commits August 21, 2026 22:15
This fork has three workflows carried over from upstream and zero runs, ever.
Two reasons, both fixed here; the third needs a human.

tests.yml was pinned to actions/checkout v3.6.0 and actions/setup-go v4.3.0.
Both run on a Node runtime GitHub has since removed from its runners, so the
job fails at the first step regardless of the code under test. Moved to
checkout v7.0.1 and setup-go v7.0.0, still pinned by SHA with the tag in a
trailing comment so the next bump is legible.

benchmark.yml targets `group: ARM LINUX SHARED, labels: arm-8core-linux`,
DataDog's self-hosted pool. It does not exist here, so both jobs queue until
they time out -- actionlint flags the label as unknown. Moved to
ubuntu-latest. Shared runners are noisy enough that a benchstat delta there
is a hint rather than a result; the workflow says so, and gains
workflow_dispatch so it can be run deliberately.

Also on tests.yml, none of which upstream had:

  - permissions: contents: read. Without the block the job inherits whatever
    the repository default is, which is not necessarily read-only.
  - persist-credentials: false, so no token is left in .git/config.
  - concurrency, keyed by workflow and ref, so a second push supersedes the
    first instead of running both.
  - timeout-minutes, so a wedged run cannot burn a full six hours.
  - fail-fast: false, to see every Go version that breaks rather than one.
  - gofmt and go vet, which nothing checked before.
  - -run '^$' on the fuzz steps, so the 60s budget is spent fuzzing instead
    of re-running the suite that already ran two steps earlier.

Every `uses:` across all three workflows is now a 40-character SHA with a
version comment; no tag-only references remain. Each step was run locally
against this branch first: gofmt, vet, build, test, -race, and both fuzz
targets pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
It passed on ubuntu-latest, in 46m54s. Upstream ran it on an 8-core ARM pool;
a shared 2-core runner is an order of magnitude slower, and that cost was
being paid on every push to every branch.

The output does not justify it. Benchmarking this repo on a GitHub-hosted
runner, base branch against itself, swings -4.9% to +5.3% between runs --
wider than most regressions worth catching. Run automatically it would report
noise for 47 minutes a PR; run deliberately, before and after a change meant
to move performance, it is still useful.

workflow_dispatch only. Dispatch from a branch to compare against main, from
main to refresh the cached baseline.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@blotus
blotus merged commit 3d69391 into main Aug 21, 2026
3 checks passed
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