MemberJunction / MemberJunction/MJ
publish.yml cannot finish: its last two steps push directly to next, which next-protect now forbids
- Dominant language
- TSQL
- Stars
- 29
- Forks
- 6
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 323
Description
**Every release from v6.1.0-edge.6 onward will publish successfully and then fail.** First seen on edge.6 ([run 34550077699](https://github.com/MemberJunction/MJ/actions/runs/34550077699)).
## What happened
`publish.yml` published v6.1.0-edge.6 correctly — npm, tag, and GitHub Release all fine, `latest` unmoved:
```
@memberjunction/cli { latest: '5.51.2', 'lts-5': '5.51.2', edge: '6.1.0-edge.6' }
git tag v6.1.0-edge.6
main version 6.1.0-edge.6
```
It then failed on **step 22, `Merge main into next and update package-lock`**:
```
remote: error: GH013: Repository rule violations found for refs/heads/next.
- Changes must be made through a pull request.
- Required status check "Check migrations" is expected.
```
**Step 23, `Record the release in release-lines.json`, would have failed identically** — it ends in the same `git push origin HEAD:next`. It shows as `skipped` only because step 22 failed first. One cause, two broken steps.
## Root cause
The `next-protect` ruleset:
```
name: next-protect
created: 2024-06-11
updated: 2026-09-03T13:29:56-05:00
bypass actors: 0
rules: pull_request, required_status_checks, deletion, non_fast_forward
```
**Updated 2026-09-03, with zero bypass actors** — so GitHub Actions cannot push to `next` either.
The timing is conclusive:
| Release | Published | Step 22 | Step 23 |
|---|---|---|---|
| v6.1.0-edge.5 | 2026-09-02 — day *before* the change | ✅ success | ✅ success |
| v6.1.0-edge.6 | 2026-09-10 — after | ❌ rejected | skipped |
Same workflow, unchanged code. Nothing about edge.6 caused this; it is simply the first release to run after `next` was locked down.
## Why it matters
The failure is **after** publish, so packages always reach npm and the tag always lands. That is the trap: the release looks broken (red X on the publish job) while actually being fine, and the genuinely missing piece — `next` never receiving the version bumps — is silent. Someone has to notice and recover by hand every time.
Manual recovery for edge.6 is #4382.
## Fix — pick one
**Option A — change the two steps to open a PR instead of pushing.** Keeps `next-protect` exactly as intended and makes the release's own back-merge reviewable like every other change. Costs: every release ends with a PR someone must merge. This is what #4382 does by hand, so the shape is already proven.
**Option B — add a bypass actor** for the Actions app on `next-protect`. One setting, restores full automation — but it reopens direct pushes to `next` for anything running as that app, which is what the 2026-09-03 change appears deliberately aimed at closing.
**Recommend A**, and recommend asking whoever made the 2026-09-03 change first — if breaking the release pipeline was an unintended side effect they may simply want a scoped bypass, and that is their call rather than ours to route around.
## Repro
```bash
gh api repos/MemberJunction/MJ/rulesets/905656 \
--jq '"updated: \(.updated_at) bypass actors: \(.bypass_actors | length)"'
gh run view 34550077699 --json jobs \
--jq '.jobs[] | select(.name|contains("publish")) | .steps[] | select(.number>=22) | "\(.conclusion)\t\(.name)"'
```
## Acceptance
- A release publishes and completes **without a manual back-merge**
- `next` receives the version bumps and `release-lines.json` entry automatically
- `next-protect` keeps whatever protection the 2026-09-03 change intended
Contributor guide
Assessment
This issue has not been assessed yet.