Automate upstream release docs PRs via Renovate#748
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Automates creation and augmentation of upstream-release documentation PRs by having Renovate bump pinned upstream versions and a workflow generate source-verified doc updates and PR metadata.
Changes:
- Add Renovate custom manager + rules to monitor
.github/upstream-projects.yamland open version-bump PRs for tracked upstream repos. - Add
Upstream Release Docsworkflow to detect the changed project, run the multi-passupstream-release-docs+docs-reviewprocess, push commits, and update PR body/reviewers. - Pin the Registry Server Swagger CDN URL to a specific tag and add tooling (
pin_files) to keep it updated.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
scripts/upstream-release/detect-change.mjs |
Detects which upstream project version changed vs origin/main and emits outputs for the workflow. |
scripts/upstream-release/apply-pin-files.mjs |
Applies per-project pin_files substitutions after version bumps (e.g., replacing @latest/old tags). |
renovate.json |
Adds a custom regex manager and packageRule to open/label upstream-content PRs on releases. |
docusaurus.config.ts |
Pins Swagger spec URL from @latest to a concrete upstream tag. |
.gitignore |
Ignores workflow signal files GAPS.md and NO_CHANGES.md. |
.github/workflows/upstream-release-docs.yml |
Implements the automation workflow that augments Renovate PRs with generated docs updates and PR body edits. |
.github/upstream-projects.yaml |
Adds the source-of-truth config for tracked upstream repos, pinned versions, docs hints, and pin substitutions. |
- Switch upstream-release scripts and the inline node snippet in the workflow from `js-yaml` to the already-declared `yaml` package, so the workflow does not rely on a transitive dependency that could disappear in a future install. Rewrites the `.load()` calls to `.parse()` to match the new package's API. - Filter out null author logins in the `gh api compare` reviewers extraction (`.commits[].author.login? // empty`) so a commit with an unlinked GitHub user cannot pass an empty value into --add-reviewer. - Replace the nested `$([ ... ] && ... || ...)` has_gaps expression with an explicit `if/else` block so the quoting stays obviously correct and resists accidental breakage in future edits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a Renovate custom manager that watches version: pins in .github/upstream-projects.yaml for the four upstream ToolHive projects. When an upstream ships, Renovate opens a version-bump PR; a new workflow reacts to push source-verified content edits produced by the upstream-release-docs skill (three passes with docs-review), assigns reviewers from non-bot release contributors, and augments the PR body in a marker-delimited section. - .github/upstream-projects.yaml: source of truth for tracked projects - renovate.json: customManagers + packageRule (ignoreUnstable, rebaseWhen: never, recreateWhen: never, labels) - .github/workflows/upstream-release-docs.yml: pull_request + dispatch - scripts/upstream-release/detect-change.mjs: finds the changed project and asserts repo: hasn't been tampered with - scripts/upstream-release/apply-pin-files.mjs: rewrites @latest pins - docusaurus.config.ts: pins Registry Server Swagger at v1.2.1 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
workflow_dispatch now accepts either `pr_number` (retry an existing Renovate PR) or `project_id` + `new_tag` (bootstrap a fresh PR without waiting for Renovate). The bootstrap path branches off main, bumps the YAML via scripts/upstream-release/bump-yaml.mjs, creates the PR with the same labels Renovate applies, and feeds its number into the rest of the workflow so content augmentation runs identically. Useful for debugging, manual updates, and validating the pipeline end-to-end right after merge without waiting for an upstream release. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
update-toolhive-reference.yml now also bumps the toolhive entry in .github/upstream-projects.yaml, applies pin_files substitutions, and applies the upstream-content label alongside autogen-docs. The PR it opens is then picked up by upstream-release-docs.yml (via its relaxed gate that accepts github-actions[bot] authors) which adds skill-generated content in a second commit. Renovate is disabled for stacklok/toolhive so it doesn't race the reference workflow. The other three tracked projects keep their Renovate-driven path unchanged. Net: one PR per stacklok/toolhive release instead of two, with the same review surface shape as Renovate-driven PRs for the other projects. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Switch upstream-release scripts and the inline node snippet in the workflow from `js-yaml` to the already-declared `yaml` package, so the workflow does not rely on a transitive dependency that could disappear in a future install. Rewrites the `.load()` calls to `.parse()` to match the new package's API. - Filter out null author logins in the `gh api compare` reviewers extraction (`.commits[].author.login? // empty`) so a commit with an unlinked GitHub user cannot pass an empty value into --add-reviewer. - Replace the nested `$([ ... ] && ... || ...)` has_gaps expression with an explicit `if/else` block so the quoting stays obviously correct and resists accidental breakage in future edits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
a0f97f2 to
959968a
Compare
The unified toolhive path had a broken seam: peter-evans opens PRs with the default GITHUB_TOKEN, and GitHub intentionally does not trigger pull_request workflows on those PRs (recursion guard). Verified on PR #747 - no on-pr.yaml run fired. So the content workflow's pull_request trigger would never fire for toolhive PRs. Fix: add workflow_call trigger to upstream-release-docs.yml and call it as a dependent job from update-toolhive-reference.yml after peter-evans completes. The Renovate path is unaffected - Renovate is a GitHub App identity whose PRs DO trigger workflows. Also: - Distinct concurrency groups per workflow (upstream-release-docs-reference vs -content) so the workflow_call from reference to content doesn't deadlock on a shared group. - Drop the "What will be added next" section from the peter-evans body; the content workflow appends its own section below. - Fix leading-whitespace leak in the bootstrap PR body by using a heredoc + sed strip instead of an inline quoted string. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per review feedback from Dan: pull the Swagger file from the upstream repo at the pinned tag into static/api-specs/ and reference the local file in docusaurus.config.ts, matching how ToolHive's own Swagger is handled. Keeps the docs build offline-friendly and makes the pin implicit in git history rather than a CDN URL template. - New scripts/upstream-release/sync-assets.mjs helper copies declared files from the shallow clone into the docs repo. No-op when a project declares no assets. - .github/upstream-projects.yaml gains an `assets:` field per project. - Replaced the `pin_files` entry for registry-server with assets. - static/api-specs/toolhive-registry-api.yaml seeded from upstream v1.2.1 (1971 lines). Regenerated automatically on every bump. - Content workflow runs sync-assets right after the shallow clone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Collapses update-toolhive-reference.yml into upstream-release-docs.yml so all four tracked projects share one trigger path, one workflow, one PR per release. Renovate now watches toolhive's version: the same as the others; the content workflow runs a conditional reference-regen step for toolhive only. Also generalizes the `assets:` schema to support three source types: - source: <path in upstream repo> (file-in-clone copy) - release_asset: <asset name> (gh release download) - release_asset: <asset name>, extract: tar-gz (download + extract) toolhive's swagger and CLI-docs tarball move from the shell script into declarative `assets:` entries. The shell script shrinks to just the CRD MDX generation + toolhive-core schema download (the parts that need custom transforms). It reuses the shallow clone the content workflow already makes. Changes: - Delete .github/workflows/update-toolhive-reference.yml - Remove workflow_call + dual concurrency groups from the content workflow (no chain seam needed without a second workflow) - Remove the Renovate "disable for stacklok/toolhive" packageRule - Extend sync-assets.mjs with release_asset + extract support - Slim update-toolhive-reference.sh; accept TOOLHIVE_CLONE_DIR to reuse the workflow's shallow clone Trade-off: toolhive reference docs now inherit Renovate's 24h minimumReleaseAge. Previously they published within minutes of a release. Acceptable for content coherence; set minimumReleaseAge: 0 per-dep if sub-hour latency becomes needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
docs-website no longer consumes `repository_dispatch: published-release` events — its reference-doc regeneration now runs via a Renovate-driven pipeline that reads the new `thv-crds.tar.gz` and re-exported core schemas introduced earlier in this PR. See stacklok/docs-website#748 for context. Changes: - Delete `.github/workflows/update-docs-website.yml` (the dispatch sender, called via workflow_call from `releaser.yml`). - Remove the `update-docs-website` job from `releaser.yml` along with its `extract-release-actor` dependency, which only existed to feed the dispatch's `assign_to` input. - Update `notify-release-failure`'s `needs:` list to drop the removed jobs. Follow-up for maintainers: the `DOCS_REPO_DISPATCH_TOKEN` repo secret can be retired — nothing references it after this change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Assumes stacklok/toolhive#4982 has landed. That PR ships three new release assets on toolhive: - thv-crds.tar.gz (the 13 CRD YAMLs) - thv-cli-docs.tar.gz (already existed) - toolhive-*.schema.json (re-exported from toolhive-core at the go.mod-pinned version) And retires the repository_dispatch chain that previously triggered our reference-regen workflow. On our side, the shell wrapper script collapses entirely: - .github/upstream-projects.yaml: toolhive gains five new release_asset entries (swagger, CLI docs tarball with extract, and the four core schemas). sync-assets.mjs handles all of them declaratively. - .github/workflows/upstream-release-docs.yml: the old "run the shell script" step becomes an inline "download + extract CRD tarball, run our three Node helpers" step. Runs only for project_id=toolhive. - A new "Commit regenerated reference assets" step lands the regen as its own commit, so the autogen-detect step below sees only skill- introduced touches (prevents false-positive warnings). - scripts/update-toolhive-reference.sh deleted. Net effect after #4982 merges: - Zero repo clones for CRD processing (tarball replaces clone) - Zero cross-repo downloads (toolhive re-exports core schemas) - Zero shell scripts for release-doc regen - Three Node helpers stay (extract-crd-schemas, generate-crd-pages, bundle-upstream-schema) — they produce docs-specific outputs and genuinely belong on our side. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…in (#4982) * Bundle CRD manifests as a release asset Adds a `thv-crds.tar.gz` tarball to each release containing the CRD YAML manifests from `deploy/charts/operator-crds/files/crds/`. Motivation: downstream consumers of the CRDs (notably stacklok/docs-website, which generates per-CRD reference pages) currently have to clone the entire toolhive repo at each release tag just to read these 13 manifests. Shipping them as a ~94KB tarball asset lets those consumers skip the clone and just `gh release download` like they already do for `thv-cli-docs.tar.gz` and `swagger.yaml`. Purely additive — no changes to existing release assets or workflows. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Re-export toolhive-core schemas as release assets Reads the toolhive-core version from go.mod at release time, downloads the four JSON schema files from that version of stacklok/toolhive-core, and ships them alongside toolhive's own release assets. Motivation: downstream consumers (notably stacklok/docs-website) currently have to replicate this logic: read go.mod, derive the core version, then fetch from a different repo's release. Re-exporting the schemas here makes toolhive's release self-contained — one `gh release download` call gets everything. Paired with #4982 (CRD manifests as release asset); together these eliminate the need for docs-website to clone toolhive or hit a second repo during its release-doc regeneration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Retire the docs-website repository_dispatch chain docs-website no longer consumes `repository_dispatch: published-release` events — its reference-doc regeneration now runs via a Renovate-driven pipeline that reads the new `thv-crds.tar.gz` and re-exported core schemas introduced earlier in this PR. See stacklok/docs-website#748 for context. Changes: - Delete `.github/workflows/update-docs-website.yml` (the dispatch sender, called via workflow_call from `releaser.yml`). - Remove the `update-docs-website` job from `releaser.yml` along with its `extract-release-actor` dependency, which only existed to feed the dispatch's `assign_to` input. - Update `notify-release-failure`'s `needs:` list to drop the removed jobs. Follow-up for maintainers: the `DOCS_REPO_DISPATCH_TOKEN` repo secret can be retired — nothing references it after this change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two improvements from Dan Barr's review of PR #748: 1. Terminology: "regenerate" was overloaded. It now reads accurately: - "sync" for release-asset downloads / file copies (swagger, CLI tarball, 4 core schemas) — nothing is actually recreated - "regenerate" reserved for the toolhive CRD MDX step which truly transforms upstream manifests into our opinionated layout - "refresh" for the combined commit that may do both The commit that lands reference updates is now titled "Refresh reference assets for <project> <tag>". 2. Gap attribution: the skill's GAPS.md format now includes the PR number and @-mentions the PR author (non-bots only). Previously a gap routed to "everyone in the reviewer pool" via a label; now each gap directly pings the engineer who built the feature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Both of Dan's points addressed in ef49684: 1. TerminologyYou were right — "regenerate" was overloaded. The language now distinguishes:
Concretely, the auto-commit message is now 2. Gap attribution to PR authorsGood catch. The prompt to the skill now requires each gap bullet in GAPS.md to reference the PR number and @-mention the PR author (bots filtered out). Format:
So when a gap lands in the PR body, the engineer who built Feature X gets directly tagged rather than "someone from the reviewer pool." The skill already deep-dives PRs in Phase 2, so it has the attribution info at hand — no additional lookups needed. Thanks for the review! |
Simpler than adding a base_ref input: workflow_dispatch always runs against `github.ref_name` (the branch passed to --ref). For production, that's main. For pre-merge testing, dispatch from the feature branch with `gh workflow run --ref feat/branch` and the bootstrap flow branches from, bumps, and opens its PR against that branch. - Bootstrap checkout uses github.ref_name - Bootstrap PR's --base uses github.ref_name - eff step emits base_ref for detect-change.mjs to use as BASE_REF - pull_request trigger: event.pull_request.base.ref - workflow_dispatch retry: gh pr view <n> --json baseRefName - workflow_dispatch bootstrap: github.ref_name Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Labels were doing two jobs — neither worth the friction of pre-creating
the labels in every repo that adopts this:
1. Gating which PRs trigger augmentation. Replaced with the existing
pull_request paths: filter (only YAML edits) + user.login check
(must be renovate[bot]). Human PRs editing the YAML are out of
scope; they should be reviewed normally without skill augmentation.
2. Human filtering of "failed" / "needs-context" PRs. Replaced with
PR body sections and a failure-path PR comment that carries the
run URL.
Changes:
- Drop labels from Renovate packageRule in renovate.json.
- Drop --label from bootstrap gh pr create.
- Drop "Add needs-human-context label" step (gaps already shown in PR
body).
- Simplify failure step to comment-only; drop upstream-docs-failed
label. The PR comment already includes the run URL + retry hint.
- Drop labeled trigger type; no longer needed without label-race
concerns.
- Drop label check from workflow_dispatch retry validation.
Also unblocks the first real dispatch, which failed on
"upstream-content not found" since the label was never pre-created.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The `./.github/actions/setup` composite starts with its own actions/checkout that defaults to the dispatching ref, so calling it after "Checkout PR branch" clobbers the PR-branch working tree with the dispatching branch's content. detect-change.mjs then compared the dispatching branch's YAML against itself and reported "No version changes detected" — blocking the first dispatch. Fix: inline the setup-node + cache + npm ci steps after the PR-branch checkout instead of calling the composite. The composite is still used in the bootstrap flow where re-checkout of the dispatching branch is harmless. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removed earlier as 'unused'. anthropics/claude-code-action@v1 needs id-token: write to fetch an OIDC token. Skill step was failing with "Could not fetch an OIDC token" on the first real dispatch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| "recreateWhen": "never", | ||
| "commitMessageTopic": "{{depName}}", | ||
| "prBodyNotes": [ | ||
| "After this PR opens, `.github/workflows/upstream-release-docs.yml` adds source-verified content edits for the new release. For `stacklok/toolhive`, the same workflow also regenerates reference docs (CLI help, Swagger, CRD schemas)." |
There was a problem hiding this comment.
One remaining instance of "regenerates" (others were addressed), but non-blocking.
| "matchManagers": ["custom.regex"], | ||
| "matchFileNames": ["**/.github/upstream-projects.yaml"], | ||
| "schedule": ["at any time"], | ||
| "minimumReleaseAge": "24 hours", |
There was a problem hiding this comment.
Just noticed this...introducing a +24-hour drift off the bat seems undesirable. Can we drop to 0, or a few hours at most, 1-4 would still allow for a smoke-test window?
A delay is sensible for third-party libraries but these are first-party Stacklok releases. The cost of "docs PR opens for a release we later yanked" is just closing the PR, or a single revert PR if already merged.
…rding (#757) * Address Dan's review feedback on #748 Two small follow-ups: 1. minimumReleaseAge: 24 hours -> 1 hour. Dan flagged that 24h is overcautious for first-party Stacklok releases. Renovate itself only runs every 4h so 1h is effectively close to 0 while still protecting against same-day yanks/reverts. 2. prBodyNotes: drop "regenerates" where we're actually just syncing. Now precisely: "syncs reference assets (CLI help, Swagger) and regenerates the CRD MDX pages" for toolhive. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Filter reviewers to repo collaborators only Previous behavior pulled every non-bot commit author from the upstream release range and passed them to `gh pr edit --add-reviewer` as a single comma-separated list. GitHub rejects reviewer requests for non-collaborators with 422, and because the API treats the list atomically, one community contributor in the range would fail the entire call and drop all valid reviewers with it. Fix: - Probe each candidate with `gh api repos/<repo>/collaborators/<user>` before adding. 204 -> keep; 404 -> skip. - Emit a separate `skipped` output listing non-collaborator contributors so the PR body can acknowledge them by name ("Other release contributors ... Thanks for the contribution!") without actually requesting review from them. Pre-existing bot-regex filter runs first so we don't waste API calls on [bot] users. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Drop non-collaborator acknowledgment from PR body Filtering out non-collaborator reviewers stays (prevents the 422 whole-call-failure). But mentioning them by name in the augmented PR body adds notification surface we don't want. Silently skip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes #749
Summary
.github/upstream-projects.yamland opens a version-bump PR whenever any of them releases..github/workflows/upstream-release-docs.ymlthat reacts to Renovate's PRs to produce source-verified content edits using theupstream-release-docsskill (run three times withdocs-review), assigns reviewers from non-bot release contributors, and augments the PR body in a marker-delimited section.@latestCDN reference for the Registry Server Swagger with a version pinned in the source-of-truth YAML.See the full design in
/Users/dimitrovr/.claude/plans/i-want-to-make-synchronous-axolotl.md(local plan file).What's tracked
Four projects in
.github/upstream-projects.yaml:toolhivestacklok/toolhivetoolhive-registry-serverstacklok/toolhive-registry-servertoolhive-studiostacklok/toolhive-studiotoolhive-cloud-uistacklok/toolhive-cloud-uiArchitecture
There are two trigger paths, both producing a single PR per upstream release.
Path A:
stacklok/toolhivereleases (unified viaupdate-toolhive-reference.yml)repository_dispatch: published-releaseto this repo (or someone invokesworkflow_dispatchmanually with a version).update-toolhive-reference.yml:version:fortoolhivein.github/upstream-projects.yamlpin_filessubstitutionsdocs/upstream-toolhive-<version>with labelsautogen-docs+upstream-contentupstream-release-docs.ymlfires on the opened PR (gated to bot authors +upstream-contentlabel), shallow-clones the upstream, runs the multi-pass skill, assigns reviewers, pushes content commits, and augments the PR body between<!-- upstream-release-docs:start -->markers.stacklok/toolhiveinrenovate.jsonso it doesn't race.Path B: the other three projects
version:drift fortoolhive-registry-server,toolhive-studio, ortoolhive-cloud-uiand opens a PR with theupstream-contentlabel.upstream-release-docs.ymlfires on that PR and does the same augmentation as Path A step 3.**Path C:
workflow_dispatch(manual)**accepts apr_numberinput for manual retry if any step fails.Security posture
pull_request_targetdetect-change.mjsrefuses to proceed if a PR tries to changerepo:alongsideversion:env:vars inrun:blocks (no direct\${{ }}shell interpolation); actionlint cleanprev_tagexistence is verified upstream before the skill runsupstream-docs-failedand comments a retry pointerTrade-offs intentionally chosen
git pushasgithub-actions[bot]. If branch protection rejects unsigned bot commits on Renovate branches, will fix-forward with a GitHub App token rather than migrate to peter-evans speculatively.groupName: each upstream release gets its own PR even when two release in the same Renovate cycle.Upstream dependencies
This PR's code is written assuming stacklok/toolhive#4982 is merged. That PR:
thv-crds.tar.gzas a release asset (13 CRD YAMLs)repository_dispatch: published-releasechain that previously triggered reference-doc regeneration on this repoAll three are purely additive on toolhive's side except the dispatch retirement, which is safe in either merge order (this repo already deleted the receiver workflow earlier in this PR).
Impact of #4982 being merged, reflected in the latest commit here
.github/upstream-projects.yaml— toolhive gains five newrelease_asset:entries; no moresource:reliance on a clone for its reference artifacts.github/workflows/upstream-release-docs.yml— the toolhive-specific step downloadsthv-crds.tar.gz, extracts to a temp dir, and runsextract-crd-schemas.mjs+generate-crd-pages.mjs+bundle-upstream-schema.mjsinline. No shell-script wrapper.scripts/update-toolhive-reference.sh— deleted entirelyA new "Commit regenerated reference assets" step commits the regen output as a distinct commit before the skill runs, so the autogen-touch detection below only sees skill-introduced changes (fixes a false-positive that would have fired on every toolhive run).
Merge ordering
Either order is safe:
workflow_dispatchretry covers the gap.Recommend: merge #4982 first if it's ready; otherwise merge #748 and coordinate the #4982 merge before the next toolhive release.
Asks dropped
Two upstream asks were explored and dropped:
extract-crd-schemas.mjs) — rejected because it would add a Node toolchain to an otherwise-pure-Go repoupstream-registry.schema.jsonin toolhive-core (would have eliminatedbundle-upstream-schema.mjs) — rejected because it introduces a URL reference to maintain upstream; bundling stays colocated with the docs renderer that needs itTest plan
at any time)version:in.github/upstream-projects.yamlon a throwaway PR (e.g., bumptoolhive-registry-serverfromv1.2.1back tov1.2.0). On next Renovate scan it should open a bump PR; confirm the workflow fires and produces expected output.anthropics/claude-code-action@v1honors the "do not ask questions" directivegh pr view --json reviewRequests)pin_filessubstitution indocusaurus.config.tsrewrites the Swagger@v1.2.1to the new taggithub-actions[bot]are accepted by branch protection (signed-commits check)GAPS.md/NO_CHANGES.mdare captured into the PR body and not committedupstream-docs-failedlabel + retry comment appear andworkflow_dispatchwithpr_number=<n>reruns augmentation idempotentlyupdate-toolhive-reference.yml: for the next ToolHive release, both workflows fire; confirm branches and labels are disjoint and both PRs open cleanlyManual validation via workflow_dispatch bootstrap
After this PR merges, you can exercise the full end-to-end flow without waiting for Renovate:
Actions → Upstream Release Docs → Run workflow, then either:
pr_numberblank, fillproject_id(e.g.toolhive-registry-server) andnew_tag(e.g.v1.3.0). The workflow createsmanual/upstream-<id>-<new_tag>, bumps the YAML, opens a PR with the right labels, and runs the full augmentation in the same run.pr_number, leave the others blank.Bootstrap mode is gated the same way as Renovate PRs (must supply both
project_idandnew_tag; collisions with an existing branch fail fast).🤖 Generated with Claude Code