267 Commits
Author SHA1 Message Date
FredApps 5b4eeb2323 fix(freebsd): fail closed if the aarch64 job has no CARGO_BUILD_TARGET
The 15 November scheduled dry-run wrote x86_64 archives in the aarch64
job because an unset PKG_CONFIG_PATH in the cross env heredoc left
CARGO_BUILD_TARGET unset, and FreeBSD sh did not abort. #242 already
stops the heredoc from expanding that unset variable. This checks that
the env file actually exported the target, and that the build and
package steps still have it, so a similar miss fails before packaging.
2026-11-15 12:17:00 +01:00
FredApps 78c3c88191 Merge pull request #234 from storytold/fix/cut-release-minor-bump
cut_release: a minor bump follows stale path versions and versioned lock names
2026-11-15 11:24:50 +01:00
Dylan M. Taylor c8f4b6ec2a fix(freebsd): include shared pkgconfig metadata in aarch64 sysroot (#247)
* fix(freebsd): include share pkgconfig in cross sysroot

* test(freebsd): cover share pkgconfig sysroot paths
2026-11-14 23:03:20 -05:00
Dylan M. Taylor 831527c68a fix(freebsd): include X11 protocol metadata in sysroot (#245) 2026-11-14 22:20:46 -05:00
skylar taylor-barrick 2537691a6b ci: share dependency-cache keys and read-only restores (#240)
* ci: share the gate dependency-cache key and read-only restores

* fix(rust-cache): compare cache directories, not their spelling

A Windows runner spells one directory two ways: git-bash reports $HOME/.cargo as
/c/Users/x/.cargo, and a native tool or workflow input passes C:\Users\x\.cargo. The
align-environment guard compared the strings, so the first Windows caller copying the
README example exited 1 with "sets ...; drop the input". It now resolves both sides when
they exist and otherwise normalises backslashes, a drive letter and its case before
comparing. Refusing a genuinely different cargo home is unchanged.

Regressions cover both Windows spellings, a trailing separator, a drive letter in either
case, two different Windows homes, and a symlinked home that resolves to $HOME/.cargo;
the five positive cases fail against the previous guard.
2026-11-14 21:01:18 -06:00
Dylan M. Taylor b85a0310a6 fix(freebsd): avoid unset variable in cross env heredoc (#242) 2026-11-14 21:35:17 -05:00
Dylan M. Taylor dd7fa77557 Merge pull request #241 from storytold/codex/sonar-rust-test-threads
ci: expose Rust test thread limit for single-job coverage
2026-11-14 19:51:30 -05:00
Dylan M. Taylor f6621c2036 test: cover optional coverage thread limit 2026-11-15 00:47:01 +00:00
Dylan M. Taylor c2d9913691 ci: apply test thread limit to coverage run 2026-11-15 00:41:04 +00:00
Dylan M. Taylor 72d2fbfb3d ci: allow limiting unsharded Rust test threads 2026-11-15 00:34:08 +00:00
Dylan M. Taylor a3f9743cb2 Merge pull request #239 from storytold/fix/freebsd-aarch64-pkgconfig
fix(freebsd): validate aarch64 pkg-config paths
2026-11-14 18:27:38 -05:00
Dylan M. Taylor 0ed80a2122 fix(freebsd): validate aarch64 pkg-config paths 2026-11-14 23:23:30 +00:00
Dylan M. Taylor 9aeb563e3f Merge pull request #238 from storytold/fix/freebsd-aarch64-sysroot
fix(freebsd): extract packages into the aarch64 sysroot
2026-11-14 18:15:57 -05:00
Dylan M. Taylor d0e829bfdb fix(freebsd): extract linked packages into aarch64 sysroot 2026-11-14 23:08:28 +00:00
Dylan M. Taylor 6c02f8de2a ci(freebsd): install WebKitGTK and libsoup dependencies (#237)
* ci(freebsd): install WebKitGTK and libsoup dependencies

* fix(freebsd): install WebKitGTK in release workflow
2026-11-14 17:58:48 -05:00
FredApps ce7c74f743 cut_release: a minor bump follows stale path versions and versioned lock names
Two apps stopped at the lock check on a minor release. pdfcraft names its
crates at 0.21.0 beside a 0.21.1 workspace, so the path dependencies were
not bumped. vectorcraft has its own crates from an older git revision in
the graph, so Cargo.lock names the version in dependency lists.
2026-11-14 21:49:43 +01:00
FredApps 9f9f16987c ci: never cancel a running main-branch Sonar scan (#151)
* ci: preserve every main-branch Sonar scan

* ci: never cancel a running main Sonar scan, as the app repos do

Per-run concurrency groups let main scans run side by side, so an older
commit's analysis can reach SonarCloud after a newer one. Keep one group
per ref and only stop cancelling on main, matching every app repo's
sonarcloud.yml.
2026-11-14 21:38:10 +01:00
FredApps f76646c68b Merge pull request #198 from storytold/ci/opt-in-sccache
gate: opt-in sccache; sonarcloud: free disk space in the background in the archive build
2026-11-13 22:08:20 +01:00
FredApps debd222436 Merge pull request #155 from storytold/fix/house-rules-preserve-local-text
Preserve local instructions when updating house rules
2026-11-13 21:24:00 +01:00
FredApps 13ad478f3b fix(house-rules): preserve BOM and fenced marker examples 2026-11-13 21:18:10 +01:00
FredApps 82834fe754 Merge pull request #105 from FredApps/fix/shared-appimage-cli-check
Run AppImage CLI regression checks in shared packaging lint
2026-11-13 21:10:46 +01:00
FredApps cb96afc6e2 Merge pull request #229 from storytold/sonarcloud/bin-exe-paths
sonarcloud: let shard tests find workspace binaries by their build path
2026-11-13 21:10:36 +01:00
FredApps 4cb15cb9f4 Merge branch 'main' into fix/shared-appimage-cli-check
# Conflicts:
#	.github/workflows/test-freebsd.yml
2026-11-13 20:46:50 +01:00
FredApps bc67c8a00c Merge branch 'main' into ci/opt-in-sccache
# Conflicts:
#	.github/workflows/gate.yml
#	README.md
2026-11-13 20:46:39 +01:00
FredApps ce1d914f7c Merge branch 'main' into fix/house-rules-preserve-local-text 2026-11-13 20:42:47 +01:00
Dylan M. Taylor 5008f8cd1b Merge pull request #230 from storytold/fix/sonar-prefetch-locked
fix(sonar): prefetch locked dependencies before unsharded coverage
2026-11-13 09:56:04 -05:00
Dylan M. Taylor 7e30ba4fdf fix(sonar): prefetch locked test dependencies 2026-11-13 14:50:09 +00:00
FredApps 00db6e35c0 sonarcloud: let shard tests find workspace binaries by their build path
Tests that run a workspace binary through env!("CARGO_BIN_EXE_<name>")
hold the build job's absolute target path. nextest extracts the archive
to a temporary directory, so in every coverage shard those tests failed
with "No such file or directory" while the gate passed them. Since #222
made shard test failures fail the scan, that turned SonarCloud red on
designcraft, cadcraft, pdfcraft and wordcraft main.

The build job now records cargo's target directory next to the archive.
Each shard extracts the archive to a known directory and links the
recorded path to it before running its partition.
2026-11-13 15:24:29 +01:00
FredApps 7d19a7f5e4 release.yml: a publish input publishes a complete draft at the end of the run (#209)
* release.yml: a publish input publishes a complete draft at the end of the run

Part E of the faster-release plan: no one waits by the run to publish. Only on the release
branch, not in a dry run, only when no build job failed (the job already requires that) or was
cancelled, and only when the draft has at least as many assets as the last published release, so
a skipped build job can't publish an incomplete release. Off by default; apps opt in.

* publish: compare with the most recently published release, and say why in the summary

gh release list orders by creation, so the newest-created release was the baseline; an older
draft published later would have been missed. Every refusal now also writes its reason to the
job summary, not only an error annotation.

* tests: publish doesn't change the FreeBSD build, so it stays out of the cache key
2026-11-13 14:09:41 +01:00
Dylan M. Taylor ea24c9c24e Merge pull request #228 from storytold/fix/sonar-craft-i18n-setup
fix(sonar): fail after Rust coverage generation errors
2026-11-13 08:02:40 -05:00
Dylan M. Taylor 174ac23ed6 fix(sonar): fail on instrumented Rust test errors 2026-11-13 12:57:30 +00:00
Dylan M. Taylor 6a0e2fae07 fix(sonar): fail after coverage generation errors 2026-11-13 12:51:55 +00:00
FredAppsandFredApps 20ebee3cb1 fix(ci): provide pinned translations to coverage tests (#227)
* fix(ci): provide pinned translations to coverage tests

* fix(ci): keep translation checkout out of scan

---------

Co-authored-by: FredApps <FredApps@users.noreply.github.com>
2026-11-13 00:33:06 -05:00
6854e6fb87 ci: show coverage test failures in shard summaries (#177)
Co-authored-by: skylartaylor <skylartaylor@users.noreply.github.com>
Co-authored-by: Dylan M. Taylor <dylan@dylanmtaylor.com>
2026-11-12 22:03:24 -05:00
FredApps 3eaa8798ac release_train: --logs is a relative folder inside the current directory (#214)
Closes SonarCloud's path-injection alert on the merged release_train.py (pythonsecurity:S8707):
an absolute path, .., or anything outside the working directory is refused before the folder is
made.
2026-11-12 21:52:12 -05:00
Dylan M. Taylor fd88e26a87 feat(gate): support caller setup commands (#224) 2026-11-12 21:51:38 -05:00
FredApps 804f702057 fix(sonar): surface archived Rust test failures after analysis (#222)
* fix(sonar): report archived Rust test failures after scanning

* test(sonar): cover shard status production and document result semantics
2026-11-12 23:38:33 +01:00
FredApps 293de72429 release.yml: a FreeBSD cache a later release can restore, with the aarch64 cross output (#216)
The release FreeBSD jobs keyed their Cargo cache on toJSON(inputs), and
contributors-artifact is contributor-snapshot-<run id>-<attempt>, so every run
wrote an entry no other run could restore: on 11 Nov every release built FreeBSD
cold. The key now holds only the inputs that change the FreeBSD build (app name,
architecture, craft-fonts ref, FreeBSD release); dry-run is left out too, so a dry
run warms the cache a release restores. A test makes every new input pick a side.

The aarch64 job cross-compiles, and Cargo writes that output to
target/aarch64-unknown-freebsd/release, which the cache action never saved: only
the host build scripts in target/release were kept. The action takes the triple as
a new target input and saves and restores that directory too.
2026-11-12 07:25:29 +01:00
FredApps 17eb0f0717 release.yml: build Windows arm64 natively on the windows-11-arm runner (#215) 2026-11-12 07:25:20 +01:00
Dylan M. Taylor 7eb307b465 egress: allow motd.ubuntu.com, esm.ubuntu.com and *.amazontrust.com:80 (#218)
Ubuntu's MOTD news and Ubuntu Pro (ESM) hooks reach motd.ubuntu.com and
esm.ubuntu.com; TLS revocation checks for Amazon-issued certificates go
to *.amazontrust.com over plain HTTP. Every Harden-Runner allow list now
names them.
2026-11-11 20:32:55 -05:00
FredApps 3951f6df01 sonarcloud: merge each shard's profiles before the scan downloads them (#210)
Each coverage shard now merges its own raw profiles into one sparse
.profdata with the archive toolchain's llvm-profdata and uploads only
that. The scan job merges the shard profiles instead of downloading
every raw profile beside the test archive, which on 11 Nov 2026 filled
the runner for vectorcraft (four ~7 GB zipped profraw artifacts).

A raw profile llvm-profdata cannot read, such as one cut short by a
test process that crashed while writing it (lightcraft, 11 Nov 2026),
now fails its shard with an error naming the file, instead of being
uploaded and failing the scan's merge.

Single-shard callers keep the cargo llvm-cov path unchanged.
2026-11-11 19:55:14 -05:00
Dylan M. Taylor ae29fbc6ec fix(sonarcloud): explicitly allow Ubuntu ESM HTTPS egress (#217) 2026-11-11 19:25:34 -05:00
FredApps 840a417e3d Release: scripts/cut_release.py cuts a release from green main without a bump pull request (#207)
* Release: scripts/cut_release.py cuts a release from green main without a bump pull request

On 11 Nov 2026 the release of 14 apps took most of the day. A large part went to version-bump pull
requests that changed only version strings yet waited on the full CI of a pull request (1-2 h of
FreeBSD, sharded SonarCloud coverage), and to rerunning it. The script commits the bump on the
newest main commit whose CI passed, merges it into release (which starts release.yml), opens the
same bump for main as its own pull request, and with --publish publishes the draft once the run
passed and has assets. Tests cover the bump: workspace and path-dependency versions, only the
workspace's own Cargo.lock entries, CRLF files, the repository hook.

* cut_release: review fixes

- A trailing comment after the workspace version stays; the value alone is replaced.
- Cargo.lock: only the workspace members' entries (cargo metadata --no-deps) change, not a local
  path dependency outside the workspace that shares the version.
- Cargo.lock is checked with a resolving cargo metadata --locked, on the bump, on release after
  the merge and on the sync branch; --no-deps never compared it with path dependency versions.
- --publish refuses a draft with fewer assets than the last release (a skipped build job leaves
  the run green), unless --allow-fewer-assets.
- The sync PR never moves main backwards: versions compare as numbers, and a main at or past the
  release gets none.
- A failed auto-merge says so, with the PR to merge by hand.
- Arguments that reach git or gh are checked first (owner/name, version, commit hash, workflow,
  title), so none can be read as an option. git, gh and cargo are required up front.

* Release: scripts/release_train.py releases many apps at once with cut_release.py

Every app in parallel, a log per app, and one summary line each (published, pushed, or stopped
and why); one app stopping doesn't stop the rest. Tested on figcraft and soundcraft with
--dry-run (both done in under a minute).

* tests: release_train options before -- in the test

* release_train: only owner/name repos and known cut_release.py options reach the subprocess
2026-11-11 23:02:43 +01:00
FredApps 603045e42d release.yml: a dry-run input builds and checks without releasing (#208)
* release.yml: a dry-run input builds and checks without releasing

For a nightly run on main that finds release-only breakage before release day. On 11 Nov 2026
gridcraft's riscv64 build, materialcraft's private-repo FreeBSD jobs, wordcraft's Print job and
the riscv64 apt mirrors each surfaced only during the release, one fix PR and release run at a
time. With dry-run: no job enters the release environment (no signing secrets; the environment
admits only the release branch), the macOS job and the draft are skipped, and the Flatpak OCI
layouts are not pushed to GHCR or Docker Hub.

* tests: the Flatpak OCI push and the release environment also stay out of a dry run
2026-11-11 22:46:06 +01:00
Dylan M. Taylor 15058dc71e ci: use StepSecurity's maintained actions (#206)
* ci: use StepSecurity's maintained actions

Each third-party action that StepSecurity publishes a secure drop-in
replacement for now uses that replacement, pinned to a commit with its
version as a comment. Versions follow what we used: the newest
StepSecurity release in the same major, or the closest major they
publish. dtolnay/rust-toolchain refs that named a toolchain (stable,
nightly, 1.76) become the replacement's `toolchain` input.

* tests: find the FreeBSD VM, SonarCloud scan and install-action steps by their StepSecurity names
2026-11-11 14:55:40 -05:00
Dylan M. Taylor 693c8dd084 sonarcloud: honour each repository's own sonar.cpd.exclusions (#205)
* sonarcloud: honour each repository's own sonar.cpd.exclusions

* sonarcloud: read sonar.cpd.exclusions with properties syntax and allow the ? wildcard
2026-11-11 14:42:26 -05:00
FredApps 5d42870ead apt: wait for cloud-init before rewriting the sources (#204)
During the ubuntu.com outage, cloud-init's apt_configure module (once per
instance, at boot) spent two 10-second DNS timeouts looking for a mirror
and then wrote ubuntu.sources from its template, after the job had
started. On those VMs configure-apt-mirrors had already pointed the
sources at its list: apt-get update fetched every index for that list,
cloud-init put the image's mirror list back, and apt-get install found
no indexes for it, so no Ubuntu package had a candidate (materialcraft's
Flatpak x86_64 job, the FreeBSD tests job on 26.04). A repro on 12
runners failed on 8, every round, and a file watcher caught cloud-init's
write landing mid-update.

wait-for-cloud-init.sh runs `cloud-init status --wait` (at most 300 s,
never failing the job) before configure-apt-mirrors and
install-riscv64-cross's select-mirrors.sh touch anything.
2026-11-11 17:57:29 +01:00
Dylan M. Taylor 95e8d67389 egress: allow *.kernel.org and *.dotsrc.org wherever apt mirrors are allowed (#203)
Block-mode Harden-Runner still flagged apt's lookups under these zones
(_https._tcp.mirrors.edge.kernel.org, _https._tcp.mirrors.dotsrc.org),
and apt failures are breaking CI across the org. Allow the whole zones on
443 next to the existing mirror hosts.
2026-11-11 11:20:38 -05:00
FredApps 3f541b8904 install-riscv64-cross: fall back to mirrors outside ubuntu.com (#202)
The release builds' Linux riscv64 job read amd64 from archive and
security.ubuntu.com and riscv64 from ports.ubuntu.com only. With no
ubuntu.com name resolving on the runners, apt spent 3m20s on failed
lookups and then found no libc6-dev:riscv64, so every app's release
failed there.

select-mirrors.sh now chooses one pair of mirrors for both architectures:
Ubuntu's own, then dotsrc (it carries both trees), then kernel.org with
TU Chemnitz's ports. It takes the first pair whose amd64 and riscv64
InRelease files answer for every suite with the same Date (Ubuntu signs
one Release for archive and ports), so Multi-Arch: same packages still
match. The image's own Ubuntu sources are disabled in that job: they
only added a second, lagging snapshot and, during the outage, the stall.

The riscv64 job runs Harden-Runner in audit mode, so release.yml needs
no allowlist change.
2026-11-11 17:01:34 +01:00
FredApps 0817d766c4 test-freebsd: show apt's view and the CPU when the package install fails (#201)
One run on 11 Nov 2026 found no candidate for tcsh or debsigs right after
an update that fetched every index from kernel.org; the runs before and
after it, under the same ubuntu.com outage, passed. Print apt-cache policy,
the architecture settings, the universe index files and whether the CPU
supports x86-64-v3, so the next failure shows the cause.
2026-11-11 16:36:11 +01:00