Skip to content

ci(release): six release workflows, audited by running them rather than reading them - #1054

Merged
gHashTag merged 10 commits into
mainfrom
fix/release-workflows
Sep 20, 2026
Merged

gHashTag merged 10 commits into
mainfrom
fix/release-workflows

Conversation

@gHashTag

@gHashTag gHashTag commented Sep 20, 2026 •

Copy link
Copy Markdown
Owner

Six release-adjacent workflows, audited by running them rather than by reading
them. Two are deleted, three are repaired, one needed nothing.

The headline finding is not a workflow bug. Extension Release had been
building zips with no manifest.json inside them — Chrome refuses to load such
a zip — and the mechanism was an unanchored .gitignore rule. extensions/
matches at any depth, so it matched deploy/trinity-nexus/extensions when the
tree moved there and swallowed both manifests and all six icons. The 53
already-tracked source files beside them kept working, which is exactly why
nothing looked wrong. .gitignore already documents this same defect for
website/, dated 2026-08-10.

Opening this pull request was itself the test for bb3107d0e: nothing built
src/vibeec on a pull request, so it drifted out of step with zig 0.15
unobserved until a release tag. It failed on all four targets, on a second zig
0.15 rename I had not fixed and had wrongly reported as clear — see the work
report below, and 2613794b6. It is green on all four now, which is the first
time src/vibeec has compiled for every target under zig 0.15.2.

