Skip to content

chore(pytest): add project.entry-points.pytest11 section to `pyproj… #160

chore(pytest): add project.entry-points.pytest11 section to `pyproj…

chore(pytest): add project.entry-points.pytest11 section to `pyproj… #160

name: CI/CD
on:
push:
branches:
- main
tags:
- 'v*'
pull_request:
workflow_dispatch:
env:
PYTHON_VERSION: '3.11.9'
jobs:
dependencies:
name: Install Dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
name: Checkout
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
- name: Create virtualenv
run: |
uv venv --system-site-packages
- name: Install dependencies
run: uv sync --frozen
type-check:
name: Type Check
needs:
- dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
name: Checkout
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
- name: Create virtualenv
run: |
uv venv --system-site-packages
- name: Type Check
run: |
uv run --frozen poe typecheck
lint:
name: Lint
needs:
- dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
name: Checkout
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
- name: Lint
run: uvx ruff check
test:
name: Test
needs:
- dependencies
runs-on: ubuntu-latest
environment:
name: test
url: https://app.codecov.io/gh/${{ github.repository }}/
steps:
- uses: actions/checkout@v4
name: Checkout
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
- name: Create virtualenv
run: |
uv venv --system-site-packages
- name: Run Tests
run: |
uv run --frozen poe test --verbosity=2 --cov-report=xml --cov-report=html --log-level=DEBUG --log-cli-level=5
- name: Collect Store Snapshots
uses: actions/upload-artifact@v4
if: always()
with:
name: snapshots
path: tests/**/results/**/*.jsonc
- name: Collect HTML Coverage Report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: htmlcov
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
flags: integration
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
build:
name: Build
needs:
- dependencies
runs-on: ubuntu-latest
outputs:
version: ${{ steps.extract-version.outputs.VERSION }}
name: ${{ steps.extract-version.outputs.NAME }}
steps:
- uses: actions/checkout@v4
name: Checkout
- uses: actions/setup-python@v5
name: Setup Python
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
- name: Extract Version
id: extract-version
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
echo "VERSION=$(uvx hatch version)" >> "$GITHUB_OUTPUT"
echo "VERSION=$(uvx hatch version)"
echo "NAME=$(uvx hatch project metadata | jq -r .name)" >> "$GITHUB_OUTPUT"
echo "NAME=$(uvx hatch project metadata | jq -r .name)"
- name: Extract Version from CHANGELOG.md
run: |
FIRST_HEADER=$(sed -n '/## /s/## //p' CHANGELOG.md | head -n 1)
if [ "$FIRST_HEADER" == "Upcoming" ]; then
# Check the version coming from extract-version starts with of x.y.z.devn
if [[ "${{ steps.extract-version.outputs.VERSION }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.dev[0-9]+ ]]; then
VERSION_CHANGELOG="This is a development version."
else
echo "Error: First header in CHANGELOG.md is 'Upcoming' but the version in pyproject.toml is not a development version."
exit 1
fi
else
VERSION_CHANGELOG=$(echo $FIRST_HEADER | sed 's/Version //')
if [ "${{ steps.extract-version.outputs.VERSION }}" =~ "^$VERSION_CHANGELOG\.dev[0-9]+" ]; then
echo "Error: Version extracted from CHANGELOG.md does not match the version in pyproject.toml"
exit 1
else
echo "Versions are consistent."
fi
fi
- name: Build
run:
SETUPTOOLS_SCM_PRETEND_VERSION=${{
steps.extract-version.outputs.VERSION }} uv build
- name: Upload wheel
uses: actions/upload-artifact@v4
with:
name: wheel
path: dist/*.whl
if-no-files-found: error
- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: binary
path: dist/*.tar.gz
if-no-files-found: error
publish:
name: Publish
if: >-
github.event_name == 'push' && (github.ref == 'refs/heads/main' ||
startsWith(github.ref, 'refs/tags/v')) || github.event_name ==
'pull_request' && github.event.pull_request.base.ref == 'main'
needs:
- type-check
- lint
- test
- build
runs-on: ubuntu-latest
environment:
name: pypi
url:
https://pypi.org/project/${{ needs.build.outputs.name }}/${{
needs.build.outputs.version }}
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
name: wheel
path: dist
- uses: actions/download-artifact@v4
with:
name: binary
path: dist
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist
release:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
name: Release
needs:
- type-check
- lint
- test
- build
- publish
runs-on: ubuntu-latest
environment:
name: release
url:
https://github.com/${{ github.repository }}/releases/tag/v${{
needs.build.outputs.version }}
permissions:
contents: write
steps:
- uses: actions/checkout@v4
name: Checkout
- name: Procure Wheel
uses: actions/download-artifact@v4
with:
name: wheel
path: artifacts
- name: Procure Binary
uses: actions/download-artifact@v4
with:
name: binary
path: artifacts
- name: Extract Changelog
id: changelog
run: |
perl -0777 -ne 'while (/## Version ${{ needs.build.outputs.version }}\n(\s*\n)*(.*?)(\s*\n)*## Version \d+\.\d+\.\d+\n/sg) {print "$2\n"}' CHANGELOG.md > CURRENT_CHANGELOG.md
{
echo "CONTENT<<EOF"
cat CURRENT_CHANGELOG.md
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Release
uses: softprops/action-gh-release@v2
with:
files: artifacts/*
tag_name: v${{ needs.build.outputs.version }}
body: |
PyPI package: https://pypi.org/project/${{ needs.build.outputs.name }}/${{ needs.build.outputs.version }}
# Changes:
${{ steps.changelog.outputs.CONTENT }}
prerelease: false
draft: false