diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 000000000..d544bdbd3 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,122 @@ +name: cd + +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+*' + +jobs: + + validate-release-tag: + + if: github.repository == 'aiidateam/aiida-quantumespresso' + runs-on: ubuntu-latest + + steps: + - name: Checkout source + - uses: actions/checkout@v2 + + - name: Set up Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: '3.8' + + - 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.8' + + - name: Install Python dependencies + run: | + pip install --upgrade pip setuptools wheel + 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.6', '3.7', '3.8', '3.9'] + + 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 --upgrade pip setuptools wheel + pip install -e .[tests] + reentry scan + + - 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.8 + uses: actions/setup-python@v2 + with: + python-version: '3.8' + + - 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 }} diff --git a/.github/workflows/validate_release_tag.py b/.github/workflows/validate_release_tag.py new file mode 100644 index 000000000..180749566 --- /dev/null +++ b/.github/workflows/validate_release_tag.py @@ -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('aiida_quantumespresso/__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