ci: migrate from Woodpecker CI to Forgejo Actions #1

Merged
fmartingr merged 17 commits from feat/forgejo-actions into master 2026-09-22 17:33:29 +02:00
Owner

Replace the Woodpecker pipelines with Actions workflows under .github/workflows, matching the conventions the other migrated repositories now use (butterrobot, smtp2shoutrrr, terraria-companion, dharma).

Workflows

  • Jobs run on ubuntu-latest, answered with the catthehacker act image — no ci-base container.
  • Short uses: resolves against github.com, so every action carries its real name: goreleaser/goreleaser-action, oven-sh/setup-bun, docker/setup-qemu-action, docker/setup-buildx-action.
  • The act image carries none of the tooling ci-base provided, so each job installs what it calls: make everywhere, build-essential for the CGO test job, upx-ucl for goreleaser's upx block, bun for the webapp build, goreleaser itself for make build.
  • e2e gets a Docker-in-Docker service so testcontainers can resolve its mapped ports from inside the job container; Playwright installs with --with-deps now that the job has sudo.

Supporting changes

  • Makefile drops unused variables and adopts a self-documenting help target.
  • .goreleaser.yml keeps dockers_v2 for the multi-platform image.
  • Containerfile moves to Alpine 3.23; nfpm description fixed.
  • e2e: shared Docker network so link creation reaches the test web server, mattn/go-sqlite3 added to the e2e module, all:dist embed directive so dot-files ship in the webapp bundle.
Replace the Woodpecker pipelines with Actions workflows under `.github/workflows`, matching the conventions the other migrated repositories now use (butterrobot, smtp2shoutrrr, terraria-companion, dharma). ## Workflows - Jobs run on `ubuntu-latest`, answered with the catthehacker act image — no `ci-base` container. - Short `uses:` resolves against github.com, so every action carries its real name: `goreleaser/goreleaser-action`, `oven-sh/setup-bun`, `docker/setup-qemu-action`, `docker/setup-buildx-action`. - The act image carries none of the tooling `ci-base` provided, so each job installs what it calls: `make` everywhere, `build-essential` for the CGO test job, `upx-ucl` for goreleaser's `upx` block, bun for the webapp build, goreleaser itself for `make build`. - `e2e` gets a Docker-in-Docker service so testcontainers can resolve its mapped ports from inside the job container; Playwright installs with `--with-deps` now that the job has sudo. ## Supporting changes - `Makefile` drops unused variables and adopts a self-documenting `help` target. - `.goreleaser.yml` keeps `dockers_v2` for the multi-platform image. - `Containerfile` moves to Alpine 3.23; nfpm description fixed. - e2e: shared Docker network so link creation reaches the test web server, `mattn/go-sqlite3` added to the e2e module, `all:dist` embed directive so dot-files ship in the webapp bundle.
Replace Woodpecker CI pipelines with GitHub/Forgejo Actions workflows
using the ci-base:1.0.0 image. Simplify Makefile by removing unused
variables and adopting a cleaner help target. Switch goreleaser from
dockers_v2 to dockers + docker_manifests for per-arch image builds.
Update Containerfile to Alpine 3.23 and fix nfpm description.
fix: use master branch in CI workflow triggers
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 6s
CI / e2e (pull_request) Failing after 1m40s
CI / test (pull_request) Failing after 3m14s
CI / build (pull_request) Successful in 4m31s
CI / format (pull_request) Successful in 1m15s
CI / lint (pull_request) Failing after 2m4s
bb660f3cd4
fix: add .gitkeep to webapp/dist for go:embed compatibility
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 5s
CI / lint (pull_request) Failing after 1m53s
CI / format (pull_request) Successful in 2m7s
CI / e2e (pull_request) Failing after 1m53s
CI / test (pull_request) Failing after 3m17s
CI / build (pull_request) Has been cancelled
d4d2a5bed3
fix: use all:dist embed directive to include dot-files
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 15s
CI / format (pull_request) Successful in 2m19s
CI / lint (pull_request) Successful in 3m53s
CI / test (pull_request) Failing after 3m26s
CI / e2e (pull_request) Failing after 1m39s
CI / build (pull_request) Successful in 3m59s
4fcf97c9fd
ci: increase test timeout to 5m for CI with race detector
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 10s
CI / lint (pull_request) Has been cancelled
CI / format (pull_request) Has been cancelled
CI / test (pull_request) Has been cancelled
CI / e2e (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
92bf5c1297
ci: use e2e/go.mod for e2e job Go version
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 7s
CI / format (pull_request) Successful in 2m36s
CI / lint (pull_request) Successful in 3m13s
CI / e2e (pull_request) Failing after 2m1s
CI / build (pull_request) Has been cancelled
CI / test (pull_request) Has been cancelled
64cffcb2e3
fix: add missing mattn/go-sqlite3 dependency to e2e module
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 12s
CI / format (pull_request) Successful in 2m52s
CI / lint (pull_request) Successful in 3m33s
CI / test (pull_request) Successful in 6m0s
CI / build (pull_request) Successful in 3m18s
CI / e2e (pull_request) Failing after 39m39s
b6cd0ddbc6
fix(e2e): make link creation reach test web server via shared network
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 11s
CI / format (pull_request) Successful in 2m38s
CI / test (pull_request) Successful in 5m0s
CI / lint (pull_request) Successful in 3m5s
CI / build (pull_request) Successful in 3m16s
CI / e2e (pull_request) Failing after 28m15s
f47010cd0f
The test web server and Hako container previously ran on isolated Docker
networks, so Hako could not fetch URLs like http://localhost:32865 (the
host-mapped port) from inside its container. Most tests passed vacuously
because they only checked DOM containers; the Archive tests failed
because they tried to click an actual link item that was never created.

