Skip to content

build(packaging): ship structured-proxy as RPM/DEB to repo.sw.foundation#55

Merged
polaz merged 6 commits into
mainfrom
build/#54-rpm-deb-packaging
Jun 21, 2026
Merged

build(packaging): ship structured-proxy as RPM/DEB to repo.sw.foundation#55
polaz merged 6 commits into
mainfrom
build/#54-rpm-deb-packaging

Conversation

@polaz

@polaz polaz commented Jun 21, 2026

Copy link
Copy Markdown
Member

Summary

Adds native RPM/DEB packaging for the structured-proxy binary and a release workflow that publishes to repo.sw.foundation, mirroring the pattern used by other SW binaries.

  • packaging/: systemd unit, sample config, sysusers declaration, RPM spec, and Debian source tree. The proxy is stateless (no data dir); the unit installs disabled because it needs a service-specific config (proto descriptors + upstream) before it can run.
  • .github/workflows/release.yml: on release creation, builds a static musl binary (amd64 + arm64), produces .rpm (Fedora 42/43/44) and .deb (bookworm/jammy/noble), attaches them to the release, uploads artifacts, and dispatches publish-from-structured-proxy to the repo repository.

Testing

Validated end-to-end on a Fedora 44 host (native rpmbuild + podman):

  • musl static build succeeds (aws-lc-sys compiles under musl); file reports static-pie, ldd reports statically linked, --help runs.
  • RPM builds; installs clean in a fedora:44 container — system user created, config is 0640 root:structured-proxy, service is disabled (not auto-started), binary runs.
  • DEB builds; installs clean in a debian:bookworm container — same result (user created, 0640 config, unit disabled, binary runs).

Not exercised locally: arm64 cross-arch and the fc42/43 + jammy/noble matrix rows (version-agnostic spec/debhelper), and the repo-side dispatch (covered by the companion PR in repo).

Companion

Requires structured-world/repo#23 to wire the publish side.

Closes #54

Package the structured-proxy binary natively for Fedora (42/43/44) and
Debian/Ubuntu (bookworm/jammy/noble) on amd64 + arm64, and ship to
repo.sw.foundation.

- packaging/: systemd unit, sample config, sysusers declaration, RPM
  spec, and Debian source tree. The proxy is stateless (no data dir);
  the unit installs disabled because it needs a service-specific config
  (proto descriptors + upstream) before it can run.
- .github/workflows/release.yml: build a static musl binary, produce
  .rpm/.deb, attach them to the release, upload artifacts, and dispatch
  the repo publish workflow.

Closes #54
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@polaz, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 8 minutes and 42 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8f2c13a7-9bf4-494d-80da-8a7cfc031f7a

📥 Commits

Reviewing files that changed from the base of the PR and between 8d55d90 and 13cefaf.

📒 Files selected for processing (13)
  • .github/workflows/release.yml
  • packaging/config.yaml
  • packaging/deb/debian/changelog
  • packaging/deb/debian/control
  • packaging/deb/debian/rules
  • packaging/deb/debian/source/format
  • packaging/deb/debian/structured-proxy.docs
  • packaging/deb/debian/structured-proxy.postinst
  • packaging/deb/debian/structured-proxy.postrm
  • packaging/manifest.json
  • packaging/rpm/structured-proxy.spec
  • packaging/structured-proxy.service
  • packaging/structured-proxy.sysusers
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch build/#54-rpm-deb-packaging

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 21, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds native RPM/DEB packaging for structured-proxy and a GitHub Actions release workflow that builds musl-static binaries (amd64 + arm64), produces packages for Fedora 42/43/44 and Debian bookworm/Ubuntu jammy/noble, and publishes them to repo.sw.foundation via a repository dispatch.

  • Workflow (.github/workflows/release.yml): builds from the exact released tag, wires build-rpm and build-deb off pre-built musl artifacts, and dispatches to the repo publisher using a scoped GitHub App token.
  • Packaging (packaging/): systemd unit with thorough sandboxing, sysusers declaration, sample config template, RPM spec, and Debian source tree — all shipping the service disabled pending operator configuration.

Confidence Score: 4/5

The packaging files and systemd unit are well-structured and safe to merge; the release workflow has a supply-chain exposure from two third-party actions pinned to mutable version tags in a context that holds write access and a private key secret.

