activescott / activescott/auth
Require CI checks before merging PRs without breaking the simple-release push to main
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
## Problem
`main` has **no branch protection** today (`GET /repos/activescott/auth/branches/main/protection` returns empty). Any PR can be merged with red, missing, or never-started checks, and the release workflow then runs against whatever landed. This came up during the 2026-08-06 GitHub Actions outage, when PR #62's `validate` and `example-e2e` jobs were cancelled by the platform without ever being assigned a runner — and the PR was still mergeable.
We want CI (`validate`, `example-e2e`) to be **required** before a PR can merge.
## Why it isn't a one-liner
The release job pushes directly to `main`. `scripts/release.ts:46` calls `simple-release`'s `GithubHosting.push()`, which commits the version bumps and pushes the commit + tags as `github-actions[bot]` (e.g. commit `857dde2`, committer `github-actions[bot]`).
Rulesets and classic branch protection gate **direct pushes** as well as PR merges. So naively requiring a PR and/or status checks on `main` rejects the release bot's push, and **publishing silently stops**.
The usual escape hatch — exempting the GitHub Actions app as a bypass actor — is unavailable here. Attempting it returns:
```
422 Validation Failed
Actor GitHub Actions integration must be part of the ruleset source or owner organization
```
`activescott` is a personal account, not an org, so `actor_type: "Integration"` bypasses aren't allowed. The draft ruleset that failed is otherwise sound: PR required (0 approvals), required status checks `validate` + `example-e2e`, plus `deletion` and `non_fast_forward` rules.
## Constraint: no long-lived credentials on runners
The obvious workaround — issue a fine-grained PAT for the repo owner, store it as an Actions secret, and have the release job push with it (then bypass via the admin repository role) — is **explicitly not wanted**. Long-lived tokens sitting in CI were the exact target of the recent npm/GitHub credential-harvesting campaigns. A solution should avoid adding a durable push credential to the runner environment.
Note the repo already avoids a long-lived npm token by using OIDC trusted publishing for `npm publish`; the git push is the remaining gap.
## Options to evaluate
1. **Release opens a PR instead of pushing.** Ruleset enforced with no bypass at all; the version-bump commit goes through an auto-merging PR. No new credential. Costs a round trip per release and some rework of `scripts/release.ts` / the workflow — needs a look at whether `simple-release` supports a PR-based flow or whether we drive it ourselves.
2. **GitHub App with short-lived tokens.** Create an app owned by the account, install it on the repo, mint an installation token at job runtime (e.g. `actions/create-github-app-token`), push with that. Tokens are minted per run and expire in an hour, so nothing durable lives on the runner — but the app's private key does become an Actions secret, so this trades one long-lived secret for another (arguably better scoped, still worth weighing against option 1).
3. **Move the repo to an organization.** Unlocks `Integration` bypass actors, making the original ruleset work as drafted. Largest blast radius; probably only worth it if there are other reasons to want an org.
4. **Status quo + convention.** Checks still run and are visible on every PR; merging red is possible but not done. Zero risk to releases, no enforcement.
## Suggested next step
Try option 1 first — it's the only one that adds no secret at all. If `simple-release` can't be driven that way without significant surgery, evaluate option 2.
## Acceptance criteria
- Merging a PR into `main` is blocked until `validate` and `example-e2e` pass.
- `chore(release)` commits and package tags still reach `main` automatically, and npm publishing still works.
- No long-lived push credential is stored in Actions secrets or on runners.
## Context / references
- The draft ruleset JSON and the 422 above were produced on 2026-08-06 while investigating this.
- Same pattern exists in `activescott/ramblefeed` (its release job also pushes to `main`), so whatever we land here is probably worth repeating there.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.