Skip to content

Commit 96c5989

Browse files
dmealingclaude
andcommitted
docs: GitHub Actions is back on — correct the prose that says otherwise
Actions was disabled 2026-09-16 and re-enabled 2026-09-20; the API confirms `{"enabled":true}` and runs are landing on main. Ten passages across AGENTS.md and docs/RELEASING.md still told the reader the opposite, including that `ci-local.sh` is "the only thing that runs" the hosted lanes, that a `v*` tag fires nothing, and that the NuGet, PyPI and Maven publish triggers are inoperative. That is worse than merely stale in RELEASING.md, which is read WHILE cutting a release: it would have talked the next cut out of the tag-triggered conformance and integration gates, and out of the only NuGet path there is. Records why it came back, because the reason is a constraint and not a preference: publish-csharp.yml uses Trusted Publishing, and the short-lived nuget.org key is minted by `id-token: write` inside a workflow run. There is no long-lived NuGet key — only a NUGET_USER username — so with Actions off, NuGet cannot be published at all. The other three registries publish locally in the RC dance and must, because publish-python.yml and publish-java.yml take no version override and would publish the committed, non-RC version; that caveat is now stated at both of those steps rather than left implicit. Keeps publish-leak-scan-status.sh documented rather than dropped: main's protection requires the leak-scan status, hygiene.yml publishes it again now, but a direct admin push to main bypasses branch protection and so never gets a PR's hosted scan. Also records the toggle's own trap — `-F enabled=true` for a typed boolean, since `-f` sends the string and 422s. History is kept where it explains a decision, marked as history, instead of being deleted outright. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015NrWUxA6euwvnFcwKxcK6A
1 parent fbc13d8 commit 96c5989

3 files changed

Lines changed: 48 additions & 46 deletions

File tree

‎AGENTS.md‎

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -109,31 +109,39 @@ runs — goes red, and a direct admin push to `main` bypasses branch protection.
109109
skipped entirely for non-TS pushes). Bypass in an emergency with `git push --no-verify`
110110
or `SKIP_TS_TYPECHECK=1 git push`.
111111

112-
**GitHub Actions is DISABLED on this repository (2026-09-16) — every check runs locally.**
113-
The workflow files are kept and unchanged, because the switch is reversible, but nothing in
114-
`.github/workflows/` fires today: not `hygiene.yml`'s leak scan on a PR, not `conformance.yml`'s
115-
nightly + `v*`-tag matrix, and not `local-ci.yml` on the self-hosted runner. **`scripts/ci-local.sh`
116-
is now the only thing that runs them**, and it already mirrors all three — `--quick` covers
117-
`hygiene.yml` in full plus the TypeScript half of `conformance.yml`, and the flagless full run
112+
**GitHub Actions is ENABLED (re-enabled 2026-09-20, and it stays on).** It was off from
113+
2026-09-16, and a good deal of the prose below was written for that period — read any claim
114+
that "nothing fires" as history. It came back because **NuGet cannot be published without
115+
it**: `publish-csharp.yml` uses Trusted Publishing (OIDC), and the short-lived key is minted
116+
by `id-token: write` INSIDE a workflow run. There is no long-lived NuGet key to publish with
117+
locally — only a `NUGET_USER` username. The other three registries publish LOCALLY in the RC
118+
dance and must: `publish-python.yml` and `publish-java.yml` take no version override, so they
119+
would publish the committed (non-RC) version; only `publish-csharp.yml` has a `version` input.
120+
(To toggle it: `gh api -X PUT repos/<owner>/<repo>/actions/permissions -F enabled=true` — `-F`
121+
for a TYPED boolean, since `-f` sends the string `"true"` and 422s.)
122+
123+
**`scripts/ci-local.sh` is still the pre-PR gate**, and it mirrors the hosted lanes —
124+
`--quick` covers `hygiene.yml` in full plus the TypeScript half of `conformance.yml`, and the
125+
flagless full run
118126
adds the C#/Java/Kotlin/Python conformance lanes, the Java reactor and `integration-tests.yml`'s
119127
Testcontainers matrix. Run `--quick` before opening a PR and the full script before a tag;
120128
`MO_CI_LIST_ONLY=1 scripts/ci-local.sh [flags]` prints what a selection would run without
121129
running it. The no-mistakes validation gate runs the script for you — see `.no-mistakes.yaml`,
122130
whose `lint` and `test` commands partition `--quick` between the two steps. That file is read
123131
from the **default branch**, so it does nothing until it is merged to `main`.
124132

