Skip to content

feat: Add XBPS packager support#1094

Open
actx4gh wants to merge 14 commits into
goreleaser:mainfrom
actx4gh:actx4gh/xbps-packager-pr1
Open

feat: Add XBPS packager support#1094
actx4gh wants to merge 14 commits into
goreleaser:mainfrom
actx4gh:actx4gh/xbps-packager-pr1

Conversation

@actx4gh

@actx4gh actx4gh commented May 27, 2026

Copy link
Copy Markdown

Problem

nFPM does not currently support generating XBPS packages.

Resolves #718.

This PR replaces the earlier closed PR #1061 with a rebuilt branch, a narrower commit history, package signature sidecar support, and additional validation against Void Linux tooling.

Change summary

This adds native XBPS package generation to nFPM.

The new xbps packager writes .xbps package archives directly in Go rather than shelling out to xbps-create. The generated package is a zstd-compressed tar archive containing the XBPS metadata files, optional lifecycle scripts, and the package payload entries consumed by normal XBPS tooling.

Supported package behavior includes:

  • architecture mapping, with explicit xbps.arch override support;
  • conventional XBPS filenames and .xbps extension support;
  • generic nFPM metadata mapped into XBPS package metadata;
  • dependencies, conflicts, provides, replaces, and XBPS reverts;
  • config-file metadata derived from existing nFPM content types;
  • xbps.short_desc, xbps.preserve, xbps.tags, and xbps.alternatives;
  • install and remove lifecycle script wrapping through XBPS INSTALL and REMOVE action dispatch;
  • optional adjacent package signature sidecar output through xbps.signature.key_file.

As such, the implementation follows nFPM’s existing first-class packager model while keeping XBPS-specific archive and metadata behavior inside the new xbps package.

Signing

This PR includes XBPS package signature sidecar support.

When xbps.signature.key_file is configured, nFPM signs the generated package digest with RSA SHA-256 and writes an adjacent <package>.xbps.sig2 file.

This is intentionally limited to package sidecar signing. It does not create or sign repository metadata, publish repositories, manage remote repositories, or orchestrate xbps-rindex --sign. Repository indexing and repository signing remain separate XBPS tooling workflows.

Runtime validation

XBPS behavior is validated primarily against Void Linux, because Void is the main public environment where this package format is exercised.

The acceptance tests use a local XBPS repository flow:

  1. generate .xbps packages with nFPM;
  2. index the local repository with xbps-rindex -a;
  3. install from that repository with XBPS tooling;
  4. query package metadata;
  5. reconfigure the package;
  6. upgrade the package;
  7. remove the package.

Covered XBPS scenarios include install, metadata/query behavior, lifecycle scripts, reconfigure, remove, upgrade, noarch packages, preserve behavior, alternatives, tags, reverts, and config metadata.

I also performed additional runtime testing in my Void/s6 VM environment using packages from my void-s6 repository:

https://codeberg.org/aaron_colichia/void-s6

That testing gave additional confidence that the generated packages work outside the unit-test-only path and can be consumed in a real Void-based environment.

Validation

Local validation run for the rebuilt branch:

  • go test ./internal/sign ./xbps .
  • go test ./...
  • go test -tags=acceptance -run '^TestXBPSSpecific$' .

A fork-local GitHub Actions preflight passed for the branch-specific checks.

Two fork-local failures were baseline or toolchain issues outside this XBPS work:

  • license-check: go-licenses/v2@latest rejects the existing dependency github.com/cyphar/filepath-securejoin as MPL-2.0.
  • docs / build: Hugo latest pulled a newer Hugo version that fails in the Hextra RSS template on .Site.Author.email.

The only branch-specific lint issue found during preflight was fixed with gofumpt.

Non-goals

This PR does not add:

  • XBPS repository publishing;
  • XBPS repository metadata signing;
  • remote repository management;
  • xbps-rindex --sign orchestration;
  • xbps-create as the production packaging backend;
  • xbps-src or void-packages template generation;
  • automatic shared-library provide/requires discovery;
  • purge lifecycle hook support;
  • a broad cross-packager signing redesign.

