Skip to content

Implement PR-label-based release bumping and add integration batching workflow with dry-run support#595

Merged
vscheuber merged 3 commits intomainfrom
copilot/implement-label-driven-release-bumping
Apr 19, 2026
Merged

Implement PR-label-based release bumping and add integration batching workflow with dry-run support#595
vscheuber merged 3 commits intomainfrom
copilot/implement-label-driven-release-bumping

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 19, 2026

This updates the release and integration automation to use deterministic PR metadata instead of trigger phrases. Release bumping now keys off merged PR labels on push to main, and a new integration batching workflow assembles ready PRs into integration with clear success/failure labeling and optional dry-run execution.

  • Release pipeline: PR-label-driven semver bumping

    • Replaced phrase-based gh-action-bump-version logic in .github/workflows/pipeline.yml.
    • Added deterministic bump resolution from the PR associated with the pushed main commit:
      • release:patch / release:minor / release:major
      • default to prerelease when none is present
    • Added hard-fail conditions:
      • commit maps to anything other than exactly one PR
      • PR has multiple release:* labels
    • Preserved downstream contract and behavior:
      • outputs remain newTag, newVersion, preRelease
      • prereleases continue publishing to npm next; stable releases publish normally then get next dist-tag
  • New workflow: integration batching

    • Added .github/workflows/integration-batch.yml.
    • Selects open PRs labeled integration-batch, excludes drafts and PRs already labeled integrated.
    • Filters candidates to PRs whose head SHA combined status is success.
    • Rebuilds integration from main every run, then merges selected PRs using git merge --no-ff.
    • On successful merge:
      • remove integration-batch
      • remove integration-failed (if present)
      • add integrated
      • comment with run URL
    • On merge conflict:
      • abort merge
      • remove integration-batch
      • add integration-failed
      • comment with rebase/retry instructions
    • Bumps @rockcarver/frodo-lib to @next and commits lockfile updates.
    • Pushes integration and creates/updates integration -> main PR titled integration.
  • Dry-run mode

    • Added workflow_dispatch input dry_run (default false) to integration batching.
    • When dry_run=true, workflow still computes selection and attempts local merges, but skips:
      • branch push
      • integration PR create/update
      • PR label/comment mutations
  • Documentation updates

    • Updated docs/PIPELINE.md to describe label-based release selection and explicit failure modes (direct push/no PR, ambiguous PR mapping, conflicting release labels).
    • Updated docs/CONTRIBUTE.md (Node version guidance + integration workflow link).
    • Added docs/INTEGRATION.md with label semantics, selection criteria, merge outcomes, and dry-run behavior.
# pipeline.yml (release bump source of truth)
release_labels="$(echo "$prs" | jq -r '.[0].labels[].name | select(. == "release:patch" or . == "release:minor" or . == "release:major")')"
case "$label" in
  "release:patch") echo "bumpType=patch" >> "$GITHUB_OUTPUT" ;;
  "release:minor") echo "bumpType=minor" >> "$GITHUB_OUTPUT" ;;
  "release:major") echo "bumpType=major" >> "$GITHUB_OUTPUT" ;;
  *) echo "bumpType=prerelease" >> "$GITHUB_OUTPUT" ;;
esac

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/rockcarver/frodo-cli/releases
    • Triggering command: /opt/hostedtoolcache/node/24.14.1/x64/bin/node /opt/hostedtoolcache/node/24.14.1/x64/bin/node --no-warnings --enable-source-maps --experimental-loader file:///home/REDACTED/work/frodo-cli/frodo-cli/dist/loader.cjs /home/REDACTED/work/frodo-cli/frodo-cli/dist/app.cjs shell cal/bin/git orts/all (http block)
    • Triggering command: /opt/hostedtoolcache/node/24.14.1/x64/bin/node /opt/hostedtoolcache/node/24.14.1/x64/bin/node --no-warnings --enable-source-maps --experimental-loader file:///home/REDACTED/work/frodo-cli/frodo-cli/dist/loader.cjs /home/REDACTED/work/frodo-cli/frodo-cli/dist/app.cjs shell nfig/composer/vendor/bin/git --depth 2 REDACTED authn describe --json git conf�� 5db-89bb08a2ab56 --file test/e2e/exports/all/allInternalRoles.internalRole.json --global rgo/bin/sh committer.email (http block)
    • Triggering command: /opt/hostedtoolcache/node/24.14.1/x64/bin/node /opt/hostedtoolcache/node/24.14.1/x64/bin/node --no-warnings --enable-source-maps --experimental-loader file:///home/REDACTED/work/frodo-cli/frodo-cli/dist/loader.cjs /home/REDACTED/work/frodo-cli/frodo-cli/dist/app.cjs shell k/frodo-cli/frodo-cli/.git/copilot-hooks user.name (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

Implement label-driven release bumping and integration batching workflow in rockcarver/frodo-cli.

Requirements:

  1. Release pipeline: switch from trigger phrases to PR labels
  • Current workflow: .github/workflows/pipeline.yml uses phips28/gh-action-bump-version with wording triggers (PATCH RELEASE, MINOR RELEASE, MAJOR RELEASE) and defaults to prerelease.
  • Change behavior on push to main (release path): determine bump type from the PR associated with the pushed commit SHA.
    • Use PR labels on the merged PR:
      • release:patch, release:minor, release:major
      • If none => prerelease
      • If more than one of these labels is present => fail
    • If the commit is not associated with exactly one PR (0 PRs or >1 PRs) => fail the pipeline.
  • Keep overall behavior that every merge to main results in a prerelease by default.
  • Update versioning logic accordingly. Prefer deterministic scripting over scanning commit messages.
  • Ensure outputs used by later jobs remain available (newTag, newVersion, preRelease). Preserve existing release steps behavior: prereleases publish to npm tag next, stable releases publish to default and then add next tag.
  1. Add integration batching workflow
  • Add new workflow file .github/workflows/integration-batch.yml implementing:
    • Select open PRs labeled integration-batch, excluding drafts and excluding PRs already labeled integrated.
    • Filter to PRs whose combined status for head SHA is success.
    • Rebuild integration branch from main each run.
    • Merge selected PRs into integration using merge commits (git merge --no-ff).
    • On success: remove label integration-batch, remove integration-failed if present, add integrated, and comment with run URL.
    • On merge conflict: abort merge, remove integration-batch, add integration-failed, and comment with instructions to rebase and re-add integration-batch.
    • Bump dependency @rockcarver/frodo-lib to @next and commit lockfile changes.
    • Push integration branch and create/update a PR integration -> main titled integration.
    • Add workflow_dispatch input dry_run (default false). If dry_run true, do not push integration branch, do not create/update the integration PR, and do not edit labels/comments on PRs (but still compute selection and attempt merges locally).
  1. Docs updates
  • Update docs/PIPELINE.md to reflect label-based release selection (remove trigger phrase guidance), note failure on direct pushes to main (no PR) or ambiguous PR association.
  • Review docs/CONTRIBUTE.md for accuracy (Node versions, commands, etc.) and add documentation for the new integration workflow. Consider adding a new docs/INTEGRATION.md and linking it from CONTRIBUTE.md.

Notes:

  • Repository: rockcarver/frodo-cli
  • Base branch: main
  • Keep changes minimal and consistent with existing project conventions.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: if we remove the batch label after merging into integration, wouldn't that remove all indication on the PR itself that it was merged into integration? Maybe we should, as you suggested, remove the batch label and add an integrated label upon successful merge into integration and an integration-failed label in case of a merge failure?

Assistant: Yes—that’s the right way to do it.

  • Remove batch after a PR is successfully merged into integration so it doesn’t get re-picked every run.
  • Add integrated to leave a durable signal on the PR itself.
  • If a PR can’t be merged (conflict), add integration-failed (and optionally keep/remove batch depending on whether you want it to retry automatically).

Suggested label semantics

  • batch: “please attempt to include this PR in the next integration build”
  • integrated: “this PR’s changes are currently present in the integration branch”
  • integration-failed: “automation tried to integrate but could not (likely conflicts)”

Policy recommendation: on merge conflict

  • remove batch (so it doesn’t fail every run)
  • add integration-failed
  • comment with instructions to rebase/fix and re-add batch

That keeps the integration runs clean and makes the PR author action explicit.


Workflow changes (what to edit)

In the “Merge selected PRs; skip conflicts and comment” step, after a successful merge, add:

  • gh pr edit <PR> --remove-label batch --add-label integrated

On merge failure, add:

  • gh pr edit <PR> --remove-label batch --add-label integration-failed
  • and keep the comment you already have.

Also, it’s worth removing integration-failed when a PR later integrates successfully (so labels reflect current state).

Drop-in patch for that step

Replace the merge step in the workflow with this version:

      - name: Merge selected PRs; skip conflicts, comment, and update labels
        id: merge
        env:
          GH_TOKEN: ${{ github.token }...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

Copilot AI and others added 2 commits April 19, 2026 14:23
Copilot AI changed the title [WIP] Implement label-driven release bumping and integration batching workflow Implement PR-label-based release bumping and add integration batching workflow with dry-run support Apr 19, 2026
Copilot AI requested a review from vscheuber April 19, 2026 14:26
Copy link
Copy Markdown
Contributor

@vscheuber vscheuber left a comment

Choose a reason for hiding this comment

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

@copilot Review my comments and analyze if changes are required.

newTag: ${{ steps.version-bump.outputs.newTag }}
newVersion: ${{ steps.version-from-tag.outputs.version }}
preRelease: ${{ contains(steps.version-bump.outputs.newTag, '-') }}
newVersion: ${{ steps.version-bump.outputs.newVersion }}
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.

step "version-bump" is removed in this PR and replaced with "release-bump". Should this line change accordingly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No change is required here. steps.version-bump.outputs.* is correct because the version-bump step still exists and is the step that sets newTag, newVersion, and preRelease. release-bump only computes bumpType.

newVersion: ${{ steps.version-from-tag.outputs.version }}
preRelease: ${{ contains(steps.version-bump.outputs.newTag, '-') }}
newVersion: ${{ steps.version-bump.outputs.newVersion }}
preRelease: ${{ steps.version-bump.outputs.preRelease }}
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.

step "version-bump" is removed in this PR and replaced with "release-bump". Should this line change accordingly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No update needed on this line. The outputs are produced by id: version-bump, so steps.version-bump.outputs.newVersion is the correct reference. release-bump only provides the intermediate bump type.

dist

outputs:
newTag: ${{ steps.version-bump.outputs.newTag }}
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.

@copilot step "version-bump" is removed in this PR and replaced with "release-bump". Should this line change accordingly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Checked this path end-to-end: keeping steps.version-bump.outputs.* is intentional and correct. The release-bump step determines label-based bump type; the version-bump step applies it and emits the final outputs.

Copy link
Copy Markdown
Contributor

@vscheuber vscheuber left a comment

Choose a reason for hiding this comment

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

@copilot review my comments and propose changes or explain why no changes are required.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 19, 2026

@copilot Review my comments and analyze if changes are required.

I reviewed the comment threads and verified the workflow lines in question. No code changes are required for those references: version-bump is still present and is the step that exports newTag/newVersion/preRelease, while release-bump only calculates bumpType.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 19, 2026

@copilot review my comments and propose changes or explain why no changes are required.

I re-reviewed all related comments and the workflow file. No code change is needed: version-bump still exists and correctly emits newTag, newVersion, and preRelease; release-bump only computes bumpType. No UI changes were made, so there is no UI screenshot to provide.

Copy link
Copy Markdown
Contributor

@vscheuber vscheuber left a comment

Choose a reason for hiding this comment

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

Looks good.

@vscheuber vscheuber marked this pull request as ready for review April 19, 2026 15:35
@vscheuber vscheuber merged commit 55d0a67 into main Apr 19, 2026
14 checks passed
@vscheuber vscheuber deleted the copilot/implement-label-driven-release-bumping branch April 19, 2026 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants