Skip to content

Add GitHub Actions workflow to automate cherry-pick hotfix PRs#4106

Open
paulmedynski wants to merge 11 commits intomainfrom
dev/paul/hotfix-action
Open

Add GitHub Actions workflow to automate cherry-pick hotfix PRs#4106
paulmedynski wants to merge 11 commits intomainfrom
dev/paul/hotfix-action

Conversation

@paulmedynski
Copy link
Copy Markdown
Contributor

@paulmedynski paulmedynski commented Mar 31, 2026

Description

Adds a new GitHub Actions workflow (.github/workflows/cherry-pick-hotfix.yml) that automates cherry-picking merged PRs into release branches when a "Hotfix <version>" label is present.

How it works:

  1. When a PR is merged to the default branch with a "Hotfix X.Y.Z" label (e.g. "Hotfix 7.0.1"), the workflow automatically cherry-picks the merge commit into release/<version>.
  2. Labels can be added before or after merge — the workflow triggers on both closed and labeled events.
  3. Multiple "Hotfix" labels on a single PR are supported; each produces an independent cherry-pick PR targeting its corresponding release branch.
  4. If the cherry-pick succeeds, a PR is created with the title [<version> Cherry-pick] <original title>.
  5. If there are merge conflicts, a placeholder PR with an empty commit is created titled [<version> Cherry-pick - CONFLICTS] <original title>, with manual resolution instructions in the body.

Engineering processes (CI, pipelines):

  • Uses a matrix strategy to fan out one job per detected hotfix version.
  • Avoids script injection by passing label names through environment variables rather than inline expressions.
  • Cherry-pick PRs are automatically assigned to the corresponding milestone.

Issues

No linked issue — this is a new engineering workflow to streamline the hotfix process.

Testing

  • Manual testing: The workflow logic (label extraction, branch naming, cherry-pick commands) was reviewed for correctness.
  • No automated tests: GitHub Actions workflows are validated by GitHub's own schema checks at push time and exercised in real PR scenarios. There is no unit test framework for workflow files in this repository. We do employ some Bash unit tests to confirm basic script functionality, but no integration tests exist for the GitHub actions themselves.
  • Justification for gap: Workflow files run in the GitHub Actions environment and cannot be meaningfully unit-tested locally. The workflow should be validated end-to-end by merging a test PR with a "Hotfix" label against a test release branch.

Guidelines

Please review the contribution guidelines before submitting a pull request:

