a687ef439c5252919f967fda80db9d3dd513ac42
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
eaf4654c0a |
test(release): make the version derivation executable, and guard it on dev
Steps 1 and 2 of this milestone shipped with no CI coverage at all, and the
reason generalises: release.yml triggers only on main and tags, so nothing
inside it is exercised until a release is already running. That is the worst
place in the repo to be unguarded, because the failure mode is silence — a
version nobody can compare looks exactly like being up to date, and nobody
reports an update they were never offered.
The fix is not a test that reads YAML. The derivation moved into
ci/version.sh, so it can be RUN, and internal/server/release_version_test.go
runs it on every push. release.yml now calls the same script, so the thing
that ships and the thing under test are one artifact rather than two copies
that agree until they don't.
test-go.yml gains 'ci/**' and '.gitea/workflows/release.yml' in its paths.
Without that the guard exists but never fires on the changes it protects,
which is the same nothing it replaces.
What is pinned, and why each one:
- HHMM is zero-padded. A build at 00:42 must emit "0042"; a stripped
leading zero shifts the segment two orders of magnitude and reverses
comparisons against every other build that day. It only bites for a
tenth of the day, so it will not be found by chance.
- The name derives from the COMMIT and the code from the BUILD. Asserted
by holding one clock and moving the other: the name must not move, the
code must.
- The code clears 1895, the highest versionCode the retired commit-count
scheme shipped. Below that Android refuses the upgrade as a downgrade
and the channel becomes a one-way door.
- The tag is the name with a `v`, never chosen.
- release.yml still calls the script, and does not derive a commit count
again. This pins the WIRING: without it every other assertion keeps
passing while the shipped path silently drifts out of coverage.
The script rejects unusable clocks rather than emitting something plausible,
and those rejections are tested — a guard that cannot fail is worse than
none, because it reads as coverage.
Falsified before committing rather than after: ran the script against good
and broken inputs and watched all three failure paths fire; verified every
asserted value by executing it rather than by reading it; and checked the
two workflow predicates catch their regressions while staying immune to a
comment that merely names the old formula.
Step 5 of 5 — Scribe task #3812, milestone #390.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SQ31KQpYbStyK5y58UmPLH
|
||
|
|
94e2cac03b |
ci(go): verify committed sqlc output matches its .sql sources — #2380
internal/db/dbq is 39 files and ~12k lines of generated Go covering 307 queries, and nothing checked that it still matched internal/db/queries. test-go.yml referenced sqlc.yaml only as a path trigger; sqlc never ran. So a hand-edit, a half-applied regen, or a migration changed without a regen would all pass CI while the typed layer quietly lied about the SQL underneath it — which is the single thing adopting sqlc is supposed to buy. This session's slice-1 change is an instance: its SQL const was verified byte-identical against its own .sql source by script, but never against what sqlc would actually emit. Nothing in the repo could have told the difference. make verify-generate runs ahead of vet/lint/test, because if the typed layer disagrees with its sources then everything downstream is testing a lie. generate-go runs sqlc as a Go tool rather than a container: the ci-go image already has Go, so this avoids docker-in-docker on the runner. It's pinned to the same SQLC_VERSION as the existing containerised `generate`, so both routes emit identical output and there is one version to bump — now annotated for Renovate per rule #44. The diff prints BEFORE the exit-code check on purpose. On failure the log then holds sqlc's exact expected output, so correcting it is a copy rather than a guess. That is also what makes new queries workable without installing anything: this workstation has neither Go nor sqlc. Makefile joins the workflow's paths:. Without it a Makefile-only change — including this one — would not trigger the workflow that now depends on it. Same class as #2204, where CI never ran on plugin/** changes. Landing this on its own, ahead of slice 3, so that if it fails it is unambiguous whether the drift came from slice 1 or from new code. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
28300e19fd |
perf(ci): turn off Postgres durability in integration tests
TRUNCATE-everything ResetDB before every test forces a commit fsync; the CI DB is rebuilt each run so durability buys nothing. ALTER SYSTEM via docker exec (the services: block can't override the postgres command line). Non-fatal so a perms surprise degrades to slow, never red. Per the playbook the operator shared from another project (~17x speedup observed there). Measure before/after in the next two CI runs. |
||
|
|
90bfcaa388 |
ci: drop pull_request triggers + add cancel-in-progress concurrency
Every commit on dev that's part of an open PR fires each workflow TWICE: once for the push event and once for the pull_request event (observable in run #43 + #44 for the same SHA in android.yml, same shape across test-web.yml and test-go.yml). The two runs check the exact same SHA — pure waste. Drop the pull_request trigger from test-web.yml, test-go.yml, and android.yml. The dev push already exercises every check that a PR would re-run. This repo has no fork PRs to cover, which is the only case pull_request would catch that push doesn't. Add a concurrency group keyed on workflow + ref with cancel-in-progress: true to every workflow including release.yml. Rapid re-pushes (or force-moving the per-day tag) now cancel the older in-flight run instead of stacking. |
||
|
|
3cf829752b |
chore(ci): migrate workflows to gitea + consolidate keystore secret
flutter / analyze-test-build (push) Failing after 2s
test-go / test (push) Successful in 33s
android / Build + lint + test (push) Failing after 41s
test-web / test (push) Successful in 41s
android / Build signed release APK (push) Has been skipped
test-go / integration (push) Successful in 11m16s
- rename .forgejo/workflows/ to .gitea/workflows/ (git mv preserves history); Gitea Actions reads either path, but the directory now matches the active platform - collapse ANDROID_STORE_PASSWORD + ANDROID_KEY_PASSWORD into a single ANDROID_KEYSTORE_PASSWORD secret (PKCS12 keystores require the two passwords to be identical, so the duplication carried no information); build.gradle.kts still reads two env vars to stay format-agnostic, both now sourced from the same secret in CI - ignore android/*.keystore, android/*.keystore.*, android/*.jks, android/keystore.properties so the regenerated signing material never reaches a remote on accident - update prose references from Forgejo to Gitea in CLAUDE.md and the docs; the historical "migrated from Forgejo" note in CLAUDE.md is kept intentionally; forgejo/upload-artifact@v3 action refs are left untouched (canonical artifact action, resolves cleanly under Gitea Actions) Operator side: ANDROID_KEY_ALIAS, ANDROID_KEYSTORE_PASSWORD, and ANDROID_KEYSTORE_B64 secrets registered in Gitea before this lands. |