Skip to content

Commit

Permalink
Add release and mergeback workflows
Browse files Browse the repository at this point in the history
This commit ensures that the changelog is updated before a release with
the correct date and version.

Also, after a release, a mergeback PR is created to ensure that the
changelog update and version bump is available in main.
  • Loading branch information
aeisenberg committed May 19, 2021
1 parent 03ff062 commit 5100571
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 5 deletions.
56 changes: 52 additions & 4 deletions .github/update-release-branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@
import requests
import subprocess
import sys
import json
import datetime
import os

EMPTY_CHANGELOG = """
# CodeQL Action: Changelog
## [UNRELEASED]
"""

# The branch being merged from.
# This is the one that contains day-to-day development work.
Expand Down Expand Up @@ -71,6 +81,13 @@ def open_pr(repo, all_commits, short_main_sha, branch_name):
body += ' - ' + get_truncated_commit_message(commit)
body += ' (@' + commit.author.login + ')'

body += '\n\nPlease review the following:\n'
body += ' - [ ] The CHANGELOG displays the correct version and date.\n'
body += ' - [ ] The CHANGELOG includes all relevant, user-facing changes since the last release.\n'
body += ' - [ ] There are no unexpected commits being merged into the ' + LATEST_RELEASE_BRANCH + ' branch.\n'
body += ' - [ ] The docs team is aware of any documentation changes that need to be released.\n'
body += ' - [ ] The mergeback PR is merged back into ' + MAIN_BRANCH + ' after this PR is merged.\n'

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

# Create the pull request
Expand All @@ -95,7 +112,7 @@ def get_conductor(repo, pull_requests, other_commits):
# This will not include any commits that exist on the release branch
# that aren't on main.
def get_commit_difference(repo):
commits = run_git('log', '--pretty=format:%H', ORIGIN + '/' + LATEST_RELEASE_BRANCH + '..' + MAIN_BRANCH).strip().split('\n')
commits = run_git('log', '--pretty=format:%H', ORIGIN + '/' + LATEST_RELEASE_BRANCH + '..' + ORIGIN + '/' + MAIN_BRANCH).strip().split('\n')

# Convert to full-fledged commit objects
commits = [repo.get_commit(c) for c in commits]
Expand Down Expand Up @@ -135,17 +152,40 @@ def get_pr_for_commit(repo, commit):
def get_merger_of_pr(repo, pr):
return repo.get_commit(pr.merge_commit_sha).author.login

def get_current_version():
with open('package.json', 'r') as f:
return json.load(f)['version']

def get_today_string():
today = datetime.datetime.today()
return '{:%d %b %Y}'.format(today)

def update_changelog(version):
if (os.path.exists('CHANGELOG.md')):
content = ''
with open('CHANGELOG.md', 'r') as f:
content = f.read()
else:
content = EMPTY_CHANGELOG

newContent = content.replace('[UNRELEASED]', version + ' - ' + get_today_string(), 1)

with open('CHANGELOG.md', 'w') as f:
f.write(newContent)


def main():
if len(sys.argv) != 3:
raise Exception('Usage: update-release.branch.py <github token> <repository nwo>')
github_token = sys.argv[1]
repository_nwo = sys.argv[2]

repo = Github(github_token).get_repo(repository_nwo)
version = get_current_version()

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

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

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

# Create the new branch and push it to the remote
print('Creating branch ' + new_branch_name)
run_git('checkout', '-b', new_branch_name, MAIN_BRANCH)
run_git('checkout', '-b', new_branch_name, ORIGIN + '/' + MAIN_BRANCH)

print('Updating changelog')
update_changelog(version)

# Create a commit that updates the CHANGELOG
run_git('add', 'CHANGELOG.md')
run_git('commit', '-m', version)

run_git('push', ORIGIN, new_branch_name)

# Open a PR to update the branch
Expand Down
65 changes: 65 additions & 0 deletions .github/workflows/post-release-mergeback.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# This workflow runs after a release of the action.
# It merges any changes from the release back into the
# main branch. Typically, this is just a single commit
# that updates the changelog.
name: Mergeback after release

on:
workflow_dispatch:
inputs:
baseBranch:
description: 'The base branch to merge into'
default: v1
required: false

push:
branches:
- main

jobs:
merge-back:
runs-on: ubuntu-latest
env:
BASE_BRANCH: "${{ github.event.inputs.baseBranch || 'v1' }}"
HEAD_BRANCH: "${{ github.ref }}"

steps:
- name: validate
run: |
if [ "$BASE_BRANCH" -eq "$HEAD_BRANCH" ]; then
echo "error::Base branch and head branch are the same $BASE_BRANCH."
exit -1
fi
- uses: actions/checkout@v2
- uses: actions/setup-node@v2

- name: Update git config
run: |
git config --global user.email "codeql-core@github.com"
git config --global user.name "CodeQL Actions Bot"
# we didn't tag the release during the update-release-branch workflow because the
# commit that actually makes it to the main branch may be different than the one
# created by the workflow. We tag now because we know the correct commit
- name: Tag release
run: |
VERSION="$(jq '.version' -r 'package.json')"
git tag -a "v$VERSION" -m "v$VERSION"
git push origin --follow-tags
- name: Create mergeback branch
run: |
NEW_BRANCH="mergeback/$HEAD_BRANCH-to-$BASE_BRANCH"
PR_TITLE="Mergeback $HEAD_BRANCH into $BASE_BRANCH"
PR_BODY="Updates version and changelog."
git checkout -b $NEW_BRANCH
# Update the changelog
perl -i -pe 's/^/## \[UNRELEASED\]\n\n/ if($.==3)' CHANGELOG.md
git add CHANGELOG.md
git commit -m "Update changelog for new version"
npm version
# Create pull request
gh pr create --base "$BASE_BRANCH" --reviewer "github/codeql-core" --title "$PR_TITLE" --body "$PR_BODY"
7 changes: 6 additions & 1 deletion .github/workflows/update-release-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.5
python-version: 3.8

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install PyGithub==1.51 requests
- name: Update git config
run: |
git config --global user.email "codeql-core@github.com"
git config --global user.name "CodeQL Actions Bot"
- name: Update release branch
run: python .github/update-release-branch.py ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }}

0 comments on commit 5100571

Please sign in to comment.