PRR flow (#52160)
* init * comment tweak * changelog * use gihub recommended method * removed content write permission * change in how to extract PR number * change in how to extract PR number * change in how to extract PR number * regex change * regex change * template updates * updated comments * set global permission to empty and moved it within each job * refactored code, created a needs step * add condition to prep * added acknowdegement section * added github comment * Moved variables to env * PRR template * PRR template changes * Added changes to cfe notifications * minor changes * Added slack message sanitization * PRR cherry-pick flow * add cherry pick to frozen release label * bug fix * use js instead of shell * use js instead of shell * template updates * frozen release as output * added some comments * pr base change * pr base change * descp change * copy changes * Added checkboxes conformation * added ack section * fixed bug * fixed bug * fixed bug * typo * bug fix * bug fix * added logic for github comment * bug fix * GH PR comment * GH PR comment for CFE flow * GH PR comment for CFE flow * changelog * In complechangelog step - extract version from branch * add validation for manual version input * log the version user entered * log the version user entered * rebased changes * Code refactor * bug fixes and formatting * code refactor * bug fixes * template updates and using context object instead of parsing * bug fixes * renamed file * moved vars to env
This commit is contained in:
parent
309f7bcdba
commit
bcbd08816b
|
@ -17,8 +17,8 @@ body:
|
|||
id: release-number
|
||||
attributes:
|
||||
label: "Which release does this request apply to?"
|
||||
description: "Format: X.Y"
|
||||
placeholder: "7.0"
|
||||
description: "Format: X.Y (Major.Minor)"
|
||||
placeholder: "9.2"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
name: 🚧 Point release request
|
||||
description: Request handling one or more pull requests(s) as point release request(s).
|
||||
title: "[PRR]: "
|
||||
labels: ["point release request"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this template to request changes to be included as part of a point release.
|
||||
**The request will be reviewed** and accepted or denied:
|
||||
|
||||
* If accepted, please test your changes in against the release branch and merge.
|
||||
* If rejected, please change the base against `trunk` and merge it.
|
||||
|
||||
In either case you are responsible for managing the pull request as usual (provide a description, assign reviewers, ensure that CI jobs pass...)
|
||||
- type: input
|
||||
id: release-number
|
||||
attributes:
|
||||
label: "Which release does this request apply to?"
|
||||
description: "Format: X.Y (Major.Minor)"
|
||||
placeholder: "9.2"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: pr-urls
|
||||
attributes:
|
||||
label: "Which PR needs to be included? (please do not enter multiple PRs)"
|
||||
description: "Pull request URL against the release branch"
|
||||
placeholder: |
|
||||
https://github.com/woocommerce/woocommerce/pull/1234
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: why-needed
|
||||
attributes:
|
||||
label: "Why does this PR need a point release?"
|
||||
placeholder: "This is a revert of ... which introduced a bug that causes ..."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
id: consequence-if-not-included
|
||||
label: "What is the consequence if this fix not being included in the point release (if any)? e.g. number of users affected and how they are affected"
|
||||
placeholder: "The ... flow will be broken for ... users"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: plan-if-defects-discovered
|
||||
attributes:
|
||||
label: "What is the plan should defects to be discovered in these PR after the point release?"
|
||||
placeholder: "Reverting this PR and ... would be enough"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: how-to-communicate
|
||||
attributes:
|
||||
label: "How should this change be communicated in the release post on the public developer blog: cc @woocommerce/developer-advocacy"
|
||||
description: "See the blog at [https://developer.woo.com/blog/](https://developer.woo.com/blog/)"
|
||||
placeholder: "There is no need to add new communication to the already planned one."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: workaround
|
||||
attributes:
|
||||
label: "Is there a workaround to the issue? If yes, how should we communicate it on the (public developer blog)[https://developer.woo.com/blog/]?"
|
||||
placeholder: "Use the ... flow instead"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: who-to-ask
|
||||
attributes:
|
||||
label: "If you’re not available and we have questions about this request, is there another person(s) and/or a team that we can ping?"
|
||||
placeholder: "@person or anyone from the ... team"
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Escape Analysis
|
||||
For the sake of expediting this request, the details below can be completed at a later time should you so choose.
|
||||
However, the Escape Analysis section is **required** for any accepted Point Release Request.
|
||||
In this section:
|
||||
* Think about how the bug escaped your team.
|
||||
* Write down ideas on how you could prevent this bug – for example, by writing automated tests, creating a new process, or updating documentation.
|
||||
* Make a plan with your team to implement the changes proposed above in order to catch the bug earlier next time and add the related tasks to your backlog.
|
||||
* Please, add a separate comment that includes the details for the Escape Analysis. Together with this Escape Analysis, please make sure to include an actionable item that covers the gap exposed by this analysis. It could be a GitHub issue, the reference of a new item to discuss in a team meeting, etc. Anything that prevents this analysis from getting lost in P2 will be useful.
|
||||
- type: checkboxes
|
||||
id: escape-analysis-completed
|
||||
attributes:
|
||||
label: "Acknowledgement"
|
||||
options:
|
||||
- label: "I understand that I need to write an incident report (aka Escape Analysis) as a comment on this post. This is required for the request to be accepted."
|
||||
required: true
|
||||
- label: "I understand that I need to create an issue as a result of the Escape Analysis and reference it in a comment on this post. This can be done at a later time, but it is required for this request to be closed."
|
||||
required: true
|
|
@ -1,3 +1,4 @@
|
|||
# This workflow is used to cherry pick PRs from release branche into trunk.
|
||||
name: New CFE workflow - Cherry pick
|
||||
on:
|
||||
pull_request:
|
||||
|
@ -86,7 +87,7 @@ jobs:
|
|||
script: |
|
||||
const event = ${{ toJSON( github.event ) }}
|
||||
|
||||
const releaseBranch = '${{ needs.verify.outputs.base_ref }}'
|
||||
const releaseBranch = process.env.BASE_REF
|
||||
const version = releaseBranch.replace( 'release/', '' )
|
||||
const pr = event.pull_request.number
|
||||
|
||||
|
@ -98,6 +99,8 @@ jobs:
|
|||
core.setOutput( 'pr', pr )
|
||||
core.setOutput( 'version', version )
|
||||
core.setOutput( 'release', releaseBranch )
|
||||
env:
|
||||
BASE_REF: ${{ needs.verify.outputs.base_ref }}
|
||||
|
||||
check-release-branch-exists:
|
||||
name: Check for existence of release branch
|
||||
|
@ -113,8 +116,11 @@ jobs:
|
|||
await github.request( 'GET /repos/{owner}/{repo}/branches/{branch}', {
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
branch: '${{ needs.prep.outputs.release }}',
|
||||
branch: process.env.RELEASE_BRANCH,
|
||||
} );
|
||||
env:
|
||||
RELEASE_BRANCH: ${{ needs.prep.outputs.release }}
|
||||
|
||||
cherry-pick-run:
|
||||
name: Run cherry pick tool
|
||||
runs-on: ubuntu-20.04
|
||||
|
@ -137,7 +143,10 @@ jobs:
|
|||
run: git checkout trunk
|
||||
|
||||
- name: Create a cherry pick branch based on trunk branch
|
||||
run: git checkout -b cherry-pick-${{ needs.prep.outputs.version }}/${{ needs.prep.outputs.pr }}
|
||||
run: git checkout -b cherry-pick-$RELEASE_BRANCH/$PR
|
||||
env:
|
||||
RELEASE_BRANCH: ${{ needs.prep.outputs.release }}
|
||||
PR: ${{ needs.prep.outputs.pr }}
|
||||
|
||||
- name: Get commit sha from PR
|
||||
id: commit-sha
|
||||
|
@ -147,32 +156,42 @@ jobs:
|
|||
const pr = await github.rest.pulls.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: '${{ needs.prep.outputs.pr }}'
|
||||
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 ${{ steps.commit-sha.outputs.sha }} -m1
|
||||
git cherry-pick $SHA -m1
|
||||
env:
|
||||
SHA: ${{ steps.commit-sha.outputs.sha }}
|
||||
|
||||
- name: Push cherry pick branch up
|
||||
run: git push origin cherry-pick-${{ needs.prep.outputs.version }}/${{ needs.prep.outputs.pr }}
|
||||
run: git push origin cherry-pick-$RELEASE_BRANCH/$PR
|
||||
env:
|
||||
RELEASE_BRANCH: ${{ needs.prep.outputs.release }}
|
||||
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 prNumber = process.env.PR;
|
||||
const releaseBranch = process.env.RELEASE_BRANCH;
|
||||
|
||||
let cherryPickPRBody = "This PR cherry-picks the following PRs into the trunk branch:\n";
|
||||
|
||||
cherryPickPRBody = `${cherryPickPRBody}` + `* #${{ needs.prep.outputs.pr }}` + "\n";
|
||||
cherryPickPRBody = `${cherryPickPRBody}` + `* #${prNumber}` + "\n";
|
||||
|
||||
const pr = await github.rest.pulls.create({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
title: "Cherry pick ${{ needs.prep.outputs.pr }} into trunk",
|
||||
head: "cherry-pick-${{ needs.prep.outputs.version }}/${{ needs.prep.outputs.pr }}",
|
||||
title: `Cherry pick ${prNumber} into trunk`,
|
||||
head: `cherry-pick-${releaseBranch}/${prNumber}`,
|
||||
base: "trunk",
|
||||
body: cherryPickPRBody
|
||||
})
|
||||
|
@ -188,6 +207,9 @@ jobs:
|
|||
issue_number: pr.data.number,
|
||||
labels: ["metric: code freeze exception"],
|
||||
});
|
||||
env:
|
||||
PR: ${{ needs.prep.outputs.pr }}
|
||||
RELEASE_BRANCH: ${{ needs.prep.outputs.release }}
|
||||
|
||||
- name: Notify Slack on failure
|
||||
if: ${{ failure() && inputs.skipSlackPing != true }}
|
||||
|
@ -198,7 +220,7 @@ jobs:
|
|||
slack-text: |
|
||||
:warning-8c: CFE cherry pick failed for '${{ needs.prep.outputs.release }}'
|
||||
|
||||
An attempt to cherry pick PR(s) into outgoing trunk 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 }}
|
||||
An attempt to cherry pick PR(s) into outgoing trunk 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 }}
|
||||
|
@ -207,8 +229,25 @@ jobs:
|
|||
slack-bot-user-oauth-access-token: ${{ secrets.CODE_FREEZE_BOT_TOKEN }}
|
||||
slack-channel: ${{ secrets.WOO_CORE_RELESES_DAILY_SLACK_CHANNEL }}
|
||||
slack-text: |
|
||||
:info: CFE cherry pick succeeded for '${{ needs.prep.outputs.release }}'
|
||||
:info: CFE cherry pick succeeded for `${{ needs.prep.outputs.release }}`
|
||||
|
||||
Please merge the following PR :pr: into trunk:
|
||||
Please merge the following PR :pr: into `trunk`:
|
||||
|
||||
${{ 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 trunk. 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-cfe-cherry-pick.yml"
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
HTML_URL: ${{ github.event.pull_request.html_url }}
|
||||
|
||||
- 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 trunk. Please merge the following PR: $CHERRY_PICK_PR"
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
HTML_URL: ${{ github.event.pull_request.html_url }}
|
||||
CHERRY_PICK_PR: ${{ steps.cherry-pick-pr.outputs.cherry-pick-pr }}
|
||||
|
|
|
@ -3,7 +3,7 @@ on:
|
|||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version override. Default version is fetched from monthly release calendar, you can override the version but make sure the that the branch release/{version} exists on remote.'
|
||||
description: 'Version override. Default version is fetched from the base branch name, you can override the version but make sure the that the branch release/{version} exists on remote. Format: X.Y (Major.Minor)'
|
||||
required: false
|
||||
default: ''
|
||||
|
||||
|
@ -21,6 +21,37 @@ jobs:
|
|||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Get version from the branch name workflow is running on
|
||||
if: ${{ github.event.inputs.version == '' }}
|
||||
uses: actions/github-script@v7
|
||||
id: extract-version
|
||||
with:
|
||||
script: |
|
||||
const refName = process.env.GITHUB_REF_NAME;
|
||||
const versionMatch = refName.match(/^release\/(\d+\.\d+)$/);
|
||||
if (versionMatch) {
|
||||
const version = versionMatch[1];
|
||||
console.log(`Extracted version: ${version}`);
|
||||
core.setOutput('version', version);
|
||||
} else {
|
||||
core.setFailed(`Branch name ${refName} does not match the expected pattern 'release/x.y'`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
- name: Validate version input override
|
||||
if: ${{ github.event.inputs.version != '' }}
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
VERSION: ${{ github.event.inputs.version }}
|
||||
with:
|
||||
script: |
|
||||
const version = process.env.VERSION;
|
||||
if (!/^\d+\.\d+$/.test(version)) {
|
||||
core.setFailed('Invalid version format. The version must be in the format X.Y');
|
||||
core.info(`Version you entered: ${version}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
|
@ -43,13 +74,8 @@ jobs:
|
|||
pnpm build
|
||||
working-directory: tools/monorepo-utils
|
||||
|
||||
- name: 'Get the versions for the accelerated and monthly releases'
|
||||
id: get-versions
|
||||
if: ${{ github.event.inputs.version == '' }}
|
||||
run: pnpm utils code-freeze get-version
|
||||
|
||||
- name: Generate changelog changes and create PR
|
||||
id: changelog
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: pnpm utils code-freeze changelog -o ${{ github.repository_owner }} -v ${{ github.event.inputs.version || steps.get-versions.outputs.monthlyVersionXY }}
|
||||
run: pnpm utils code-freeze changelog -o ${{ github.repository_owner }} -v ${{ github.event.inputs.version || steps.extract-version.outputs.version }}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
name: New CFE workflow notifications
|
||||
name: New CFE/PRR workflow notifications
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
@ -7,7 +7,7 @@ permissions: {}
|
|||
|
||||
jobs:
|
||||
prep:
|
||||
if: github.event.label.name == 'CFE Approved' || github.event.label.name == 'CFE Rejected'
|
||||
if: github.event.label.name == 'Approved' || github.event.label.name == 'Rejected'
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
release_number: ${{ steps.extract-release.outputs.RELEASE_NUMBER }}
|
||||
|
@ -38,24 +38,44 @@ jobs:
|
|||
}
|
||||
|
||||
cfe-created:
|
||||
if: github.event.label.name == 'code freeze exception'
|
||||
if: github.event.label.name == 'code freeze exception' || github.event.label.name == 'point release request'
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Set Slack Message
|
||||
id: set-message
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const event = context.payload;
|
||||
const labelName = event.label?.name;
|
||||
const issueTitle = event.issue.title;
|
||||
const issueUrl = event.issue.html_url;
|
||||
|
||||
let message = '';
|
||||
|
||||
// Determine the type of message based on the label name
|
||||
if (labelName === 'code freeze exception') {
|
||||
message = `:arrow_right: New CFE request: ${issueTitle} ${issueUrl}`;
|
||||
} else {
|
||||
message = `:arrow_right: New PRR request: ${issueTitle} ${issueUrl}`;
|
||||
}
|
||||
|
||||
// Set the message as a core output
|
||||
core.setOutput('SLACK_MESSAGE', message);
|
||||
|
||||
- name: Notify Slack
|
||||
uses: archive/github-actions-slack@v2.0.0
|
||||
id: notify
|
||||
with:
|
||||
slack-bot-user-oauth-access-token: ${{ secrets.CODE_FREEZE_BOT_TOKEN }}
|
||||
slack-channel: ${{ secrets.WOO_RELEASE_SLACK_CHANNEL }}
|
||||
slack-text: |
|
||||
:arrow_right: New CFE request: ${{ github.event.issue.title }}
|
||||
${{ github.event.issue.html_url }}
|
||||
slack-text: ${{ steps.set-message.outputs.SLACK_MESSAGE }}
|
||||
slack-optional-unfurl_links: false
|
||||
slack-optional-unfurl_media: false
|
||||
continue-on-error: true
|
||||
|
||||
cfe-approved:
|
||||
if: github.event.label.name == 'CFE Approved'
|
||||
request-approved:
|
||||
if: ${{ github.event.label.name == 'Approved' }}
|
||||
runs-on: ubuntu-20.04
|
||||
needs:
|
||||
- prep
|
||||
|
@ -95,7 +115,17 @@ jobs:
|
|||
PR_NUMBER: ${{ steps.extract-pr.outputs.PR_NUMBER }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh pr edit "$PR_NUMBER" --add-label "cherry pick to trunk" --repo "$OWNER/$REPO"
|
||||
gh pr edit $PR_NUMBER --add-label "cherry pick to trunk" --repo "$OWNER/$REPO"
|
||||
|
||||
- name: Add label 'cherry pick to frozen release' to PR
|
||||
if: contains(github.event.issue.labels.*.name, 'point release request')
|
||||
env:
|
||||
OWNER: ${{ github.event.repository.owner.login }}
|
||||
REPO: ${{ github.event.repository.name }}
|
||||
PR_NUMBER: ${{ steps.extract-pr.outputs.PR_NUMBER }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh pr edit $PR_NUMBER --add-label "cherry pick to frozen release" --repo "$OWNER/$REPO"
|
||||
|
||||
- name: Apply Milestone to the Issue
|
||||
env:
|
||||
|
@ -113,21 +143,39 @@ jobs:
|
|||
run: |
|
||||
gh issue comment "$ISSUE_URL" --body "This request has been approved. Please merge the PR to release branch."
|
||||
|
||||
- name: Set Slack Message
|
||||
id: set-message
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const event = context.payload; // Accessing the event directly from the context
|
||||
const labelName = event.label?.name;
|
||||
const issueTitle = event.issue.title;
|
||||
const issueUrl = event.issue.html_url;
|
||||
|
||||
let message = '';
|
||||
|
||||
if (labelName === 'code freeze exception') {
|
||||
message = `:white_check_mark: CFE request approved: ${issueTitle} ${issueUrl}`;
|
||||
} else {
|
||||
message = `:white_check_mark: PRR request approved: ${issueTitle} ${issueUrl}`;
|
||||
}
|
||||
|
||||
core.setOutput('SLACK_MESSAGE', message);
|
||||
|
||||
- name: Notify Slack
|
||||
uses: archive/github-actions-slack@v2.0.0
|
||||
id: notify
|
||||
with:
|
||||
slack-bot-user-oauth-access-token: ${{ secrets.CODE_FREEZE_BOT_TOKEN }}
|
||||
slack-channel: ${{ secrets.WOO_CORE_RELESES_DAILY_SLACK_CHANNEL }}
|
||||
slack-text: |
|
||||
:white_check_mark: CFE request approved: ${{ github.event.issue.title }}
|
||||
${{ github.event.issue.html_url }}
|
||||
slack-text: ${{ steps.set-message.outputs.SLACK_MESSAGE }}
|
||||
slack-optional-unfurl_links: false
|
||||
slack-optional-unfurl_media: false
|
||||
continue-on-error: true
|
||||
|
||||
cfe-rejected:
|
||||
if: github.event.label.name == 'CFE Rejected'
|
||||
request-rejected:
|
||||
if: ${{ github.event.label.name == 'Rejected' }}
|
||||
runs-on: ubuntu-20.04
|
||||
needs:
|
||||
- prep
|
||||
|
@ -143,12 +191,33 @@ jobs:
|
|||
echo "Applying milestone: $MILESTONE"
|
||||
gh issue edit "$ISSUE_URL" --milestone "$MILESTONE"
|
||||
|
||||
- name: Close CFE Issue
|
||||
- name: Close the request
|
||||
env:
|
||||
ISSUE_URL: ${{ github.event.issue.html_url }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh issue close --comment "Closing issue as CFE is rejected - $ISSUE_URL. Please switch the base to trunk and merge." "$ISSUE_URL"
|
||||
gh issue close "$ISSUE_URL" --comment "Closing issue the request is rejected - $ISSUE_URL. Please switch the base to trunk and merge."
|
||||
|
||||
- name: Set Slack Message
|
||||
id: set-message
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const event = context.payload;
|
||||
const labelName = event.label?.name;
|
||||
const issueTitle = event.issue.title;
|
||||
const issueUrl = event.issue.html_url;
|
||||
|
||||
let message = '';
|
||||
|
||||
if (labelName === 'code freeze exception') {
|
||||
message = `:x: CFE request rejected: ${issueTitle} ${issueUrl}`;
|
||||
} else {
|
||||
message = `:x: PRR request rejected: ${issueTitle} ${issueUrl}`;
|
||||
}
|
||||
|
||||
core.setOutput('SLACK_MESSAGE', message);
|
||||
|
||||
|
||||
- name: Notify Slack
|
||||
uses: archive/github-actions-slack@v2.0.0
|
||||
|
@ -156,9 +225,7 @@ jobs:
|
|||
with:
|
||||
slack-bot-user-oauth-access-token: ${{ secrets.CODE_FREEZE_BOT_TOKEN }}
|
||||
slack-channel: ${{ secrets.WOO_CORE_RELESES_DAILY_SLACK_CHANNEL }}
|
||||
slack-text: |
|
||||
:x: CFE request rejected: ${{ github.event.issue.title }}
|
||||
${{ github.event.issue.html_url }}
|
||||
slack-text: ${{ steps.set-message.outputs.SLACK_MESSAGE }}
|
||||
slack-optional-unfurl_links: false
|
||||
slack-optional-unfurl_media: false
|
||||
continue-on-error: true
|
|
@ -0,0 +1,295 @@
|
|||
# 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 }}
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: dev
|
||||
|
||||
Point release request flow for development use.
|
Loading…
Reference in New Issue