diff --git a/.github/bin/check-version.sh b/.github/bin/check-version.sh new file mode 100755 index 0000000..f24e8a9 --- /dev/null +++ b/.github/bin/check-version.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# This file is part of indico-patcher. +# Copyright (C) 2023 UNCONVENTIONAL + +set -e + +# Fail if the tag version is not passed +if [ -z "$1" ]; then + echo "::error::No tag version passed." + exit 1 +fi + +# Get the tag version from the argument +TAG_VERSION=$1 + +# Get the version from pyproject.toml +PROJECT_VERSION="$(grep 'version =' pyproject.toml | cut -d '"' -f 2)" + +# Check if the tag version matches the project version +if [ "${TAG_VERSION}" != "${PROJECT_VERSION}" ]; then + echo "::error::Tag version ${TAG_VERSION} doesn't match project version ${PROJECT_VERSION}." + exit 1 +fi diff --git a/.github/bin/extract-changelog.py b/.github/bin/extract-changelog.py new file mode 100755 index 0000000..9ffdea3 --- /dev/null +++ b/.github/bin/extract-changelog.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# This file is part of indico-patcher. +# Copyright (C) UNCONVENTIONAL + +import re +import sys +from pathlib import Path + +CHANGELOG_FILENAME = "CHANGELOG.md" + + +def extract_section(version): + path = Path(CHANGELOG_FILENAME) + text = path.read_text() + + # Check that the changelog contains a section for the given version + re_start = rf"^## ({re.escape(version)})(.*)$" + if not (match := re.search(re_start, text, re.MULTILINE)): + print(f"::error::Version {version} not found in {CHANGELOG_FILENAME}.") + sys.exit(1) + + # Check that the given version is not marked as unreleased + if "unreleased" in match.group(2).lower(): + print(f"::error::Version {version} is marked as unreleased in {CHANGELOG_FILENAME}.") + sys.exit(1) + + # Extract the changes for the given version + re_end = r"^## (.*)$" + text = text[match.end(0):] + if match := re.search(re_end, text, re.MULTILINE): + text = text[:match.start()] + + return text.strip() + + +def main(): + version = sys.argv[1] + out_path = None + if len(sys.argv) > 2: + out_path = Path(sys.argv[2]) + changelog = extract_section(version) + if not out_path: + print(changelog) + return + out_path.write_text(changelog) + print(f"Changelog for {version} written to {out_path}.") + + +if __name__ == "__main__": + main() diff --git a/.github/workflows/releasing.yaml b/.github/workflows/releasing.yaml new file mode 100644 index 0000000..b0756c8 --- /dev/null +++ b/.github/workflows/releasing.yaml @@ -0,0 +1,90 @@ +name: releasing + +on: + push: + tags: + - 'v*' + +jobs: + check: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - name: Check tag version + run: | + .github/bin/check-version.sh "${GITHUB_REF#refs/tags/v}" + + build: + needs: check + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - name: Install poetry + run: | + pipx install poetry + - name: Build package + run: | + poetry build + - name: Extract changelog + run: | + .github/bin/extract-changelog.py ${{ github.ref_name }} /tmp/changelog.md + - uses: actions/upload-artifact@v3 + name: Upload build artifacts + with: + name: wheel + retention-days: 7 + path: ./dist/*.whl + - uses: actions/upload-artifact@v3 + name: Upload changelog + with: + name: changelog + retention-days: 7 + path: /tmp/changelog.md + + release: + needs: build + runs-on: ubuntu-22.04 + permissions: + contents: write + steps: + - uses: actions/download-artifact@v3 + - name: Draft release + run: >- + gh release create + --draft + --repo ${{ github.repository }} + --title ${{ github.ref_name }} + --notes-file changelog/changelog.md + ${{ github.ref_name }} + wheel/* + env: + GH_TOKEN: ${{ github.token }} + + publish: + needs: release + environment: + name: pypi + url: https://pypi.org/project/indico-patcher/ + runs-on: ubuntu-22.04 + permissions: + contents: write + id-token: write + steps: + - uses: actions/download-artifact@v3 + - name: Publish package to Test PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + packages-dir: wheel/ + - name: Publish package to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: wheel/ + - name: Publish release + run: >- + gh release edit + --draft=false + --repo ${{ github.repository }} + ${{ github.ref_name }} + env: + GH_TOKEN: ${{ github.token }}