Skip to content

Commit b7dd4a6

Browse files
authored
Merge 800a951 into eeaefb6
2 parents eeaefb6 + 800a951 commit b7dd4a6

File tree

3 files changed

+197
-16
lines changed

3 files changed

+197
-16
lines changed

.github/update-release-branch.py

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@
44
import requests
55
import subprocess
66
import sys
7+
import json
8+
import datetime
9+
import os
10+
11+
EMPTY_CHANGELOG = """
12+
# CodeQL Action and CodeQL Runner Changelog
13+
14+
## [UNRELEASED]
15+
16+
"""
717

818
# The branch being merged from.
919
# This is the one that contains day-to-day development work.
@@ -49,32 +59,40 @@ def open_pr(repo, all_commits, short_main_sha, branch_name):
4959
commits_without_pull_requests = sorted(commits_without_pull_requests, key=lambda c: c.commit.author.date)
5060

5161
# Start constructing the body text
52-
body = 'Merging ' + short_main_sha + ' into ' + LATEST_RELEASE_BRANCH
62+
body = []
63+
body.append('Merging ' + short_main_sha + ' into ' + LATEST_RELEASE_BRANCH)
5364

5465
conductor = get_conductor(repo, pull_requests, commits_without_pull_requests)
55-
body += '\n\nConductor for this PR is @' + conductor
66+
body.append('')
67+
body.append('Conductor for this PR is @' + conductor)
5668

5769
# List all PRs merged
5870
if len(pull_requests) > 0:
59-
body += '\n\nContains the following pull requests:'
71+
body.append('')
72+
body.append('Contains the following pull requests:')
6073
for pr in pull_requests:
6174
merger = get_merger_of_pr(repo, pr)
62-
body += '\n- #' + str(pr.number)
63-
body += ' - ' + pr.title
64-
body += ' (@' + merger + ')'
75+
body.append('- #' + str(pr.number) + ' - ' + pr.title +' (@' + merger + ')')
6576

6677
# List all commits not part of a PR
6778
if len(commits_without_pull_requests) > 0:
68-
body += '\n\nContains the following commits not from a pull request:'
79+
body.append('')
80+
body.append('Contains the following commits not from a pull request:')
6981
for commit in commits_without_pull_requests:
70-
body += '\n- ' + commit.sha
71-
body += ' - ' + get_truncated_commit_message(commit)
72-
body += ' (@' + commit.author.login + ')'
82+
body.append('- ' + commit.sha + ' - ' + get_truncated_commit_message(commit) + ' (@' + commit.author.login + ')')
83+
84+
body.append('')
85+
body.append('Please review the following:')
86+
body.append(' - [ ] The CHANGELOG displays the correct version and date.')
87+
body.append(' - [ ] The CHANGELOG includes all relevant, user-facing changes since the last release.')
88+
body.append(' - [ ] There are no unexpected commits being merged into the ' + LATEST_RELEASE_BRANCH + ' branch.')
89+
body.append(' - [ ] The docs team is aware of any documentation changes that need to be released.')
90+
body.append(' - [ ] The mergeback PR is merged back into ' + MAIN_BRANCH + ' after this PR is merged.')
7391

7492
title = 'Merge ' + MAIN_BRANCH + ' into ' + LATEST_RELEASE_BRANCH
7593

7694
# Create the pull request
77-
pr = repo.create_pull(title=title, body=body, head=branch_name, base=LATEST_RELEASE_BRANCH)
95+
pr = repo.create_pull(title=title, body='\n'.join(body), head=branch_name, base=LATEST_RELEASE_BRANCH)
7896
print('Created PR #' + str(pr.number))
7997

8098
# Assign the conductor
@@ -95,7 +113,7 @@ def get_conductor(repo, pull_requests, other_commits):
95113
# This will not include any commits that exist on the release branch
96114
# that aren't on main.
97115
def get_commit_difference(repo):
98-
commits = run_git('log', '--pretty=format:%H', ORIGIN + '/' + LATEST_RELEASE_BRANCH + '..' + MAIN_BRANCH).strip().split('\n')
116+
commits = run_git('log', '--pretty=format:%H', ORIGIN + '/' + LATEST_RELEASE_BRANCH + '..' + ORIGIN + '/' + MAIN_BRANCH).strip().split('\n')
99117

