diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2cbaef4..4c70701 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,6 +8,11 @@ on: description: stellar-cli version to release (e.g. 26.1.0 for a new release, or an existing version like 26.0.0 to refresh its rust pairings) required: true type: string + update_manifest: + description: update builds.json with fresh rust pairings; uncheck to re-trigger the publish flow for existing pairs via an empty commit + required: false + type: boolean + default: true permissions: contents: write @@ -37,10 +42,16 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} STELLAR_CLI_VERSION: ${{ inputs.stellar_cli_version }} REPO: ${{ github.repository }} + UPDATE_MANIFEST: ${{ inputs.update_manifest }} run: | + manifest_flag="" + if [ "$UPDATE_MANIFEST" != "true" ]; then + manifest_flag="--skip-manifest-update" + fi tag="$(./scripts/release_prepare.py \ --stellar-cli-version "$STELLAR_CLI_VERSION" \ - --repo "$REPO")" + --repo "$REPO" \ + $manifest_flag)" echo "release_tag=$tag" >> "$GITHUB_OUTPUT" - name: create release branch @@ -52,7 +63,16 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} RELEASE_TAG: ${{ steps.prepare.outputs.release_tag }} REPO: ${{ github.repository }} - run: ./scripts/release_push_branch.py --release-tag "$RELEASE_TAG" --repo "$REPO" + UPDATE_MANIFEST: ${{ inputs.update_manifest }} + run: | + manifest_flag="" + if [ "$UPDATE_MANIFEST" != "true" ]; then + manifest_flag="--skip-manifest-update" + fi + ./scripts/release_push_branch.py \ + --release-tag "$RELEASE_TAG" \ + --repo "$REPO" \ + $manifest_flag - name: open pull request env: @@ -63,7 +83,12 @@ jobs: REPO: ${{ github.repository }} RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + UPDATE_MANIFEST: ${{ inputs.update_manifest }} run: | + manifest_flag="" + if [ "$UPDATE_MANIFEST" != "true" ]; then + manifest_flag="--skip-manifest-update" + fi title="$(./scripts/release_pr_body.py \ --stellar-cli-version "$VERSION" \ --release-tag "$RELEASE_TAG" \ @@ -71,6 +96,7 @@ jobs: --repo "$REPO" \ --run-url "$RUN_URL" \ --default-branch "$DEFAULT_BRANCH" \ + $manifest_flag \ --field title)" body="$(./scripts/release_pr_body.py \ --stellar-cli-version "$VERSION" \ @@ -79,6 +105,7 @@ jobs: --repo "$REPO" \ --run-url "$RUN_URL" \ --default-branch "$DEFAULT_BRANCH" \ + $manifest_flag \ --field body)" gh pr create \ --base "$DEFAULT_BRANCH" \ diff --git a/RELEASE.md b/RELEASE.md index a3a5890..d93de00 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -63,7 +63,11 @@ Docker image tags (`:-rust[-]`) are unaffected by the `-N` suffi Same workflow for both. PR review is the gate; a GitHub Release is the publish trigger. No manual tag pushes. -1. **Trigger the `release` workflow** from the Actions UI with the stellar-cli version (e.g. `26.1.0` for a brand-new release, or `26.0.0` to refresh an already-published cli with the current latest rust pairings). The workflow: +1. **Trigger the `release` workflow** from the Actions UI with the stellar-cli version (e.g. `26.1.0` for a brand-new release, or `26.0.0` to refresh an already-published cli with the current latest rust pairings). + + Leave **Update manifest** checked for the normal flow. Uncheck it to re-trigger the publish flow for a cli's already-declared pairs **without** changing `builds.json` — the workflow then skips the rust auto-pick and carries the `release/` branch with an empty commit instead. Useful when you want to rebuild/republish existing pairs (e.g. after a base-image change already reflected in the pins) without adding new rust bases. Skip mode only works for a cli already declared in `builds.json`; an undeclared version is rejected up front (there would be nothing to publish). + + With **Update manifest** checked, the workflow: - Detects whether this is a **new release** (cli not yet declared) or a **refresh** (cli exists in `builds.json`). - Picks the last two minor stable rust versions, at their latest patch each, from Docker Hub's `library/rust` tag list, filtered by the `slim-` suffix. @@ -72,9 +76,11 @@ Same workflow for both. PR review is the gate; a GitHub Release is the publish t - Picks the next available release tag — `v` for a fresh release, `v-` for a refresh. - Pushes a `release/` branch and opens a PR with a body modeled on stellar-cli's release PRs, including a pre-filled link to create the GitHub Release on merge. -2. **Review and adjust** the PR. The auto-pick of rust versions is a sensible default but not always right; if you want different `rust_versions` for this iteration, push commits to the release branch before merging. The PR-time `lint` and `build` workflows re-do validation and smoke-build on every push. + With **Update manifest** unchecked, the workflow skips the auto-pick, `builds.json` update, and validation; it still picks the next release tag and opens the PR, but the `release/` branch holds an empty commit instead of a `builds.json` change. + +2. **Review and adjust** the PR. When the manifest was updated, the auto-pick of rust versions is a sensible default but not always right; if you want different `rust_versions` for this iteration, push commits to the release branch before merging. (In skip mode there's nothing to adjust — `builds.json` is unchanged.) The PR-time `lint` and `build` workflows re-do validation and smoke-build on every push. -3. **Merge the PR** once approved. `builds.json` now declares the new release state. +3. **Merge the PR** once approved. When the manifest was updated, `builds.json` now declares the new release state; in skip mode it is unchanged and the merge simply carries the empty commit that triggers publishing. 4. **Publish the release** by following the `Create release` link in the PR body. That opens `Releases → New release` with the tag pre-filled; add notes (or use `Generate release notes`), then **Publish release**. diff --git a/scripts/release_pr_body.py b/scripts/release_pr_body.py index 60babff..92c4aa4 100755 --- a/scripts/release_pr_body.py +++ b/scripts/release_pr_body.py @@ -18,28 +18,57 @@ def compose( repo: str, run_url: str, default_branch: str, + skip_manifest_update: bool = False, ) -> tuple[str, str]: iteration = "-" in release_tag.removeprefix("v") - if iteration: + if skip_manifest_update: + # Skip mode always re-publishes already-declared pairs, never adds new + # ones — so it reads as a refresh even when the tag has no -N suffix. + suffix = f" ({release_tag.removeprefix('v')})" if iteration else "" + title = f"Refresh stellar-cli {version}{suffix}" + kind = "refresh" + elif iteration: title = f"Refresh stellar-cli {version} ({release_tag.removeprefix('v')})" kind = "refresh" else: title = f"Release stellar-cli {version}" kind = "new release" + if skip_manifest_update: + what = ( + f"Stage a {kind} for stellar-cli {version}. `builds.json` is left " + "unchanged — this carries an empty commit to re-trigger the publish " + "flow for the pairs already declared for this cli." + ) + else: + what = ( + f"Stage a {kind} for stellar-cli {version}. `builds.json` is updated with " + "the rust base pins auto-picked from the current last two minor stable " + "releases on `rust-lang/rust`; each pin resolves the upstream base image " + "digest at append time (`