fix(ci): unbreak GitHub and Forgejo pipelines #1

Merged
hutao merged 3 commits from fix/ci-green into main 2026-09-13 09:40:31 +00:00
Owner

Every failing job had its own cause; none of them shared a fix.

fmt / clippy — both CIs

  • AI_MAX_TOKENS landed unformatted in 4cd0fbf.
  • Two lints had gone un-run: a redundant & in a format! argument (src/commands/level_cmds/level.rs:54) and .iter() over a map where only the values are used (src/data/embed_media.rs:147).
  • AI_MAX_TOKENS is now gated behind ai. Its only consumer is data::ai::provider, which lives under #[cfg(feature = "ai")] (src/data/mod.rs:1), so the no-feature leg of the matrix failed -D dead-code.

docker — GitHub

Debian bullseye is EOL and its security suite is archived, so apt-get update aborts with:

E: Release file for http://deb.debian.org/debian-security/dists/bullseye-security/InRelease is expired

and exits 100. Both stages move to bookworm.

test / docker — Forgejo

The runner created service containers on Docker's default bridge — the one network with no embedded DNS — so postgres and redis never resolved. The wait loop burned its full timeout and sqlx migrate run then failed with an address-lookup error naming no host.

The runner-side fix is hutao/vps fix/forgejo-runner-network (container.network: ""), which must merge and deploy before this repo's Forgejo test job can pass. The loop here now exits non-zero and names the unreachable host instead of falling through.

The docker job is dropped. Job containers get no Docker socket by design (container.docker_host: "-"), and both ways around that cost more than the job is worth:

  • A docker:dind service needs container.privileged: true, which privileges every job container. A workflow's own options: --privileged is silently dropped — the runner's mergeJobOptions (act/container/docker/run.go:430) only honours --health-*, --volume, --tmpfs, --memory and --hostname.
  • A host-side dind needs a privileged daemon reachable from the job network, i.e. from every other container on the box.

.github/workflows/full.yml already builds the image on every push to main, which is all this job duplicated.

Verification

All seven matrix legs pass locally (fmt, 3× clippy -D warnings, 3× build). The wait loop was tested both ways — reachable → 0, unreachable → 1 naming the host.

The Docker build is unverified locally (no Docker on the dev machine); this PR's GitHub run is its first real test.

No CHANGELOG.md entry per AGENTS.md:89 — CI/build plumbing and lint fixes, no behavior change.

Co-authored-by: Claude Opus 5 (1M context) noreply@anthropic.com

Every failing job had its own cause; none of them shared a fix. ## fmt / clippy — both CIs - `AI_MAX_TOKENS` landed unformatted in 4cd0fbf. - Two lints had gone un-run: a redundant `&` in a `format!` argument (`src/commands/level_cmds/level.rs:54`) and `.iter()` over a map where only the values are used (`src/data/embed_media.rs:147`). - `AI_MAX_TOKENS` is now gated behind `ai`. Its only consumer is `data::ai::provider`, which lives under `#[cfg(feature = "ai")]` (`src/data/mod.rs:1`), so the no-feature leg of the matrix failed `-D dead-code`. ## docker — GitHub Debian bullseye is EOL and its security suite is archived, so `apt-get update` aborts with: ``` E: Release file for http://deb.debian.org/debian-security/dists/bullseye-security/InRelease is expired ``` and exits 100. Both stages move to bookworm. ## test / docker — Forgejo The runner created service containers on Docker's **default** bridge — the one network with no embedded DNS — so `postgres` and `redis` never resolved. The wait loop burned its full timeout and `sqlx migrate run` then failed with an address-lookup error naming no host. The runner-side fix is hutao/vps `fix/forgejo-runner-network` (`container.network: ""`), **which must merge and deploy before this repo's Forgejo `test` job can pass.** The loop here now exits non-zero and names the unreachable host instead of falling through. The `docker` job is dropped. Job containers get no Docker socket by design (`container.docker_host: "-"`), and both ways around that cost more than the job is worth: - A `docker:dind` **service** needs `container.privileged: true`, which privileges *every* job container. A workflow's own `options: --privileged` is silently dropped — the runner's `mergeJobOptions` (`act/container/docker/run.go:430`) only honours `--health-*`, `--volume`, `--tmpfs`, `--memory` and `--hostname`. - A **host-side dind** needs a privileged daemon reachable from the job network, i.e. from every other container on the box. `.github/workflows/full.yml` already builds the image on every push to main, which is all this job duplicated. ## Verification All seven matrix legs pass locally (`fmt`, 3× `clippy -D warnings`, 3× `build`). The wait loop was tested both ways — reachable → 0, unreachable → 1 naming the host. **The Docker build is unverified locally** (no Docker on the dev machine); this PR's GitHub run is its first real test. No `CHANGELOG.md` entry per `AGENTS.md:89` — CI/build plumbing and lint fixes, no behavior change. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
fix(ci): unbreak GitHub and Forgejo pipelines
All checks were successful
Rust, Docker, Code Coverage / fmt (pull_request) Successful in 16s
Rust, Docker, Code Coverage / clippy () (pull_request) Successful in 1m19s
Rust, Docker, Code Coverage / clippy (--all-features) (pull_request) Successful in 1m43s
Rust, Docker, Code Coverage / clippy (--features "opentelemetry ai-openrouter util-download") (pull_request) Successful in 1m39s
Rust, Docker, Code Coverage / build () (pull_request) Successful in 1m41s
Rust, Docker, Code Coverage / build (--all-features) (pull_request) Successful in 2m20s
Rust, Docker, Code Coverage / build (--features "opentelemetry ai-openrouter util-download") (pull_request) Successful in 2m20s
Rust, Docker, Code Coverage / test (pull_request) Successful in 4m37s
aea631a470
Every job that was failing had its own cause; none of them shared a fix.