100118
# Convert to full-fledged commit objects
101119
commits = [repo.get_commit(c) for c in commits]
@@ -135,17 +153,40 @@ def get_pr_for_commit(repo, commit):
135153
def get_merger_of_pr(repo, pr):
136154
return repo.get_commit(pr.merge_commit_sha).author.login
137155

156+
def get_current_version():
157+
with open('package.json', 'r') as f:
158+
return json.load(f)['version']
159+
160+
def get_today_string():
161+
today = datetime.datetime.today()
162+
return '{:%d %b %Y}'.format(today)
163+
164+
def update_changelog(version):
165+
if (os.path.exists('CHANGELOG.md')):
166+
content = ''
167+
with open('CHANGELOG.md', 'r') as f:
168+
content = f.read()
169+
else:
170+
content = EMPTY_CHANGELOG
171+
172+
newContent = content.replace('[UNRELEASED]', version + ' - ' + get_today_string(), 1)
173+
174+
with open('CHANGELOG.md', 'w') as f:
175+
f.write(newContent)
176+
177+
138178
def main():
139179
if len(sys.argv) != 3:
140180
raise Exception('Usage: update-release.branch.py <github token> <repository nwo>')
141181
github_token = sys.argv[1]
142182
repository_nwo = sys.argv[2]
143183

144184
repo = Github(github_token).get_repo(repository_nwo)
185+
version = get_current_version()
145186

146187
# Print what we intend to go
147188
print('Considering difference between ' + MAIN_BRANCH + ' and ' + LATEST_RELEASE_BRANCH)
148-
short_main_sha = run_git('rev-parse', '--short', MAIN_BRANCH).strip()
189+
short_main_sha = run_git('rev-parse', '--short', ORIGIN + '/' + MAIN_BRANCH).strip()
149190
print('Current head of ' + MAIN_BRANCH + ' is ' + short_main_sha)
150191

151192
# See if there are any commits to merge in
@@ -157,7 +198,7 @@ def main():
157198
# The branch name is based off of the name of branch being merged into
158199
# and the SHA of the branch being merged from. Thus if the branch already
159200
# exists we can assume we don't need to recreate it.
160-
new_branch_name = 'update-' + LATEST_RELEASE_BRANCH + '-' + short_main_sha
201+
new_branch_name = 'update-v' + version + '-' + short_main_sha
161202
print('Branch name is ' + new_branch_name)
162203

163204
# Check if the branch already exists. If so we can abort as this script
@@ -168,7 +209,15 @@ def main():
168209

169210
# Create the new branch and push it to the remote
170211
print('Creating branch ' + new_branch_name)
171-
run_git('checkout', '-b', new_branch_name, MAIN_BRANCH)
212+
run_git('checkout', '-b', new_branch_name, ORIGIN + '/' + MAIN_BRANCH)
213+
214+
print('Updating changelog')
215+
update_changelog(version)
216+
217+
# Create a commit that updates the CHANGELOG
218+
run_git('add', 'CHANGELOG.md')
219+
run_git('commit', '-m', version)
220+
172221
run_git('push', ORIGIN, new_branch_name)
173222

