mirror of
https://github.com/github/codeql-action.git
synced 2026-05-21 13:04:08 +00:00
Merge pull request #3914 from github/henrymercer/auto-rebuild-release-prs
Release process: Automatically rebuild PRs
This commit is contained in:
@@ -41,7 +41,38 @@ runs:
|
||||
git add .
|
||||
git commit -m "Update changelog and version after ${VERSION}"
|
||||
|
||||
git push origin "${NEW_BRANCH}"
|
||||
# Update the build artifacts with the new version number
|
||||
- name: Rebuild the Action
|
||||
shell: bash
|
||||
run: |
|
||||
set -exu
|
||||
npm ci
|
||||
npm run build
|
||||
|
||||
- name: Check for rebuild changes
|
||||
id: rebuild_changes
|
||||
shell: bash
|
||||
run: |
|
||||
set -exu
|
||||
git add --all
|
||||
if git diff --cached --quiet; then
|
||||
echo "has_changes=false" >> "${GITHUB_OUTPUT}"
|
||||
else
|
||||
echo "has_changes=true" >> "${GITHUB_OUTPUT}"
|
||||
fi
|
||||
|
||||
- name: Commit rebuild
|
||||
if: steps.rebuild_changes.outputs.has_changes == 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
set -exu
|
||||
git commit -m "Rebuild"
|
||||
|
||||
- name: Push mergeback branch
|
||||
shell: bash
|
||||
env:
|
||||
NEW_BRANCH: "${{ inputs.branch }}"
|
||||
run: git push origin "${NEW_BRANCH}"
|
||||
|
||||
- name: Create PR
|
||||
shell: bash
|
||||
@@ -60,8 +91,6 @@ runs:
|
||||
|
||||
Please do the following:
|
||||
|
||||
- [ ] Remove and re-add the "Rebuild" label to the PR to trigger just this workflow.
|
||||
- [ ] Wait for the "Rebuild" workflow to push a commit updating the distribution files.
|
||||
- [ ] Mark the PR as ready for review to trigger the full set of PR checks.
|
||||
- [ ] Approve and merge the PR. When merging the PR, make sure "Create a merge commit" is
|
||||
selected rather than "Squash and merge" or "Rebase and merge".
|
||||
@@ -74,7 +103,6 @@ runs:
|
||||
--head "${NEW_BRANCH}" \
|
||||
--base "${BASE_BRANCH}" \
|
||||
--title "${pr_title}" \
|
||||
--label "Rebuild" \
|
||||
--body "${pr_body}" \
|
||||
--assignee "${GITHUB_ACTOR}" \
|
||||
--draft
|
||||
|
||||
@@ -18,7 +18,7 @@ runs:
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 24
|
||||
cache: 'npm'
|
||||
|
||||
- name: Set up Python
|
||||
|
||||
@@ -19,6 +19,10 @@ No user facing changes.
|
||||
# Changing it requires a transition period where both old and new versions are supported.
|
||||
BACKPORT_COMMIT_MESSAGE = 'Update version and changelog for v'
|
||||
|
||||
# Commit message used for rebuild commits, both those produced by this script and those produced
|
||||
# by the `Rebuild Action` workflow (`.github/workflows/rebuild.yml`).
|
||||
REBUILD_COMMIT_MESSAGE = 'Rebuild'
|
||||
|
||||
# Name of the remote
|
||||
ORIGIN = 'origin'
|
||||
|
||||
@@ -43,6 +47,28 @@ def run_git(*args, allow_non_zero_exit_code=False):
|
||||
raise Exception(f'Call to {" ".join(cmd)} exited with code {p.returncode} stderr: {p.stderr.decode("ascii")}.')
|
||||
return p.stdout.decode('ascii')
|
||||
|
||||
# Runs the given command, streaming output to the console.
|
||||
# Raises an error if the command does not exit successfully.
|
||||
def run_command(*args):
|
||||
cmd = list(args)
|
||||
print(f'Running `{" ".join(cmd)}`.')
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
# Rebuilds the action and commits any changes.
|
||||
def rebuild_action():
|
||||
# For backports, the only source-level change vs the source branch is the new version number,
|
||||
# so we just need to refresh the version embedded in `lib/`.
|
||||
run_command('npm', 'ci')
|
||||
run_command('npm', 'run', 'build')
|
||||
|
||||
run_git('add', '--all')
|
||||
# `git diff --cached --quiet` exits 0 if there are no staged changes, 1 if there are.
|
||||
if subprocess.run(['git', 'diff', '--cached', '--quiet']).returncode == 0:
|
||||
print('Rebuild produced no changes; skipping Rebuild commit.')
|
||||
else:
|
||||
run_git('commit', '-m', REBUILD_COMMIT_MESSAGE)
|
||||
print('Created Rebuild commit.')
|
||||
|
||||
# Returns true if the given branch exists on the origin remote
|
||||
def branch_exists_on_remote(branch_name):
|
||||
return run_git('ls-remote', '--heads', ORIGIN, branch_name).strip() != ''
|
||||
@@ -98,9 +124,11 @@ def open_pr(
|
||||
body.append('Please do the following:')
|
||||
if len(conflicted_files) > 0:
|
||||
body.append(' - [ ] Ensure `package.json` file contains the correct version.')
|
||||
body.append(' - [ ] Add commits to this branch to resolve the merge conflicts ' +
|
||||
body.append(' - [ ] Add a commit to this branch to resolve the merge conflicts ' +
|
||||
'in the following files:')
|
||||
body.extend([f' - [ ] `{file}`' for file in conflicted_files])
|
||||
body.extend([f' - `{file}`' for file in conflicted_files])
|
||||
body.append(' - [ ] Rebuild the Action locally (`npm run build`) and push any changes to the ' +
|
||||
f'built output in `lib` as a separate commit named exactly `{REBUILD_COMMIT_MESSAGE}`.')
|
||||
body.append(' - [ ] Ensure another maintainer has reviewed the additional commits you added to this ' +
|
||||
'branch to resolve the merge conflicts.')
|
||||
body.append(' - [ ] Ensure the CHANGELOG displays the correct version and date.')
|
||||
@@ -108,10 +136,6 @@ def open_pr(
|
||||
body.append(f' - [ ] Check that there are not any unexpected commits being merged into the `{target_branch}` branch.')
|
||||
body.append(' - [ ] Ensure the docs team is aware of any documentation changes that need to be released.')
|
||||
|
||||
if not is_primary_release:
|
||||
body.append(' - [ ] Remove and re-add the "Rebuild" label to the PR to trigger just this workflow.')
|
||||
body.append(' - [ ] Wait for the "Rebuild" workflow to push a commit updating the distribution files.')
|
||||
|
||||
body.append(' - [ ] Mark the PR as ready for review to trigger the full set of PR checks.')
|
||||
body.append(' - [ ] Approve and merge this PR. Make sure `Create a merge commit` is selected rather than `Squash and merge` or `Rebase and merge`.')
|
||||
|
||||
@@ -120,13 +144,11 @@ def open_pr(
|
||||
body.append(' - [ ] Merge all backport PRs to older release branches, that will automatically be created once this PR is merged.')
|
||||
|
||||
title = f'Merge {source_branch} into {target_branch}'
|
||||
labels = ['Rebuild'] if not is_primary_release else []
|
||||
|
||||
# Create the pull request
|
||||
# PR checks won't be triggered on PRs created by Actions. Therefore mark the PR as draft so that
|
||||
# a maintainer can take the PR out of draft, thereby triggering the PR checks.
|
||||
pr = repo.create_pull(title=title, body='\n'.join(body), head=new_branch_name, base=target_branch, draft=True)
|
||||
pr.add_to_labels(*labels)
|
||||
print(f'Created PR #{str(pr.number)}')
|
||||
|
||||
# Assign the conductor
|
||||
@@ -385,8 +407,9 @@ def main():
|
||||
# releases.
|
||||
run_git('revert', vOlder_update_commits[0], '--no-edit')
|
||||
|
||||
# Also revert the "Rebuild" commit created by Actions.
|
||||
rebuild_commit = run_git('log', '--grep', '^Rebuild$', '--format=%H').split()[0]
|
||||
# Also revert the "Rebuild" commit, whether created by this script or by the
|
||||
# `Rebuild Action` workflow.
|
||||
rebuild_commit = run_git('log', '--grep', f'^{REBUILD_COMMIT_MESSAGE}$', '--format=%H').split()[0]
|
||||
print(f' Reverting {rebuild_commit}')
|
||||
run_git('revert', rebuild_commit, '--no-edit')
|
||||
|
||||
@@ -401,9 +424,10 @@ def main():
|
||||
run_git('add', '.')
|
||||
run_git('commit', '--no-edit')
|
||||
|
||||
# Migrate the package version number from a vLatest version number to a vOlder version number
|
||||
# Migrate the package version number from a vLatest version number to a vOlder version number.
|
||||
# `package-lock.json` is updated as part of the subsequent rebuild step (see `rebuild_action`).
|
||||
print(f'Setting version number to {version} in package.json')
|
||||
replace_version_package_json(get_current_version(), version) # We rely on the `Rebuild` workflow to update package-lock.json
|
||||
replace_version_package_json(get_current_version(), version)
|
||||
run_git('add', 'package.json')
|
||||
|
||||
# Migrate the changelog notes from vLatest version numbers to vOlder version numbers
|
||||
@@ -426,6 +450,13 @@ def main():
|
||||
run_git('add', 'CHANGELOG.md')
|
||||
run_git('commit', '-m', f'Update changelog for v{version}')
|
||||
|
||||
if not is_primary_release:
|
||||
if len(conflicted_files) == 0:
|
||||
print('Rebuilding the Action.')
|
||||
rebuild_action()
|
||||
else:
|
||||
print(f'Skipping automatic rebuild because the merge produced conflicts in {conflicted_files}.')
|
||||
|
||||
run_git('push', ORIGIN, new_branch_name)
|
||||
|
||||
# Open a PR to update the branch
|
||||
|
||||
@@ -48,6 +48,9 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0 # ensure we have all tags and can push commits
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: 'npm'
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
Reference in New Issue
Block a user