Skip to content

Commit

Permalink
Devops: Add continuous deployment to CI workflow (#680)
Browse files Browse the repository at this point in the history
The CI workflow is updated to trigger deployment of the package to PyPI
when a new tag is pushed to the main repository and the pre-commit and
tests have passed successfully. As a final check, the tag label is
compared with the version defined in the `aiida_vasp/__init__.py` to
make sure they match and prevent accidental incorrect tags.
  • Loading branch information
sphuber committed Jan 4, 2024
1 parent c4dbb2c commit 3baf87b
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 1 deletion.
40 changes: 39 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
name: aiida-vasp

on: [push, pull_request]
on:
push:
branches:
- '**'
tags:
- v[0-9]+.[0-9]+.[0-9]+*
pull_request:

jobs:
pre-commit:
Expand Down Expand Up @@ -96,3 +102,35 @@ jobs:
with:
name: aiida-vasp
fail_ci_if_error: true

validate-release-tag:
if: github.repository == 'aiida-vasp/aiida-vasp' && github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Validate the tag version against the package version
run: python .github/workflows/validate_release_tag.py $GITHUB_REF

publish:
name: Publish to PyPI
runs-on: ubuntu-latest
needs: [pre-commit, tests, validate-release-tag]
steps:
- name: Checkout source
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v4
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 }}
36 changes: 36 additions & 0 deletions .github/workflows/validate_release_tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- 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()
TAG_PREFIX = 'refs/tags/v'
assert args.GITHUB_REF.startswith(TAG_PREFIX), f'GITHUB_REF should start with "{TAG_PREFIX}": {args.GITHUB_REF}'
tag_version = args.GITHUB_REF[len(TAG_PREFIX):]
package_version = get_version_from_module(Path('aiida_vasp/__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

0 comments on commit 3baf87b

Please sign in to comment.