174223
# Open a PR to update the branch
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# This workflow runs after a release of the action.
2+
# It merges any changes from the release back into the
3+
# main branch. Typically, this is just a single commit
4+
# that updates the changelog.
5+
name: Tag release and merge back
6+
7+
on:
8+
workflow_dispatch:
9+
inputs:
10+
baseBranch:
11+
description: 'The base branch to merge into'
12+
default: main
13+
required: false
14+
15+
push:
16+
branches:
17+
- v1
18+
19+
pull_request:
20+
paths:
21+
- .github/workflows/post-release-mergeback.yml
22+
23+
jobs:
24+
merge-back:
25+
runs-on: ubuntu-latest
26+
if: github.repository == 'github/codeql-action'
27+
env:
28+
BASE_BRANCH: "${{ github.event.inputs.baseBranch || 'main' }}"
29+
HEAD_BRANCH: "${{ github.head_ref || github.ref }}"
30+
# Would like to use the github/codeql-core team, but that is not working
31+
DEFAULT_REVIEWER: "aeisenberg"
32+
33+
steps:
34+
- name: Dump GitHub context
35+
env:
36+
GITHUB_CONTEXT: "${{ toJson(github) }}"
37+
run: echo "$GITHUB_CONTEXT"
38+
39+
- uses: actions/checkout@v2
40+
- uses: actions/setup-node@v2
41+
42+
- name: Update git config
43+
run: |
44+
git config --global user.email "[email protected]"
45+
git config --global user.name "github-actions[bot]"
46+
47+
- name: Get version and new branch
48+
id: getVersion
49+
run: |
50+
VERSION="v$(jq '.version' -r 'package.json')"
51+
SHORT_SHA="${GITHUB_SHA:0:8}"
52+
echo "::set-output name=version::$VERSION"
53+
NEW_BRANCH="mergeback/${VERSION}-to-${BASE_BRANCH}-${SHORT_SHA}"
54+
echo "::set-output name=newBranch::$NEW_BRANCH"
55+
56+
57+
- name: Dump branches
58+
env:
59+
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
60+
run: |
61+
echo "BASE_BRANCH $BASE_BRANCH"
62+
echo "HEAD_BRANCH $HEAD_BRANCH"
63+
echo "NEW_BRANCH $NEW_BRANCH"
64+
65+
- name: Create mergeback branch
66+
env:
67+
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
68+
run: |
69+
git checkout -b "$NEW_BRANCH"
70+
71+
- name: Check for tag
72+
id: check
73+
env:
74+
VERSION: "${{ steps.getVersion.outputs.version }}"
75+
run: |
76+
set +e # don't fail on an errored command
77+
git ls-remote --tags origin | grep "$VERSION"
78+
EXISTS="$?"
79+
if [ "$EXISTS" -ne 0 ]; then
80+
echo "::set-output name=exists::true"
81+
echo "Tag $TAG exists. Not going to re-release."
82+
fi
83+
84+
# we didn't tag the release during the update-release-branch workflow because the
85+
# commit that actually makes it to the release branch is a merge commit,
86+
# and not yet known during the first workflow. We tag now because we know the correct commit.
87+
- name: Tag release
88+
if: steps.check.outputs.exists == 'true'
89+
env:
90+
VERSION: ${{ steps.getVersion.outputs.version }}
91+
run: |
92+
git tag -a "$VERSION" -m "$VERSION"
93+
git push origin --follow-tags "$VERSION"
94+
95+
- name: Create mergeback branch
96+
if: steps.check.outputs.exists == 'true'
97+
env:
98+
VERSION: "${{ steps.getVersion.outputs.version }}"
99+
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
100+
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
101+
run: |
102+
set -exu
103+
PR_TITLE="Mergeback $VERSION $HEAD_BRANCH into $BASE_BRANCH"
104+
PR_BODY="Updates version and changelog."
105+
106+
# Update the changelog
107+
perl -i -pe 's/^/## \[UNRELEASED\]\n\n/ if($.==3)' CHANGELOG.md
108+
git add .
109+
git commit -m "Update changelog and version after $VERSION"
110+
npm version patch
111+
112+
# when running this workflow on a PR, this is just a test.
113+
# so put into draft mode.
114+
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
115+
DRAFT="--draft"
116+
else
117+
DRAFT=""
118+
fi
119+
120+
git push origin "$NEW_BRANCH"
121+
gh pr create \
122+
--head "$NEW_BRANCH" \
123+
--base "$BASE_BRANCH" \
124+
--title "$PR_TITLE" \
125+
--body "$PR_BODY" \
126+
--reviewer "$DEFAULT_REVIEWER" \
127+
"$DRAFT"

.github/workflows/update-release-branch.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,17 @@ jobs:
2222
- name: Set up Python
2323
uses: actions/setup-python@v2
2424
with:
25-
python-version: 3.5
25+
python-version: 3.8
2626

2727
- name: Install dependencies
2828
run: |
2929
python -m pip install --upgrade pip
3030
pip install PyGithub==1.51 requests
3131
32+
- name: Update git config
33+
run: |
34+
git config --global user.email "[email protected]"
35+
git config --global user.name "github-actions[bot]"
36+
3237
- name: Update release branch
3338
run: python .github/update-release-branch.py ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }}

0 commit comments

Comments
 (0)