{
  "version": 1,
  "head_sha": "2613794b6a7cfcf2c839ca6de652c9ade8e19e30",
  "summary": "Six release-adjacent workflows were audited by running them, not by reading them. Two are deleted, three are repaired, one needed nothing. The extension release had been building zips with no manifest.json inside since the tree moved under deploy/trinity-nexus, and the mechanism was an unanchored .gitignore rule that hid twelve files without breaking the fifty-three already tracked beside them.",
  "changes": [
    "Anchored extensions/ and trinity-nexus/ in .gitignore: unanchored, both matched deploy/trinity-nexus/extensions at depth three and silently swallowed every file added after the move.",
    "Restored the twelve lost extension files from tag ext-v2.0.0, both browser manifests and all six icons across chrome/icons and firefox/icons.",
    "Repointed every path in extension-release.yml from the removed top-level extension/ to deploy/trinity-nexus/extensions.",
    "Deleted build-release.yml, which built a Tauri application removed from this repository on 2026-01-31.",
    "Deleted trinity-binary-release.yml, a duplicate that raced release.yml for the same v* tag and the same release body.",
    "Narrowed build-compiler-release.yml to compiler-v* tags only, so it no longer overwrites Binary Release notes on a v* tag.",
    "Added a pull_request trigger on src/vibeec/** to build-compiler-release.yml, so the compiler is built before a release tag rather than after one.",
    "Migrated forty Writergate call sites across nineteen src/vibeec files to std.fs.File.stdout().deprecatedWriter() and its stderr and stdin counterparts.",
    "Renamed thirty-three managed ArrayList sites across twelve files to std.array_list.Managed, which is the pre-0.15 type under its new name, so no call site changes.",
    "Pinned every macOS job to macos-14: zig 0.15.2 cannot link its own build runner against libc on the macOS 26 SDK that macos-latest now carries.",
    "Replaced the archived goto-bus-stop/setup-zig with mlugg/setup-zig@v2, and softprops/action-gh-release@v1 with v2, everywhere they appeared.",
    "Set make_latest false on both side releases, so a compiler or extension tag cannot displace Trinity at the top of the releases page.",
    "Renamed the compiler release assets from vibee-* to vibeec-*, a naming collision that made two different programs look like one.",
    "Un-swallowed both Test binary steps and gated them to the native target, instead of appending an echo to a binary that cannot execute on the runner.",
    "Rewrote dev-enforcement.yml, which GitHub has never parsed: steps was indented under if, so every run since c523c41b0 reported an empty jobs array.",
    "Removed session-check, which judged every pull request by .trinity/dev_session.json and queried a key that is null in that file.",
    "Added firebird to all five archive steps in release.yml; build.zig installs it unconditionally and no release had ever shipped it."
  ],
  "tests": [
    {
      "command": "gh api repos/gHashTag/trinity/actions/jobs/106089046354/logs (probe job: every error in src/vibeec)",
      "result": "Reported exit 1 and three error lines",
      "status": "failed",
      "evidence": "Its last line was: === exit 1, 3 error lines. The job was green because it was continue-on-error and captured the exit code instead of returning it, and I read the green tick rather than the line under it. The error was compiler.zig:827: struct array_list.Aligned has no member named init."
    },
    {
      "command": "gh run view 35514890254 --json jobs (probe jobs for binaries and the extension)",
      "result": "Both reported what they were asked for",
      "status": "passed",
      "evidence": "firebird installed at 3111768 bytes by the top-level build, and both extension zips assemble with manifest_version 3 and 2 asserted through jq -e after the restore."
    },
    {
      "command": "gh release view v10.1.1",
      "result": "Four archives plus checksums.txt published",
      "status": "passed",
      "evidence": "trinity-linux-amd64, trinity-linux-arm64, trinity-macos-amd64, trinity-macos-arm64 tarballs and checksums.txt, produced by the repaired release.yml on the v10.1.1 tag."
    },
    {
      "command": "python3 -c 'import yaml,sys; print(list(yaml.safe_load(open(sys.argv[1]))[\"jobs\"]))' .github/workflows/dev-enforcement.yml",
      "result": "Parses, reporting title-check and pr-status",
      "status": "passed",
      "evidence": "Before the rewrite the same command raised: mapping values are not allowed here, line 54, column 12 — which is why GitHub reported runs with an empty jobs array."
    },
    {
      "command": "gh run view 35515424344 --json jobs (Dev Workflow Enforcement, on this pull request)",
      "result": "Both jobs ran real steps, first time ever",
      "status": "passed",
      "evidence": "PR Title Format: Validate PR title format=success. Update PR Status: Mark in progress=success, with the two close-event steps correctly skipped. Every earlier run of this workflow had an empty jobs array."
    },
    {
      "command": "git check-ignore -v against every path under deploy/trinity-nexus/extensions",
      "result": "Exactly eleven files became committable",
      "status": "passed",
      "evidence": "The twelfth, chrome/icons/README.md, stays hidden by .gitignore line 315 (*.md), and the packaging step already excludes *.md, so no shipped artifact changes."
    },
    {
      "command": "gh run view 35515424324 (Build Compiler Release, first run, at bb3107d0e)",
      "result": "All four target jobs failed identically",
      "status": "failed",
      "evidence": "compiler.zig:827:41: error: struct array_list.Aligned([]const u8,null) has no member named init — the same line the probe had already printed. This is what the new pull_request trigger exists to catch, and it caught it on its first run."
    },
    {
      "command": "gh run view 35515807566 (Build Compiler Release, at 2613794b6)",
      "result": "All four target jobs green, release skipped",
      "status": "passed",
      "evidence": "x86_64-linux-gnu, aarch64-linux-gnu, x86_64-macos and aarch64-macos all built, and Create Release was correctly skipped on a pull request. The two native Test binary steps ran ./vibeec --version un-swallowed and exited zero. This is the first time src/vibeec has compiled for all four targets under zig 0.15.2."
    }
  ],
  "limitations": [
    "Build Compiler Release is green for all four targets, but only for what compiler.zig reaches. Zig analyses lazily, and the other hundred and fifty files under src/vibeec are outside that import closure and remain unchecked.",
    "The ArrayList change is a rename to std.array_list.Managed, which zig 0.15 marks deprecated. The real unmanaged migration is in progress in this tree file by file, and twelve more files still need it.",
    "Local zig is 0.16.0 and cannot check any of this: it has removed std.heap.GeneralPurposeAllocator and std.process.argsAlloc, and stops on the first before reaching any ArrayList. CI is the only instrument.",
    "Six other unanchored .gitignore directory rules still hide files below top level (bin, demos, mcp, models, runtime — twenty-seven files in all), and were left alone deliberately.",
    "The PR title check warns and exits zero. Fifteen of the last hundred and twenty merged titles fail it, so making it binding would reject this repository's own recent history.",
    "The Windows job in release.yml still runs and still fails: seventeen files use POSIX-only APIs that zig refuses to compile for that target. That is a portability project, not a workflow line.",
    "pr-status cannot label a pull request opened from a fork, because fork events receive a read-only GITHUB_TOKEN no matter what the permissions block asks for.",
    "macos-14 is pinned, not fixed. When ZIG_VERSION moves to a zig that can read the macOS 26 SDK, the pin should come back out."
  ],
  "tags": ["ci", "release", "zig", "gitignore", "workflows"],
  "blog": {
    "title": "The release workflows that had never produced a release",
    "summary": "An audit of six release-adjacent GitHub Actions workflows, carried out by running each one instead of reading it. Two were deleted, three repaired, one was already correct — and the worst defect turned out to be a single unanchored line in .gitignore.",
    "outline": [
      "A workflow that fails on every run is loud, and a workflow that has never run at all is silent. dev-enforcement.yml was the second kind: GitHub could not parse the file, so it reported a failed run with an empty jobs array and the file path where the workflow name should have been. No job started, so there were no logs to read, and the emptiness itself was the diagnosis.",
      "Extension Release was worse, because it succeeded. Every step passed and the zips it uploaded contained no manifest.json, which Chrome will refuse to load. The cause was three directories away from the workflow: an unanchored .gitignore rule matches at any depth, so extensions/ matched deploy/trinity-nexus/extensions when the tree was moved there, and quietly excluded both manifests and all six icons.",
      "Already-tracked files keep working when a gitignore rule starts matching them, which is precisely what makes this class of defect invisible. Fifty-three source files under that directory were committed before the move and carried on being committed afterwards. Only the twelve files added or re-added later vanished, and nothing in the build said so.",
      "The macOS failures were never in build.zig. An earlier diagnosis of this same breakage located a missing link_libc flag at build.zig line 1345; a three-job probe workflow disproved it in one run. zig 0.15.2 cannot link its own build runner against libc on the macOS 26 SDK that macos-latest now carries, and the failing symbols come from build_zcu.o before any repository code is compiled at all.",
      "That same probe then caught me out. Its vibeec job was continue-on-error and its script captured zig's exit code rather than returning it, so the job was green whatever zig said — and I read the green tick instead of the line underneath, which said exit 1 with three error lines. An enumerator job cannot prove a build, and a tick over a printed error list is not evidence of anything.",
      "Zig analyses function bodies lazily, so an error list is only ever the first wave. Fixing the four errors the compiler reported produced exactly one more on the next round, then another rename behind that one, and one error per CI cycle is not a schedule. Each wave since has gone in as a single mechanical rewrite across every site rather than as the one line the compiler happened to name.",
      "src/vibeec had no pull-request build gate of any kind, which is the real reason it drifted out of step with zig 0.15 unobserved. A release tag was the first thing that noticed, which is the most expensive moment available to discover it. The trigger added here builds the four binaries on every pull request that touches the tree, and it failed on all four the first time it ran — which is the trigger working, not the trigger being wrong.",
      "The title check warns rather than fails, and the reason is measured rather than assumed: a hundred and five of the last hundred and twenty merged pull request titles match the conventional pattern, and fifteen do not. Those fifteen are Russian-language prose and README prefixes — a different convention, not malformed input — so a blocking gate would reject twelve percent of this repository's own recent history on a rule nobody agreed to."
    ]
  }
}

gHashTag and others added 9 commits September 20, 2026 20:40
Build & Release fires on every v* tag and runs three jobs -- macOS, Windows,
Linux -- each of which does `cargo install tauri-cli --locked` and then
`cargo tauri build` in `vibee-browser/`. That directory was removed on
2026-01-31 by 182df46, "refactor: clean up project root". Twenty-one files,
deliberately. The only vibee-browser left in the tree is
archive/vibee-browser-chromium/, which is a set of Chromium patches, not a
Tauri project -- `cargo tauri build` has nothing to point at.

So the workflow cannot be repaired into working; there is no source. What it
did instead was worse than failing quietly: its release job calls
action-gh-release with make_latest: true and a body that begins "## VIBEE
Browser", against the same tag Binary Release publishes. Whichever of the two
finished last decided what the Trinity release said it was.

The product is gone. The workflow goes with it; the file stays in history for
whoever revives the browser.
Trinity Binary Release and Binary Release build the same product from the same
tree for the same five targets, and both end by calling action-gh-release with
make_latest: true against the tag that triggered them. That is not two
workflows with bugs; it is two authors of one release body. Whichever finished
last decided whether users were told about four downloads or five.

Repairing this one would not have removed the race, and it needed repairing
everywhere anyway:

  -Draylib=false is not a declared option. `zig build -h` on a working runner
  lists -Dtarget -Dcpu -Dofmt -Ddynamic-linker -Doptimize -Dci -Dtreesitter,
  and passing an unknown -D kills the job in ten seconds.

  macos-13 for the amd64 job. On 2026-09-20 that image sat queued for the whole
  of a fifty-minute run and never started; the target is a cross-compile
  anyway.

  macos-latest for the arm64 job -- macOS 26.6 with the Xcode 26.6 SDK, where
  zig 0.15.2 cannot link `pub fn main() void {}` against libc. Measured on all
  three images.

  The macOS jobs `cd release/macos-amd64 && zip -r ../../trinity-*.zip *`,
  which writes the zip to the repository root, then upload from `release/`.
  Even on a green build those two artifacts were empty.

  Every binary is copied with `[ -f x ] && cp x || echo "not found"`, so a
  build that produced nothing still tarred, uploaded and published.

  The Windows job has no continue-on-error, and 17 source files cannot compile
  for that target.

Binary Release is the survivor: it shipped v10.1.1 on four platforms. The one
thing this file had that it did not is `firebird`, which moves across in the
next commit.
Build Compiler Release has never built anything since zig moved to 0.15:
src/vibeec/compiler.zig is the root of the vibeec binary and does not compile.
The sibling copy under src/phi-engine/vibeec_original was ported and this one
was not, so the idiom used here is the one that copy already uses and that
src/tri/pathology.zig and src/sacred/caps_report.zig compile with today.

  type_checker.zig:287 -- TypeChecker.init was declared to return Self while
  calling TypeRegistry.init, which returns an error union. Both its own tests
  at 531 and 542 and compiler.zig:152 already write 'try TypeChecker.init',
  so the declaration was the thing out of step, not the four callers.

  compiler.zig:474 and 513 -- std.io.getStdOut() no longer exists. File.stdout()
  needs a buffer for .writer(), and these two functions print a help screen
  once; deprecatedWriter() is the same GenericWriter they were written against.

Zig analyses lazily, so this is the first wave and probably not the last. Each
round is measured on the runner rather than guessed -- the local toolchain is
0.16.0 and cannot stand in for 0.15.2.
Extension Release has been pointed at `extension/` since the tree was moved to
deploy/trinity-nexus/extensions. Every step after checkout ran against a
directory that does not exist, so the workflow could not have produced a
loadable extension on any tag since the move.

The move also lost twelve files -- both manifests and all six icons -- and the
reason it lost exactly those is in .gitignore. Two unanchored rules,
`extensions/` and `trinity-nexus/`, each match at any depth, so both matched
deploy/trinity-nexus/extensions. The 53 sibling source files were already
tracked and kept working; only files added AFTER the move were swallowed, which
is why nothing looked broken. That is the identical defect the comment three
lines below already records for `website/` on 2026-08-10. Anchoring both rules
exposes exactly twelve files repo-wide and nothing else -- measured, not
assumed; no top-level trinity-nexus/ exists, so that rule was protecting
nothing. The manifests and icons are restored from tag ext-v2.0.0.

chrome/icons/README.md stays ignored by the repo-wide `*.md` rule. The packaging
step excludes `*.md` from the zip, so it changes no artifact.

Six other rules in that block hide files below top level too (bin, demos, mcp,
models, runtime -- 27 files between them). They are not in the path of a release
workflow and are left alone rather than swept in here.

Build Compiler Release, separately:

- It fired on `v*`, publishing its own release body with its own asset table
  against the same tag as Binary Release. Whichever finished last won. Narrowed
  to `compiler-v*`, which was already in its trigger list.
- macos-latest is the SDK-26 wall that zig 0.15.2 cannot link its build runner
  against. Pinned to macos-14, same measurement as release.yml.
- goto-bus-stop/setup-zig is deprecated; mlugg/setup-zig@v2 everywhere.
- The notes claimed "Zig 0.13.0 used for compilation" while the env pins 0.15.2,
  linked downloads to gHashTag/vibee-lang (not this repository), and advertised
  ghcr.io/ghashtag/vibee -- an image nothing builds, under a tag that does not
  trigger docker-build.yml at all. The real image is ghcr.io/ghashtag/trinity.
- Artifacts named `vibee-*` were the `vibeec` binary, which is a different
  program from the `vibee` that Binary Release ships. Renamed to `vibeec-*`.
- Both "Test binary" steps ended in `|| echo "continuing"`, so they could not
  fail, and the macOS one ran against an x86_64 binary that cannot execute on
  an arm64 runner. Gated to the native target and allowed to fail.
- make_latest pinned false on both non-headline workflows: the action defaults
  it to true, which would put a compiler or extension tag above Trinity.

