296 lines
13 KiB
YAML
296 lines
13 KiB
YAML
|
# This workflow is used to cherry pick PRs into a frozen release branch.
|
||
|
name: New PRR workflow - Cherry pick
|
||
|
on:
|
||
|
pull_request:
|
||
|
types: [closed]
|
||
|
workflow_dispatch:
|
||
|
inputs:
|
||
|
skipSlackPing:
|
||
|
description: 'Skip Slack Ping: If true, the Slack ping will be skipped (useful for testing)'
|
||
|
type: boolean
|
||
|
required: false
|
||
|
default: false
|
||
|
|
||
|
env:
|
||
|
GIT_COMMITTER_NAME: 'WooCommerce Bot'
|
||
|
GIT_COMMITTER_EMAIL: 'no-reply@woocommerce.com'
|
||
|
GIT_AUTHOR_NAME: 'WooCommerce Bot'
|
||
|
GIT_AUTHOR_EMAIL: 'no-reply@woocommerce.com'
|
||
|
|
||
|
permissions: {}
|
||
|
|
||
|
jobs:
|
||
|
verify:
|
||
|
name: Verify
|
||
|
runs-on: ubuntu-20.04
|
||
|
outputs:
|
||
|
run: ${{ steps.check.outputs.run }}
|
||
|
base_ref: ${{ steps.fetch_pr_details.outputs.base_ref }}
|
||
|
steps:
|
||
|
- name: Fetch Pull Request Details
|
||
|
if: github.event.pull_request
|
||
|
id: fetch_pr_details
|
||
|
uses: actions/github-script@v7
|
||
|
with:
|
||
|
script: |
|
||
|
const pullRequestUrl = context.payload.pull_request.url;
|
||
|
const prDetails = await github.request(pullRequestUrl);
|
||
|
|
||
|
const labels = prDetails.data.labels.map(label => label.name);
|
||
|
console.log('Labels:', labels);
|
||
|
|
||
|
if (!labels.includes('cherry pick to frozen release')) {
|
||
|
console.log('Label "cherry pick to frozen release" not found. Exiting job.');
|
||
|
process.exit(0);
|
||
|
}
|
||
|
|
||
|
core.setOutput('base_ref', prDetails.data.base.ref);
|
||
|
env:
|
||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
|
|
||
|
- name: check
|
||
|
id: check
|
||
|
uses: actions/github-script@v7
|
||
|
with:
|
||
|
script: |
|
||
|
const baseRef = process.env.BASE_REF;
|
||
|
console.log("baseRef:", baseRef);
|
||
|
|
||
|
let run = false;
|
||
|
|
||
|
const isBot = context.payload.pull_request && ( context.payload.pull_request.user.login == 'github-actions[bot]' || context.payload.pull_request.user.type == 'Bot' );
|
||
|
console.log("isBot:", isBot);
|
||
|
console.log("baseRef.startsWith('release/'):", baseRef.startsWith('release/'));
|
||
|
|
||
|
if ( !isBot && baseRef.startsWith( 'release/' ) ) {
|
||
|
core.setOutput( 'run', 'true' );
|
||
|
} else {
|
||
|
core.setOutput( 'run', 'false' );
|
||
|
}
|
||
|
env:
|
||
|
BASE_REF: ${{ steps.fetch_pr_details.outputs.base_ref }}
|
||
|
|
||
|
prep:
|
||
|
name: Prep inputs
|
||
|
runs-on: ubuntu-20.04
|
||
|
if: needs.verify.outputs.run == 'true'
|
||
|
needs: verify
|
||
|
outputs:
|
||
|
release: ${{ steps.prep-inputs.outputs.release }}
|
||
|
frozenRelease: ${{ steps.prep-inputs.outputs.frozenRelease }}
|
||
|
pr: ${{ steps.prep-inputs.outputs.pr }}
|
||
|
version: ${{ steps.prep-inputs.outputs.version }}
|
||
|
steps:
|
||
|
- name: Prep inputs
|
||
|
id: prep-inputs
|
||
|
uses: actions/github-script@v7
|
||
|
with:
|
||
|
script: |
|
||
|
const event = ${{ toJSON( github.event ) }}
|
||
|
|
||
|
const releaseBranch = process.env.BASE_REF
|
||
|
const version = releaseBranch.replace( 'release/', '' )
|
||
|
const pr = event.pull_request.number
|
||
|
|
||
|
// Split the version to get major and minor parts
|
||
|
let [major, minor] = version.split('.').map(Number)
|
||
|
|
||
|
// Check if minor version is 9, increment major and reset minor
|
||
|
if (minor === 9) {
|
||
|
major += 1
|
||
|
minor = 0
|
||
|
} else {
|
||
|
// Otherwise, just increment the minor version
|
||
|
minor += 1
|
||
|
}
|
||
|
|
||
|
// Create the frozen release branch name
|
||
|
const frozenRelease = `release/${major}.${minor}`
|
||
|
|
||
|
// Output the values
|
||
|
console.log('releaseBranch:', releaseBranch)
|
||
|
console.log('version:', version)
|
||
|
console.log('pr:', pr)
|
||
|
console.log('frozenRelease:', frozenRelease)
|
||
|
|
||
|
core.setOutput('pr', pr)
|
||
|
core.setOutput('version', version)
|
||
|
core.setOutput('release', releaseBranch)
|
||
|
core.setOutput('frozenRelease', frozenRelease)
|
||
|
env:
|
||
|
BASE_REF: ${{ needs.verify.outputs.base_ref }}
|
||
|
|
||
|
check-release-branch-exists:
|
||
|
name: Check for existence of release branch
|
||
|
runs-on: ubuntu-20.04
|
||
|
needs: prep
|
||
|
steps:
|
||
|
- name: Check for release branch
|
||
|
id: release-breanch-check
|
||
|
uses: actions/github-script@v7
|
||
|
with:
|
||
|
script: |
|
||
|
// This will throw an error for non-200 responses, which prevents subsequent jobs from completing, as desired.
|
||
|
await github.request( 'GET /repos/{owner}/{repo}/branches/{branch}', {
|
||
|
owner: context.repo.owner,
|
||
|
repo: context.repo.repo,
|
||
|
branch: process.env.RELEASE_BRANCH,
|
||
|
} );
|
||
|
env:
|
||
|
RELEASE_BRANCH: ${{ needs.prep.outputs.release }}
|
||
|
|
||
|
check-frozen-release-branch-exists:
|
||
|
name: Check for existence of frozen release branch
|
||
|
runs-on: ubuntu-20.04
|
||
|
needs: prep
|
||
|
steps:
|
||
|
- name: Check for release branch
|
||
|
id: release-breanch-check
|
||
|
uses: actions/github-script@v7
|
||
|
with:
|
||
|
script: |
|
||
|
// This will throw an error for non-200 responses, which prevents subsequent jobs from completing, as desired.
|
||
|
await github.request( 'GET /repos/{owner}/{repo}/branches/{branch}', {
|
||
|
owner: context.repo.owner,
|
||
|
repo: context.repo.repo,
|
||
|
branch: process.env.FROZEN_RELEASE_BRANCH,
|
||
|
} );
|
||
|
env:
|
||
|
FROZEN_RELEASE_BRANCH: ${{ needs.prep.outputs.frozenRelease }}
|
||
|
|
||
|
cherry-pick-run:
|
||
|
name: Run cherry pick tool
|
||
|
runs-on: ubuntu-20.04
|
||
|
permissions:
|
||
|
actions: write
|
||
|
contents: write
|
||
|
pull-requests: write
|
||
|
needs: [prep, check-release-branch-exists, check-frozen-release-branch-exists]
|
||
|
if: success()
|
||
|
steps:
|
||
|
- name: Checkout release branch
|
||
|
uses: actions/checkout@v3
|
||
|
with:
|
||
|
fetch-depth: 0
|
||
|
|
||
|
- name: Git fetch the frozen release branch
|
||
|
run: git fetch origin $FROZEN_RELEASE_BRANCH
|
||
|
env:
|
||
|
FROZEN_RELEASE_BRANCH: ${{ needs.prep.outputs.frozenRelease }}
|
||
|
|
||
|
- name: Checkout frozen release branch
|
||
|
run: git checkout $FROZEN_RELEASE_BRANCH
|
||
|
env:
|
||
|
FROZEN_RELEASE_BRANCH: ${{ needs.prep.outputs.frozenRelease }}
|
||
|
|
||
|
- name: Create a cherry pick branch
|
||
|
run: git checkout -b cherry-pick-$FROZEN_RELEASE_BRANCH/$PR
|
||
|
env:
|
||
|
FROZEN_RELEASE_BRANCH: ${{ needs.prep.outputs.frozenRelease }}
|
||
|
PR: ${{ needs.prep.outputs.pr }}
|
||
|
|
||
|
- name: Get commit sha from PR
|
||
|
id: commit-sha
|
||
|
uses: actions/github-script@v7
|
||
|
with:
|
||
|
script: |
|
||
|
const pr = await github.rest.pulls.get({
|
||
|
owner: context.repo.owner,
|
||
|
repo: context.repo.repo,
|
||
|
pull_number: process.env.PR
|
||
|
})
|
||
|
|
||
|
core.setOutput( 'sha', pr.data.merge_commit_sha )
|
||
|
env:
|
||
|
PR: ${{ needs.prep.outputs.pr }}
|
||
|
|
||
|
- name: Cherry pick
|
||
|
run: |
|
||
|
git cherry-pick $SHA -m1
|
||
|
env:
|
||
|
SHA: ${{ steps.commit-sha.outputs.sha }}
|
||
|
|
||
|
- name: Push cherry pick branch up
|
||
|
run: git push origin cherry-pick-$FROZEN_RELEASE_BRANCH/$PR
|
||
|
env:
|
||
|
FROZEN_RELEASE_BRANCH: ${{ needs.prep.outputs.frozenRelease }}
|
||
|
PR: ${{ needs.prep.outputs.pr }}
|
||
|
|
||
|
- name: Create the PR for cherry pick branch
|
||
|
id: cherry-pick-pr
|
||
|
uses: actions/github-script@v7
|
||
|
with:
|
||
|
script: |
|
||
|
const frozenReleaseBranch = process.env.FROZEN_RELEASE_BRANCH;
|
||
|
const prNumber = process.env.PR;
|
||
|
|
||
|
let cherryPickPRBody = `This PR cherry-picks the following PRs into the frozen release branch: ${frozenReleaseBranch}`;
|
||
|
|
||
|
cherryPickPRBody = `${cherryPickPRBody}\n* #${prNumber}\n`;
|
||
|
|
||
|
const pr = await github.rest.pulls.create({
|
||
|
owner: context.repo.owner,
|
||
|
repo: context.repo.repo,
|
||
|
title: `Cherry pick ${prNumber} into frozen release: ${frozenReleaseBranch}`,
|
||
|
head: `cherry-pick-${frozenReleaseBranch}/${prNumber}`,
|
||
|
base: frozenReleaseBranch,
|
||
|
body: cherryPickPRBody
|
||
|
});
|
||
|
|
||
|
core.setOutput('cherry-pick-pr', pr.data.html_url);
|
||
|
console.log('cherry-pick-pr URL:', pr.data.html_url);
|
||
|
|
||
|
// label PR
|
||
|
await github.rest.issues.addLabels({
|
||
|
owner: context.repo.owner,
|
||
|
repo: context.repo.repo,
|
||
|
issue_number: pr.data.number,
|
||
|
labels: ["metric: point release request"],
|
||
|
});
|
||
|
env:
|
||
|
PR: ${{ needs.prep.outputs.pr }}
|
||
|
FROZEN_RELEASE_BRANCH: ${{ needs.prep.outputs.frozenRelease }}
|
||
|
|
||
|
- name: Notify Slack on failure
|
||
|
if: ${{ failure() && inputs.skipSlackPing != true }}
|
||
|
uses: archive/github-actions-slack@v2.0.0
|
||
|
with:
|
||
|
slack-bot-user-oauth-access-token: ${{ secrets.CODE_FREEZE_BOT_TOKEN }}
|
||
|
slack-channel: ${{ secrets.WOO_CORE_RELESES_DAILY_SLACK_CHANNEL }}
|
||
|
slack-text: |
|
||
|
:warning-8c: Point release request cherry pick failed for `${{ needs.prep.outputs.release }}`
|
||
|
|
||
|
An attempt to cherry pick PR(s) into outgoing `${{ needs.prep.outputs.frozenRelease }}` for `${{ needs.prep.outputs.release }}` has failed. This could be due to a merge conflict or something else that requires manual attention. Please check: https://github.com/woocommerce/woocommerce/pull/${{ needs.prep.outputs.pr }}
|
||
|
|
||
|
- name: Notify Slack on success
|
||
|
if: ${{ success() && inputs.skipSlackPing != true }}
|
||
|
uses: archive/github-actions-slack@v2.0.0
|
||
|
with:
|
||
|
slack-bot-user-oauth-access-token: ${{ secrets.CODE_FREEZE_BOT_TOKEN }}
|
||
|
slack-channel: ${{ secrets.WOO_CORE_RELESES_DAILY_SLACK_CHANNEL }}
|
||
|
slack-text: |
|
||
|
:info: Point release request cherry pick succeeded for `${{ needs.prep.outputs.release }}`
|
||
|
|
||
|
Please merge the following PR :pr: into `${{ needs.prep.outputs.frozenRelease }}`:
|
||
|
|
||
|
${{ steps.cherry-pick-pr.outputs.cherry-pick-pr }}
|
||
|
|
||
|
- name: Comment on PR about the failed cherry pick
|
||
|
if: ${{ failure() }}
|
||
|
run: |
|
||
|
gh pr comment $HTML_URL --body "Cherry picking failed for the frozen release: $FROZEN_RELEASE_BRANCH. Please do it manually. Or debug, what happened and run the workflow again. Workflow link for debugging:https://github.com/${{ github.repository_owner }}/${{ github.repository }}/actions/workflows/new-prr-cherry-pick.yml"
|
||
|
env:
|
||
|
GH_TOKEN: ${{ github.token }}
|
||
|
HTML_URL: ${{ github.event.pull_request.html_url }}
|
||
|
FROZEN_RELEASE_BRANCH: ${{ needs.prep.outputs.frozenRelease }}
|
||
|
|
||
|
- name: Comment on PR about the cherry picked PRs to be merged
|
||
|
if: ${{ success() }}
|
||
|
run: |
|
||
|
gh pr comment $HTML_URL --body "Cherry picking was successful for frozen release: $FROZEN_RELEASE_BRANCH. Please merge the following PR: $CHERRY_PICK_PR"
|
||
|
env:
|
||
|
GH_TOKEN: ${{ github.token }}
|
||
|
HTML_URL: ${{ github.event.pull_request.html_url }}
|
||
|
FROZEN_RELEASE_BRANCH: ${{ needs.prep.outputs.frozenRelease }}
|
||
|
CHERRY_PICK_PR: ${{ steps.cherry-pick-pr.outputs.cherry-pick-pr }}
|