125-
**A green `leak-scan` check on a PR is a LOCAL scan, not a hosted one.** `main`'s protection
126-
requires that one status, and `hygiene.yml` was the only thing that ever published it — so with
127-
Actions off, nothing could merge. Rather than weaken the rule, `scripts/publish-leak-scan-status.sh`
128-
runs `.githooks/leak-scan.sh` and reports that exact result as the `leak-scan` commit status,
129-
bound to the SHA it scanned. Run it after pushing, once per head you want mergeable. It publishes
130-
the real verdict only — a failed scan publishes `failure` — and refuses outright on a dirty tree,
131-
on a HEAD that moved mid-scan, or with no credential. The status description repeats the caveat,
132-
so the PR page carries it too. No hosted scan runs while Actions is off, on any branch.
133+
**`leak-scan` is hosted again.** `main`'s protection requires that one status, and `hygiene.yml`
134+
is the only thing that publishes it — so while Actions was off, nothing could merge. Rather than
135+
weaken the rule, `scripts/publish-leak-scan-status.sh` runs `.githooks/leak-scan.sh` and reports
136+
that exact result as the `leak-scan` commit status, bound to the SHA it scanned. With Actions on
137+
you do NOT need it; keep it for the next time Actions is off, and for a direct admin push to
138+
`main` (which bypasses branch protection and so never gets a PR's hosted scan). It publishes the
139+
real verdict only — a failed scan publishes `failure` — and refuses outright on a dirty tree, on
140+
a HEAD that moved mid-scan, or with no credential. A status it published is a LOCAL scan, and its
141+
description says so on the PR page.
133142

134143
**Lane selection is "not known-green", not "affected"** (`scripts/ci-ports-to-run.sh`).
135-
This is how `local-ci.yml` chooses its lanes, so it is dormant while Actions is off — but
136-
it is still committed and still gated, and it is what resumes if Actions comes back.
144+
This is how `local-ci.yml` chooses its lanes, and with Actions back on it is live again.
137145
The selector unions the ports this push touched (`scripts/ci-affected-ports.sh`) with
138146
the ports whose *newest* verdict on `main` is not a success, read from the workflow's
139147
own run history — so a stale red lane gets **re-run**, not merely reported. Affected

‎docs/RELEASING.md‎

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -201,11 +201,11 @@ Publish in tier order so a dependent never lands before its dependency. **`forge
201201
a review found eight defects in 172 lines. If you change a gate, change its case there —
202202
and check the change against a mutation, not just a green run.
203203

204-
**A second effect, dormant while Actions is off.** `conformance.yml` and
205-
`integration-tests.yml` used to be the heavy gates that ran on a `v*` tag and nowhere
206-
else; today they run nowhere, and step 3 above is what gates the cut instead. The
207-
ordering still earns its place, because if Actions is re-enabled those runs land on the
208-
FINAL coordinated tree — all four registries bumped, docs refreshed, payload true —
204+
**A second effect.** `conformance.yml` and `integration-tests.yml` are the heavy gates
205+
that run on a `v*` tag and nowhere else. (They were dormant while Actions was off,
206+
2026-09-16 to 09-20, and step 3 above was what gated the cut instead; step 3 still
207+
earns its place, because it is the only gate that runs BEFORE the tag.) The ordering
208+
matters because those runs land on the FINAL coordinated tree — all four registries bumped, docs refreshed, payload true —
209209
instead of the npm-only commit, which is a tree that never actually shipped.
210210
`publish-npm.yml` triggers on `npm-v*`, not `v*`, so moving the tag does not re-trigger
211211
a publish.
@@ -264,7 +264,7 @@ days**.
264264

265265
**The gate: `node scripts/check-metamodel-version.mjs`** (runs in the `gates` lane, so any
266266
`scripts/ci-local.sh` run that includes `gates` enforces it — `--quick`, `--only gates`, or
267-
the flagless full run; hosted CI does not, because Actions is disabled here). It diffs
267+
the flagless full run). It diffs
268268
`expected-registry.json` — already the byte-exact bill of materials every port is gated
269269
against — against its content at the **last release tag**, classifies every difference,
270270
and fails if the declared version did not move by at least the amount the change
@@ -408,11 +408,10 @@ diff explained.
408408
> improvement (research-backed, not yet adopted)" that `.claude/skills/releasing/SKILL.md`
409409
> still files it under.
410410
>
411-
> **That replacement is itself inoperative right now: GitHub Actions is disabled on this
412-
> repository (2026-09-16), so `publish-npm.yml` cannot fire** and a registration would have
413-
> no runner to serve it. The publishing path that replaces the token after the 2027
414-
> deadline is being decided and is not written down yet; until it is, the local-token
415-
> procedure above is the only npm publishing path that runs.
411+
> The publishing path that replaces the token after the 2027 deadline is being decided and
412+
> is not written down yet; until it is, the local-token procedure above is the npm
413+
> publishing path we actually use. (It was additionally blocked while Actions was off,
414+
> 2026-09-16 to 09-20 — Actions is back on, so `publish-npm.yml` can fire again.)
416415
- `bun publish` does **not** apply `publishConfig` field overrides (bin/main/exports) — only
417416
`access`/`tag` (oven-sh/bun#19205). So fields like `bin` must be correct at the top level, not
418417
swapped via `publishConfig`.
@@ -546,11 +545,9 @@ and deleting a dist-tag is package access. Measured across all 14 packages on 20
546545
the prerelease install path, which is the actual harm; the tag continuing to exist alongside an
547546
identical `latest` is cosmetic.
548547
549-
**The CI route is inoperative right now (2026-09-16): GitHub Actions is disabled on this
550-
repository, so the dispatch below cannot run**, and the replacement path is being decided.
551-
Until it lands, the `dist-tag add` above is what repoints the tag — run from your machine,
552-
per package. The dispatch is kept because the switch is reversible: it ran the whole
553-
set from CI, where the publish token already lives — Actions →
548+
Either route works: the `dist-tag add` above run from your machine, per package, or the CI
549+
dispatch, which does the whole set at once from where the publish token already lives —
550+
Actions →
554551
**npm dist-tag** → Run workflow → tag `next`, action `add`, version `<version>`
555552
([`.github/workflows/npm-dist-tag.yml`](../.github/workflows/npm-dist-tag.yml); the set and its
556553
order come from `scripts/publish-set.mjs`, never a list maintained there). Action `ls` is the
@@ -593,11 +590,9 @@ The workflow [`.github/workflows/publish-csharp.yml`](../.github/workflows/publi
593590
the four projects, exchanges a GitHub OIDC token for a short-lived (~1 hour) nuget.org key via
594591
`NuGet/login@v1`, then `dotnet nuget push`es.
595592
596-
**Both triggers are inoperative right now (2026-09-16): GitHub Actions is disabled on this
597-
repository, so neither the manual dispatch nor a `csharp-v*` tag can run anything** — and a
598-
NuGet publish fundamentally needs Actions for its OIDC exchange, so there is no local
599-
stand-in; the replacement path is being decided. The workflow and the one-time setup below
600-
are kept as the mechanism record, because the switch is reversible. Trigger it manually
593+
**A NuGet publish fundamentally needs Actions for its OIDC exchange — there is no local
594+
stand-in.** That is why Actions was re-enabled on 2026-09-20 after four days off: with it
595+
disabled, NuGet simply cannot be published. Trigger it manually
601596
(**Actions → publish-csharp → Run workflow**, with an optional version override) or by
602597
pushing a `csharp-v*` tag once it fires again.
603598
@@ -660,19 +655,18 @@ lock the repo/owner IDs against resurrection attacks.)
660655
dotnet tool install --global --add-source /tmp/mo-nupkg MetaObjects.Cli && dotnet meta --help
661656
```
662657
3. **Run persistence conformance** if the runtime/codegen changed: `scripts/integration-test.sh csharp`.
663-
4. **Publish:** GitHub → **Actions → publish-csharp → Run workflow** (or push a `csharp-v<version>` tag)
664-
— **inoperative while Actions is off (2026-09-16)**; see the note under "How we publish" above.
658+
4. **Publish:** GitHub → **Actions → publish-csharp → Run workflow** (or push a `csharp-v<version>` tag).
659+
This is the one registry that CANNOT be published locally — see "How we publish" above.
665660
5. **Verify** on nuget.org: all four packages listed and **owned by the `metaobjects` org**
666661
(indexing/validation takes a few minutes).
667662
668663
# Releasing the Python package to PyPI
669664
670665
How to publish the **`metaobjects`** Python package to PyPI: push a `python-v<version>` tag and
671-
the workflow publishes it with the `PYPI_API_TOKEN` repo secret. **That trigger is inoperative
672-
right now (2026-09-16): GitHub Actions is disabled on this repository, so the tag fires
673-
nothing** — and PyPI publishing here runs only through the workflow, so there is no local
674-
stand-in; the replacement path is being decided. The workflow description below is kept as the
675-
mechanism record, because the switch is reversible.
666+
the workflow publishes it with the `PYPI_API_TOKEN` repo secret. PyPI publishing here runs
667+
only through that workflow — there is no local stand-in. Note `publish-python.yml` takes no
668+
version override, so it publishes the COMMITTED version: in the RC dance, do not fire it for
669+
a pre-release you have not committed.
676670
677671
## What gets published
678672
@@ -764,8 +758,8 @@ versioned on its own major line — npm major + 7, so `7.x` while npm was `0.x`
764758
3. **Deploy — ONE of two routes, never both** (a second deploy of a published version fails
765759
with `Component … already exists`): push a `java-v<maven-version>` tag, and
766760
`publish-java.yml` runs the deploy below in CI with the signing secrets (how `8.0.4`
767-
shipped — **inoperative while Actions is off, 2026-09-16**: GitHub Actions is disabled on
768-
this repository, so the tag fires nothing); or run `mvn -Prelease deploy` from `server/java`.
761+
shipped; it takes no version override, so it deploys the COMMITTED version — do not fire
762+
it for an uncommitted pre-release); or run `mvn -Prelease deploy` from `server/java`.
769763
The `central-publishing-maven-plugin`
770764
(`<publishingServerId>central</publishingServerId>`, `<autoPublish>true</autoPublish>`) uploads
771765
the signed bundle and auto-releases — **no manual staging → release promotion**. Auth + the GPG

server/typescript/packages/codegen-ts/test/relation-resolver-m2m-warn.test.ts renamed to server/typescript/packages/codegen-ts/test/relation-resolver-m2m-unpairable.test.ts

File renamed without changes.

0 commit comments

Comments
 (0)