Skip to content

Commit

Permalink
formta and release: out with BK, in with GHA
Browse files Browse the repository at this point in the history
  • Loading branch information
agnesgaroux committed Oct 25, 2024
1 parent 739c6ba commit 45cc5fe
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 391 deletions.
24 changes: 0 additions & 24 deletions .buildkite/pipeline.yml

This file was deleted.

81 changes: 81 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: "Release new version of the module"

on:
push:
branches:
- main

permissions:
id-token: write
contents: write

jobs:
autoformat:
uses: ./.github/workflows/tf_formatting.yml

# First, check if there is a RELEASE.md file in the root of the repository.
# If not, no release will be created and subsequent steps and jobs will be skipped.
check-for-release-file:
runs-on: ubuntu-latest
outputs:
has-release: ${{ steps.check-for-release-file.outputs.has-release }}
needs: autoformat
steps:
- uses: actions/checkout@v4
- name: Check for RELEASE.md file
id: check-for-release-file
run: |
if [ ! -f ./RELEASE.md ]; then
echo "has-release=false" >> $GITHUB_OUTPUT
echo "No release detected. Exiting."
exit 0
fi
echo "has-release=true" >> $GITHUB_OUTPUT
create-release:
runs-on: ubuntu-latest
outputs:
new-version: ${{ steps.create-release.outputs.new-version }}
needs: check-for-release-file
if: needs.check-for-release-file.outputs.has-release == 'true'
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Update CHANGELOG.md and version
id: create-release
run: |
git fetch --tags
LATEST_TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
python3 gha_scripts/create_release.py ${LATEST_TAG} $(pwd)
VERSION_TAG="$(cat CHANGELOG.md | grep -m1 -o 'v[0-9]\+\.[0-9]\+\.[0-9]\+')"
echo "new-version=${VERSION_TAG:1}" >> $GITHUB_OUTPUT
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v1
with:
app-id: 129326 # App ID of the Wellcome Collection app
private-key: ${{ secrets.WELLCOME_COLLECTION_APP_PRIVATE_KEY }}

# We need to give the GitHub action full repo privileges so that it can push the release directly into main
- name: Configure git
run: |
git config --global user.name "GitHub on behalf of Wellcome Collection"
git config --global user.email "[email protected]"
git remote set-url origin https://x-access-token:${{ steps.generate-token.outputs.token }}@github.com/${{ github.repository }}.git
- name: Commit and push changes
run: |
git checkout main
git pull
git add CHANGELOG.md
git rm RELEASE.md
NEW_TAG="v${{ steps.create-release.outputs.new-version }}"
git commit -m "$(printf "Bump version to ${NEW_TAG}\n\n[skip ci]")"
git tag ${NEW_TAG}
git push origin main
git push origin --tags
39 changes: 39 additions & 0 deletions .github/workflows/tf_formatting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Runs auto-formatting script on push to any branch
name: "Run terraform formatting"

on:
push:
branches-ignore:
- main
workflow_call:

permissions:
id-token: write
contents: write

jobs:
autoformat:
name: autoformat
runs-on: ubuntu-latest
steps:
- name: Check out project
uses: actions/checkout@v4

- name: terraform format (recursive)
uses: dflook/terraform-fmt@v1

- name: Check for formatting changes
id: check_formatting_changes
run: |
if [[ -n $(git status --porcelain) ]]; then
echo "changes=true" >> "$GITHUB_OUTPUT";
fi
- name: Commit and push formatting changes
if: steps.check_formatting_changes.outputs.changes == 'true'
run: |
git config user.name "Github on behalf of Wellcome Collection"
git config user.email "[email protected]"
git commit -am "Apply auto-formatting rules"
git push
15 changes: 0 additions & 15 deletions Dockerfile

This file was deleted.

14 changes: 0 additions & 14 deletions docker-compose.yml

This file was deleted.

99 changes: 99 additions & 0 deletions gha_scripts/create_release.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env python

import datetime as dt
import os
import re
import sys

RELEASE_TYPE = re.compile(r"^RELEASE_TYPE: +(major|minor|patch)")
VALID_RELEASE_TYPES = ('major', 'minor', 'patch')

CHANGELOG_HEADER = re.compile(r"^## v\d+\.\d+\.\d+ - \d\d\d\d-\d\d-\d\d$")


def get_new_version_tag(latest_version: str, release_type: str):
version_info = [int(i) for i in latest_version.lstrip('v').split('.')]

bump = VALID_RELEASE_TYPES.index(release_type)
version_info[bump] += 1
for i in range(bump + 1, len(version_info)):
version_info[i] = 0
return 'v' + '.'.join(map(str, version_info))


def _get_changelog_version_heading(new_version_tag: str):
date = dt.datetime.utcnow().strftime('%Y-%m-%d')
return f'## {new_version_tag} - {date}'


def update_changelog(release_contents: str, new_version_tag: str):
with open(CHANGELOG_FILE) as f:
changelog_contents = f.read()

assert '\r' not in changelog_contents
lines = changelog_contents.split('\n')
assert changelog_contents == '\n'.join(lines)

for i, line in enumerate(lines):
if CHANGELOG_HEADER.match(line):
beginning = '\n'.join(lines[:i])
rest = '\n'.join(lines[i:])
assert '\n'.join((beginning, rest)) == changelog_contents
break

new_version_heading = _get_changelog_version_heading(new_version_tag)

new_changelog_parts = [
beginning.strip(),
new_version_heading,
release_contents,
rest
]

with open(CHANGELOG_FILE, 'w') as f:
f.write('\n\n'.join(new_changelog_parts))

def parse_release_file():
"""
Parses the release file, returning a tuple (release_type, release_contents)
"""
with open(RELEASE_FILE) as i:
release_contents = i.read()

release_lines = release_contents.split('\n')

m = RELEASE_TYPE.match(release_lines[0])
if m is not None:
release_type = m.group(1)
if release_type not in VALID_RELEASE_TYPES:
print('Unrecognised release type %r' % (release_type,))
sys.exit(1)
del release_lines[0]
release_contents = '\n'.join(release_lines).strip()
else:
print(
'RELEASE.md does not start by specifying release type. The first '
'line of the file should be RELEASE_TYPE: followed by one of '
'major, minor, or patch, to specify the type of release that '
'this is (i.e. which version number to increment). Instead the '
'first line was %r' % (release_lines[0],)
)
sys.exit(1)

return release_type, release_contents


def create_release():
latest_version_tag = sys.argv[1]

release_type, release_contents = parse_release_file()
new_version_tag = get_new_version_tag(latest_version_tag, release_type)

update_changelog(release_contents, new_version_tag)

if __name__ == '__main__':
ROOT = sys.argv[2]
CHANGELOG_FILE = os.path.join(ROOT, 'CHANGELOG.md')
RELEASE_FILE = os.path.join(ROOT, 'RELEASE.md')

create_release()
Loading

0 comments on commit 45cc5fe

Please sign in to comment.