From 2e51e9c41f7a0272dd74339eaa980e72c55f2c6f Mon Sep 17 00:00:00 2001 From: Valentin Haudiquet Date: Tue, 25 Aug 2026 20:07:58 +0200 Subject: [PATCH] Add CI with checks and automated release builds Gitea Actions workflow (.gitea/workflows/ci.yml): - check job: ruff format --check, ruff check, ty check on pushes to main - release job on v* tags: build a standalone Linux executable with PyInstaller (--onefile), smoke-test it, create a Gitea release via the API and upload the binary as an asset Also add a pyinstaller build dependency group and bump to 0.3.0. --- .gitea/workflows/ci.yml | 75 +++++++++++++++++++++++++++++++++++++++++ .gitignore | 2 ++ README.md | 15 +++++++++ pyproject.toml | 3 +- 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/ci.yml diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..025273a --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,75 @@ +name: CI + +on: + push: + branches: [main] + tags: ["v*"] + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: astral-sh/setup-uv@v5 + + - name: Install dependencies + run: uv sync --frozen + + - name: Format check + run: uv run ruff format --check src + + - name: Lint + run: uv run ruff check src + + - name: Type check + run: uv run ty check + + release: + needs: check + if: startsWith(gitea.ref, 'refs/tags/v') + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + + - uses: astral-sh/setup-uv@v5 + + - name: Install dependencies + run: uv sync --frozen --group build + + - name: Build standalone executable + run: > + uv run pyinstaller + --onefile + --name weekly-activity + --paths src + --clean + --noconfirm + src/weekly_activity/cli.py + + - name: Smoke-test executable + run: ./dist/weekly-activity --help + + - name: Create release and upload artifact + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + API: ${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }} + TAG: ${{ gitea.ref_name }} + ASSET: weekly-activity-linux-amd64 + run: | + set -eu + AUTH="Authorization: token ${GITEA_TOKEN}" + RELEASE_ID=$(curl -sf -X POST "$API/releases" \ + -H "$AUTH" -H "Content-Type: application/json" \ + -d "{\"tag_name\":\"$TAG\",\"name\":\"$TAG\",\"body\":\"Automated release of $TAG\"}" \ + | python3 -c 'import json, sys; print(json.load(sys.stdin)["id"])' \ + ) || true + if [ -z "${RELEASE_ID:-}" ]; then + RELEASE_ID=$(curl -sf "$API/releases/tags/$TAG" -H "$AUTH" \ + | python3 -c 'import json, sys; print(json.load(sys.stdin)["id"])') + fi + curl -sf -X POST "$API/releases/$RELEASE_ID/assets?name=$ASSET" \ + -H "$AUTH" -F "attachment=@dist/weekly-activity" \ + | python3 -c 'import json, sys; print("uploaded:", json.load(sys.stdin)["browser_download_url"])' diff --git a/.gitignore b/.gitignore index 073583a..7f01758 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,7 @@ __pycache__/ *.pyc dist/ +build/ +*.spec *.egg-info/ .ruff_cache/ diff --git a/README.md b/README.md index bcb3036..69468e8 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,21 @@ uv run ruff check src # lint uv run ty check # type check ``` +## CI / releases + +Gitea Actions (`.gitea/workflows/ci.yml`) runs two jobs: + +- **check** — format, lint, and type check on every push to `main` +- **release** — on `v*` tags: builds a standalone Linux executable with + PyInstaller, smoke-tests it, creates a Gitea release, and uploads the + binary as an asset + +Cut a release with: + +```bash +git tag vX.Y.Z && git push origin vX.Y.Z +``` + ## Dependencies - **launchpadlib** — Launchpad REST API client diff --git a/pyproject.toml b/pyproject.toml index d6be673..e2ce52b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "weekly-activity" -version = "0.2.0" +version = "0.3.0" description = "Weekly activity report (merge proposals, pull requests, bugs, issues) for Launchpad and GitHub." requires-python = ">=3.11" dependencies = [ @@ -19,6 +19,7 @@ build-backend = "hatchling.build" [dependency-groups] dev = ["ruff>=0.6", "ty>=0.0.1"] +build = ["pyinstaller>=6"] [tool.hatch.build.targets.wheel] packages = ["src/weekly_activity"]