Skip to content

Commit 7510620

Browse files
committed
Release process: Automatically rebuild PRs
1 parent c8a3492 commit 7510620

4 files changed

Lines changed: 77 additions & 17 deletions

File tree

.github/actions/prepare-mergeback-branch/action.yml

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,38 @@ runs:
4141
git add .
4242
git commit -m "Update changelog and version after ${VERSION}"
4343
44-
git push origin "${NEW_BRANCH}"
44+
# Update the build artifacts with the new version number
45+
- name: Rebuild the Action
46+
shell: bash
47+
run: |
48+
set -exu
49+
npm ci
50+
npm run build
51+
52+
- name: Check for rebuild changes
53+
id: rebuild_changes
54+
shell: bash
55+
run: |
56+
set -exu
57+
git add --all
58+
if git diff --cached --quiet; then
59+
echo "has_changes=false" >> "${GITHUB_OUTPUT}"
60+
else
61+
echo "has_changes=true" >> "${GITHUB_OUTPUT}"
62+
fi
63+
64+
- name: Commit rebuild
65+
if: steps.rebuild_changes.outputs.has_changes == 'true'
66+
shell: bash
67+
run: |
68+
set -exu
69+
git commit -m "Rebuild"
70+
71+
- name: Push mergeback branch
72+
shell: bash
73+
env:
74+
NEW_BRANCH: "${{ inputs.branch }}"
75+
run: git push origin "${NEW_BRANCH}"
4576

4677
- name: Create PR
4778
shell: bash
@@ -60,8 +91,6 @@ runs:
6091
6192
Please do the following:
6293
63-
- [ ] Remove and re-add the "Rebuild" label to the PR to trigger just this workflow.
64-
- [ ] Wait for the "Rebuild" workflow to push a commit updating the distribution files.
6594
- [ ] Mark the PR as ready for review to trigger the full set of PR checks.
6695
- [ ] Approve and merge the PR. When merging the PR, make sure "Create a merge commit" is
6796
selected rather than "Squash and merge" or "Rebase and merge".
@@ -74,7 +103,6 @@ runs:
74103
--head "${NEW_BRANCH}" \
75104
--base "${BASE_BRANCH}" \
76105
--title "${pr_title}" \
77-
--label "Rebuild" \
78106
--body "${pr_body}" \
79107
--assignee "${GITHUB_ACTOR}" \
80108
--draft

.github/actions/release-initialise/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ runs:
1818
- name: Set up Node
1919
uses: actions/setup-node@v6
2020
with:
21-
node-version: 20
22-
cache: 'npm'
21+
node-version: 24
22+
cache: 'npm' # shared with the "Rebuild Action" workflow
2323

2424
- name: Set up Python
2525
uses: actions/setup-python@v6

.github/update-release-branch.py

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
# Changing it requires a transition period where both old and new versions are supported.
2020
BACKPORT_COMMIT_MESSAGE = 'Update version and changelog for v'
2121

22+
# Commit message used for rebuild commits, both those produced by this script and those produced
23+
# by the `Rebuild Action` workflow (`.github/workflows/rebuild.yml`).
24+
REBUILD_COMMIT_MESSAGE = 'Rebuild'
25+
2226
# Name of the remote
2327
ORIGIN = 'origin'
2428

@@ -43,14 +47,36 @@ def run_git(*args, allow_non_zero_exit_code=False):
4347
raise Exception(f'Call to {" ".join(cmd)} exited with code {p.returncode} stderr: {p.stderr.decode("ascii")}.')
4448
return p.stdout.decode('ascii')
4549

50+
# Runs the given command, streaming output to the console.
51+
# Raises an error if the command does not exit successfully.
52+
def run_command(*args):
53+
cmd = list(args)
54+
print(f'Running `{" ".join(cmd)}`.')
55+
subprocess.run(cmd, check=True)
56+
57+
# Rebuilds the action and commits any changes.
58+
def rebuild_action():
59+
# For backports, the only source-level change vs the source branch is the new version number,
60+
# so we just need to refresh the version embedded in `lib/`.
61+
run_command('npm', 'ci')
62+
run_command('npm', 'run', 'build')
63+
64+
run_git('add', '--all')
65+
# `git diff --cached --quiet` exits 0 if there are no staged changes, 1 if there are.
66+
if subprocess.run(['git', 'diff', '--cached', '--quiet']).returncode == 0:
67+
print('Rebuild produced no changes; skipping Rebuild commit.')
68+
else:
69+
run_git('commit', '-m', REBUILD_COMMIT_MESSAGE)
70+
print('Created Rebuild commit.')
71+
4672
# Returns true if the given branch exists on the origin remote
4773
def branch_exists_on_remote(branch_name):
4874
return run_git('ls-remote', '--heads', ORIGIN, branch_name).strip() != ''
4975