fmt/clippy (both CIs): `AI_MAX_TOKENS` landed unformatted in 4cd0fbf, and
two lints had gone un-run — a redundant `&` in a `format!` argument and an
`.iter()` over a map where only the values are used. `AI_MAX_TOKENS` is also
gated behind `ai` now: its only consumer is `data::ai::provider`, which lives
under `#[cfg(feature = "ai")]`, so the no-feature leg of the matrix failed
`-D dead-code`.

docker (GitHub): Debian bullseye is EOL and its security suite is archived,
so `apt-get update` now aborts with "Release file ... is expired" and exit
100. Both stages move to bookworm.

test/docker (Forgejo): the runner creates service containers on docker's
DEFAULT bridge, the one network with no embedded DNS, so `postgres` and
`redis` never resolved — the wait loop burned its full timeout and
`sqlx migrate run` then failed with an address-lookup error naming no host.
Fixed on the runner side (vps: container.network ""); the loop here now
exits non-zero and names the unreachable host instead of falling through.
The `docker` job is dropped: job containers get no docker socket by design
(container.docker_host "-"), and both ways around that cost more than the
job is worth. A `docker:dind` service needs container.privileged, which
privileges EVERY job container — a workflow's own `options: --privileged` is
silently dropped, since the runner's mergeJobOptions only honours
--health-*, --volume, --tmpfs, --memory and --hostname. A host-side dind
needs a privileged daemon reachable from the job network, i.e. from every
other container on the box. GitHub already builds the image on every push to
main, which is all this job duplicated.

No CHANGELOG entry: CI/build plumbing and lint fixes, no behavior change.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
`check_coverage "src/data/ai/review/guilds" 90` outlived the code it
gated — /ai-review was removed in #42 and `src/data/ai/review/` with it.
The pattern now matches no SF: line, so `lf` stays 0 and check_coverage
returns 1 on "no lines found".

Under `set -e` that aborts the whole script at that line, so the global
`check_coverage "src/" 70` below it has not run since #42. Both CIs mark
the step `continue-on-error: true`, and GitHub reports a continue-on-error
step as `success`, so nothing surfaced it — Forgejo printing
`exitcode '1': failure` is what made it visible.

Verified against the lcov.info artifact from the last green run: with the
stale gate gone all three checks run and pass, the global one at 78%.

The stale `src/data/ai/review/(agent|client|github)\.rs` entry in
DISCORD_BOUND goes too — same removed module.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
perf(ci): drop dev debuginfo from the clippy and build matrices
All checks were successful
Rust, Docker, Code Coverage / fmt (pull_request) Successful in 15s
Rust, Docker, Code Coverage / clippy () (pull_request) Successful in 1m16s
Rust, Docker, Code Coverage / clippy (--all-features) (pull_request) Successful in 1m42s
Rust, Docker, Code Coverage / clippy (--features "opentelemetry ai-openrouter util-download") (pull_request) Successful in 1m37s
Rust, Docker, Code Coverage / build () (pull_request) Successful in 1m35s
Rust, Docker, Code Coverage / build (--all-features) (pull_request) Successful in 2m7s
Rust, Docker, Code Coverage / build (--features "opentelemetry ai-openrouter util-download") (pull_request) Successful in 2m5s
Rust, Docker, Code Coverage / test (pull_request) Successful in 4m40s
240ba821d8
Measured on --all-features, clean: 375s -> 357s wall, and the target
directory 2.3G -> 1.4G. The time is noise; the 39% smaller directory is
the point, because that is what the Actions cache has to upload and
download on every job once caching is enabled (vps#9).

Not set on `test`. That job runs cargo llvm-cov, whose line mapping is
worth more than a smaller cache round-trip.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
hutao merged commit 6f5d32ce76 into main 2026-09-13 09:40:31 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
hutao/serenity-discord-bot!1
No description provided.