Files
blocker/.gitea/workflows/README.md
SellPL af8b28f6c6
CI / ci (pull_request) Has been cancelled
CI / android (pull_request) Has been cancelled
docs: add Gitea workflows, issue/PR templates, README and licence notice
ci.yml calls `scripts/ci.sh` rather than restating the checks: a workflow that
reimplements them becomes a second definition of "done", and the two drift.

Android runs as a separate job. It fails when the SDK is absent while ci.sh
skips it — a developer should not be blocked by a missing toolchain, but a
silently skipped Android build in CI means regressions ship unnoticed. Every
action is pinned to an exact version.

LICENSE.md records that no licence is chosen yet, and why it is not a formality:
the choice is upstream of the UI toolkit decision, since Slint is GPL-3.0.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-01 15:56:13 +03:00

4.0 KiB

Gitea Actions setup

The owner has not yet confirmed whether a runner is registered on this Gitea. Until one is, scripts/ci.sh is the only thing gating merges, and every check must be run locally before opening a PR.

The workflows in this directory are written for act_runner, Gitea's act-compatible runner, which executes jobs in Docker. They are also close enough to GitHub Actions syntax that a GitHub-style runner would work with the labels adjusted.


Labels these workflows expect

File runs-on Needs
ci.yml → ci ubuntu-latest Rust toolchain, no Android SDK
ci.yml → android android-build JDK 17 + Android SDK 35

If your runner is registered under different labels, change runs-on here. Both must be changed together — a mismatch shows up as a job that queues forever, with no error message, which is the worst failure mode of a mislabelled runner.


Registering act_runner

On the runner host, with Docker present:

# 1. Generate a registration token, in Gitea's UI:
#    Site Administration → Actions → Runners → Create new runner
#    Copy the token.

# 2. Register. --instance is the URL Gitea is reachable at *from the runner*.
act_runner register \
  --instance https://git.valiq.vu \
  --token "<REGISTRATION_TOKEN>" \
  --name blocker-ci \
  --labels ubuntu-latest:docker://node:20-bookworm \
  --labels android-build:docker://ghcr.io/cirruslabs/android-sdk:34

# 3. Start it.
./act_runner run --server http://localhost:8080

Each --labels entry is name:docker://image. The runner runs the job inside that container, so the image must contain everything the job needs:

  • ubuntu-latest — needs bash, git, curl, and Rust. The workflow installs Rust via dtolnay/rust-toolchain, so a Rust-free base image is fine.
  • android-build — needs JDK 17 and the Android SDK, hence the Cirrus Labs image.

Running act_runner as a service

# /etc/systemd/system/act_runner.service
[Unit]
Description=Gitea Actions runner
After=docker.service
Requires=docker.service

[Service]
Type=simple
User=git
WorkingDirectory=/opt/act_runner
ExecStart=/opt/act_runner/act_runner run --server http://localhost:3000 --config /opt/act_runner/config.yml
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

What the runner still needs from the owner

CLAUDE.md section 10.4 says to ask whether the runner has the Android SDK. Not yet answered. The two behaviours are deliberately different until it is:

  • scripts/ci.sh skips Android when no SDK is found, and prints SKIP with the reason. A developer should not be blocked from running checks by a missing toolchain.
  • The android job in CI fails when the SDK is missing. A silently skipped Android build in CI means Android regressions ship unnoticed.

Same check, opposite defaults, because the contexts are opposite. If you would rather the CI job also skip, say so and it will be changed — but the failure mode of the current setting is "you find out from a user", which is worse.


Why the workflow calls scripts/ci.sh

ci.yml runs bash scripts/ci.sh rather than repeating the fmt/clippy/test/size steps inline.

The reason is drift. A workflow that reimplements the checks is a second definition of "done". The two diverge — someone adds a check locally, forgets CI, and green ticks mean nothing. One script, two callers, no drift.

The workflow keeps separate steps for checkout, toolchain install, caching, and artifact upload, because those are genuinely different between a runner and a laptop.


Action pinning

Every action is pinned to an exact version (@v4.1.7, not @v4, and never @main).

A floating tag means upstream can change what runs in your CI without a review, a tag can be repointed, and @main can change arbitrarily. On a self-hosted runner that is a supply chain problem: the code that decides whether a change is safe to merge is code someone else controls.

Bumping a pin is its own commit, so the diff shows what changed.