5076
# Opens a PR from the given branch to the target branch
5177
def open_pr(
5278
repo, all_commits, source_branch_short_sha, new_branch_name, source_branch, target_branch,
53-
conductor, is_primary_release, conflicted_files):
79+
conductor, is_primary_release, conflicted_files, needs_rebuild):
5480
# Sort the commits into the pull requests that introduced them,
5581
# and any commits that don't have a pull request
5682
pull_requests = []
@@ -108,10 +134,6 @@ def open_pr(
108134
body.append(f' - [ ] Check that there are not any unexpected commits being merged into the `{target_branch}` branch.')
109135
body.append(' - [ ] Ensure the docs team is aware of any documentation changes that need to be released.')
110136

111-
if not is_primary_release:
112-
body.append(' - [ ] Remove and re-add the "Rebuild" label to the PR to trigger just this workflow.')
113-
body.append(' - [ ] Wait for the "Rebuild" workflow to push a commit updating the distribution files.')
114-
115137
body.append(' - [ ] Mark the PR as ready for review to trigger the full set of PR checks.')
116138
body.append(' - [ ] Approve and merge this PR. Make sure `Create a merge commit` is selected rather than `Squash and merge` or `Rebase and merge`.')
117139

@@ -120,13 +142,11 @@ def open_pr(
120142
body.append(' - [ ] Merge all backport PRs to older release branches, that will automatically be created once this PR is merged.')
121143

122144
title = f'Merge {source_branch} into {target_branch}'
123-
labels = ['Rebuild'] if not is_primary_release else []
124145

125146
# Create the pull request
126147
# PR checks won't be triggered on PRs created by Actions. Therefore mark the PR as draft so that
127148
# a maintainer can take the PR out of draft, thereby triggering the PR checks.
128149
pr = repo.create_pull(title=title, body='\n'.join(body), head=new_branch_name, base=target_branch, draft=True)
129-
pr.add_to_labels(*labels)
130150
print(f'Created PR #{str(pr.number)}')
131151

132152
# Assign the conductor
@@ -385,8 +405,9 @@ def main():
385405
# releases.
386406
run_git('revert', vOlder_update_commits[0], '--no-edit')
387407

388-
# Also revert the "Rebuild" commit created by Actions.
389-
rebuild_commit = run_git('log', '--grep', '^Rebuild$', '--format=%H').split()[0]
408+
# Also revert the "Rebuild" commit, whether created by this script or by the
409+
# `Rebuild Action` workflow.
410+
rebuild_commit = run_git('log', '--grep', f'^{REBUILD_COMMIT_MESSAGE}$', '--format=%H').split()[0]
390411
print(f' Reverting {rebuild_commit}')
391412
run_git('revert', rebuild_commit, '--no-edit')
392413

@@ -401,9 +422,10 @@ def main():
401422
run_git('add', '.')
402423
run_git('commit', '--no-edit')
403424

404-
# Migrate the package version number from a vLatest version number to a vOlder version number
425+
# Migrate the package version number from a vLatest version number to a vOlder version number.
426+
# `package-lock.json` is updated as part of the subsequent rebuild step (see `rebuild_action`).
405427
print(f'Setting version number to {version} in package.json')
406-
replace_version_package_json(get_current_version(), version) # We rely on the `Rebuild` workflow to update package-lock.json
428+
replace_version_package_json(get_current_version(), version)
407429
run_git('add', 'package.json')
408430

409431
# Migrate the changelog notes from vLatest version numbers to vOlder version numbers
@@ -426,6 +448,13 @@ def main():
426448
run_git('add', 'CHANGELOG.md')
427449
run_git('commit', '-m', f'Update changelog for v{version}')
428450

451+
if not is_primary_release:
452+
if len(conflicted_files) == 0:
453+
print('Rebuilding the Action.')
454+
rebuild_action()
455+
else:
456+
print(f'Skipping automatic rebuild because the merge produced conflicts in {conflicted_files}.')
457+
429458
run_git('push', ORIGIN, new_branch_name)
430459

431460
# Open a PR to update the branch

.github/workflows/post-release-mergeback.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ jobs:
4848
with:
4949
fetch-depth: 0 # ensure we have all tags and can push commits
5050
- uses: actions/setup-node@v6
51+
with:
52+
node-version: 24
53+
cache: 'npm' # shared with the "Rebuild Action" workflow
5154
- uses: actions/setup-python@v6
5255
with:
5356
python-version: '3.12'

0 commit comments

Comments
 (0)