When I forked winfunc/opcode to build opcode-lucho, I assumed the
boring part was already solved: the repository came with five GitHub Actions workflows (pr-check.yml,
build-test.yml, build-linux.yml, build-macos.yml, release.yml), so I thought I only had to start
opening PRs and let the checks do their job.
pr-check.yml failed on every single one of my first PRs. Neither cause had anything to do with my code.
Cause one: system dependencies that were never installed
The error was Package glib-2.0 was not found in the pkg-config search path. Tauri needs system
dependencies to compile on Linux, and pr-check.yml never installed them on ubuntu-latest before
running cargo check. The correct dependency list already existed in build-test.yml, in the same
repository—it had simply never been carried over to the workflow that runs on every PR.
Cause two: cargo check needs a dist/index.html that tsc never produces
With the system dependencies fixed, pr-check was still red. The workflow ran bun run check, which in
this repository means tsc --noEmit && cargo check. The problem lives in web_server.rs: it uses
include_str! to embed dist/index.html into the binary through Tauri’s generate_context!. That file
does not exist until the frontend is built—and tsc --noEmit does exactly what its name says: it type
checks, but emits nothing. cargo check was looking for a file nobody had built yet.
The solution was to run bun run build before cargo check in the workflow, not afterward or in
parallel.
A third finding while fixing the first two
build-test.yml—the workflow that builds the app on all three platforms—had never run at all: it targeted
the main and develop branches, which do not exist in this fork (the flow here is task branch → PR →
dev → master). This was not a subtle configuration bug; it was an entire workflow pointing nowhere.
With both pr-check causes fixed and the build-test branches corrected, pr-check now passes in 7m51s
and build-test builds all three platforms without intervention.
What this exposed: red checks blocked nothing
While investigating why CI had never been green, I found something worse: because there was no branch protection, a PR had once been merged with red checks. CI could fail as loudly as it wanted, and nothing stopped anyone.
I added rulesets to master and dev with no bypass—not even for me as admin. They require an open PR and
a green bun run check before merging, and block force pushes and branch deletion. I verified them by
pushing directly to master: GitHub rejected it with GH013.
That revealed the twist I did not expect: protection rulesets are unavailable for private repositories on GitHub Free. The repository was still private at the time, and the API returned a 403 with a direct message: “Upgrade to GitHub Pro or make this repository public.” There is no way to protect a branch in a private repository without paying. The sequence was forced into the opposite of what I would have chosen beforehand: make the repository public first, then close the protection gap.
Forking a large codebase is not only inheriting code. It is inheriting its infrastructure too, including all of its silent breakage. Nobody warns you—you discover it by opening the first PR.