Note

I used AI assistance to help scaffold and organize the shape of this PR, then reviewed the code and performed the validation above. I can answer implementation questions about the changes.

@pull-request-size pull-request-size Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label May 27, 2026
@actx4gh actx4gh marked this pull request as draft May 27, 2026 23:02
@actx4gh actx4gh marked this pull request as ready for review May 27, 2026 23:10
@actx4gh actx4gh force-pushed the actx4gh/xbps-packager-pr1 branch from 0ebddea to 77b4247 Compare June 18, 2026 03:32
@caarlos0 caarlos0 requested a review from Copilot June 18, 2026 03:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a first-class XBPS packager to nFPM (Void Linux), including optional .xbps.sig2 sidecar signing support, plus schema/docs updates and acceptance coverage to validate install/upgrade/lifecycle behavior using Void tooling.

Changes:

  • Introduce xbps packager that writes zstd-compressed tar-based .xbps archives directly in Go, mapping nFPM metadata to XBPS props.plist/files.plist.
  • Add optional package-sidecar signing via RSA/SHA-256 digest signatures and extend internal RSA helpers to support SHA-256 digests.
  • Add acceptance scenarios, JSON schema, CLI/docs updates, and Taskfile smoke build entry for XBPS.
Show a summary per file
File Description
xbps/xbps.go New XBPS packager implementation (archive + metadata + optional sidecar signing).
xbps/xbps_test.go Unit tests for XBPS packaging, metadata, scripts, and signature sidecar.
nfpm.go Adds XBPS config structs, env expansion for XBPS fields, and arch validation update.
nfpm_test.go Tests for arch override validation and XBPS env-expansion + passphrase behavior.
internal/sign/rsa.go Adds SHA-256 digest signing/verification helpers and refactors signing logic.
internal/sign/rsa_test.go Tests for SHA-256 digest signing/verification and error paths.
internal/cmd/root.go Registers the new xbps packager and updates CLI descriptions.
cmd/nfpm/main.go Updates version/app description to mention xbps.
acceptance_test.go Registers xbps packager for acceptance and adds XBPS acceptance scenarios.
testdata/acceptance/xbps.dockerfile Void-based acceptance Dockerfile to validate XBPS install/upgrade flows.
testdata/acceptance/xbps.lifecycle.yaml Acceptance config for lifecycle script behavior.
testdata/acceptance/xbps.metadata.yaml Acceptance config for metadata fields (tags/reverts/alternatives/preserve).
testdata/acceptance/xbps.noarch.yaml Acceptance config for noarch mapping.
testdata/acceptance/xbps.upgrade.v1.yaml Acceptance config for upgrade v1 package.
testdata/acceptance/xbps.upgrade.v2.yaml Acceptance config for upgrade v2 package.
testdata/acceptance/xbps.current.v1.txt Upgrade scenario payload fixture (v1).
testdata/acceptance/xbps.current.v2.txt Upgrade scenario payload fixture (v2).
testdata/acceptance/xbps.preserve.v1.txt Upgrade scenario preserve fixture.
www/static/schema.json Regenerated schema including xbps config definitions.
www/content/docs/quick-start.md Documents xbps usage and a Void smoke-check flow.
www/content/docs/configuration.md Documents XBPS-specific config fields and signing sidecar behavior.
www/content/docs/cmd/nfpm.md Updates CLI docs to mention XBPS.
www/content/docs/cmd/nfpm_package.md Updates --packager options list to include xbps.
www/content/docs/cmd/nfpm_jsonschema.md Updates CLI docs to mention XBPS.
www/content/docs/cmd/nfpm_init.md Updates CLI docs to mention XBPS.
www/content/docs/cmd/nfpm_completion.md Updates CLI docs to mention XBPS.
www/content/docs/arch-mapping.md Adds XBPS architecture mapping table to docs.
www/content/docs/_index.md Updates docs landing page to mention xbps as a supported format.
Taskfile.yml Adds an XBPS packaging line to the build smoke task.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 29/29 changed files
  • Comments generated: 5

