Skip to content

Ci/pr size check - #338

Merged
AlexAxthelm merged 9 commits into
mainfrom
ci/pr-size-check
Oct 21, 2026
Merged

AlexAxthelm merged 9 commits into
mainfrom
ci/pr-size-check

Conversation

@AlexAxthelm

@AlexAxthelm AlexAxthelm commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

Adds a CI check to the "Admin" family to check that PRs are smallish (currently 600 LoC changed/added/removed). The bulk of this is in a bash script inlined in the workflow file (should be extracted if we move this over to RMI/actions), which has some modest hardening (such as checking that line limit is an integer, or failing if the exemptions are malformed).

Some neat features:

  • Can exempt certain files (lockfiles can really blow up the line limits)
  • Don't run for certain HEAD branches: next, production, so that releases and backmerges, which are gong to be bigger than a single PR's worth

What

Adds a Check PR size job to Admin Checks. It fails a PR that changes more than 600 lines (additions + deletions), so oversized PRs get split before they reach review.

How it works

  • New reusable workflow admin-pr-size.yml, called from admin.yml, with three inputs:
    • max_lines: default 600. Must be a whole number; anything else fails the check with a clear error.
    • ignore: newline-delimited git glob pathspecs that aren't counted. Stitch passes **/uv.lock and **/package-lock.json.
    • exempt_head_branches: JSON array of source branches in this repo whose PRs skip the check. Stitch passes main, next, production (release promotions and backmerges).
  • Counts lines with git diff --numstat from the merge base with the target branch's current tip to the PR head. This matches GitHub's "Files changed" view. git diff --stat is printed to the job log so authors can see where the lines are.
  • Only runs on pull_request events. It's skipped on push/schedule/dispatch runs of Admin Checks. Fork PRs are never exempt, even from a branch named main.
  • Documented in CONTRIBUTING.md under "PR Size".

Impact on recent PRs

Of the last ~48 non-release PRs, 7 would have failed: #316, #293, #283, #282, #277, #276, #267. Dependabot PRs pass because lockfiles are ignored (#270: 607 raw lines → 16 counted).

Not in this PR

  • Not a required status check yet. Follow-up: add Check PR size / Check PR size to gitflow-main.overlay.json and update the live ruleset at the same time.
  • Retargeting a PR's base doesn't re-run the check until the next push, because Admin Checks uses the default pull_request event types.

Testing

AI assistance

Claude Code drafted the workflow and docs, ran the local replays above, and reviewed the branch. I made the design decisions (fail with no override, configurable ignore list, release/backmerge exemption, not required yet), simplified the script and messages, and reviewed each change before committing.

🤖 Generated with Claude Code

AlexAxthelm and others added 6 commits October 20, 2026 15:42
Add a reusable admin-pr-size workflow that fails a pull request when it
changes more than `max_lines` lines (additions + deletions, default 600),
counted with `git diff --numstat` against the merge base. An `ignore`
input takes git glob pathspecs whose changes are not counted; stitch
ignores uv.lock and package-lock.json.

Release promotions and backmerges (PRs whose source branch is main, next,
or production) are exempt, and the check only runs on pull_request
events. It is not yet a required status check.

Document the limit in CONTRIBUTING.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A PR from a fork's `main` (the usual way external contributors submit,
per CONTRIBUTING.md) matched the release/backmerge exemption because it
only compared the source branch name. Also require the head repository
to be this repository.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Use origin/$BASE_REF instead of the event's base SHA as the left side of
the three-dot diff. If the base SHA predates a merge of the target into
the PR branch, the merge base falls back to it and the target's own
changes get counted (replaying #282 this way gives 7040 lines instead of
650).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Move the release/backmerge branch list out of the reusable workflow and
into admin.yml, next to the ignore list, so all of stitch's PR size
policy lives in the caller. The input is a JSON array because the
job-level `if:` can only read lists via fromJSON(); it defaults to no
exemptions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`max_lines` is a number input, so decimals are accepted, but the `-gt`
comparison is integer-only. Inside an `if`, its error status was treated
as false and the check passed (e.g. 1014 lines vs max_lines=600.5).
Validate it up front and fail with a clear message instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

CD summary b7948f3

Frontend: https://witty-mushroom-017a3dc1e-338.westus2.1.azurestaticapps.net

Deployments (3)
service url fqdn
api open pr-0338-api.purplegrass-c07d0a94.westus2.azurecontainerapps.io
frontend https://witty-mushroom-017a3dc1e-338.westus2.1.azurestaticapps.net
stitch-llm open pr-0338-llm.purplegrass-c07d0a94.westus2.azurecontainerapps.io
Database (1)
db_name postgres_host postgres_port postgres_db
pr_0338 stitch-dev.postgres.database.azure.com 5432 pr_0338
Jobs (2)
job image postgres_db api_url auth_mode
db-migrations ghcr.io/rmi/stitch-api:pr-0338@sha256:fc4bc9ad3b229857d3e4ec92580cec7b362761d9932d20f402b07e1f74010390 pr_0338
seed ghcr.io/rmi/stitch-seed:pr-0338@sha256:4eb21dabaf03de8d1db2eeb375dfa911371fdbb5835cc6361e095ccb93b35618 https://pr-0338-api.purplegrass-c07d0a94.westus2.azurecontainerapps.io/api/v1 stitch-client-bearer-token
Images (3)
build_time commit_time git_sha image image_digest
2026-10-20T14:50:00Z 2026-10-20T14:49:40Z 5ce8055 ghcr.io/rmi/stitch-api:pr-0338 ghcr.io/rmi/stitch-api:pr-0338@sha256:fc4bc9ad3b229857d3e4ec92580cec7b362761d9932d20f402b07e1f74010390
2026-10-20T14:49:58Z 2026-10-20T14:49:40Z 5ce8055 ghcr.io/rmi/stitch-seed:pr-0338 ghcr.io/rmi/stitch-seed:pr-0338@sha256:4eb21dabaf03de8d1db2eeb375dfa911371fdbb5835cc6361e095ccb93b35618
2026-10-20T14:50:01Z 2026-10-20T14:49:40Z 5ce8055 ghcr.io/rmi/stitch-stitch-llm:pr-0338 ghcr.io/rmi/stitch-stitch-llm:pr-0338@sha256:5601053519298cc6ea47ad2b0268a04a7801e9428361cd00ec9c35564878a3c6

@github-actions

Copy link
Copy Markdown

CD summary 4c7728d

Frontend: https://witty-mushroom-017a3dc1e-338.westus2.1.azurestaticapps.net

Deployments (3)
service url fqdn
api open pr-0338-api.purplegrass-c07d0a94.westus2.azurecontainerapps.io
frontend https://witty-mushroom-017a3dc1e-338.westus2.1.azurestaticapps.net
stitch-llm open pr-0338-llm.purplegrass-c07d0a94.westus2.azurecontainerapps.io
Database (1)
db_name postgres_host postgres_port postgres_db
pr_0338 stitch-dev.postgres.database.azure.com 5432 pr_0338
Jobs (1)
job image postgres_db
db-migrations ghcr.io/rmi/stitch-api:pr-0338@sha256:89b3f6bc5fa5c1dcec2b57bb2f62880554e1f8bb23c5f25f123e7568e99fec97 pr_0338
Images (3)
build_time commit_time git_sha image image_digest
2026-10-20T14:56:30Z 2026-10-20T14:56:04Z f3a67e9 ghcr.io/rmi/stitch-api:pr-0338 ghcr.io/rmi/stitch-api:pr-0338@sha256:89b3f6bc5fa5c1dcec2b57bb2f62880554e1f8bb23c5f25f123e7568e99fec97
2026-10-20T14:56:53Z 2026-10-20T14:56:04Z f3a67e9 ghcr.io/rmi/stitch-seed:pr-0338 ghcr.io/rmi/stitch-seed:pr-0338@sha256:895add6c38e9298b5575d58c1146eb3d6a9e8e7b5c88c3e8a556e99300458516
2026-10-20T14:56:28Z 2026-10-20T14:56:04Z f3a67e9 ghcr.io/rmi/stitch-stitch-llm:pr-0338 ghcr.io/rmi/stitch-stitch-llm:pr-0338@sha256:f3b60b7d5337dc6ec19436a353cc741eec2e7cb252b6e25556bad54fe138dc35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Two moderate findings remain regarding exemption input validation and the check being modifiable by the PR itself.

1 open issue
What changed in this PR

Adds a reusable Admin CI check limiting pull requests to 600 changed lines, with lockfile exclusions and branch exemptions.

Changes:

  • Documents PR size policy.
  • Integrates the check into Admin Checks.
  • Adds diff-based counting, validation, and exemptions.
File Description
CONTRIBUTING.md Documents PR size limits and exemptions.
.github/​workflows/​admin.yml Configures the PR-size check.
.github/​workflows/​admin-pr-size.yml Implements validation, exemptions, and line counting.

Review effort: Lite

Comment thread .github/workflows/admin-pr-size.yml Outdated
@github-actions

Copy link
Copy Markdown

CD summary b1a90e2

Frontend: https://witty-mushroom-017a3dc1e-338.westus2.1.azurestaticapps.net

Deployments (3)
service url fqdn
api open pr-0338-api.purplegrass-c07d0a94.westus2.azurecontainerapps.io
frontend https://witty-mushroom-017a3dc1e-338.westus2.1.azurestaticapps.net
stitch-llm open pr-0338-llm.purplegrass-c07d0a94.westus2.azurecontainerapps.io
Database (1)
db_name postgres_host postgres_port postgres_db
pr_0338 stitch-dev.postgres.database.azure.com 5432 pr_0338
Jobs (1)
job image postgres_db
db-migrations ghcr.io/rmi/stitch-api:pr-0338@sha256:51289a67187091beab3a541fadbd9efb2f98b8e71318e1042ad06dd77cf1e934 pr_0338
Images (3)
build_time commit_time git_sha image image_digest
2026-10-20T15:08:07Z 2026-10-20T15:07:42Z b86411a ghcr.io/rmi/stitch-api:pr-0338 ghcr.io/rmi/stitch-api:pr-0338@sha256:51289a67187091beab3a541fadbd9efb2f98b8e71318e1042ad06dd77cf1e934
2026-10-20T15:08:01Z 2026-10-20T15:07:42Z b86411a ghcr.io/rmi/stitch-seed:pr-0338 ghcr.io/rmi/stitch-seed:pr-0338@sha256:3c29aa13d94b7ed4f779d37686dc414ce82579ba5a53cdf8668aab1176174426
2026-10-20T15:08:01Z 2026-10-20T15:07:42Z b86411a ghcr.io/rmi/stitch-stitch-llm:pr-0338 ghcr.io/rmi/stitch-stitch-llm:pr-0338@sha256:72501767a1efe88963cee19b08a2d51feb97d91c3262a3fd5bb96906c297f673

The job-level `if:` used contains(fromJSON(...)), which matches
substrings if the input isn't an array and ignores case, so a same-repo
branch named `Main` or `NEXT` was exempt. Check the exemption in the
bash step with an exact, case-sensitive match instead, and make
exempt_head_branches newline-delimited like `ignore`. Exempt PRs now
pass with a notice instead of being skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

CD summary 7149c98

Database (1)
db_name postgres_host postgres_port postgres_db
pr_0338 stitch-dev.postgres.database.azure.com 5432 pr_0338
Jobs (1)
job image postgres_db
db-migrations ghcr.io/rmi/stitch-api:pr-0338@sha256:c74266db14c72c08155b248a35a3e4d4d723f07bacef0e5c0f992ca76f47b18d pr_0338
Images (3)
build_time commit_time git_sha image image_digest
2026-10-20T15:34:09Z 2026-10-20T15:33:49Z 52748de ghcr.io/rmi/stitch-api:pr-0338 ghcr.io/rmi/stitch-api:pr-0338@sha256:c74266db14c72c08155b248a35a3e4d4d723f07bacef0e5c0f992ca76f47b18d
2026-10-20T15:34:08Z 2026-10-20T15:33:49Z 52748de ghcr.io/rmi/stitch-seed:pr-0338 ghcr.io/rmi/stitch-seed:pr-0338@sha256:6e957368ca5b5a45800fa19924ce735c0dd910ef969ba3e3f1f8e9b0cf739cc3
2026-10-20T15:34:11Z 2026-10-20T15:33:49Z 52748de ghcr.io/rmi/stitch-stitch-llm:pr-0338 ghcr.io/rmi/stitch-stitch-llm:pr-0338@sha256:e4a7c61c70954a1ba3a7341731041fff8c2275218cb5a1648b1787de6dceb79a

@mbarlow12 mbarlow12 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. 💯

@mbarlow12

mbarlow12 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

I also just realized that I'd absolutely use this locally during development. I think Claude could also make some great use of it as a halting condition and/or warning. It's a strong signal that the workstream might be going in an undesirable direction, especially if it's run early in implementation and there's a lot left to change.

It could as a bit of a self-check that's run periodically by the agent, and if it fails, the agent knows to stop and discuss the plan/design with the user. Or could be use in a loop to keep tests passing while reducing change size.

@AlexAxthelm

Copy link
Copy Markdown
Collaborator Author

I also just realized that I'd absolutely use this locally during development. I think Claude could also make some great use of it as a halting condition and/or warning. It's a strong signal that the workstream might be going in an undesirable direction, especially if it's run early in implementation and there's a lot left to change.

It could as a bit of a self-check that's run periodically by the agent, and if it fails, the agent knows to stop and discuss the plan/design with the user. Or could be use in a loop to keep tests passing while reducing change size.

Hmm. one of the things that I was back-and-forthing with myself with on this was to pull the inline bash script out to a separate file. But that sounds useful so that we could invoke it separately in local dev cycles

@AlexAxthelm
AlexAxthelm merged commit b8bc878 into main Oct 21, 2026
51 of 53 checks passed
@AlexAxthelm
AlexAxthelm deleted the ci/pr-size-check branch October 21, 2026 06:47

This branch was successfully deployed

1 active deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants