Commit graph

15 commits

Author SHA1 Message Date
Bryan Helmkamp
e9bccbcc1c
ci: re-enable scheduled nightly release 2026-06-25 08:34:43 -04:00
Bryan Helmkamp
bbce4c7a2f
ci: disable scheduled nightly release 2026-06-10 10:12:56 -04:00
Bryan Helmkamp
b5de404354
ci: lock Cargo resolution and fix cancellation flake (#461)
Some checks failed
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
TypeScript / Typecheck (push) Has been cancelled
TypeScript / Test (push) Has been cancelled
TypeScript / Build (push) Has been cancelled
## Summary

Enforce Cargo lockfile use across CI and release automation so jobs fail
on stale `Cargo.lock` state instead of resolving dependencies
implicitly. This adds `--locked` to Rust CI, release builds/tests,
nightly release tagging, the TypeScript workflow's embedded Rust build,
and helper-owned Cargo calls in `fabro-dev`.

This also fixes the Linux CI flake exposed by the PR: canceling a
durably blocked in-process run could take the abort path while the
workflow was still unwinding a human-input gate, causing
`run.failed(cancelled)` to be followed by `run.unblocked`. That invalid
event order broke projection rebuilds and made `GET /runs/{id}` return
404. Cancellation now uses the durable lifecycle status when selecting
the in-process blocked-run path, so the pending interview is cancelled
before the terminal event is emitted.

The release command's intentional `cargo update --workspace` step is
unchanged, because that step updates `Cargo.lock` after bumping the
workspace version.

## Testing

- `cargo nextest run --locked -p fabro-dev --features dev -E
'test(dry_run_computes_stable_version_from_date) |
test(dry_run_prints_equivalent_build_commands)'`
- `cargo --locked dev release --dry-run --skip-tests --release-date
2026-01-01`
- `cargo --locked dev docs check`
- `cargo nextest run --locked -p fabro-server --features test-support
cancel_durably_blocked_in_process_run_cancels_pending_interview_without_abort_signal
--status-level fail --final-status-level fail --show-progress none`
- `cargo nextest run --locked -p fabro-server --features test-support
--test it scenario::lifecycle --profile ci --status-level fail
--final-status-level fail --show-progress none --no-fail-fast`
- Linux Docker stress reproduction: `cargo nextest run --locked -p
fabro-server --features test-support --test it
scenario::lifecycle::full_http_lifecycle_cancel --profile ci
--stress-count 200 --status-level fail --final-status-level fail
--show-progress none`
- `cargo +nightly-2026-04-14 fmt --check --all`
- `cargo +nightly-2026-04-14 clippy --locked -p fabro-dev --features dev
--all-targets -- -D warnings`
- `cargo +nightly-2026-04-14 clippy --locked -p fabro-server --features
test-support --all-targets -- -D warnings`
- `git diff --check`

Full `cargo nextest run --locked -p fabro-dev --features dev` currently
has two unrelated policy-test failures:
`policy::catalog_builtin_references_stay_in_allowlist` and
`policy::workflow_template_rendering_call_sites_stay_in_allowlist`.

---

[![Compound
Engineering](https://img.shields.io/badge/Compound_Engineering-6366f1)](https://github.com/EveryInc/compound-engineering-plugin)
🤖 Generated with GPT-5 via [Codex](https://openai.com/codex)

---------

Co-authored-by: Release Repro <release-repro@example.com>
2026-05-30 15:07:41 -04:00
Bryan Helmkamp
d37f75a878
feat(dev): group cargo dev spa and docs commands 2026-04-25 19:40:59 -04:00
Bryan Helmkamp
5e28ec0f82
Merge remote-tracking branch 'origin/main'
# Conflicts:
#	.github/workflows/nightly.yml
#	bin/dev/release.sh
2026-04-24 17:04:55 -04:00
Bryan Helmkamp
a03c689a44
feat(dev): port release automation 2026-04-24 16:00:25 -04:00
Bryan Helmkamp
db071953c0
ci: isolate nightly release test credentials 2026-04-24 15:08:51 -04:00
Bryan Helmkamp
c8b807f303
ci: freeze bun lockfile and widen typescript path filter
Prevents silent bun.lock drift across CI runs (root cause of the
nightly fabro-spa staleness failure) and re-runs typescript.yml when
nightly.yml itself changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 07:32:24 -04:00
Bryan Helmkamp
231faa6cc9
ci(nightly): use client-id for create-github-app-token
v3.1.0+ of actions/create-github-app-token deprecates `app-id` in
favor of the GitHub App's Client ID. Reads from the new
FABRO_RELEASES_APP_CLIENT_ID variable in the nightly environment.
2026-04-18 12:36:23 -04:00
Bryan Helmkamp
cce8a22269
ci: install Rust via dtolnay/rust-toolchain on arm64 runners
Release run 24607436574 failed on both aarch64 Linux compiles with
"rustup: command not found" — the ubuntu-*-arm-32-cores runner images
don't ship with rustup preinstalled, while the x86_64 variants do. Our
rust.yml and typescript.yml already use dtolnay/rust-toolchain@stable;
switch release.yml and nightly.yml to the same action so rustup is
bootstrapped regardless of runner image. Targets are passed via the
action's `targets:` input instead of a manual `rustup target add`.
2026-04-18 11:40:05 -04:00
Bryan Helmkamp
0c35a998ab
ci(nightly): run Tag nightly on 32-core runner
Matches the faster runner release.yml already uses for release-mode
nextest + build work, cutting Tag nightly wall time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 10:54:22 -04:00
Bryan Helmkamp
c1554ba2bd
ci(nightly): upgrade create-github-app-token to v3.1.1
v2.2.2 runs on Node.js 20, which GitHub is forcing to Node.js 24 on
June 2, 2026 and removing entirely on September 16, 2026. Bump to
v3.1.1 which runs on Node.js 24. The `app-id`/`private-key` inputs we
use are unchanged (`app-id` is deprecated in favor of `client-id`, but
still accepted).
2026-04-18 10:09:00 -04:00
Bryan Helmkamp
31fa23eb6a
chore(ci): default workflows to no permissions
Start every workflow with permissions: {} and grant the minimum
required per job, following Astral's defense-in-depth pattern so a
newly added job can't silently inherit repo read access.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 01:30:43 -04:00
Bryan Helmkamp
d52e6829c2
feat(docker): publish multi-arch server image to GHCR
Replace the docker/Dockerfile-based api+web compose setup with a
single root Dockerfile that runs the fabro server with the embedded
web UI on port 80, persists state under /storage, and drops to a
non-root fabro user with CAP_NET_BIND_SERVICE.

The release workflow stages the prebuilt Linux binaries from the
compile job into a buildx context and publishes multi-arch images
to ghcr.io/fabro-sh/fabro as :<version> (always), :latest (stable
tags only), and :nightly (nightly tags only).

Also address zizmor findings in nightly.yml (pinned
create-github-app-token, persist-credentials: false with explicit
remote URL setup) and release.yml (no-cache on tag-triggered
setup-bun to close the cache-poisoning path).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 19:39:10 -04:00
Bryan Helmkamp
d525071d14
feat(ci): add automated nightly release workflow
New .github/workflows/nightly.yml that fires daily at 09:00 UTC (plus
on-demand via workflow_dispatch) and runs bin/dev/release.sh nightly to
tag a fresh pre-release. Tag shape: v0.X.Y-nightly.N. Skips cleanly when
HEAD is already the commit referenced by the newest v*-nightly.* tag.

The job runs in the `nightly` environment, which scopes the
`FABRO_RELEASES_APP_PRIVATE_KEY` secret and `FABRO_RELEASES_APP_ID`
variable to just this workflow and restricts deployments to `main`.
`actions/create-github-app-token` mints an installation token on the
`Fabro Releases` GitHub App; that token authenticates both the checkout
(so the bump commit + tag can push back to main) and any downstream git
operations release.sh performs. Commits are attributed to
`fabro-releases[bot]`.

Pre-tag testing stays in release.sh's verify_release_tests, so a broken
main fails the nightly workflow before a dud version bump commit lands.
The tag push then triggers the existing release.yml, which publishes
the GH prerelease and updates Formula/fabro-nightly.rb in the tap.

Prerequisites (all done manually):
- GitHub App `Fabro Releases` installed on fabro + homebrew-tap
- `nightly` environment with the app credentials

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 11:48:34 -04:00