chore: add release workflow and semver versioning

Mirror adn-monitor: python-semantic-release on develop, no RC phase.
Runtime version from pyproject.toml; starting at 2.0.0.
pull/9/head
Rodrigo Pérez 3 months ago
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

@ -2,6 +2,8 @@
All notable changes to **adn-server** are documented here.
<!-- version list -->
## [2.0.0-rc.4] - 2026-06-18
### Added

@ -1,6 +1,6 @@
# ADN DMR Peer Server
**Version 2.0.0-rc.4** — pairs with **adn-monitor 2.0.0-rc.5** (report v2 slim wire + JSON HELLO).
**Version 2.0.0** — pairs with **adn-monitor 2.0.0** (report v2 slim wire + JSON HELLO).
ADN DMR conference bridge server. Configuration is YAML; the codebase follows clean architecture (domain, application, infrastructure). v2 adds integrated **PROXY**, **SubscriptionStore** routing, report v2 to the monitor, and a unified **`adn-server.py`** entrypoint (`--echo`, `--doctor`, `--no-proxy`). See [CHANGELOG.md](CHANGELOG.md).

@ -1,5 +1,6 @@
# ADN DMR Peer Server
# GPL v3. Derived from ADN DMR Server / HBlink.
# Version: bumped automatically by python-semantic-release (.github/workflows/release.yml).
[build-system]
requires = ["setuptools>=61", "wheel"]
@ -7,7 +8,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "adn-server"
version = "2.0.0-rc.4"
version = "2.0.0"
description = "ADN DMR Peer Server"
readme = "README.md"
license = { text = "GPL-3.0-or-later" }
@ -26,6 +27,9 @@ selfservice = ["mysqlclient>=2.0"]
dev = ["pytest>=7.0", "jsonschema>=4.0", "paho-mqtt>=2.0"]
docs = ["mkdocs>=1.6", "mkdocs-material>=9.5", "pymdown-extensions>=10.3", "mkdocs-mermaid2-plugin>=1.1"]
[project.scripts]
adn-server = "adn_server.main:main"
[tool.setuptools.packages.find]
where = ["src"]
@ -43,5 +47,34 @@ markers = [
# Entrypoints adjust sys.path before importing the package (intentional E402).
"src/adn_server/main.py" = ["E402"]
[project.scripts]
adn-server = "adn_server.main:main"
[tool.semantic_release]
build_command = ""
tag_format = "v{version}"
commit_message = "chore(release): {version}"
version_toml = ["pyproject.toml:project.version"]
version_variables = ["README.md:**Version"]
[tool.semantic_release.branches.develop]
match = "develop"
prerelease = false
[tool.semantic_release.branches.master]
match = "master"
prerelease = false
[tool.semantic_release.commit_parser_options]
allowed_tags = ["build", "chore", "ci", "docs", "feat", "fix", "perf", "style", "refactor", "test"]
minor_tags = ["feat"]
patch_tags = ["fix", "perf"]
[tool.semantic_release.changelog.default_templates]
mode = "update"
changelog_file = "CHANGELOG.md"
[tool.semantic_release.remote]
name = "origin"
type = "github"
ignore_token_for_push = false
[tool.semantic_release.remote.token]
env = "GH_TOKEN"

@ -37,4 +37,6 @@
"""ADN DMR Peer Server — conference bridge (rewrite of bridge_master)."""
__version__ = "2.0.0-rc.4"
from .version import __version__, read_version, repo_root
__all__ = ["__version__", "read_version", "repo_root"]

@ -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…
Cancel
Save

Powered by TurnKey Linux.