Skip to content

Add GitHub CI on native amd64 + arm64 and move to Python 3.14 - #1

Merged
Macaron27 merged 1 commit into
mainfrom
ci/github-actions
Sep 27, 2026
Merged

Macaron27 merged 1 commit into
mainfrom
ci/github-actions

Conversation

@Macaron27

@Macaron27 Macaron27 commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

What

CI (.github/workflows/ci.yml) runs on pushes to main, pull requests and manual runs. Each job runs on native amd64 (ubuntu-24.04) and arm64 (ubuntu-24.04-arm) runners.

Job Checks
test hash-locked install, ruff format --check, ruff check, mypy --strict, pytest with a 90% branch-coverage floor (currently 93.7%)
docker buildx image build (GHA layer cache), then a smoke run hardened like docker-compose.yml (--read-only --cap-drop ALL --security-opt no-new-privileges) that must exit 2 with config error, a check that the container runs as UID 10001, and docker compose config validation
  • Hardening: permissions: contents: read, every action pinned to a full commit SHA (tag in a comment), persist-credentials: false, per-ref concurrency (superseded PR runs are cancelled), and job timeouts.
  • Dependabot (.github/dependabot.yml): weekly grouped bumps for the pinned actions, plus patch-only bumps for the Python base image.

Python 3.14 everywhere, so the version CI tests is the version the image ships:

  • Dockerfile pinned to python:3.14.7-slim-trixie, currently the same image as python:3.14-slim (digest 51dafde81dbd);
  • requirements.txt regenerated for 3.14. audioop-lts is now unconditional and typing-extensions is gone;
  • requires-python = ">=3.14", and ruff/mypy now target 3.14.

Why

The image had never been built: there was no Docker runtime on the dev machine. This PR's CI run is the first real build and smoke test of the image, on both architectures. GitHub's standard arm64 Linux runners are free for public repositories (runner docs source), so arm64 builds and tests run natively instead of under QEMU emulation.

Notes for the reviewer

  • bot/webhooks/server.py: the only code change. With target py314, ruff format rewrites except (A, B): to the PEP 758 form except A, B:. They mean the same thing, and test_rejects_bad_json_unknown_format_and_huge_body covers that line.
  • pip is deliberately not in Dependabot. The lock is hash-pinned uv pip compile output; regenerating it is documented in the README.
  • Verified locally before pushing (macOS arm64, Python 3.14.7):
    • fresh venv installed from the lock only: 87 passed, coverage 93.67%;
    • ruff and mypy --strict clean;
    • actionlint 1.7.12 with ShellCheck 0.11.0: 0 issues;
    • every locked package has a hash-verified cp314 Linux wheel for amd64 and aarch64 (17 each);
    • the Dockerfile stages replayed locally: pip removed, 12/12 modules precompiled, exit code 2 on empty config.
  • Not verified locally: an actual docker build. This PR's CI run is that check.
  • Not included: publishing an image to GHCR. That's a release step, left for a follow-up.

README badges (05b4c9e): CI (tracks main), top language, Docker, Discord, last commit and license. Each badge links somewhere relevant, and the brand colours come from Simple Icons.

🤖 Generated with Claude Code

CI (.github/workflows/ci.yml), on push to main, PRs and manual runs:
- test (amd64, arm64): hash-locked install, ruff format/lint, mypy --strict,
  pytest with a 90% branch-coverage floor
- docker (amd64, arm64): native buildx build with GHA layer cache, smoke run
  hardened like compose (read-only, cap-drop ALL, no-new-privileges; must
  exit 2 with "config error"), non-root UID check, compose file validation
- least-privilege token (contents: read), SHA-pinned actions, no persisted
  checkout credentials, per-ref concurrency, job timeouts

Uses GitHub's free arm64 runners for public repos (ubuntu-24.04-arm), so
arm64 is built and tested natively instead of under QEMU.

Python 3.14 everywhere so what is tested is what ships: image pinned to
python:3.14.7-slim-trixie, lock regenerated for 3.14 (all 17 Linux wheels
verified for cp314 on both arches), ruff/mypy targets bumped. ruff's py314
formatter applies PEP 758 unparenthesized except in the webhook handler.

Dependabot: weekly grouped action SHA bumps and Python patch-only base image
bumps. pip stays manual (hash-locked uv output).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Macaron27
Macaron27 merged commit e945f71 into main Sep 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant