ci(stlc): stop the seal step opening no-op PRs - #7
Merged
Conversation
`stlc build` writes a fresh empty `seal` commit into each staging SDK repo on every run. Its SHA lands in `stainless/custom-code/*.json` as `base` (and sometimes `integrated`), so the tracking files came back dirty on every run even though the generated code was byte-identical — every seal commit since 2026-08-24 has `files=0` and the same tree (`e47029ff80` for python, `d7d81c1d43` for typescript). With auto-merge disabled on this repo, `gh pr merge --auto` fails and only warns, so PR #6 sat open from 2026-09-04 and the 6-hourly cron force-pushed a new head onto it four times a day, mailing every repo watcher each time. Resolve each changed SHA to the tree it points at and skip the seal when no tree actually moved. Anything unresolvable — a new or deleted file, a change to a non-SHA field, a commit the API cannot return — is treated as a real change, so the guard can only ever suppress verified churn. Also cut the cron from every 6h to daily; it is only a backstop for a missed `repository_dispatch: seal-custom-code`, which already fires eagerly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
With the churn guard in place a seal PR only appears when custom code genuinely moved, so it warrants review rather than an automatic squash. Drop the `gh pr merge --auto` attempt (which never worked here anyway — `allow_auto_merge` is false on this repo, so it only ever emitted a warning) and surface the waiting PR by number instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
✱ stlc build✅ python code · compare
✅ typescript code · compare
Diagnostics:
|
| Level | Code | Message | Targets |
|---|---|---|---|
Python/PublishingWithoutOIDC | Publishing security issue: trusted publishing with OIDC is not enabled.#/targets/python/publish/pypi | python | |
TypeScript/PublishingWithoutOIDC | Publishing security issue: trusted publishing with OIDC is not enabled.#/targets/typescript/publish/npm | typescript | |
| 💡 note | ReadmeExample/UnknownResponseProperty | Response property `chunking_options` is not defined on the response for method `create`.(resource) classifications.universal > (method) create | python |
Build metadata
| Build | bd_76JPXHrs-crisp-pouch |
| Timestamp | 2026-09-07T21:31:14.953Z |
| stlc | 20323f6 |
| Spec hash | 155f43207a56 |
| Config hash | b715dd754785 |
This comment is auto-generated by stlc and is kept up to date as you push.
If you push new commits, re-run this workflow to update this comment.
Last updated: 2026-09-07 21:33:00 UTC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
stlc buildwrites a fresh emptysealcommit into each staging SDK repo on every run. Its SHA lands instainless/custom-code/*.jsonasbase(and sometimesintegrated), so the tracking files come back dirty on every run even when the generated code is byte-identical.Every
sealcommit since 2026-08-24 hasfiles=0and an identical tree:Note
9bd01165and707a1c50share a parent — they are siblings, not a chain. Each run builds a throwaway empty commit and abandons the previous one. TypeScript is the same: one tree,d7d81c1d43, unchanged since 2026-08-31.Because
allow_auto_mergeisfalseon this repo,gh pr merge --autofails and only emits a::warning::. PR #6 therefore sat open from 2026-09-04, and the 6-hourly cron force-pushed a new head onto it four times a day — mailing every repo watcher each time.Fix
Churn guard in the seal step. Before committing, resolve each changed
base/integratedSHA to the tree it points at and skip the seal when no tree moved. It fails safe in every direction — a new or deleted file, a change to a non-SHA field, or a commit the API cannot resolve all count as a real change — so it can only ever suppress verified churn.Cron cut from every 6h to daily. It is only a backstop for a missed
repository_dispatch: seal-custom-code, which already fires eagerly when an SDK repo seals custom code.Verification
Guard body run against live repo data:
main7b1a0b41 → seal 707a1c50)base→ commit with a genuinely different treebranch) changedOn the real case:
That third line is worth noting: even the
Build SDKcommits on stagingmainare content-free.YAML parses and every
run:block passesbash -n.Merging policy
Seal PRs are deliberately not auto-merged. With the churn guard in place a seal PR only appears when custom code genuinely moved, which warrants a human look. The
gh pr merge --autoattempt is dropped — it never worked here anyway, sinceallow_auto_mergeisfalseon this repo, so it only ever emitted a warning. The step now surfaces the waiting PR by number instead:allow_auto_mergestays off.🤖 Generated with Claude Code