Changes:
- Add a shared Docker network so both containers can communicate by alias
- Test web server registers as hako-testserver and returns that as its URL
- Hako container joins the same network and can resolve the alias
- CreateLink now navigates to /home before each call so it can be invoked
  multiple times in a row (the form redirects to /links after submission)
- IsVisible uses .First() to avoid Playwright strict-mode errors when a
  selector matches multiple elements
- Archive tests use .link-item instead of the never-matching
  a[href*='/links/'] selector
- Bump Dockerfile.e2e Alpine to 3.23 to match the production Containerfile
ci: align Forgejo Actions with migrated repo conventions
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 7s
CI / format (pull_request) Successful in 1m14s
CI / lint (pull_request) Successful in 2m57s
CI / e2e (pull_request) Failing after 21s
CI / test (pull_request) Successful in 5m22s
CI / build (pull_request) Successful in 4m23s
53fcfe7267
Bump ci-base to 1.1.0 and actions to v7, add Docker buildx setup for
releases, restore dockers_v2 for multi-arch images, and set testcontainers
env vars on the e2e job.

Co-authored-by: Cursor <cursoragent@cursor.com>
fix(ci): mount Docker socket for e2e job on Forgejo Actions
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 10s
CI / format (pull_request) Successful in 2m28s
CI / lint (pull_request) Successful in 2m58s
CI / e2e (pull_request) Failing after 1s
CI / test (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
ffa604ee87
The e2e job runs testcontainers inside a ci-base container, which needs
the host Docker socket mounted. Also preserve TESTCONTAINERS_RYUK_DISABLED
from CI env and wait for archive UI before asserting in archive tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
fix(ci): use Docker-in-Docker service for e2e testcontainers
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 7s
CI / format (pull_request) Successful in 2m31s
CI / lint (pull_request) Successful in 3m9s
CI / e2e (pull_request) Failing after 1m31s
CI / build (pull_request) Has been cancelled
CI / test (pull_request) Has been cancelled
439a600721
Mounting the host socket via container options is blocked by the runner,
so run a dind service and point DOCKER_HOST at it instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
fix(ci): install Playwright system deps before browser download
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 11s
CI / format (pull_request) Successful in 2m33s
CI / lint (pull_request) Successful in 3m20s
CI / build (pull_request) Has been cancelled
CI / test (pull_request) Has been cancelled
CI / e2e (pull_request) Failing after 1m35s
68905fab6c
The --with-deps flag fails in the DinD job container; install Ubuntu
packages explicitly and download chromium from the e2e module context.

Co-authored-by: Cursor <cursoragent@cursor.com>
fix(ci): simplify e2e job and default testcontainers for CI
Some checks failed
CI / format (pull_request) Successful in 2m37s
CI / lint (pull_request) Successful in 3m9s
CI / build (pull_request) Has been cancelled
CI / goreleaser-lint (pull_request) Successful in 9s
CI / e2e (pull_request) Failing after 41s
CI / test (pull_request) Has been cancelled
9b1ce9ddf7
Drop DinD service (breaks apt/playwright in the job container) and the
workflow env overrides that masked the e2e script config. Default Ryuk
disabled in e2e.sh for CI friendliness.

Co-authored-by: Cursor <cursoragent@cursor.com>
fix(ci): combine DinD with Playwright install without --with-deps
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 13s
CI / format (pull_request) Successful in 3m4s
CI / lint (pull_request) Successful in 3m58s
CI / e2e (pull_request) Failing after 1m48s
CI / test (pull_request) Successful in 5m42s
CI / build (pull_request) Successful in 3m8s
5fbd6788a4
DinD is required for testcontainers but breaks apt-based --with-deps;
install chromium only after the daemon is ready.

Co-authored-by: Cursor <cursoragent@cursor.com>
ci: run workflows on the GitHub-compatible runner
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 6s
CI / format (pull_request) Failing after 31s
CI / lint (pull_request) Failing after 1m6s
CI / e2e (pull_request) Failing after 1m54s
CI / test (pull_request) Successful in 5m4s
CI / build (pull_request) Successful in 4m44s
ccda656c00
The forge resolves a short `uses:` against github.com, so every action
carries its real name: goreleaser/goreleaser-action, oven-sh/setup-bun,
docker/setup-qemu-action, docker/setup-buildx-action.

Jobs run on ubuntu-latest, answered with the catthehacker act image, so
the ci-base container is gone. That image carries none of the tooling
ci-base provided, so each job installs what it calls: make everywhere,
build-essential for the CGO test job, upx-ucl for the goreleaser `upx`
block, bun for the webapp build and goreleaser itself for `make build`.

Playwright installs with --with-deps again now that the job has sudo.
ci: retry dockerd in the e2e docker-in-docker service
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 13s
CI / format (pull_request) Successful in 1m35s
CI / e2e (pull_request) Failing after 1m32s
CI / lint (pull_request) Successful in 3m1s
CI / test (pull_request) Successful in 5m48s
CI / build (pull_request) Successful in 4m50s
78f49b2525
containerd needs about 10.04 seconds to boot in the runner's container
and dockerd waits exactly ten, so the first attempt always exits with
"timeout waiting for containerd to start" and the job never sees a
daemon. The second attempt wins, because containerd's files are in the
page cache by then. Measured on the runner: ready after roughly 45
seconds, with one retry.

The wait loop goes from 60 to 120 tries to cover that on a loaded host.
fix(e2e): move off the retired Playwright driver CDN
All checks were successful
CI / goreleaser-lint (pull_request) Successful in 8s
CI / format (pull_request) Successful in 1m33s
CI / lint (pull_request) Successful in 3m23s
CI / build (pull_request) Successful in 3m5s
CI / test (pull_request) Successful in 4m38s
CI / e2e (pull_request) Successful in 26m24s
d4457cc4f6
playwright-go v0.5200.1 fetches its driver from playwright.azureedge.net
and two sibling mirrors. Microsoft retired that CDN, so the e2e job died
on a 404 before it ever reached a test. The replacement host serves no
builds/driver zip for any version — 1.52 through 1.62 all answer 400 —
so there is nothing to pin or mirror to.

v0.6100.0 onwards pulls playwright-core from npm and Node from
nodejs.org instead, and moves the module path back to
github.com/mxschmitt/playwright-go. Take v0.6201.1, the latest. The
Playwright 1.52 to 1.62 jump needs no changes beyond the import path.

The CLI must match the module the tests link against, and the three
places that ran it had already drifted apart: the workflow pinned
v0.5200.1, the Makefile and scripts/e2e.sh asked for @latest. Both now
read the version from e2e/go.mod, and the workflow calls make e2e-install.
fmartingr merged commit 291aed39f1 into master 2026-09-22 17:33:29 +02: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
fmartingr/hako!1
No description provided.