diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..2dfb069 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,48 @@ +name: Create release on tag + +on: + push: + tags: + - "v*.*.*" + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Ensure tag commit is on main + run: | + git fetch origin main:refs/remotes/origin/main + git merge-base --is-ancestor "$GITHUB_SHA" "origin/main" + + - name: Check version matches tag + run: | + TAG_VERSION="${GITHUB_REF_NAME#v}" + python - <<'PY' + import pathlib + import os + + expected = os.environ["TAG_VERSION"] + values = {} + exec(pathlib.Path("version/version.py").read_text(), None, values) + actual = values["VERSION"] + + if actual != expected: + raise SystemExit( + f"version/version.py VERSION={actual!r} " + f"does not match tag {expected!r}" + ) + PY + + - name: Create GitHub release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.ref_name }} + generate_release_notes: true diff --git a/tests/test_release_workflow.py b/tests/test_release_workflow.py new file mode 100644 index 0000000..f1956f6 --- /dev/null +++ b/tests/test_release_workflow.py @@ -0,0 +1,30 @@ +from pathlib import Path + + +WORKFLOW_FILE = Path('.github/workflows/release.yml') + + +def test_release_workflow_exists_and_triggers_on_version_tags(): + assert WORKFLOW_FILE.exists() + content = WORKFLOW_FILE.read_text() + assert 'on:' in content + assert 'tags:' in content + assert '- "v*.*.*"' in content + + +def test_release_workflow_checks_tag_commit_is_on_main(): + content = WORKFLOW_FILE.read_text() + command = ( + 'git merge-base --is-ancestor "$GITHUB_SHA" ' + '"origin/main"' + ) + assert 'Ensure tag commit is on main' in content + assert command in content + + +def test_release_workflow_checks_version_and_generates_notes(): + content = WORKFLOW_FILE.read_text() + assert 'version/version.py' in content + assert 'VERSION' in content + assert 'softprops/action-gh-release@v2' in content + assert 'generate_release_notes: true' in content