@paulmedynski paulmedynski requested a review from a team as a code owner March 31, 2026 13:18
Copilot AI review requested due to automatic review settings March 31, 2026 13:18
@github-project-automation github-project-automation bot moved this to To triage in SqlClient Board Mar 31, 2026
@paulmedynski paulmedynski added the Area\Engineering Use this for issues that are targeted for changes in the 'eng' folder or build systems. label Mar 31, 2026
@paulmedynski paulmedynski moved this from To triage to In review in SqlClient Board Mar 31, 2026
@paulmedynski paulmedynski added this to the 7.1.0-preview1 milestone Mar 31, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new GitHub Actions workflow to automate creating cherry-pick PRs from merged hotfix PRs onto corresponding release/* branches based on Hotfix <version> labels, streamlining the hotfix backport process.

Changes:

  • Introduces .github/workflows/cherry-pick-hotfix.yml triggered by pull_request closed and labeled events.
  • Detects hotfix versions from PR labels and fans out a matrix job (one cherry-pick per version).
  • Creates either a normal cherry-pick PR or a “CONFLICTS” placeholder PR with manual resolution instructions.

Copilot AI review requested due to automatic review settings March 31, 2026 14:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

- main
- feat/**
- dev/**
- release/**
Copy link
Copy Markdown
Contributor Author

@paulmedynski paulmedynski Mar 31, 2026

Choose a reason for hiding this comment

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

I think this, and the similar pipeline YAML changes, future-proof us when making new release branches, but I would like a second opinion. I feel like we used to have patterns like this, and then removed them, but I forget why.

- Tag reviewers based on `CODEOWNERS` file

## 🌿 Branch Naming
- All branches created by AI agents **must** use the `dev/automation/` prefix (e.g. `dev/automation/fix-connection-timeout`).
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.

Hopefully this will avoid us having top-level branch paths like copilot/, etc.

Copilot AI review requested due to automatic review settings March 31, 2026 15:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Copilot AI review requested due to automatic review settings March 31, 2026 15:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Copilot AI review requested due to automatic review settings March 31, 2026 16:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 31, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.48%. Comparing base (60d4b92) to head (269ef41).
⚠️ Report is 11 commits behind head on main.

❗ There is a different number of reports uploaded between BASE (60d4b92) and HEAD (269ef41). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (60d4b92) HEAD (269ef41)
CI-SqlClient 1 0
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4106      +/-   ##
==========================================
- Coverage   73.22%   66.48%   -6.75%     
==========================================
  Files         280      274       -6     
  Lines       43000    65778   +22778     
==========================================
+ Hits        31486    43731   +12245     
- Misses      11514    22047   +10533     
Flag Coverage Δ
CI-SqlClient ?
PR-SqlClient-Project 66.48% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI review requested due to automatic review settings April 1, 2026 11:06
@paulmedynski paulmedynski force-pushed the dev/paul/hotfix-action branch from 269ef41 to dd13252 Compare April 1, 2026 11:06
…aming

- Switch from pull_request to pull_request_target so fork PRs have
  write permissions for push and PR creation.
- Detect parent count before cherry-pick: only pass --mainline 1 for
  true merge commits (2+ parents), omit it for squash merges.
- Parse major.minor from the Hotfix label version for the target
  release branch name (e.g. 'Hotfix 7.0.1' targets release/7.0),
  while preserving the full version in PR titles, milestones, and
  cherry-pick branch names.
…bel validation

- Remove --count from git rev-list so parent detection works correctly
  for both merge and squash-merge commits
- Use CHERRY_PICK_BRANCH variable in conflict resolution instructions
  instead of hardcoded branch prefix
- Tighten Hotfix label regex to only accept X.Y.Z semver format
…estone lookup, MAINLINE_FLAG in body, CI indentation

- Add default-branch guard to prevent recursive cherry-picks from release branches
- For 'labeled' events, only process the newly added label; skip if cherry-pick
  branch or PR already exists
- Look up milestone before creating PR; if missing, omit --milestone and add a
  note to the PR description
- Build CHERRY_PICK_CMD conditionally so empty MAINLINE_FLAG doesn't produce
  trailing '' in conflict-resolution instructions
- Fix CI pipeline branch list indentation under include:
Add a pre-check using 'git cherry' to determine if the merge
commit's patch is already present on the target release branch.
If so, the job exits cleanly with a notice instead of producing
an empty commit or a misleading CONFLICTS PR.
Move inline shell scripts from cherry-pick-hotfix.yml into standalone
files under .github/scripts/:

- extract-hotfix-versions.sh: Parses 'Hotfix X.Y.Z' labels from PR
  metadata and emits a JSON version matrix for fan-out.

- cherry-pick-to-release.sh: Cherry-picks a merge commit onto the
  corresponding release branch and opens a PR (or a CONFLICTS PR
  with manual resolution instructions).

Both scripts include:
- Full header documentation with overview, env vars, and examples
- Runtime --help / -h support
- Input validation with clear error messages
- Comments on all non-obvious operations

Add bats-core test suites under .github/scripts/tests/:
- 18 tests for extract-hotfix-versions.sh (label parsing, edge cases,
  duplicate detection, event-type handling)
- 15 tests for cherry-pick-to-release.sh (version derivation,
  already-applied detection, merge type handling, milestone lookup,
  conflict path)

Also fixes a quoting bug in the MILESTONE_NOTE assignment that caused
'command not found' when the milestone didn't exist.
- Replace git ls-remote with gh api for branch existence check in
  extract-hotfix-versions.sh (detect-versions job has no checkout)
- Put cherry-pick options (--mainline 1) before SHA operand
- Fix conflict-resolution command to put options before SHA
- Update bats test mocks to match new gh api usage
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

…ITORY validation

- Replace duplicated --help heredocs with awk extraction of the header
  comment block in both scripts, eliminating content drift.
- Add GITHUB_REPOSITORY to required env var validation in
  extract-hotfix-versions.sh (was used with set -u but not validated).
- Pass --repo to 'gh pr list' so it works without a .git directory.
- Set GITHUB_REPOSITORY in bats test setup() for deterministic runs.
- Update test assertions to match uppercase header comment headings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area\Engineering Use this for issues that are targeted for changes in the 'eng' folder or build systems.

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

2 participants