Skip to content

Commit

Permalink
Merge pull request #13 from kraken-tech/release-to-pypi
Browse files Browse the repository at this point in the history
Add release-to-pypi GHA workflow
  • Loading branch information
meshy authored May 7, 2024
2 parents cbe89e8 + d217d3f commit 77131f8
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 27 deletions.
62 changes: 62 additions & 0 deletions .github/workflows/release-to-pypi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
name: Release to PyPI

on:
pull_request:
push:
tags:
- v*

jobs:
build:
name: Build dist package
runs-on: ubuntu-22.04
timeout-minutes: 5

steps:
- name: Clone the code
uses: actions/checkout@v4

- uses: hynek/build-and-inspect-python-package@v2

verify:
name: Verify versions
runs-on: ubuntu-22.04
timeout-minutes: 5
if: github.repository_owner == 'kraken-tech' && github.ref == 'refs/heads/main'

steps:
- name: Clone the code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install requirements
run: make install

- name: Verify version
run: ./scripts/verify-version-tag.py

release:
name: Publish to pypi.org
environment: release
if: github.repository_owner == 'kraken-tech' && github.ref == 'refs/heads/main'
needs: [build, verify]
runs-on: ubuntu-22.04
timeout-minutes: 5

permissions:
id-token: write

steps:
- name: Download packages
uses: actions/download-artifact@v4
with:
name: Packages
path: dist

- name: Upload package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ where = ["src"]
name = "django_integrity"
version = "0.0-alpha"
license.file = "LICENSE"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
# We cannot decide for users if they want to use psycopg2, psycopg2-binary, or
Expand Down Expand Up @@ -64,6 +65,7 @@ dev = [

# CLI utils
"rich",
"tomli >= 1.1.0 ; python_version < '3.11'",
"typer",
]

Expand Down
69 changes: 42 additions & 27 deletions requirements/development.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --extra=dev --output-file=requirements/development.txt --unsafe-package=django pyproject.toml
#
asgiref==3.7.2
# via django
cachetools==5.3.2
asgiref==3.8.1
# via
# django
# django-stubs
cachetools==5.3.3
# via tox
chardet==5.2.0
# via tox
Expand All @@ -18,78 +20,91 @@ distlib==0.3.8
# via virtualenv
dj-database-url==2.1.0
# via django_integrity (pyproject.toml)
django-stubs==4.2.7
django-stubs==5.0.0
# via django_integrity (pyproject.toml)
django-stubs-ext==4.2.7
django-stubs-ext==5.0.0
# via django-stubs
environs==10.3.0
environs==11.0.0
# via django_integrity (pyproject.toml)
filelock==3.13.1
exceptiongroup==1.2.1
# via pytest
filelock==3.14.0
# via
# tox
# virtualenv
iniconfig==2.0.0
# via pytest
markdown-it-py==3.0.0
# via rich
marshmallow==3.20.2
marshmallow==3.21.2
# via environs
mdurl==0.1.2
# via markdown-it-py
mypy==1.8.0
mypy==1.10.0
# via django_integrity (pyproject.toml)
mypy-extensions==1.0.0
# via mypy
mypy-json-report==1.1.0
mypy-json-report==1.2.0
# via django_integrity (pyproject.toml)
packaging==23.2
packaging==24.0
# via
# marshmallow
# pyproject-api
# pytest
# tox
platformdirs==4.2.0
platformdirs==4.2.1
# via
# tox
# virtualenv
pluggy==1.4.0
pluggy==1.5.0
# via
# pytest
# tox
pygments==2.17.2
pygments==2.18.0
# via rich
pyproject-api==1.6.1
# via tox
pytest==8.0.0
pytest==8.2.0
# via
# django_integrity (pyproject.toml)
# pytest-django
pytest-django==4.8.0
# via django_integrity (pyproject.toml)
python-dotenv==1.0.1
# via environs
rich==13.7.0
# via django_integrity (pyproject.toml)
ruff==0.2.1
rich==13.7.1
# via
# django_integrity (pyproject.toml)
# typer
ruff==0.4.3
# via django_integrity (pyproject.toml)
sqlparse==0.4.4
shellingham==1.5.4
# via typer
sqlparse==0.5.0
# via django
tox==4.12.1
tomli==2.0.1 ; python_version < "3.11"
# via
# django-stubs
# django_integrity (pyproject.toml)
# mypy
# pyproject-api
# pytest
# tox
tox==4.15.0
# via django_integrity (pyproject.toml)
typer==0.9.0
typer==0.12.3
# via django_integrity (pyproject.toml)
types-pytz==2024.1.0.20240203
# via django-stubs
types-pyyaml==6.0.12.12
types-pyyaml==6.0.12.20240311
# via django-stubs
typing-extensions==4.9.0
typing-extensions==4.11.0
# via
# asgiref
# dj-database-url
# django-stubs
# django-stubs-ext
# mypy
# typer
virtualenv==20.25.0
virtualenv==20.26.1
# via tox

# The following packages are considered to be unsafe in a requirements file:
Expand Down
84 changes: 84 additions & 0 deletions scripts/verify-version-tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/usr/bin/env python
"""
A script to help with making a new release.
This script verifies that the current commit has a tag,
that the tag matches the version in the `pyproject.toml` file,
and that the tag is in the CHANGELOG.
"""
import pathlib
import re
import subprocess
import sys

import rich
import typer
from packaging.version import InvalidVersion, Version


if sys.version_info >= (3, 11):
import tomllib
else:
# We can remove this when we drop support for Python 3.10.
import tomli as tomllib


PYPROJECT_FILE = pathlib.Path(__file__).resolve().parent.parent / "pyproject.toml"
CHANGELOG_FILE = pathlib.Path(__file__).resolve().parent.parent / "CHANGELOG.md"
app = typer.Typer()


@app.command()
def main():
# Get the tags on the current commit.
tags = (
subprocess.check_output(["git", "tag", "--points-at", "HEAD"]).decode().split()
)

# Find a tag that looks like a version.
versions: list[Version] = []
for tag in tags:
try:
version = Version(tag)
except InvalidVersion:
rich.print(f"[yellow]Skipping non-version tag:[/] {tag}")
else:
versions.append(version)

if not versions:
rich.print("[red]No version tags found.")
raise typer.Abort()
elif len(versions) > 1:
rich.print(f"[red]Multiple version tags found:[/] {versions}.")
raise typer.Abort()

(tag_version,) = versions

# Get the version from the pyproject.toml file.
pyproject_content = PYPROJECT_FILE.read_text()
project_config = tomllib.loads(pyproject_content)
project_version_str = project_config["project"]["version"]
project_version = Version(project_version_str)

# Check that the tag matches the version.
if tag_version == project_version:
rich.print("[green]Tag matches version in pyproject.toml.")
else:
rich.print("[red]Versions do not match:")
rich.print(f" Git tag: {tag_version}")
rich.print(f" Package: {project_version}")
raise typer.Abort()

# Check that the tag is in the CHANGELOG.
return_code = subprocess.run(
["git", "grep", rf"\bv{tag_version}\b", "HEAD", "--", str(CHANGELOG_FILE)],
).returncode
if return_code == 0:
rich.print("[green]Tag found in CHANGELOG.")
else:
rich.print(f"[red]Tag not committed to CHANGELOG:[/] {tag_version}.")
raise typer.Abort()


if __name__ == "__main__":
app()

0 comments on commit 77131f8

Please sign in to comment.