The workflow's use of mutable @v2 tags for Swatinem/rust-cache and softprops/action-gh-release means a tag update by either action maintainer — or a compromise — runs arbitrary code with contents:write and access to RELEASER_APP_PRIVATE_KEY, directly affecting the integrity of published release assets.

.github/workflows/release.yml — specifically the two third-party action references at lines 54 and 80/161/255.

Important Files Changed

Filename Overview
.github/workflows/release.yml New release workflow: builds musl-static binaries, RPMs, and DEBs across arches/distros and publishes to repo.sw.foundation. Two third-party actions (Swatinem/rust-cache, softprops/action-gh-release) are pinned to mutable tags rather than commit SHAs, creating a supply-chain risk in a workflow that has contents:write and release-app secret access.
packaging/rpm/structured-proxy.spec New RPM spec: stages pre-built musl binary, uses sysusers for user creation, installs config as 0640 root:structured-proxy with noreplace, and wires correct systemd scriptlet macros.
packaging/deb/debian/structured-proxy.postinst Creates the system user via adduser and sets config ownership to root:structured-proxy 0640 without masking failures (set -e in effect), so a broken user setup fails loudly.
packaging/deb/debian/rules Stages pre-built binary and packaging assets into the debhelper install tree; skips configure/build/test/strip overrides correctly; installs unit with --no-enable --no-start.
packaging/structured-proxy.service Systemd unit with thorough sandboxing (ProtectSystem=strict, ProtectHome, PrivateTmp, NoNewPrivileges, etc.); ships disabled with documentation guiding operators to keep referenced files under /etc/structured-proxy.
packaging/manifest.json Publisher manifest declaring RPM (Fedora 42/43/44, x86_64+aarch64) and DEB (bookworm/jammy/noble) targets; matches the workflow matrix.
packaging/deb/debian/structured-proxy.postrm Removes the system user and group on purge only, preserving them on remove so reinstalls retain config ownership.
packaging/deb/debian/control Standard control file targeting amd64+arm64, depends on systemd and adduser matching postinst requirements.
packaging/structured-proxy.sysusers Declarative sysusers.d entry creating a no-home, nologin system account for the proxy.
packaging/config.yaml Sample config template shipped disabled; documents that referenced file paths must live under /etc/structured-proxy for ProtectHome compatibility.
packaging/deb/debian/changelog Placeholder changelog with version 0.0.0; CI overwrites it with the real version before dpkg-buildpackage.
packaging/deb/debian/source/format Source format set to 3.0 (native), appropriate for a package whose upstream and Debian packaging live in the same repository.
packaging/deb/debian/structured-proxy.docs Installs README.md as package documentation.

Reviews (3): Last reviewed commit: "fix(packaging): check out the released t..." | Re-trigger Greptile

Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml
Comment thread packaging/manifest.json
Comment thread packaging/structured-proxy.service
Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml
Comment thread packaging/deb/debian/structured-proxy.postinst
polaz added 4 commits June 21, 2026 17:06
The packaged config exposes shield.redis_url for multi-instance shared
rate limiting, but a default-features build omits the redis backend and
silently falls back to per-process counters. Build with --features redis
so the documented config surface actually works.
chown/chmod of the config were suffixed with || true, so a failed
ownership setup would still report a successful install while leaving
/etc/structured-proxy/config.yaml unreadable by the service user. Drop
the mask so set -e fails the install loudly at the cause.
The hardened unit runs with ProtectHome=yes and ProtectSystem=strict, so
files referenced from the config (descriptors, PEM keys) must live under
/etc/structured-proxy rather than a home directory. Document this in the
sample config and the unit.
The release workflow builds and publishes Fedora RPMs for x86_64 and
aarch64, but the manifest advertised only x86_64, so the docs site
listed a single arch. Reflect both architectures that actually ship.
Comment thread .github/workflows/release.yml
A manual workflow_dispatch re-run passes tag_name, but the checkout did
not pin it as the ref, so the build could compile whatever ref triggered
the run while labeling binaries and release assets with a different tag.
Pin ref to the resolved tag in every package job.
@polaz
polaz merged commit d860352 into main Jun 21, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

build(packaging): ship structured-proxy as RPM/DEB to repo.sw.foundation

1 participant