Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

format and release: out with BK, in with GHA #55

Merged
merged 1 commit into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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

31 changes: 0 additions & 31 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