Skip to content

Commit

Permalink
Merge 800a951 into eeaefb6
Browse files Browse the repository at this point in the history
  • Loading branch information
aeisenberg authored May 21, 2021
2 parents eeaefb6 + 800a951 commit b7dd4a6
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 16 deletions.
79 changes: 64 additions & 15 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 and CodeQL Runner Changelog
## [UNRELEASED]
"""

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

# Start constructing the body text
body = 'Merging ' + short_main_sha + ' into ' + LATEST_RELEASE_BRANCH
body = []
body.append('Merging ' + short_main_sha + ' into ' + LATEST_RELEASE_BRANCH)

conductor = get_conductor(repo, pull_requests, commits_without_pull_requests)
body += '\n\nConductor for this PR is @' + conductor
body.append('')
body.append('Conductor for this PR is @' + conductor)

# List all PRs merged
if len(pull_requests) > 0:
body += '\n\nContains the following pull requests:'
body.append('')
body.append('Contains the following pull requests:')
for pr in pull_requests:
merger = get_merger_of_pr(repo, pr)
body += '\n- #' + str(pr.number)
body += ' - ' + pr.title
body += ' (@' + merger + ')'
body.append('- #' + str(pr.number) + ' - ' + pr.title +' (@' + merger + ')')

# List all commits not part of a PR
if len(commits_without_pull_requests) > 0:
body += '\n\nContains the following commits not from a pull request:'
body.append('')
body.append('Contains the following commits not from a pull request:')
for commit in commits_without_pull_requests:
body += '\n- ' + commit.sha
body += ' - ' + get_truncated_commit_message(commit)
body += ' (@' + commit.author.login + ')'
body.append('- ' + commit.sha + ' - ' + get_truncated_commit_message(commit) + ' (@' + commit.author.login + ')')

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

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

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

# Assign the conductor
Expand All @@ -95,7 +113,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 +153,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 +198,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 +209,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
127 changes: 127 additions & 0 deletions .github/workflows/post-release-mergeback.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# 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: Tag release and merge back

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

push:
branches:
- v1

pull_request:
paths:
- .github/workflows/post-release-mergeback.yml

jobs:
merge-back:
runs-on: ubuntu-latest
if: github.repository == 'github/codeql-action'
env:
BASE_BRANCH: "${{ github.event.inputs.baseBranch || 'main' }}"
HEAD_BRANCH: "${{ github.head_ref || github.ref }}"
# Would like to use the github/codeql-core team, but that is not working
DEFAULT_REVIEWER: "aeisenberg"

steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: "${{ toJson(github) }}"
run: echo "$GITHUB_CONTEXT"

- uses: actions/checkout@v2
- uses: actions/setup-node@v2

- name: Update git config
run: |
git config --global user.email "[email protected]"
git config --global user.name "github-actions[bot]"
- name: Get version and new branch
id: getVersion
run: |
VERSION="v$(jq '.version' -r 'package.json')"
SHORT_SHA="${GITHUB_SHA:0:8}"
echo "::set-output name=version::$VERSION"
NEW_BRANCH="mergeback/${VERSION}-to-${BASE_BRANCH}-${SHORT_SHA}"
echo "::set-output name=newBranch::$NEW_BRANCH"
- name: Dump branches
env:
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
run: |
echo "BASE_BRANCH $BASE_BRANCH"
echo "HEAD_BRANCH $HEAD_BRANCH"
echo "NEW_BRANCH $NEW_BRANCH"
- name: Create mergeback branch
env:
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
run: |
git checkout -b "$NEW_BRANCH"
- name: Check for tag
id: check
env:
VERSION: "${{ steps.getVersion.outputs.version }}"
run: |
set +e # don't fail on an errored command
git ls-remote --tags origin | grep "$VERSION"
EXISTS="$?"
if [ "$EXISTS" -ne 0 ]; then
echo "::set-output name=exists::true"
echo "Tag $TAG exists. Not going to re-release."
fi
# we didn't tag the release during the update-release-branch workflow because the
# commit that actually makes it to the release branch is a merge commit,
# and not yet known during the first workflow. We tag now because we know the correct commit.
- name: Tag release
if: steps.check.outputs.exists == 'true'
env:
VERSION: ${{ steps.getVersion.outputs.version }}
run: |
git tag -a "$VERSION" -m "$VERSION"
git push origin --follow-tags "$VERSION"
- name: Create mergeback branch
if: steps.check.outputs.exists == 'true'
env:
VERSION: "${{ steps.getVersion.outputs.version }}"
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
run: |
set -exu
PR_TITLE="Mergeback $VERSION $HEAD_BRANCH into $BASE_BRANCH"
PR_BODY="Updates version and changelog."
# Update the changelog
perl -i -pe 's/^/## \[UNRELEASED\]\n\n/ if($.==3)' CHANGELOG.md
git add .
git commit -m "Update changelog and version after $VERSION"
npm version patch
# when running this workflow on a PR, this is just a test.
# so put into draft mode.
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
DRAFT="--draft"
else
DRAFT=""
fi
git push origin "$NEW_BRANCH"
gh pr create \
--head "$NEW_BRANCH" \
--base "$BASE_BRANCH" \
--title "$PR_TITLE" \
--body "$PR_BODY" \
--reviewer "$DEFAULT_REVIEWER" \
"$DRAFT"
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 "[email protected]"
git config --global user.name "github-actions[bot]"
- name: Update release branch
run: python .github/update-release-branch.py ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }}

0 comments on commit b7dd4a6

Please sign in to comment.