From 0b3c483c0babc5f1a7e5c2fb5fa27c545458c798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD=20=D0=A2=D1=80=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Tue, 20 Oct 2026 23:28:13 +0300 Subject: [PATCH] CI: a tag push builds, tests and publishes the release The artifacts and the GitHub release were made by hand (`python -m build` plus `gh release create`). `.github/workflows/release.yml` now does it from the pushed tag: Python and PWA tests, the sdist/wheel build, a check that the wheel carries the PWA, an install-and-serve smoke test of that wheel, and `gh release create` with the generated notes (prepended by `.github/release-notes.md`) and the three assets (wheel, sdist, udev rule). A `workflow_dispatch` run does everything except publish, so the pipeline can be exercised without minting a release; the artifacts land in the run. A tag that does not match version.py/PWA_VERSION fails before anything is published. --- .github/release-notes.md | 14 +++++ .github/workflows/release.yml | 99 +++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 .github/release-notes.md create mode 100644 .github/workflows/release.yml diff --git a/.github/release-notes.md b/.github/release-notes.md new file mode 100644 index 0000000..6cb4c29 --- /dev/null +++ b/.github/release-notes.md @@ -0,0 +1,14 @@ +Install the wheel below — the PWA is bundled inside it: + +``` +pip install ./simtrace_analyser-*.whl +simtrace-analyser-server --capture gsmtap +``` + +The UI is then served at http://127.0.0.1:8081/. If your system Python is +externally managed (PEP 668 — common on Arch and Fedora), install into a +virtual environment first (`python3 -m venv .venv && . .venv/bin/activate`). + +The source archive is the same tree a clone would have: unzip it and run +`./start.sh` (Linux/macOS) or `start.bat` (Windows). Direct SIMtrace2 capture +on Linux additionally needs the attached `70-simtrace2-pysniff.rules` udev rule. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8dc7c21 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,99 @@ +name: Release + +# A pushed v* tag publishes a GitHub release with the wheel, the sdist and the +# udev rule. A manual run (workflow_dispatch) does everything except publish, +# so the pipeline can be exercised without minting a release. + +on: + push: + tags: ['v*'] + workflow_dispatch: + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: The tag matches the version strings + if: startsWith(github.ref, 'refs/tags/') + run: | + version=$(python -c "from simtrace_analyser.version import __version__; print(__version__)") + if [ "$GITHUB_REF_NAME" != "v$version" ]; then + echo "tag $GITHUB_REF_NAME does not match version.py ($version)" >&2 + exit 1 + fi + grep -q "PWA_VERSION = '$version'" frontend/index.html + + - name: Install build tooling + run: python -m pip install --upgrade pip build + + - name: Python tests + run: python -m unittest discover -s tests + + - name: PWA tests + working-directory: frontend + run: node --test + + - name: Build the sdist and the wheel + run: python -m build --sdist --wheel + + - name: The wheel bundles the PWA + run: | + python - <<'PY' + import glob + import zipfile + wheel = glob.glob('dist/*.whl')[0] + names = zipfile.ZipFile(wheel).namelist() + for required in ('simtrace_analyser/web/index.html', + 'simtrace_analyser/web/sw.js'): + assert required in names, '%s is missing from %s' % (required, wheel) + print('%s: %d entries, PWA bundled' % (wheel, len(names))) + PY + + - name: The installed wheel serves the PWA + run: | + python -m venv /tmp/smoke + /tmp/smoke/bin/pip install --no-deps dist/*.whl + cd /tmp + /tmp/smoke/bin/simtrace-analyser-server --capture disabled \ + --db /tmp/smoke.db --port 8099 & + server=$! + for _ in $(seq 1 20); do + if curl -fsS http://127.0.0.1:8099/ -o /tmp/served-index.html; then + break + fi + sleep 0.5 + done + kill "$server" + cmp /tmp/served-index.html "$GITHUB_WORKSPACE/frontend/index.html" + /tmp/smoke/bin/python -c \ + "import simtrace_analyser.__main__ as m; p = m._default_web_dir(); assert p.endswith('/simtrace_analyser/web'), p" + + - name: Keep the artifacts + uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/* + + - name: Publish the release + if: startsWith(github.ref, 'refs/tags/') + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "$GITHUB_REF_NAME" \ + --title "$GITHUB_REF_NAME" \ + --generate-notes \ + --notes-file .github/release-notes.md \ + dist/*.whl dist/*.tar.gz 70-simtrace2-pysniff.rules