Skip to content

SOW v0.5.0

Latest

Choose a tag to compare

@github-actions github-actions released this 29 Sep 07:14

SOW 0.5.0 makes SOW practical for existing flat YUM repositories and closes the integrity,
recovery, and publication findings of a full pre-release review. The main addition is
sow create --metadata-timestamp SECONDS: a publisher can keep a valid, nondecreasing
publication time when replacing another metadata generator, including repositories served
to EL7 YUM clients.

The sow/v3 configuration and the public pool/ + dists/ layout do not change.

Full release notes: English · 中文

⚠️ Upgrading a 0.3 or 0.4 Managed workspace requires an explicit migration

Stop all Workspace writers and back up the whole Workspace with a tool that preserves hard
links: DEB by-hash entries are hard links, and macOS cp -a does not keep them (use GNU
cp -a, rsync -aH, or tar). Install 0.5.0, then migrate each Repository before any
ordinary read or write:

sow repo migrate REPOSITORY -C /srv/sow   # reports schema=12->13
sow build -r REPOSITORY -C /srv/sow
sow check -r REPOSITORY -C /srv/sow

Schema v13 indexes candidate pool paths, so add no longer scans unrelated publication
history. The updated RPM authentication and APT metadata contracts require one rebuild of
affected Dists; afterwards, unchanged RPMs reuse matching Built evidence. Until a Repository
is migrated, its write commands exit 5 and name the command to run. The transition is
one-way: do not reopen a migrated database with an older binary.

Highlights

Publication time for existing YUM repositories. create --metadata-timestamp writes an
explicit time to the three RPM repomd.xml data records. The default stays 0, so output
remains reproducible; package bytes, compressed XML, and DEB indexes are unaffected. SOW does
not read the wall clock for you, and the publisher still signs the new repomd.xml. The
YUM migration guide covers the
surrounding maintenance flow.

Safer mutations. Incompatible signing policies and colliding pool paths are rejected
before Desired state commits. Pool paths are compared case-insensitively, even for identical
bytes, and case-insensitive workspaces and filesystem targets also reject source directories
that differ only by case. Historical Dist-removal cleanup no longer deletes a package that was
re-added to another Dist.

Publication integrity. Payload URLs are reserved against local and historical publication
identities, and no backend ever overwrites an immutable payload. Local gc ignores inventory
entries that exist only remotely, such as payloads kept by report-only R2 maintenance. R2
target GC remains report-only; do not delete reported objects by hand, because the next
publish requires the remote prefix to match its recorded inventory exactly.

Recovery and interruption. Ctrl-C (SIGINT) and SIGTERM return 130 only for the
command's own interruption; a failed operation is recorded before its temporary package bytes
are removed, and the next write command finishes any cleanup that exceeded its budget.
Interrupted v0.4.0 operations, including adds that omitted a non-empty, fully excluded Dist,
now have bounded recovery paths.

Signing. New GPG metadata signatures use SHA-256 regardless of local preferences, and new
builds require a currently usable metadata key. Agent signing freezes GnuPG time, including
for a signature made within the current second, and pins the actual usable subkey. APT
verification accepts GnuPG's final-newline convention without relaxing content binding.

Toolchain and packaging

Building from source now requires Go 1.27.1; the dependency graph uses x/crypto v0.56.0
and the release workflows pin GoReleaser v2.18.2. Archives, RPMs, and DEBs now ship
THIRD_PARTY_NOTICES generated from all four release package graphs. Source govulncheck
on the release commit reports no reachable vulnerabilities; the required x/crypto module still
carries advisory GO-2026-5932 (no fixed version yet), whose affected package SOW does not
import, so scans of stripped binaries can still report the module.

The S3-compatible integration test now runs against a digest-pinned
pgsty/silo image, the MinIO-compatible object store
maintained by PGSTY, because the upstream minio/minio image is no longer available on
Docker Hub.

RPM format v6 signatures are not supported in 0.5.0; use RPM format v4 packages for
package-signing workflows.

Verification

The release commit passed the full Go suite, race tests, vet, staticcheck, dead-code
reachability, vulnerability and RPM-fork provenance checks, clean source delivery, archive and
package verification in CI, and repository-client and S3-compatible publication tests in
Integration.

The release set contains four Linux/macOS archives (amd64, arm64), two RPMs, two DEBs, and
SHA256SUMS. Every archive contains sow, README.md, CHANGELOG.md, LICENSE, and
THIRD_PARTY_NOTICES. Platform-specific install commands are on the
download page.

Changelog

  • 4045dd30 update project readme with more info
  • 2c3ecf39 chore: consolidate documentation and QA layout
  • d4aabb72 fix(create): support YUM metadata publication timestamps
  • b2c71721 build: require Go 1.27.1 and x/crypto v0.56.0
  • 267894e9 build: ship third-party license notices and pin GoReleaser
  • 8df8e180 fix: resolve v0.5.0 pre-release review findings
  • 9c299061 fix(path): tolerate concurrent read-locked hardlinks during authentication (J5-r4-1, J5-pre-1)
  • 79f1f83c fix(state): reject case-variant spellings of known pool paths even for identical bytes (C2-r4-1)
  • 5a9514a0 fix(gc): skip remote-only inventory roots without local objects (C2-r4-5)
  • dc2d72bd fix(cli): map exit 130 only to the command's own cancellation (E16-r4-1)
  • e8cd88bb fix(check): treat any terminal operation's stage tail as cleanup (A2-r4-1)
  • c78eafb8 fix(signing): wait until GnuPG can freeze the current-second signing time (C12-r4-1)
  • 103ffde0 fix(recovery): finish v0.4.0 applied adds that omitted a non-empty excluded Dist (B2-r4-1)
  • e89ee5ab fix(schema): report an old schema as migration required and point to repo migrate (E4-r4-2)
  • 4a41e3b7 perf(add): query pool path owners only for new coordinates (C2-r4-3)
  • 0aa4ffdb fix(add): reject source-directory case aliases on case-insensitive workspaces (B23-r4-1)
  • 6825dc37 fix(publish): refuse case aliases before an attempt on case-insensitive filesystem targets (C2-r4-2); report cancellation instead of digest mismatch
  • 0cf672ce fix(cli): strip exactly one optional 0x/0X signing key prefix (I6-r4-1)
  • bae9e173 fix(r2): reject non-regular credential files without blocking (C8)
  • 7d453f87 fix(add): tell the user the next write finishes interrupted cleanup (A3-r4-1)
  • 75b91f67 feat(migrate): report schema before and after an explicit migration (E4-r4-1)
  • 500039fe fix(lock): classify a symlinked lock parent as integrity without a nil wrap (LOCK-pre)
  • c65754a0 fix: reject abort without an attempt, hint at case-alias exits, avoid duplicate cancellation text
  • 7fe0b88d chore(release): prepare v0.5.0
  • c41aba47 test(r2): replace the withdrawn MinIO fixture with pinned PGSTY Silo

Full Changelog: v0.4.0...v0.5.0