check-rust.yml ran cargo check and cargo test without --locked: a
Cargo.lock out of step with Cargo.toml was rewritten in the job's
checkout, and the suppression guard, the windows-sys guard and cargo
audit then read the rewritten lockfile instead of the committed one.
Both now pass --locked, and the windows-sys guard comment says the
lockfile it reads is the committed one.
release.yml built the shipped binaries the same way. Both npx tauri
build calls now end with `-- --locked`, which the Tauri CLI hands to its
runner (cargo, or cargo-xwin for Windows, which passes it to cargo
build).
cargo-xwin, the runner of the Windows build, runs with the updater
signing key in its environment and was installed at whatever version
crates.io served on the day of the tag. It is pinned at 0.23.1, the
version the v0.17.2 release installed (run 570), and its version is
printed in the job log.
Refs #449
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow-ups of the review of PR #418.
- check-latest-json.jq wants exactly one document and release.yml calls it
with -s: under jq 1.6, the release container's, an empty file passed the
check (no output, status 0) and two documents were judged on the last one,
so the job would have deleted the published manifest and uploaded the bad
one. Two tests cover both cases.
- build-latest-json.test.mjs runs the text of release.yml's "Publish
latest.json to package registry" step against a fake curl: DELETE then PUT
on a valid manifest, exit 1 and no request on a refused one.
- check-frontend no longer ignores .claude/** and release.yml (decision of
Max): the test reads verify-release.sh and runs the Publish step, so "on
every pull request" holds. REVIEW.md, CLAUDE.md and architecture.md follow.
- release.yml: stale ".deb fallback" comment fixed.
- qa-update-cycle.md: a tauri dev build on Linux shows TargetsNotFound,
expected since #418.
Refs #461Resolves#419
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-ups of PR #416. The check that release.yml runs before
deleting the published manifest moves from an inline jq program to
scripts/check-latest-json.jq, which release.yml applies with
`jq -e --arg version ... -f`. scripts/build-latest-json.test.mjs now runs
that same filter on every pull request: on the script's output, on a
wrong version, on nine broken manifests and on the shape published up to
v0.17.1. It also compares the key lists of the script, of the filter and
of verify-release.sh, so a list left behind shows before the tag.
Two new cases pin the version argument: 0.18.0 must come out as 0.18.0
(the other fixtures pass 0.17.1, the version the bundle names carry, so a
script that ignored its argument passed them all), and an empty version
must fail. Both mutations survived the review's pass.
No change to what the manifest holds: still four keys.
Refs #320
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
latest.json only had linux-x86_64, built from the .deb. An .rpm install
looks up linux-x86_64-rpm first, then fell back on linux-x86_64,
downloaded the .deb and refused it (InvalidUpdaterFormat).
- scripts/build-latest-json.sh writes linux-x86_64-deb,
linux-x86_64-rpm, linux-x86_64 (the .deb, as a fallback) and
windows-x86_64 from the release assets. It fails unless it finds
exactly one .deb, one .rpm and one -setup.exe, each with a non-empty
.sig. The JSON comes from jq alone, notes read with --rawfile, file
names encoded with @uri like the upload step.
- scripts/build-latest-json.test.mjs (vitest) runs it under
bash -e -o pipefail on a temporary assets dir; check-frontend
installs jq.
- release.yml calls the script, writes the notes output under a random
delimiter, checks the manifest with jq before the registry DELETE,
and names the .rpm instead of an AppImage in the release notes.
- verify-release.sh requires the four keys, the extension of each URL
and the minisign file: of each signature, and exits 1 on any failure.
- Docs: release skill, qa-update-cycle section 3 (rpm procedure, keys,
reason and removal condition of the fallback), architecture, README,
CHANGELOG, STATE.
Resolves#320
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Node 20 reached end of life on 2026-04-30. check-frontend.yml, audit.yml
and release.yml now install Node.js 24 through NodeSource's setup_24.x,
as check-rust.yml has done since #375. Each step still prints
`node --version` in the job log.
The concurrency comment of check-rust.yml claimed the key cancels
obsolete runs on force-push. la-compagnie-maximus docs/forgejo-ops.md
measured the opposite on Forgejo 8.0.3: no pull_request run was
cancelled by a later one, and push runs are cancelled without the key.
The comment now states that measurement; the keys stay (harmless,
meaningful where honoured), and check-frontend.yml and audit.yml point
to it.
release.yml names the trust it places in NodeSource: the script runs as
root in the job container, whose Node.js then runs `npx tauri build`
with TAURI_SIGNING_PRIVATE_KEY. Kept on purpose, also documented in
docs/architecture.md, whose release.yml section described two jobs
(windows-latest, ubuntu-22.04) where there is one containerised job
cross-compiling Windows with cargo-xwin.
release.yml only runs on a tag, so Node 24 there is proven at the next
release: the /release skill now reads `node --version` from the release
run's log (step 9), and STATE.md lists it under the checks due at the
next release.
No CHANGELOG entry: CI only.
Resolves#376
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The new token_store module (#78) depends on `sync-secret-service` via
`dbus-secret-service`, which in turn links to libdbus-1 at build time
through the `dbus` crate. Add `libdbus-1-dev` to:
- `check.yml` rust job (alongside the existing webkit/appindicator
system deps), so every PR run compiles the keyring backend.
- `release.yml` Linux deps step, so tagged builds link correctly.
Runtime requires `libdbus-1-3`, which is present on every desktop
Linux distro by default, so `.deb` / `.rpm` depends stay unchanged.
Also add a non-blocking `cargo audit` step to check.yml to surface
advisories across the transitive dep graph (zbus, dbus-secret-service,
etc.) without failing unrelated PRs.
Drop `appimage` from `bundle.targets` in tauri.conf.json: the release
workflow explicitly builds `--bundles deb,rpm` so AppImage was never
shipped, and its presence in the config risks a silent fallback to
plaintext token storage for anyone running `tauri build` locally
without libsecret/libdbus bundled into the AppImage. No behaviour
change for CI; follow-up to re-enable AppImage properly would need a
linuxdeploy workflow that bundles the backend.
Refs #66
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create CHANGELOG.fr.md with full French translation of all versions
- Add ChangelogPage (/changelog) accessible from Settings
- Replace hardcoded i18n release notes with file-based approach:
loads CHANGELOG.md or CHANGELOG.fr.md based on user language
- CI copies changelogs to public/ during release build
- Update CLAUDE.md with bilingual changelog deployment process (fixes#10)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The automatic GITHUB_TOKEN does not have package permissions in Forgejo.
Use a dedicated PACKAGE_TOKEN secret with the package scope instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The DELETE endpoint for Forgejo generic packages is /api/v1/packages/
while the upload (PUT) endpoint is /api/packages/. Using the wrong
endpoint caused silent failures, leaving stale latest.json in the
registry. Also fail the CI step explicitly on upload failure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Forgejo generic package API uses /api/packages/ not /api/v1/packages/
for both upload and deletion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents "Release has no Tag" error when re-running a build for
a tag that already has a release.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The DELETE was using the upload URL instead of the API v1 package
endpoint, so old versions were never actually deleted, causing 409
on re-upload and leaving stale latest.json.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The ${{ steps.changelog.outputs.notes }} expression was being interpolated
directly into shell commands, causing parse errors when the changelog
contained special characters, markdown, or backticks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix updater: strip v-prefix from version in latest.json, and delete
old package before re-uploading to avoid 409 conflicts.
Add frontend log capture (console intercept) with a log viewer card
in the settings page (filterable, copyable, clearable).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
linuxdeploy cannot run inside Docker containers even with
APPIMAGE_EXTRACT_AND_RUN. Use --bundles deb,rpm instead.
Update latest.json to use .deb for linux-x86_64 platform.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
linuxdeploy needs FUSE which is unavailable in containers.
This env var makes it extract instead of mounting.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Docker container steps don't share shell state. Set PATH at job level
to include /root/.cargo/bin and remove per-step source cargo/env.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Forgejo runner's default image uses glibc 2.39, which produces
binaries incompatible with Pop!_OS / Ubuntu 22.04 (glibc 2.35).
Build inside container: ubuntu:22.04 with Node.js and Rust installed.
Bump to v0.4.4.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Forgejo has no /releases/latest/download/ route (GitHub-specific)
- Upload latest.json to generic package registry for a stable endpoint
- Fix Linux signature collection: use .AppImage.sig (not .tar.gz.sig)
- Collect all platform signatures (.deb.sig, .rpm.sig, .AppImage.sig)
- Bump to v0.4.3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tauri CLI filters --bundles values by host OS. The nsis target is already
configured in tauri.conf.json and auto-selected for Windows targets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Windows cross-compile (cargo-xwin) to Forgejo CI workflow
- Add libsqlite3-sys bundled for cross-compile compatibility
- Switch updater endpoint from GitHub to self-hosted Forgejo
- Collect Windows NSIS assets and include windows-x86_64 in latest.json
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tauri requires TAURI_SIGNING_PRIVATE_KEY_PASSWORD to be defined,
even when the key has no password.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace dtolnay/rust-toolchain, actions/setup-node, and swatinem/rust-cache
with shell commands since they are not mirrored on code.forgejo.org.
Use https://github.com/ prefix for checkout action.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add .forgejo/workflows/release.yml for Forgejo Actions
- Update signing pubkey for new key pair
- Sync Cargo.toml version to 0.4.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>