From 0a7843ce12256db8ae2ce7dfe7f041c069ccc0b3 Mon Sep 17 00:00:00 2001 From: Igor Davydenko Date: Wed, 22 Jun 2022 19:35:52 +0200 Subject: [PATCH] ci: Refactor CI workflows and actions (#160) By creating next composite actions in: - Install Python & poetry - Run pre-commit - Run tests And by creating "Build & deploy package" reusable workflow. --- .../install_python_and_poetry/action.yml | 45 ++++++ .github/actions/run_pre_commit/action.yml | 23 +++ .github/actions/run_tests/action.yml | 53 +++++++ .github/workflows/ci.yml | 135 +++--------------- .github/workflows/ci_package.yml | 48 +++++++ .github/workflows/release_pr.yml | 17 +-- .github/workflows/release_tag.yml | 17 +-- pyproject.toml | 4 +- 8 files changed, 196 insertions(+), 146 deletions(-) create mode 100644 .github/actions/install_python_and_poetry/action.yml create mode 100644 .github/actions/run_pre_commit/action.yml create mode 100644 .github/actions/run_tests/action.yml create mode 100644 .github/workflows/ci_package.yml diff --git a/.github/actions/install_python_and_poetry/action.yml b/.github/actions/install_python_and_poetry/action.yml new file mode 100644 index 0000000..b856f3d --- /dev/null +++ b/.github/actions/install_python_and_poetry/action.yml @@ -0,0 +1,45 @@ +name: "Install Python & poetry" +description: "Composite action to setup Python, install poetry, and setup cache for venv." + +inputs: + python-version: + description: "Python version to use" + required: false + python-version-file: + description: "Read Python version from given file" + required: false + poetry-version: + description: "Poetry version to use" + required: false + default: "1.1.13" + +outputs: + python-path: + description: "Absolute path to Python executable" + value: "${{ steps.python.outputs.python-path }}" + python-version: + description: "Installed Python version" + value: "${{ steps.python.outputs.python-version }}" + poetry-version: + description: "Installed poetry version" + value: "${{ inputs.poetry-version }}" + +runs: + using: "composite" + steps: + - id: "python" + name: "Install Python" + uses: "actions/setup-python@v4.0.0" + with: + python-version: "${{ inputs.python-version }}" + python-version-file: "${{ inputs.python-version-file }}" + + - name: "Install poetry" + shell: "bash" + run: "pipx install --python='${{ steps.python.outputs.python-path }}' poetry==${{ inputs.poetry-version }}" + + - name: "Cache venv" + uses: "actions/cache@v3.0.4" + with: + path: "./.venv/" + key: "venv-${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ hashFiles('poetry.lock') }}" diff --git a/.github/actions/run_pre_commit/action.yml b/.github/actions/run_pre_commit/action.yml new file mode 100644 index 0000000..7f9f403 --- /dev/null +++ b/.github/actions/run_pre_commit/action.yml @@ -0,0 +1,23 @@ +name: "Run pre-commit hooks" +description: "Composite action to install project, setup mypy cache and run pre-commit hooks." + +inputs: + python-version: + description: "Python version to use" + required: true + +runs: + using: "composite" + steps: + - name: "Install package" + run: "poetry install" + shell: "bash" + + - name: "Cache mypy" + uses: "actions/cache@v3.0.4" + with: + path: "./.mypy_cache/" + key: "mypy-${{ runner.os }}-${{ inputs.python-version }}" + + - name: "Run pre-commit" + uses: "pre-commit/action@v3.0.0" diff --git a/.github/actions/run_tests/action.yml b/.github/actions/run_tests/action.yml new file mode 100644 index 0000000..2d4e0b0 --- /dev/null +++ b/.github/actions/run_tests/action.yml @@ -0,0 +1,53 @@ +name: "Run pre-commit hooks" +description: "Composite action to install tox & tox-gh-actions and run tests via tox." + +inputs: + python-path: + description: "Path to Python executable" + required: true + python-version: + description: "Installed Python version" + required: true + tox-version: + description: "Tox version to use" + required: false + default: "3.25.0" + tox-gh-actions-version: + description: "Tox GitHub Actions plugin version to use" + required: false + default: "2.9.1" + use-coveralls: + description: "Send coverage to Coveralls" + required: false + default: "false" + coveralls-token: + description: "GitHub token to use, when sending coverage to Coveralls" + required: false + +runs: + using: "composite" + steps: + - name: "Install tox & tox-gh-actions" + run: | + set -euo pipefail + + pipx install --python='${{ inputs.python-path }}' tox==${{ inputs.tox-version }} + pipx inject tox tox-gh-actions==${{ inputs.tox-gh-actions-version }} + shell: "bash" + + - name: "Cache tox" + uses: "actions/cache@v3.0.4" + with: + path: "./.tox/" + key: "tox-${{ inputs.python-version }}" + + - name: "Run tests" + run: "tox" + shell: "bash" + + - name: "Send coverage to Coveralls" + if: "${{ inputs.use-coveralls == 'true' }}" + env: + GITHUB_TOKEN: "${{ inputs.coveralls-token }}" + run: "poetry run python3 -m coveralls --service=github" + shell: "bash" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c55a3e1..8d2b898 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,15 +13,6 @@ on: env: PYTHONUNBUFFERED: "1" - # Get latest versions by running, - # - # ```bash - # pip-latest-release poetry tox tox-gh-actions twine - # ``` - POETRY_VERSION: "1.1.13" - TOX_VERSION: "3.25.0" - TOX_GH_ACTIONS_VERSION: "2.9.1" - TWINE_VERSION: "4.0.1" jobs: dev: @@ -36,22 +27,10 @@ jobs: steps: - uses: "actions/checkout@v3.0.2" - - name: "Install Python" - uses: "actions/setup-python@v4.0.0" + - uses: "./.github/actions/install_python_and_poetry" with: python-version-file: ".python-version" - - name: "Install poetry" - uses: "snok/install-poetry@v1.3.1" - with: - version: "${{ env.POETRY_VERSION }}" - - - name: "Cache venv" - uses: "actions/cache@v3.0.4" - with: - path: "./.venv/" - key: "venv-dev-${{ hashFiles('poetry.lock') }}" - - name: "Install package" run: "poetry install" @@ -77,112 +56,52 @@ jobs: matrix: python-version: ["3.7", "3.8", "3.9", "3.10", "3.11.0-beta.3"] include: - - python-version: "3.7" - python-cache-key: "3.7" - - - python-version: "3.8" - python-cache-key: "3.8" - - - python-version: "3.9" - python-cache-key: "3.9" - - python-version: "3.10" - python-cache-key: "dev" - - - python-version: "3.11.0-beta.3" - python-cache-key: "3.11.0-beta.3" + dev: "true" runs-on: "ubuntu-latest" + continue-on-error: "${{ startsWith(matrix.python-version, '3.11') }}" steps: - uses: "actions/checkout@v3.0.2" - - name: "Install Python" - uses: "actions/setup-python@v4.0.0" + - id: "python_and_poetry" + uses: "./.github/actions/install_python_and_poetry" with: python-version: "${{ matrix.python-version }}" - - name: "Install poetry" - uses: "snok/install-poetry@v1.3.1" - with: - version: "${{ env.POETRY_VERSION }}" - - - name: "Install other deps" - run: "python3 -m pip install tox==${{ env.TOX_VERSION }} tox-gh-actions==${{ env.TOX_GH_ACTIONS_VERSION }}" - - - name: "Cache venv" - uses: "actions/cache@v3.0.4" + - if: "${{ matrix.dev == 'true' }}" + uses: "./.github/actions/run_pre_commit" with: - path: "./.venv/" - key: "venv-${{ matrix.python-cache-key }}-${{ hashFiles('poetry.lock') }}" - - - name: "Install package with dev dependencies" - if: "${{ matrix.python-cache-key == 'dev' }}" - run: "poetry install" - - - name: "Install package without dev dependencies" - if: "${{ matrix.python-cache-key != 'dev' }}" - run: "poetry install --no-dev" - - - name: "Run pre-commit" - if: "${{ matrix.python-cache-key == 'dev' }}" - uses: "pre-commit/action@v3.0.0" + python-version: "${{ steps.python_and_poetry.outputs.python-version }}" - name: "Setup git for test needs" run: | set -euo pipefail + git config --global init.defaultBranch main git config --global user.name badabump-release-bot[bot] git config --global user.email badabump-release-bot[bot]@users.noreply.github.com - - name: "Run tests" - run: "python3 -m tox" - - - name: "Send report to coveralls" - if: "${{ matrix.python-cache-key == 'dev' }}" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - run: "poetry run python3 -m coveralls --service=github" + - uses: "./.github/actions/run_tests" + with: + python-path: "${{ steps.python_and_poetry.outputs.python-path }}" + python-version: "${{ steps.python_and_poetry.outputs.python-version }}" + use-coveralls: "${{ matrix.dev }}" + coveralls-token: "${{ secrets.GITHUB_TOKEN }}" package: needs: ["test"] - name: "Build & deploy package" - runs-on: "ubuntu-latest" - - steps: - - uses: "actions/checkout@v3.0.2" - - - name: "Install Python" - uses: "actions/setup-python@v4.0.0" - with: - python-version-file: ".python-version" - - - name: "Install poetry" - uses: "snok/install-poetry@v1.3.1" - with: - version: "${{ env.POETRY_VERSION }}" - - - name: "Build package" - run: "poetry build" - - - name: "Check package" - run: | - set -euo pipefail - - python3 -m pip install twine==${{ env.TWINE_VERSION }} - python3 -m twine check ./dist/* - - - name: "Publish package" - if: "${{ github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') }}" - uses: "pypa/gh-action-pypi-publish@v1.5.0" - with: - user: "${{ secrets.PYPI_USERNAME }}" - password: "${{ secrets.PYPI_PASSWORD }}" + uses: "./.github/workflows/ci_package.yml" + secrets: + PYPI_USERNAME: "${{ secrets.PYPI_USERNAME }}" + PYPI_PASSWORD: "${{ secrets.PYPI_PASSWORD }}" release: needs: ["package"] if: "${{ startsWith(github.ref, 'refs/tags/') }}" + name: "Create GitHub release" runs-on: "ubuntu-latest" @@ -197,22 +116,10 @@ jobs: git fetch --depth=1 origin +refs/tags/*:refs/tags/* git fetch --prune --unshallow - - name: "Install Python" - uses: "actions/setup-python@v4.0.0" + - uses: "./.github/actions/install_python_and_poetry" with: python-version-file: ".python-version" - - name: "Install poetry" - uses: "snok/install-poetry@v1.3.1" - with: - version: "${{ env.POETRY_VERSION }}" - - - name: "Cache venv" - uses: "actions/cache@v3.0.4" - with: - path: ".venv" - key: "venv-dev-${{ hashFiles('poetry.lock') }}" - - name: "Install package without dev dependencies" run: "poetry install --no-dev" diff --git a/.github/workflows/ci_package.yml b/.github/workflows/ci_package.yml new file mode 100644 index 0000000..1fba507 --- /dev/null +++ b/.github/workflows/ci_package.yml @@ -0,0 +1,48 @@ +name: "Build & deploy package" + +on: + workflow_call: + inputs: + twine-version: + description: "Twine version to use." + type: "string" + required: false + default: "4.0.1" + + secrets: + PYPI_USERNAME: + description: "PyPI username to use." + required: true + PYPI_PASSWORD: + description: "PyPI password (token) to use." + required: true + +jobs: + package: + name: "Build & deploy package" + + runs-on: "ubuntu-latest" + + steps: + - uses: "actions/checkout@v3.0.2" + + - id: "python_and_poetry" + uses: "./.github/actions/install_python_and_poetry" + with: + python-version-file: ".python-version" + + - name: "Build package" + run: "poetry build" + + - name: "Install twine" + run: "pipx install --python='${{ steps.python_and_poetry.outputs.python-path }}' twine==${{ inputs.twine-version }}" + + - name: "Check package" + run: "twine check ./dist/*" + + - name: "Publish package" + if: "${{ startsWith(github.ref, 'refs/tags/') }}" + uses: "pypa/gh-action-pypi-publish@v1.5.0" + with: + user: "${{ secrets.PYPI_USERNAME }}" + password: "${{ secrets.PYPI_PASSWORD }}" diff --git a/.github/workflows/release_pr.yml b/.github/workflows/release_pr.yml index 015e31d..c352678 100644 --- a/.github/workflows/release_pr.yml +++ b/.github/workflows/release_pr.yml @@ -14,12 +14,11 @@ on: env: PYTHONUNBUFFERED: "1" - POETRY_VERSION: "1.1.13" jobs: create_release_pr: if: "${{ github.actor == 'playpauseandstop' }}" - name: "Create release PR" + name: "Create Release PR" runs-on: "ubuntu-latest" @@ -35,22 +34,10 @@ jobs: git fetch --depth=1 origin +refs/tags/*:refs/tags/* || : git fetch --prune --unshallow - - name: "Install Python" - uses: "actions/setup-python@v4.0.0" + - uses: "./.github/actions/install_python_and_poetry" with: python-version-file: ".python-version" - - name: "Install poetry" - uses: "snok/install-poetry@v1.3.1" - with: - version: "${{ env.POETRY_VERSION }}" - - - name: "Cache venv" - uses: "actions/cache@v3.0.4" - with: - path: ".venv" - key: "venv-dev-${{ hashFiles('poetry.lock') }}" - - name: "Install badabump" run: "poetry install --no-dev" diff --git a/.github/workflows/release_tag.yml b/.github/workflows/release_tag.yml index c74225d..bfba3bb 100644 --- a/.github/workflows/release_tag.yml +++ b/.github/workflows/release_tag.yml @@ -10,12 +10,11 @@ on: env: PYTHONUNBUFFERED: "1" - POETRY_VERSION: "1.1.13" jobs: create_release_tag: if: "${{ startsWith(github.head_ref, 'chore/release-') && github.event.pull_request.merged == true }}" - name: "Create release tag" + name: "Auto Create Release Tag" runs-on: "ubuntu-latest" @@ -31,22 +30,10 @@ jobs: token: "${{ steps.token.outputs.token }}" ref: "main" - - name: "Install Python" - uses: "actions/setup-python@v4.0.0" + - uses: "./.github/actions/install_python_and_poetry" with: python-version-file: ".python-version" - - name: "Install poetry" - uses: "snok/install-poetry@v1.3.1" - with: - version: "${{ env.POETRY_VERSION }}" - - - name: "Cache venv" - uses: "actions/cache@v3.0.4" - with: - path: ".venv" - key: "venv-dev-${{ hashFiles('poetry.lock') }}" - - name: "Install badabump" run: "poetry install --no-dev" diff --git a/pyproject.toml b/pyproject.toml index 576d41a..83518a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -118,7 +118,7 @@ python = 3.8: py38 3.9: py39 3.10: py310 - 3.11.0-beta.3: py311 + 3.11: py311 [testenv] passenv = @@ -131,7 +131,7 @@ whitelist_externals = poetry commands_pre = poetry install commands = - poetry run python -m pytest + poetry run python3 -m pytest [testenv:py310-minimum-requirements] commands_pre =