Skip to content

Commit 00eeac8

Browse files
authored
Add script to merge main into all active feature branches on a regular schedule. (#1394)
* Add workflow for automatically updating feature branches weekly. * Corrected filename, and added inputs. * Remove trailing spaces. * Fix workflow. * Fix workflow name. * Fix syntax. * Fix syntax. * List remote branches instead. * Clean up script. * Untab. * Add branch list for debugging. * Untab. * Specify remote branches. * Skip second stage if no first. * Typo * Error. * List all branches. * Fix logic. * Fix spacing. * Fix output * Fix parameters. * Fix merge to use origin. * Remove debug echos. * Add git config. * Fix PR creation. * Fix PR creation. * Fix automatic push.
1 parent 3cd0dca commit 00eeac8

File tree

1 file changed

+119
-4
lines changed

1 file changed

+119
-4
lines changed

.github/workflows/update-feature-branches.yml

+119-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,126 @@ name: Update Feature Branches
22
on:
33
workflow_dispatch:
44
inputs:
5+
branch_patterns:
6+
description: 'Space-separated list of feature branch patterns'
7+
default: 'feature_branch/*'
8+
required: true
9+
main_branch:
10+
description: 'Main branch to merge'
11+
default: 'main'
12+
required: true
13+
schedule:
14+
- cron: "0 16 * * 1" # Mondays, 4pm UTC = 9am PST / 10am PDT
15+
16+
env:
17+
defaultBranchPattern: "feature_branch/*"
18+
defaultMainBranch: "main"
19+
triggerTestsLabel: "tests-requested: quick"
520

621
jobs:
7-
no_op:
8-
name: no-op
22+
list_feature_branches:
23+
name: list-feature-branches
24+
runs-on: ubuntu-20.04
25+
outputs:
26+
branch_list: ${{ steps.get-branches.outputs.branch_list }}
27+
steps:
28+
- name: Check out repo (if needed)
29+
if: ${{ github.event.inputs.branch_list == '' }}
30+
uses: actions/checkout@v3
31+
32+
- name: Get list of feature branches
33+
id: get-branches
34+
run: |
35+
branch_pattern='origin/${{ env.defaultBranchPattern }}'
36+
if [[ -n '${{ github.event.inputs.branch_patterns }}' ]]; then
37+
branch_pattern=origin/$(echo '${{ github.event.inputs.branch_patterns }}' | sed 's| | origin/|g')
38+
fi
39+
git remote update
40+
echo "Branch pattern: ${branch_pattern}"
41+
branch_list=$(git branch --list --all "${branch_pattern}")
42+
if [[ -n ${branch_list} ]]; then
43+
# If there's at least one entry, process the list.
44+
echo "Remote branch list: ${branch_list}"
45+
# Remove remotes/origin/ from each branch.
46+
branch_list=$(echo ${branch_list} | sed 's| remotes/origin/| |g' | sed 's|^remotes/origin/||')
47+
# Change spaces to commas.
48+
branch_list=$(echo ${branch_list} | sed 's/ /,/g')
49+
# Add quotes around each branch name.
50+
branch_list='"'$(echo ${branch_list} | sed 's/,/","/g')'"'
51+
fi
52+
echo "::warning ::Branch list: [${branch_list}]"
53+
echo "branch_list=[${branch_list}]" >> $GITHUB_OUTPUT
54+
55+
create_merge_prs:
56+
name: create-merge-pr-${{ matrix.branch_name }}
57+
needs: [ list_feature_branches ]
958
runs-on: ubuntu-20.04
59+
if: ${{ needs.list_feature_branches.outputs.branch_list != '[]' }}
60+
strategy:
61+
fail-fast: false
62+
matrix:
63+
branch_name: ${{ fromJson(needs.list_feature_branches.outputs.branch_list) }}
1064
steps:
11-
- name: noop
12-
run: true
65+
- name: Get token for firebase-workflow-trigger
66+
uses: tibdex/github-app-token@v1
67+
id: generate-token
68+
with:
69+
app_id: ${{ secrets.WORKFLOW_TRIGGER_APP_ID }}
70+
private_key: ${{ secrets.WORKFLOW_TRIGGER_APP_PRIVATE_KEY }}
71+
72+
- name: Setup python
73+
uses: actions/setup-python@v4
74+
with:
75+
python-version: 3.7
76+
77+
- uses: actions/checkout@v3
78+
with:
79+
ref: ${{ matrix.branch_name }}
80+
fetch-depth: 0
81+
submodules: false
82+
83+
- name: Install prerequisites
84+
run: |
85+
python scripts/gha/install_prereqs_desktop.py
86+
python -m pip install requests
87+
88+
- name: Create merge PR
89+
id: create-pr
90+
run: |
91+
git config user.email "[email protected]"
92+
git config user.name "firebase-workflow-trigger-bot"
93+
git config core.commentChar "%" # so we can use # in git commit messages
94+
95+
main_branch='${{ env.defaultMainBranch }}'
96+
if [[ -n '${{ github.event.inputs.main_branch }}' ]]; then
97+
main_branch='${{ github.event.inputs.main_branch }}'
98+
fi
99+
# Attempt a merge, then check if any files changed.
100+
git merge --no-commit --no-ff "origin/${main_branch}" || true
101+
if git diff --quiet ${{ matrix.branch_name }}; then
102+
# No merge necessary.
103+
echo "::warning ::No merge needed for ${{ matrix.branch_name }}, won't create pull request."
104+
echo "created_pr_number=0" >> $GITHUB_OUTPUT
105+
exit 0
106+
fi
107+
108+
# Undo the actual merge. Let the PR creation handle it.
109+
git merge --abort
110+
111+
date_str=$(date "+%b %d, %Y")
112+
113+
pr_title="Automatic merge of ${main_branch} into ${{ matrix.branch_name }} - ${date_str}"
114+
pr_body="Automatic merge of ${main_branch} into ${{ matrix.branch_name }}.
115+
116+
> Created on ${date_str} by [${{github.workflow}} workflow]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID).
117+
"
118+
pr_number=$(python scripts/gha/create_pull_request.py --token ${{ steps.generate-token.outputs.token }} --base "${{ matrix.branch_name }}" --head "${main_branch}" --title "${pr_title}" --body "${pr_body}")
119+
echo "created_pr_number=${pr_number}" >> $GITHUB_OUTPUT
120+
121+
- name: Set test trigger label.
122+
uses: actions-ecosystem/action-add-labels@v1
123+
if: ${{ steps.create-pr.outputs.created_pr_number }}
124+
with:
125+
github_token: ${{ steps.generate-token.outputs.token }}
126+
number: ${{ steps.create-pr.outputs.created_pr_number }}
127+
labels: "${{ env.triggerTestsLabel }}"

0 commit comments

Comments
 (0)