-
Notifications
You must be signed in to change notification settings - Fork 0
deployment
Active contributors: elwina
Capto ships as a Windows desktop app plus a landing site and API docs, all driven by GitHub Actions. CI and Release are deliberately separate: a green CI run only proves the tree builds and passes checks, it never publishes anything. Only a tagged Release produces installers, and only a push to main updates the site + docs. This page walks the pipelines, versioning, installer layout, FFmpeg supply chain, hosting, the in-app updater flow, and the release checklist. The canonical source is docs/CI.md; this page condenses it and maps the pieces to repo paths.
| Workflow | File | Trigger | What it does |
|---|---|---|---|
| CI | .github/workflows/ci.yml |
push / PR to main
|
Rust fmt + test --workspace + clippy (warn-only) + cargo build --timings (report uploaded as an artifact); frontend tsc + lint + format + jscpd + knip + bundle-size gate + real Vite build; cargo check for x64 + arm64; FFmpeg pin download with attestation; repo-hygiene and PII scans; agent package dry-runs; devcontainer build + smoke. |
| Release | .github/workflows/release.yml |
tag v* or manual |
NSIS installers for x64 + arm64 with embedded FFmpeg + CLI (cli\capto.exe); signed updater artifacts; mirrors latest.json onto a rolling updater tag; appends an auto-generated commit changelog. |
| Pages | .github/workflows/pages.yml |
push to main or manual |
Deploys one GitHub Pages artifact: website/ at the site root and workspace rustdoc under /docs/. This is the only workflow allowed to write the github-pages environment. |
| Droid review |
.github/workflows/droid.yml + .github/workflows/droid-review.yml
|
@droid mentions / PRs |
Factory Droid AI code + security review. Requires the FACTORY_API_KEY secret; not a required check, a missing key only skips these jobs. |
| CI alert | .github/workflows/ci-alert.yml |
workflow_run on CI/Release/Pages completion |
On a required workflow failure, opens (or bumps) a [build-health] GitHub issue with the failing run URL, turns red CI into tracked work with no external service. |
| CodeQL | .github/workflows/codeql.yml |
push/PR + weekly cron | Semantic JavaScript/TypeScript analysis (Rust support is still beta, so it is left out). |
| Secret scan | .github/workflows/secret-scan.yml |
push/PR | Gitleaks over full repo history; uploads redacted SARIF to the Security tab. |
The pipeline a commit and a tag travel is:
flowchart LR
A[push/PR to main] --> B[CI<br/>rust test+clippy+timings<br/>frontend gates<br/>x64+arm64 check<br/>FFmpeg pin+attestation]
B --> C{push to main?}
C -->|yes| D[Pages<br/>website + rustdoc once]
T[tag v* or manual] --> R[Release<br/>NSIS x64+arm64<br/>embedded FFmpeg+CLI]
R --> U[updater tag<br/>latest.json mirror]
R --> C2[CI alert / Droid<br/>on failure / on demand]
Because the CI and Release paths are separate, a merged PR or green CI never blocks a release, and a release never surprises maintainers by running day-to-day checks.
- Workspace version is 1.0.0 (
Cargo.toml). It is kept in lockstep withapps/desktop/src-tauri/tauri.conf.json,scripts/check-version-drift.ps1(run in CI hygiene) fails if the two drift. - Git tags
v1.*are stable;v0.*were treated as prerelease (prerelease: startsWith(github.ref_name, 'v0.')in.github/workflows/release.yml). - A rolling canary tag supports staged rollouts before stable users get an update (see Updates).
Custom NSIS templates:
-
apps/desktop/src-tauri/windows/installer.nsi, Tauri NSIS template fork. Fixes install to%LOCALAPPDATA%\Capto(no directory chooser, per-user /currentUserinstall mode) and keeps CLI/FFmpeg paths stable. -
apps/desktop/src-tauri/windows/hooks.nsh, wired viatauri.conf.json→bundle.windows.nsis.installerHooks. Adds$INSTDIR\clito the user PATH with the EnVar NSIS plugin (registry-based, noNSIS_MAX_STRLENtruncation, idempotent add, exact delete on uninstall). Onlycli\is added, never$INSTDIR, soCapto.execannot shadowcaptoon case-insensitive Windows.
What ships in the installer:
- The Tauri app executable, FFmpeg sidecar via
externalBin, resources, and the staged CLI. - The bundled CLI lives at
<install>\cli\capto.exeand is on PATH after install (open a new terminal and runcapto doctor). The CLI is not published as a separate Release asset, seeapps/desktop/src-tauri/binaries/README.md. - Start-menu shortcut, optional desktop shortcut, file associations, deep links, and an uninstaller with a delete-app-data option.
There is no MSI and no directory chooser: install location is fixed. The CLI stage step is cargo build -p capto-cli --release + scripts/copy-cli.ps1.
The encoder sidecar never comes from system PATH. It is downloaded only from elwina/capto-ffmpeg Releases, pinned in .github/capto-ffmpeg.env (currently CAPTO_FFMPEG_REPO=elwina/capto-ffmpeg, CAPTO_FFMPEG_TAG=v1.0.0-n9.0).
-
scripts/download-ffmpeg.ps1selects the asset by Rust target triple, verifies SHA-256 against the releaseSHA256SUMS, and (in CI/Release) runsgh attestation verify(Sigstore / Artifact Attestations) when-VerifyAttestationis passed. - It copies
ffmpeg-windows-x86_64.exe/ffmpeg-windows-aarch64.exetoapps/desktop/src-tauri/binaries/ffmpeg-<triple>.exefor TauriexternalBin, and writes acapto-ffmpeg.jsonmetadata file. -
apps/desktop/src-tauri/binaries/capto.exeis bundled as a Tauri resource (tauri.conf.json), so the CI check builds and stages the CLI beforecargo check.
Supply-chain trust is covered in Security.
| Display | Rust target | Installer | Bundled CLI |
|---|---|---|---|
| x64 | x86_64-pc-windows-msvc |
NSIS .exe
|
<install>\cli\capto.exe (+ user PATH) |
| arm64 | aarch64-pc-windows-msvc |
NSIS .exe
|
<install>\cli\capto.exe (+ user PATH) |
The *-windows-msvc strings are Rust target triples (Windows ABI); release names use x64 / arm64.
| Host | URL / path | Driver |
|---|---|---|
| GitHub Pages |
https://elwina.github.io/Capto/ (site root) + /docs/ (rustdoc) |
.github/workflows/pages.yml → deploy job (actions/deploy-pages) |
| Cloudflare Pages |
https://capto.elwina.work/ (primary) / capto.pages.dev
|
CF dashboard Git integration (no workflow, no API token secret) |
-
GitHub Pages deploys one artifact containing both the static
website/landing page (site root) andcargo doc --workspace --no-deps --exclude capto-appunder/docs/. It is the only workflow allowed to write thegithub-pagesenvironment (a comment inpages.ymlexplains why: two previous deployers were silently overwriting each other). -
Cloudflare Pages is dual-active for the same
website/. Because this is a monorepo, the CF project's Root directory must be set towebsite(otherwise CF deploys the whole repo as a static site). The custom domain CNAME (capto.elwina.work→capto.pages.dev) must be added in Tencent Cloud DNS whereelwina.worklives.
The in-app updater reads latest.json from endpoints in order (see Updates):
- Cloudflare Worker mirror,
https://capto-update-proxy.elwina-vardal.workers.dev/updates/latest.json(worker-first; free CDN edge, avoidsapi.github.comrate limits; see Updater mirror). - GitHub,
https://github.com/elwina/Capto/releases/download/updater/latest.json.
Each Release signs latest.json with minisign (TAURI_SIGNING_PRIVATE_KEY secret), and the publish-updater-manifest job mirrors it onto a rolling updater tag so the check URL never changes. For staged rollouts, publish to a canary tag, validate, then promote the same latest.json to updater.
- Run the hygiene gates:
scripts/scan-tech-debt.ps1,scripts/check-file-size.ps1,scripts/check-version-drift.ps1,scripts/scan-dead-flags.ps1. - Run the full test suites:
cargo test --workspaceandnpm test --prefix apps/desktop. - Bump the version in lockstep:
Cargo.tomlworkspace +apps/desktop/src-tauri/tauri.conf.json+package.json. - Tag
v*(v1.x= stable); push the tag. -
.github/workflows/release.ymlbuilds both NSIS installers, mirrorslatest.jsonto theupdatertag, and appends the changelog. - Verify the installers on a Windows box: install, confirm
<install>\cli\capto.exeis on PATH in a new terminal, and exercise the update path. - If a canary was used, promote it (publish the same
latest.jsonto theupdatertag) and remove the supersededcanarytag.
Aligned with Tauri's current pipeline docs and Node 24 runners: actions/checkout@v7, actions/setup-node@v6 with node-version: "24", tauri-apps/tauri-action@v1. Secret handling notes: GITHUB_TOKEN is used for attestation reads and release writes; FACTORY_API_KEY (Droid) and TAURI_SIGNING_PRIVATE_KEY / TAURI_SIGNING_PRIVATE_KEY_PASSWORD (updater) are Actions secrets and never committed.
-
Updates, signing, canary, and the
updater/canarytags. - Updater mirror, the Cloudflare Worker behind the worker-first endpoint.
- Security, trust boundaries, the sidecar supply chain, and repo defenses referenced throughout this page.
-
docs/CI.md, the canonical CI / release document this page summarizes.