Mirror adn-monitor: python-semantic-release on develop, no RC phase. Runtime version from pyproject.toml; starting at 2.0.0.pull/9/head
parent
6307ea35c3
commit
d3938d8636
@ -0,0 +1,76 @@
|
||||
# Release workflow
|
||||
#
|
||||
# develop: python-semantic-release on push → semver tag + GitHub Release → sync master
|
||||
|
||||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: release-${{ github.repository }}-${{ github.ref_name }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: develop
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Reset to workflow SHA
|
||||
run: git reset --hard ${{ github.sha }}
|
||||
|
||||
- name: Semantic Release
|
||||
id: semantic
|
||||
uses: python-semantic-release/python-semantic-release@v10.5.3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
git_committer_name: github-actions[bot]
|
||||
git_committer_email: 41898282+github-actions[bot]@users.noreply.github.com
|
||||
vcs_release: "false"
|
||||
|
||||
- name: Create GitHub Release
|
||||
if: steps.semantic.outputs.released == 'true' && steps.semantic.outputs.tag != ''
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAG: ${{ steps.semantic.outputs.tag }}
|
||||
VERSION: ${{ steps.semantic.outputs.version }}
|
||||
RELEASE_NOTES: ${{ steps.semantic.outputs.release_notes }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if gh release view "$TAG" >/dev/null 2>&1; then
|
||||
echo "Release already exists for $TAG"
|
||||
gh release view "$TAG" --json url -q .url
|
||||
exit 0
|
||||
fi
|
||||
NOTES_FILE="$(mktemp)"
|
||||
if [[ -n "$RELEASE_NOTES" ]]; then
|
||||
printf '%s\n' "$RELEASE_NOTES" > "$NOTES_FILE"
|
||||
else
|
||||
printf 'Release %s\n' "$VERSION" > "$NOTES_FILE"
|
||||
fi
|
||||
gh release create "$TAG" --title "$VERSION" --notes-file "$NOTES_FILE"
|
||||
rm -f "$NOTES_FILE"
|
||||
|
||||
- name: Verify GitHub Release
|
||||
if: steps.semantic.outputs.released == 'true' && steps.semantic.outputs.tag != ''
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAG: ${{ steps.semantic.outputs.tag }}
|
||||
run: gh release view "$TAG"
|
||||
|
||||
- name: Sync master from develop
|
||||
if: steps.semantic.outputs.released == 'true'
|
||||
run: |
|
||||
git fetch origin develop
|
||||
git push origin origin/develop:refs/heads/master
|
||||
@ -0,0 +1,53 @@
|
||||
# ADN DMR Peer Server - package version
|
||||
#
|
||||
# Copyright (C) 2026 Rodrigo Pérez, CE5RPY <ce5rpy@qmd.cl>
|
||||
#
|
||||
# Bumped by python-semantic-release in pyproject.toml; runtime reads checkout or metadata.
|
||||
|
||||
"""Version helpers for CLI, HELLO, and deploy scripts."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def repo_root() -> Path:
|
||||
"""Repository root (parent of ``src/``)."""
|
||||
return Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def _version_from_pyproject() -> str:
|
||||
try:
|
||||
import tomllib
|
||||
except ModuleNotFoundError:
|
||||
import tomli as tomllib # type: ignore[no-redef]
|
||||
|
||||
data = tomllib.loads((repo_root() / "pyproject.toml").read_text(encoding="utf-8"))
|
||||
ver = data.get("project", {}).get("version")
|
||||
if isinstance(ver, str) and ver.strip():
|
||||
return ver.strip()
|
||||
raise ValueError("project.version missing in pyproject.toml")
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def read_version() -> str:
|
||||
"""Human-readable version from ``pyproject.toml`` in checkout, else package metadata."""
|
||||
pyproject_path = repo_root() / "pyproject.toml"
|
||||
if pyproject_path.is_file():
|
||||
try:
|
||||
return _version_from_pyproject()
|
||||
except ValueError:
|
||||
pass
|
||||
from importlib.metadata import PackageNotFoundError, version
|
||||
|
||||
try:
|
||||
return version("adn-server")
|
||||
except PackageNotFoundError as e:
|
||||
raise ValueError(
|
||||
f"adn-server not installed and no pyproject.toml version: {pyproject_path}"
|
||||
) from e
|
||||
|
||||
|
||||
__version__ = read_version()
|
||||
@ -0,0 +1,28 @@
|
||||
"""pyproject.toml version and CLI --version."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from adn_server import __version__, read_version, repo_root
|
||||
|
||||
|
||||
def test_read_version_matches_pyproject():
|
||||
text = (repo_root() / "pyproject.toml").read_text(encoding="utf-8")
|
||||
m = re.search(r'^version\s*=\s*"([^"]+)"', text, re.MULTILINE)
|
||||
assert m, "project.version missing in pyproject.toml"
|
||||
assert read_version() == m.group(1)
|
||||
assert __version__ == read_version()
|
||||
|
||||
|
||||
def test_adn_server_cli_version():
|
||||
proc = subprocess.run(
|
||||
[sys.executable, "-m", "adn_server.main", "--version"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
cwd=str(repo_root()),
|
||||
)
|
||||
assert proc.stdout.strip() == f"adn-server {read_version()}"
|
||||
Loading…
Reference in new issue