The probe gains a third job that builds the WASM module, packages both zips and
asserts manifest_version 3 and 2 by reading them back out of the archives.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Round two reported exactly one error -- compiler.zig:186 -- because zig
analyses lazily and each fix only exposes the next unreferenced body. Fixing
them one at a time costs a full CI cycle per line, and the tree has forty of
them. They are all the same mechanical substitution, so they all move together:

  std.io.getStdOut().writer()  ->  std.fs.File.stdout().deprecatedWriter()
  std.io.getStdErr().writer()  ->  std.fs.File.stderr().deprecatedWriter()
  std.io.getStdIn().reader()   ->  std.fs.File.stdin().deprecatedReader()
  std.io.getStdOut()           ->  std.fs.File.stdout()

deprecatedWriter returns the old GenericWriter, so `.any()` and `.print()` keep
working and nothing downstream has to change -- compiler.zig:186 hands its
result straight to ColorWriter.init as an AnyWriter.

igla_local_coder.zig:84 is left alone on purpose. That line is inside a `\\`
string literal: it is Zig source this file EMITS, not Zig source it compiles.
Rewriting it would change the generator's output, which is a separate question
from making this build.

Also, keeping the promise from the trinity-binary-release deletion: the probe
shows `zig build -Dci=true` installs firebird unconditionally alongside tri and
vibee -- 3.1 MB, present in zig-out/bin on a clean Linux run. It is now in all
five archive steps and named in the release notes, so the one thing the deleted
workflow shipped that release.yml did not is no longer lost.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GitHub could not parse dev-enforcement.yml. `steps:` was indented one level too
deep, under `if:`, so the pr-status job had no steps key. An unschedulable
workflow is reported as a failed run with an empty jobs array and the file path
where the workflow name should be -- which is exactly what every run since
c523c41 looks like, on every branch, including branches this work never
touched. `gh run view --log-failed` returns nothing because no job ever started.

So the "Phase 4 CI enforcement" added in #357 has enforced nothing for its
entire life. Fixing the indentation is one line; what the three jobs would then
do is the actual question, and two of them answer it badly.

session-check is removed. It read .trinity/dev_session.json, a committed
snapshot of one developer's local session, currently
{"state":"COMMITTED","issue_id":503,...}. The job queried `.issue_number`, which
does not exist in that file, so its "no active issue" guard compared the string
"null" against "0" and passed. It would have judged every pull request by a file
that does not change with the pull request -- green by accident rather than
green by absence, which is not an improvement.

ci-check is replaced by title-check. The original ran `git log -1` with no
checkout step, in an empty directory; even with one, HEAD on a pull_request
event is a synthetic merge commit whose subject is "Merge ... into ...". Its
regex `^\[a-f]+\((feat|fix|...)\(` requires a literal `[`, then `a-f`, then
parens around the type, and matches no conventional commit that has ever been
written. `$COMMIT` was never assigned, so the issue-ID branch tested an empty
string and took `exit 1` every time.

The replacement checks the pull request title, and warns rather than fails. That
is a measurement, not timidity: 105 of the last 120 merged pull requests match
the pattern and 15 do not, and the 15 are Russian-language prose titles and
`README:` prefixes -- a different convention, not malformed input. Making this
blocking would reject 12.5% of the repository's own recent history under a rule
nobody has agreed to, so the switch is left as a documented one-line change for
whoever decides to agree to it. The title reaches the script through env, never
through ${{ }} interpolation, so a pull request titled `$(...)` does not run on
the runner.

pr-status now works. The labels it wants -- status:in-progress,
status:completed -- do exist in this repository, so the job was only ever
missing `permissions: pull-requests: write`, a GH_TOKEN, and a PR number. Its
second step tested for action 'closed' while the workflow listened only for
[opened, synchronize], so the label could be applied and never removed;
'closed' is now a trigger and there is a third step for a close without a merge.
The job is continue-on-error because labelling is cosmetic and must not stand
between a change and its merge, and because a fork pull request gets a
read-only token no matter what permissions asks for.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
It existed to measure what could not be read, and each answer is now a line of
committed code rather than a claim:

  1. `zig build -Dci=true` installs firebird unconditionally -- 3.1 MB in
     zig-out/bin on a clean Linux runner, alongside tri and vibee and 45 others.
     firebird is in all five archive steps of release.yml because of that run,
     not because trinity-binary-release.yml used to copy it behind a
     `[ -f ] || echo "not found"` guard.

  2. src/vibeec reported one error per round, because zig analyses lazily and
     each fix only exposes the next unreferenced body. That is what turned a
     forty-site mechanical port into a forty-cycle CI loop, and why the whole
     migration went in at once instead.

  3. The extension packages end to end at its new paths: the WASM module builds,
     both zips assemble, and manifest_version reads back as 3 from the Chrome
     archive and 2 from the Firefox one -- asserted with `jq -e` inside the
     probe, so a zip with no manifest in it could not have passed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
