activescott / activescott/auth

Require CI checks before merging PRs without breaking the simple-release push to main

Open
#63 0 comments 0 reactions 0 assignees View on GitHub
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.