Comment thread xbps/xbps.go
Comment thread nfpm.go Outdated
Comment on lines 305 to 307
// RPM specific
c.RPM.Packager = os.Expand(c.RPM.Packager, c.envMappingFunc)

@actx4gh actx4gh Jun 18, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@caarlos0 appears to have existed prior to the PR, but smell looks valid so addressed. please confirm or let me know if you want to back this out.

Comment thread www/content/docs/quick-start.md Outdated
Comment thread testdata/acceptance/xbps.dockerfile
Comment thread internal/sign/rsa.go
@actx4gh actx4gh force-pushed the actx4gh/xbps-packager-pr1 branch from 77b4247 to d674ac3 Compare June 18, 2026 04:45
@codecov

codecov Bot commented Jun 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.46789% with 101 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.51%. Comparing base (64b788a) to head (d674ac3).

Files with missing lines Patch % Lines
xbps/xbps.go 80.92% 57 Missing and 34 partials ⚠️
internal/sign/rsa.go 82.05% 5 Missing and 2 partials ⚠️
internal/cmd/root.go 0.00% 2 Missing ⚠️
cmd/nfpm/main.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1094      +/-   ##
==========================================
+ Coverage   73.97%   75.51%   +1.54%     
==========================================
  Files          22       23       +1     
  Lines        2778     3292     +514     
==========================================
+ Hits         2055     2486     +431     
- Misses        497      550      +53     
- Partials      226      256      +30     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

actx4gh added 13 commits June 20, 2026 21:42
Add the XBPS packager-specific config structs, override wiring,
environment expansion, and validation support needed by later packager
commits.

See goreleaser#718
Enforce XBPS architecture validation rules using the same
packager-specific override pattern as the existing package formats.

See goreleaser#718
Register the XBPS packager skeleton with filename, extension, and
architecture mapping behavior.

See goreleaser#718
Generate native XBPS archives with deterministic metadata, payload
entries, config-file metadata, and dependency fields.

See goreleaser#718
Wrap generic install and remove lifecycle scripts in XBPS INSTALL and
REMOVE action handlers.

See goreleaser#718
Add XBPS metadata support for short descriptions, preserve, tags,
reverts, and alternatives.

See goreleaser#718
Extend the internal RSA signing helper to support SHA-256 digest
signing while preserving existing behavior.

See goreleaser#718
Write adjacent XBPS signature sidecar files when
xbps.signature.key_file is configured.

See goreleaser#718
Validate XBPS install, metadata, reconfigure, remove, upgrade, noarch,
and preserve behavior on Void Linux.

See goreleaser#718
Include XBPS in the existing package smoke command matrix.

See goreleaser#718
Document native XBPS generation, Void runtime scope, config fields,
architecture mapping, and signature sidecar limits.

See goreleaser#718
Format validation test blocks to satisfy the repository gofumpt check.

See goreleaser#718
Require PKCS#8 signing keys to be RSA keys, keep XBPS symlink metadata aligned with the tar payload, remove duplicate RPM environment expansion, and avoid listing XBPS twice in the quick-start packager text.

Validated with go test ./internal/sign ./xbps ., go test ./..., and go test -tags=acceptance -run '^TestXBPSSpecific$' .

See goreleaser#718
@actx4gh actx4gh force-pushed the actx4gh/xbps-packager-pr1 branch from d674ac3 to 2a03543 Compare June 21, 2026 02:44
Add tests for RSA key-loading failures, non-RSA PKCS#8 rejection, XBPS plist error handling, directory metadata, and content-entry open failures.

Validated with go test ./internal/sign ./xbps ., go build ./..., go vet ./..., go test ./..., and go test -tags=acceptance -run '^TestXBPSSpecific$' .

See goreleaser#718
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support xbps packages

2 participants