Cherry-pick a pull request #656
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Cherry-pick a pull request | |
on: | |
workflow_dispatch: | |
inputs: | |
PULL_REQUEST_NUMBER: | |
description: The number of a pull request to CP | |
required: true | |
NEW_VERSION: | |
description: The new app version (leave empty if running manually) | |
required: false | |
default: '' | |
jobs: | |
validateActor: | |
runs-on: ubuntu-latest | |
outputs: | |
IS_DEPLOYER: ${{ fromJSON(steps.isDeployer.outputs.IS_DEPLOYER) || github.actor == 'OSBotify' }} | |
steps: | |
- id: isDeployer | |
run: | | |
if gh api /orgs/Expensify/teams/mobile-deployers/memberships/${{ github.actor }} --silent; then | |
echo "IS_DEPLOYER=true" >> "$GITHUB_OUTPUT" | |
else | |
echo "IS_DEPLOYER=false" >> "$GITHUB_OUTPUT" | |
fi | |
env: | |
GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} | |
createNewVersion: | |
needs: validateActor | |
if: ${{ fromJSON(needs.validateActor.outputs.IS_DEPLOYER) && github.event.inputs.NEW_VERSION == '' }} | |
uses: Expensify/App/.github/workflows/createNewVersion.yml@main | |
secrets: inherit | |
cherryPick: | |
needs: [validateActor, createNewVersion] | |
if: ${{ always() && fromJSON(needs.validateActor.outputs.IS_DEPLOYER) }} | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout staging branch | |
uses: actions/checkout@v3 | |
with: | |
ref: staging | |
token: ${{ secrets.OS_BOTIFY_TOKEN }} | |
- uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main | |
with: | |
GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} | |
- name: Get merge commit for CP pull request | |
id: getCPMergeCommit | |
uses: Expensify/App/.github/actions/javascript/getPullRequestDetails@main | |
with: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
USER: ${{ github.actor }} | |
PULL_REQUEST_NUMBER: ${{ github.event.inputs.PULL_REQUEST_NUMBER }} | |
- name: Save correct NEW_VERSION to env | |
env: | |
NEW_VERSION: ${{ github.event.inputs.NEW_VERSION }} | |
run: | | |
if [ -z "$NEW_VERSION" ]; then | |
echo "NEW_VERSION=${{ needs.createNewVersion.outputs.NEW_VERSION }}" >> "$GITHUB_ENV" | |
echo "New version is ${{ env.NEW_VERSION }}" | |
else | |
echo "NEW_VERSION=${{ github.event.inputs.NEW_VERSION }}" >> "$GITHUB_ENV" | |
echo "New version is ${{ env.NEW_VERSION }}" | |
fi; | |
- name: Cherry-pick the version-bump to staging | |
run: | | |
# Find the commit for the version-bump | |
git fetch origin main | |
git switch main | |
VERSION_BUMP_COMMIT="$(git log --format='%H' --author='OSBotify' --grep 'Update version to ${{ env.NEW_VERSION }}')" | |
# Cherry-pick it to staging | |
git switch staging | |
git cherry-pick -S -x --mainline 1 --strategy=recursive -Xtheirs "$VERSION_BUMP_COMMIT" | |
- name: Cherry-pick the merge commit of target PR | |
id: cherryPick | |
run: | | |
echo "Attempting to cherry-pick ${{ steps.getCPMergeCommit.outputs.MERGE_COMMIT_SHA }}" | |
if git cherry-pick -S -x --mainline 1 ${{ steps.getCPMergeCommit.outputs.MERGE_COMMIT_SHA }}; then | |
echo "🎉 No conflicts! CP was a success, PR can be automerged 🎉" | |
echo "HAS_CONFLICTS=false" >> "$GITHUB_OUTPUT" | |
else | |
echo "😞 PR can't be automerged, there are merge conflicts in the following files:" | |
git --no-pager diff --name-only --diff-filter=U | |
git add . | |
GIT_MERGE_AUTOEDIT=no git cherry-pick --continue | |
echo "HAS_CONFLICTS=true" >> "$GITHUB_OUTPUT" | |
fi | |
- name: Push changes | |
run: | | |
if [[ ${{steps.cherryPick.outputs.HAS_CONFLICTS}} == 'true' ]]; then | |
git checkout -b ${{ github.actor }}-cherry-pick-staging-${{ github.event.inputs.PULL_REQUEST_NUMBER }}-${{ github.run_attempt }} | |
git push --set-upstream origin ${{ github.actor }}-cherry-pick-staging-${{ github.event.inputs.PULL_REQUEST_NUMBER }}-${{ github.run_attempt }} | |
else | |
git push origin staging | |
fi | |
- name: Create Pull Request to manually finish CP | |
if: fromJSON(steps.cherryPick.outputs.HAS_CONFLICTS) | |
id: createPullRequest | |
run: | | |
gh pr create \ | |
--title "🍒 Cherry pick PR #${{ github.event.inputs.PULL_REQUEST_NUMBER }} to staging 🍒" \ | |
--body "🍒 Cherry pick https://github.com/Expensify/App/pull/${{ github.event.inputs.PULL_REQUEST_NUMBER }} to staging 🍒" \ | |
--label "Engineering,Hourly" \ | |
--base "staging" | |
sleep 5 | |
gh pr comment --body \ | |
"This pull request has merge conflicts and can not be automatically merged. :disappointed: | |
Please manually resolve the conflicts, push your changes, and then request another reviewer to review and merge. | |
**Important:** There may be conflicts that GitHub is not able to detect, so please _carefully_ review this pull request before approving." | |
gh pr edit --add-assignee "${{ github.actor }},${{ steps.getCPMergeCommit.outputs.MERGE_ACTOR }}" | |
env: | |
GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} | |
- name: 'Announces a CP failure in the #announce Slack room' | |
uses: 8398a7/action-slack@v3 | |
if: ${{ failure() }} | |
with: | |
status: custom | |
custom_payload: | | |
{ | |
channel: '#announce', | |
attachments: [{ | |
color: "#DB4545", | |
pretext: `<!subteam^S4TJJ3PSL>`, | |
text: `💥 Failed to CP https://github.com/Expensify/App/pull/${{ github.event.inputs.PULL_REQUEST_NUMBER }} to staging 💥`, | |
}] | |
} | |
env: | |
GITHUB_TOKEN: ${{ github.token }} | |
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} |