-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add continous deployment files (#84)
Add CD workflow and useful scripts.
- Loading branch information
Showing
4 changed files
with
239 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,4 +9,4 @@ | |
"pullRequestNo": 81 | ||
} | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
name: cd | ||
|
||
on: | ||
push: | ||
tags: | ||
- 'v[0-9]+.[0-9]+.[0-9]+*' | ||
|
||
jobs: | ||
|
||
validate-release-tag: | ||
|
||
if: github.repository == 'aiidateam/aiida-hubbard' | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout source | ||
uses: actions/checkout@v2 | ||
|
||
- name: Set up Python 3.9 | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: '3.9' | ||
|
||
- name: Validate the tag version against the package version | ||
run: python .github/workflows/validate_release_tag.py $GITHUB_REF | ||
|
||
pre-commit: | ||
|
||
needs: [validate-release-tag] | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
|
||
- name: Cache Python dependencies | ||
uses: actions/cache@v1 | ||
with: | ||
path: ~/.cache/pip | ||
key: pip-pre-commit-${{ hashFiles('**/setup.json') }} | ||
restore-keys: | ||
pip-pre-commit- | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: '3.9' | ||
|
||
- name: Install Python dependencies | ||
run: pip install -e .[pre-commit,tests] | ||
|
||
- name: Run pre-commit | ||
run: pre-commit run --all-files || ( git status --short ; git diff ; exit 1 ) | ||
|
||
tests: | ||
|
||
needs: [validate-release-tag] | ||
runs-on: ubuntu-latest | ||
|
||
strategy: | ||
matrix: | ||
python-version: ['3.9', '3.10', '3.11', '3.12'] | ||
|
||
services: | ||
postgres: | ||
image: postgres:12 | ||
rabbitmq: | ||
image: rabbitmq:latest | ||
ports: | ||
- 5672:5672 | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
|
||
- name: Cache Python dependencies | ||
uses: actions/cache@v1 | ||
with: | ||
path: ~/.cache/pip | ||
key: pip-${{ matrix.python-version }}-tests-${{ hashFiles('**/setup.json') }} | ||
restore-keys: | ||
pip-${{ matrix.python-version }}-tests | ||
|
||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
|
||
- name: Install Python dependencies | ||
run: pip install -e .[tests] | ||
|
||
- name: Run pytest | ||
run: pytest -sv tests | ||
|
||
publish: | ||
|
||
name: Publish to PyPI | ||
needs: [pre-commit, tests] | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout source | ||
uses: actions/checkout@v2 | ||
|
||
- name: Set up Python 3.9 | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: '3.9' | ||
|
||
- name: Install flit | ||
run: pip install flit~=3.4 | ||
|
||
- name: Build and publish | ||
run: flit publish | ||
env: | ||
FLIT_USERNAME: __token__ | ||
FLIT_PASSWORD: ${{ secrets.PYPI_KEY }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#!/bin/bash | ||
# -*- coding: utf-8 -*- | ||
"""Script for automatically updating the `CHANGELOG.md` based on the commits since the latest release tag.""" | ||
from pathlib import Path | ||
import re | ||
import subprocess | ||
|
||
DEFAULT_CHANGELOG_SECTIONS = """ | ||
### ‼️ Breaking changes | ||
### ✨ New features | ||
### 🗑️ Deprecations | ||
### 👌 Improvements | ||
### 🐛 Bug fixes | ||
### 📚 Documentation | ||
### 🔧 Maintenance | ||
### ⬆️ Update dependencies | ||
### 🧪 Tests | ||
### ♻️ Refactor | ||
""" | ||
|
||
|
||
def update_changelog(): | ||
"""Update the `CHANGELOG.md` for a first draft of the release.""" | ||
print('🔍 Checking the current version number') | ||
current_changelog = Path('CHANGELOG.md').read_text(encoding='utf-8') | ||
|
||
from aiida_hubbard import __version__ | ||
|
||
if str(__version__) in current_changelog: | ||
print('🛑 Current version already in `CHANGELOG.md`. Skipping...') | ||
return | ||
|
||
print('⬆️ Found updated version number, adapting `CHANGELOG.md`.') | ||
tags = subprocess.run(['git', 'tag', '--sort=v:refname'], capture_output=True, check=True, encoding='utf-8').stdout | ||
latest_tag = re.findall(r'(v\d\.\d\.\d)\n', tags)[-1] | ||
|
||
print(f'🔄 Comparing with latest tag `{latest_tag}`.') | ||
commits = subprocess.run(['git', 'log', "--pretty=format:'%h|%H|%s'", f'{latest_tag}..origin/master'], | ||
capture_output=True, | ||
check=True, | ||
encoding='utf-8').stdout | ||
|
||
pr_pattern = re.compile(r'\(\S(?P<pr_number>\d+)\)') | ||
|
||
changelog_message = f'## v{__version__}\n' + DEFAULT_CHANGELOG_SECTIONS | ||
|
||
for commit in commits.splitlines(): | ||
|
||
# Remove the PR number from the commit message | ||
pr_match = pr_pattern.search(commit) | ||
|
||
if pr_match is not None: | ||
pr_number = pr_match.groupdict()['pr_number'] | ||
commit = commit.replace(fr'(#{pr_number})', '') | ||
|
||
# Add the commit hash (short) to link to the changelog | ||
commit = commit.strip("'") | ||
hash_short, hash_long, message = commit.split('|', maxsplit=2) | ||
message += f' [[{hash_short}](https://github.com/aiidateam/aiida-hubbard/commit/{hash_long})]' | ||
changelog_message += f'\n* {message}' | ||
|
||
with Path('CHANGELOG.md').open('w', encoding='utf8') as handle: | ||
handle.write(changelog_message + '\n\n' + current_changelog) | ||
|
||
print("🚀 Success! Finalise the `CHANGELOG.md` and let's get this baby released.") | ||
|
||
|
||
if __name__ == '__main__': | ||
update_changelog() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# -*- coding: utf-8 -*- | ||
"""Validate that the version in the tag label matches the version of the package.""" | ||
import argparse | ||
import ast | ||
from pathlib import Path | ||
|
||
|
||
def get_version_from_module(content: str) -> str: | ||
"""Get the ``__version__`` attribute from a module. | ||
.. note:: This has been adapted from :mod:`setuptools.config`. | ||
""" | ||
try: | ||
module = ast.parse(content) | ||
except SyntaxError as exception: | ||
raise IOError('Unable to parse module.') from exception | ||
|
||
try: | ||
return next( | ||
ast.literal_eval(statement.value) for statement in module.body if isinstance(statement, ast.Assign) | ||
for target in statement.targets if isinstance(target, ast.Name) and target.id == '__version__' | ||
) | ||
except StopIteration as exception: | ||
raise IOError('Unable to find the `__version__` attribute in the module.') from exception | ||
|
||
|
||
if __name__ == '__main__': | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('GITHUB_REF', help='The GITHUB_REF environmental variable') | ||
args = parser.parse_args() | ||
assert args.GITHUB_REF.startswith('refs/tags/v'), f'GITHUB_REF should start with "refs/tags/v": {args.GITHUB_REF}' | ||
tag_version = args.GITHUB_REF[11:] | ||
package_version = get_version_from_module(Path('src/aiida_hubbard/__init__.py').read_text(encoding='utf-8')) | ||
error_message = f'The tag version `{tag_version}` is different from the package version `{package_version}`' | ||
assert tag_version == package_version, error_message |