Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: publish

on:
push:
tags: ["v*", "!archive/**"]

permissions:
contents: read

concurrency:
group: publish-${{ github.ref }}
cancel-in-progress: false

jobs:
version:
runs-on: ubuntu-24.04
outputs:
version: ${{ steps.version.outputs.version }}
prerelease: ${{ steps.version.outputs.prerelease }}
major: ${{ steps.version.outputs.major }}
minor: ${{ steps.version.outputs.minor }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
- name: Tag matches the declared version
id: version
run: |
uv run --no-project --with packaging python - <<'EOF' >> "$GITHUB_OUTPUT"
import os, subprocess, sys
from packaging.version import Version
declared = Version(subprocess.check_output(["uvx", "--from", "poetry", "--with", "poetry-dynamic-versioning[plugin]", "poetry", "version", "--short"], text=True).strip())
# org tag convention: vX.Y.Z or vX.Y.Z-rc.N, which must spell exactly the declared version
base = declared.base_version
expected = f"v{base}-rc.{declared.pre[1]}" if declared.pre and declared.pre[0] == "rc" else f"v{declared}"
if os.environ["GITHUB_REF_NAME"] != expected or declared.dev is not None or declared.local:
sys.exit(f"tag {os.environ['GITHUB_REF_NAME']} does not match poetry-dynamic-versioning {declared} (expected {expected})")
print(f"version={declared}")
print(f"prerelease={str(declared.is_prerelease).lower()}")
print(f"major={declared.major}")
print(f"minor={declared.major}.{declared.minor}")
EOF

tests:
needs: version
uses: ./.github/workflows/tests.yml
secrets: inherit

pypi:
environment: pypi
needs: [version, tests]
runs-on: ubuntu-24.04
permissions:
id-token: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
- run: uv build
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2

release:
needs: [pypi]
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: anchore/sbom-action@66cbf4bc1f1c0d2edc94016e65bc221b6bb0ad6c # v0.24.3
with:
path: .
format: spdx-json
output-file: ${{ github.event.repository.name }}-${{ github.ref_name }}.spdx.json
upload-artifact: false
upload-release-assets: false
- name: GitHub Release with SBOM
env:
GH_TOKEN: ${{ github.token }}
run: |
PRERELEASE=()
if [[ "$GITHUB_REF_NAME" == *-rc.* ]]; then PRERELEASE=(--prerelease); fi
gh release create "$GITHUB_REF_NAME" "${{ github.event.repository.name }}-$GITHUB_REF_NAME.spdx.json" \
--repo "$GITHUB_REPOSITORY" --verify-tag --generate-notes "${PRERELEASE[@]}"
98 changes: 23 additions & 75 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,113 +3,61 @@ on:
push:
branches:
- master
- dev
pull_request:
workflow_call:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
lint:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- run: |
pipx install ruff
ruff check
ruff format
pipx install poetry
poetry install --only dev --no-root
poetry run ruff check
poetry run ruff format --check
test:
needs: lint
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
strategy:
# if one python version fails, let the others finish
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y tesseract-ocr chromium-browser
sudo apt install -y tesseract-ocr
pip install poetry
poetry install
# chromium-browser on ubuntu-24.04 is a snap shim that fails to install. The image ships chrome, but AppArmor
# blocks the unprivileged user namespaces its sandbox needs.
- name: Allow the Chrome sandbox
run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
- name: Run tests
env:
CHROME_DEVEL_SANDBOX: /usr/lib/chromium/chrome-sandbox
run: |
poetry run pytest -s -vv --disable-warnings --cov-report xml:cov.xml --cov=webcap .
- name: Upload Code Coverage
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./cov.xml
verbose: true

publish:
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install poetry build
poetry self add "poetry-dynamic-versioning[plugin]"
- name: Get current version from Poetry
id: get_version
run: |
VERSION=$(poetry version --short)
echo "VERSION=$VERSION" | tee -a $GITHUB_ENV
- name: Fetch latest tag
run: |
git fetch --tags
LATEST_TAG=$(git describe --tags $(git rev-list --tags --max-count=1) 2>/dev/null || echo "v0.0.0")
echo "LATEST_TAG=$LATEST_TAG" | tee -a $GITHUB_ENV
- name: Detect version change
run: |
# Retrieve and strip "v" prefix if present
PREVIOUS_VERSION="${{ env.LATEST_TAG }}"
CURRENT_VERSION="${{ env.VERSION }}"

echo "PREVIOUS_VERSION=$PREVIOUS_VERSION"
echo "CURRENT_VERSION=$CURRENT_VERSION"

# Extract major.minor for comparison
CURRENT_MAJOR_MINOR=$(echo "${CURRENT_VERSION#v}" | cut -d '.' -f 1-2)
PREVIOUS_MAJOR_MINOR=$(echo "${PREVIOUS_VERSION#v}" | cut -d '.' -f 1-2)

# Compare versions
if [ "$CURRENT_MAJOR_MINOR" == "$PREVIOUS_MAJOR_MINOR" ]; then
echo "VERSION_CHANGE=false" | tee -a $GITHUB_ENV
else
echo "VERSION_CHANGE=true" | tee -a $GITHUB_ENV
fi
shell: bash
- name: Build PyPi package
if: github.ref == 'refs/heads/master'
run: poetry build
- name: Publish PyPi package
if: github.ref == 'refs/heads/master'
uses: pypa/gh-action-pypi-publish@release/v1.12
with:
password: ${{ secrets.PYPI_API_TOKEN }}
- name: Tag the release
if: github.ref == 'refs/heads/master' && env.VERSION_CHANGE == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "${{ env.VERSION }}" -m "Release ${{ env.VERSION }}"
git push origin "refs/tags/${{ env.VERSION }}"
4 changes: 2 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ line-length = 119
lint.ignore = ["E402", "E721", "E741", "F401", "F403", "F405", "E713"]

[tool.poetry.group.dev.dependencies]
ruff = ">=0.9.1,<0.12.0"
ruff = "==0.11.10"
pytest-httpserver = "^1.1.0"
pytest-asyncio = "^0.25.2"
poetry-dynamic-versioning = "^1.4.1"
Expand All @@ -49,4 +49,3 @@ build-backend = "poetry_dynamic_versioning.backend"
[tool.poetry-dynamic-versioning]
enable = true
metadata = true
format = "v0.1.{distance}"
Loading