SOW is a local RPM/DEB repository manager written in Go. SOW 0.3 supports two workflows:
sow createturns a directory of RPM or DEB packages into a simple repository. RPM packages can be signed with--sign-with/-S; adding--overwritedeliberately re-signs every RPM with that key.- Managed workspaces model repositories and distributions explicitly, retain Desired and Built state, publish immutable Generations, and provide bounded locking, recovery, validation, queries, change reports, and operation logs.
The authoritative user and design documentation lives at
sow.pgsty.com. The
design section describes the current
Repository-scoped single-payload model. Historical PRDs, review material,
migration programs, and dated evidence remain available from Git history and
version tags; they are not a second documentation authority. The remaining
docs/ tree only records this ownership boundary.
Go 1.26.5 or newer is required. Repository signing additionally requires a usable GPG installation and key.
make help
make build
make run ARGS=version
make test-core # focused repository-manager tests
make test # all Go packages plus the patched RPM module
make check # format, module, vet, staticcheck, deadcode, focused testsThe binary is written to bin/sow. Its default version is 0.3.0; release
builds also inject that version at link time.
Place packages in one directory, then run:
sow create ./packages
# Sign currently unsigned RPM packages with one key.
sow create ./packages --sign-with 0123456789ABCDEF
# Re-sign every RPM, including packages that already carry a signature.
sow create ./packages --sign-with 0123456789ABCDEF --overwriteThe directory may contain RPMs, DEBs, or both; SOW emits metadata for every
format it finds. RPM output is consumable as a normal YUM/DNF repository, and
DEB output is consumable as a flat APT repository. --pigsty enables the
accepted Pigsty layout conventions. Run sow help create for the complete
option contract.
sow init ./lab
sow repo new local --workdir ./lab
sow dist new stable --format rpm --workdir ./lab --repo local
sow add ./packages/example.rpm --workdir ./lab --repo local --dist stable
sow build --workdir ./lab --repo local
sow check --workdir ./lab --repo local
sow status --workdir ./lab --repo local
sow changes --workdir ./lab --repo local
sow log --workdir ./lab --repo localManaged repositories expose only pool/ + dists/; package hardlinks are not a
canonical layout requirement. Configure a filesystem or r2 target in
sow.yml, then use sow publish TARGET. sow gc collects unreachable local
payloads, while sow gc TARGET performs target-scoped maintenance. R2 target
maintenance is deliberately report-only and never deletes remote objects.
If a publication stops before durable commit intent, sow publish TARGET --abort
reconciles and abandons it without copying or deleting remote objects;
already-created payload/checksum objects remain exact private inventory evidence
and may be reused. After commit intent, recovery is forward-only. A configured
target with an Applied Checkpoint also fences removal of its published Dist,
architecture, or signing pointers: retire/unbind that target, or configure a
differently named target on a new prefix, before withdrawing those views.
The one-copy boundary is one Repository per publish prefix. Publishing the same Repository to two prefixes deliberately stores one payload copy in each prefix. Filesystem target roots are compared by their effective canonical paths, even when their endpoint spellings differ; an RPM leaf export must remain outside the Repository, private state, and every configured filesystem publication root.
Default EL dnf reposync is not supported for the canonical parent-relative
RPM layout. When a self-contained RPM leaf is explicitly required, use
sow export rpm-leaf DIST ARCH DIR; it copies by default, while --hardlink
is an opt-in local optimization for a same-filesystem, trusted read-only export.
Use sow help, sow help COMMAND, or sow help GROUP SUBCOMMAND as the
authoritative CLI reference shipped with the binary. Machine consumers can use
the closed --json envelopes and documented exit-code contract.
make release-localmake release-local uses GoReleaser to build a local snapshot under dist/.
It creates Linux/macOS archives for amd64/arm64 plus RPM and DEB packages for
both Linux architectures. Linux package revisions use the project suffix
1PGSTY, for example sow-0.3.0-1PGSTY.x86_64.rpm and
sow_0.3.0-1PGSTY_amd64.deb.
GitHub Actions runs regular checks in CI and real Docker-backed client/S3
coverage in Integration. Pushing an exact semantic-version tag creates a
draft release:
Maintainers can additionally run a read-only hosted Cloudflare R2 check with
make test-r2-live. It requires SOW_REAL_R2_ENDPOINT, BUCKET, PREFIX,
OBJECT_KEY, OBJECT_SHA256, ACCESS_KEY_ID, and SECRET_ACCESS_KEY using
the common SOW_REAL_R2_ prefix. The fixture must be immutable and carry the
matching sow-sha256 object metadata; the test never writes or deletes it.
git tag -a v0.3.0 -m "SOW v0.3.0"
git push origin v0.3.0The tag workflow verifies that the tag points into main, agrees with the
source version, and then lets GoReleaser create a draft GitHub Release. Publishing
that draft is a separate manual decision. The workflow does not build or publish
a Docker image.
Documentation ownership and the repository boundary are described in
design/README.md.
SOW is licensed under the Apache License, Version 2.0. Bundled third-party components remain under their respective licenses.