src/vibeec had drifted out of step with zig 0.15 and nothing said so. No
workflow built it on a pull request, so the first thing to notice was a release
tag -- the one moment when discovering it is most expensive and least useful.
The port in 5ff9802 was measured through a throwaway probe for exactly that
reason.

A pull_request trigger scoped to src/vibeec/** and this file closes it. The
create-release job is already gated on startsWith(github.ref, 'refs/tags/'), so
a pull request builds all four binaries, runs the native smoke test, and
publishes nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the status:in-progress 🔵 Agent working label Sep 20, 2026
The probe's vibeec job was `continue-on-error: true` and its script captured
the exit code instead of returning it, so the job was green no matter what zig
said. Its last line was `=== exit 1, 3 error lines`, and the error was this one:

  compiler.zig:827:41: error: struct 'array_list.Aligned([]const u8,null)'
  has no member named 'init'

An enumerator job cannot prove a build. I reported "vibeec compiles" on the
strength of a green tick over an error list the same job had already printed.

The defect itself is zig 0.15's other rename: std.ArrayList is now the
UNMANAGED list, so `.init(allocator)` is gone from it and every call site would
have to start passing an allocator to append/deinit/toOwnedSlice.
std.array_list.Managed is the old type under its new name, with the same API,
so this is a rename rather than a migration -- 33 sites across 12 files, no
call site touched.

That is deliberate, not lazy. This tree is doing the real unmanaged migration
file by file: parser_v3, type_checker, verilog_codegen, gen_vibee_parser and
gen_parser_types already say `const ArrayList = std.ArrayListUnmanaged;` at the
top and pass allocators through. Converting twelve more files inside a
workflow-repair change would bury it. compiler.zig now carries the note saying
which line to look at.

kv_cache.zig is the one file that is half-migrated in place: four fields are
constructed `= .{}` (unmanaged) and five with `.init(allocator)`. Only the
latter moved; the unmanaged ones were left exactly as they are.

Local zig cannot check this: it is 0.16.0, which has removed
std.heap.GeneralPurposeAllocator and std.process.argsAlloc, and stops on the
first of those before reaching any ArrayList. CI is the only instrument here.
@gHashTag
gHashTag merged commit b07a9a8 into main Sep 20, 2026
38 of 45 checks passed
@gHashTag
gHashTag deleted the fix/release-workflows branch September 20, 2026 14:21
@github-actions github-actions Bot added status:completed Done and removed status:in-progress 🔵 Agent working labels Sep 20, 2026
dmitrii-f-t27 added a commit to dmitrii-f-t27/trinity that referenced this pull request Sep 21, 2026
Three workflows depend on repository secrets (PROJECT_TOKEN, CLAUDE_CODE_OAUTH_TOKEN)
that GitHub withholds on pull_request events from forks, so every fork PR has been
collecting red checks that can never pass: add-to-project ("Input required and not
supplied: github-token"), pr-opened ("set the GH_TOKEN environment variable") and
claude-review (empty claude_code_oauth_token). Each job now skips when the PR head
repository is not this repository; same-repo PRs and issue events are unchanged.

The branch also archived .github/workflows/dev-enforcement.yml, which had not
parsed since gHashTag#357. That part is dropped: gHashTag#1054 rewrote the file on main, it parses,
and its pr-status job already carries continue-on-error for fork pull requests.
Only the three guards remain.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gHashTag
gHashTag restored the fix/release-workflows branch September 28, 2026 10:01
dmitrii-f-t27 added a commit that referenced this pull request Oct 1, 2026
Three workflows depend on repository secrets (PROJECT_TOKEN, CLAUDE_CODE_OAUTH_TOKEN)
that GitHub withholds on pull_request events from forks, so every fork PR has been
collecting red checks that can never pass: add-to-project ("Input required and not
supplied: github-token"), pr-opened ("set the GH_TOKEN environment variable") and
claude-review (empty claude_code_oauth_token). Each job now skips when the PR head
repository is not this repository; same-repo PRs and issue events are unchanged.

The branch also archived .github/workflows/dev-enforcement.yml, which had not
parsed since #357. That part is dropped: #1054 rewrote the file on main, it parses,
and its pr-status job already carries continue-on-error for fork pull requests.
Only the three guards remain.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant