Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ complytime-providers/
│ └── changes/ # Active change specs
├── .opencode/ # Agent definitions & convention packs
├── .goreleaser.yaml # GoReleaser v2 release config
├── go-vendor-tools.toml # Vendored license detection config (Fedora RPM)
└── complytime-providers.spec # RPM packaging spec
```

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

### Infrastructure

- Modernized RPM spec for Fedora Go Packaging Guidelines: adopted `go-vendor-tools` for vendored license handling, replaced raw `go build` with `%gobuild` macro, switched to forge macros and `%autorelease`, added aggregated vendored license expression, and introduced main `complytime-providers` package for shared license files.
- Consolidated duplicate tar.gz extraction code from ampel and OPA providers into shared `internal/archive/` package, eliminating code duplication and ensuring consistent security behavior across providers.

### Breaking Changes
Expand Down
116 changes: 71 additions & 45 deletions complytime-providers.spec
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
# SPDX-License-Identifier: Apache-2.0

%global goipath github.com/complytime/complytime-providers
%global base_url https://%{goipath}
%bcond check 1

%global app_dir complytime
# Go binaries include their own debug info; standard RPM debuginfo extraction
# does not produce useful output for Go executables.
%global debug_package %{nil}

# https://github.com/complytime/complytime-providers
%global goipath github.com/complytime/complytime-providers
Version: 0.1.0

%gometa -f

Name: complytime-providers
Version: 0.1.0
Release: 1%{?dist}
Release: %autorelease
Summary: Compliance scanning providers for complyctl
License: Apache-2.0
URL: %{base_url}
Source0: %{base_url}/archive/refs/tags/v%{version}.tar.gz

BuildRequires: golang >= 1.26
BuildRequires: go-rpm-macros
# License includes vendored dependency licenses.
# Generated by go-vendor-tools; verify with:
# go_vendor_license --config go-vendor-tools.toml report expression
License: Apache-2.0 AND BSD-3-Clause AND ISC AND MIT AND MPL-2.0
URL: %{gourl}
Source0: %{gosource}
# Generated by go-vendor-tools
Source1: %{archivename}-vendor.tar.bz2
Source2: go-vendor-tools.toml

BuildRequires: go-vendor-tools
ExclusiveArch: %{go_arches}

%gometa -f

%description
Compliance scanning providers that extend complyctl with support for
different policy validation platforms (PVPs). Each provider communicates
Expand All @@ -32,7 +38,8 @@ can install only the providers they need.

%package openscap
Summary: OpenSCAP scanning provider for complyctl
Requires: complyctl >= 0.0.8
Requires: %{name} = %{version}-%{release}
Requires: complyctl >= 1.0.0
Requires: openscap-scanner
Requires: scap-security-guide

Expand All @@ -47,7 +54,8 @@ and follows the complyctl-provider-* discovery convention.

%package ampel
Summary: Ampel scanning provider for complyctl
Requires: complyctl >= 0.0.8
Requires: %{name} = %{version}-%{release}
Requires: complyctl >= 1.0.0

%description ampel
Ampel scanning provider that extends complyctl with Ampel evaluation
Expand All @@ -61,7 +69,8 @@ not currently packaged in Fedora and must be installed separately.

%package opa
Summary: OPA/Conftest scanning provider for complyctl
Requires: complyctl >= 0.0.8
Requires: %{name} = %{version}-%{release}
Requires: complyctl >= 1.0.0
Requires: git

%description opa
Expand All @@ -73,55 +82,72 @@ NOTE: Requires the 'conftest' CLI tool at runtime. This tool is not
currently packaged in Fedora and must be installed separately.

%prep
%goprep -k
%goprep -A
%setup -q -T -D -a1 %{forgesetupargs}
%autopatch -p1

# TODO(2027-01): remove F43 workaround
# Fedora 43 ships Go 1.25 but go.mod may require Go 1.26+ due to
# transitive dependency requirements. Lower the directive to the
# system Go major.minor so rpmbuild succeeds with GOTOOLCHAIN=local.
# Fedora 43 EOL: 2026-12-09 — remove this block after EOL.
# Reference: https://packages.fedoraproject.org/pkgs/golang/golang/
%if 0%{?fedora} == 43
sed -i 's/^go [0-9].*/go 1.25/' go.mod
sed -i '/^## explicit; go /s/go [0-9]\..*/go 1.25/' vendor/modules.txt
%endif

%generate_buildrequires
%go_vendor_license_buildrequires -c %{S:2}

%build
# Set up environment variables and flags to build properly and securely
%set_build_flags
export GO111MODULE=on

# Inject version via ldflags (mirrors complyctl's pattern)
GO_LD_EXTRAFLAGS="-X %{goipath}/internal/version.version=%{version}"

# Define and create the output directory for binaries
GO_BUILD_BINDIR=./bin
mkdir -p ${GO_BUILD_BINDIR}
%global gomodulesmode GO111MODULE=on
export GO_LDFLAGS="-X %{goipath}/internal/version.version=%{version}"

# Build all provider binaries
go build -mod=vendor -buildmode=pie -ldflags "${LDFLAGS} ${GO_LD_EXTRAFLAGS}" -o ${GO_BUILD_BINDIR}/complyctl-provider-openscap ./cmd/openscap-provider
go build -mod=vendor -buildmode=pie -ldflags "${LDFLAGS} ${GO_LD_EXTRAFLAGS}" -o ${GO_BUILD_BINDIR}/complyctl-provider-ampel ./cmd/ampel-provider
go build -mod=vendor -buildmode=pie -ldflags "${LDFLAGS} ${GO_LD_EXTRAFLAGS}" -o ${GO_BUILD_BINDIR}/complyctl-provider-opa ./cmd/opa-provider
%gobuild -o %{gobuilddir}/bin/complyctl-provider-openscap %{goipath}/cmd/openscap-provider
%gobuild -o %{gobuilddir}/bin/complyctl-provider-ampel %{goipath}/cmd/ampel-provider
%gobuild -o %{gobuilddir}/bin/complyctl-provider-opa %{goipath}/cmd/opa-provider

%install
%go_vendor_license_install -c %{S:2}
install -d -m 0755 %{buildroot}%{_libexecdir}/%{app_dir}/providers

install -p -m 0755 bin/complyctl-provider-openscap %{buildroot}%{_libexecdir}/%{app_dir}/providers/complyctl-provider-openscap
install -p -m 0755 bin/complyctl-provider-ampel %{buildroot}%{_libexecdir}/%{app_dir}/providers/complyctl-provider-ampel
install -p -m 0755 bin/complyctl-provider-opa %{buildroot}%{_libexecdir}/%{app_dir}/providers/complyctl-provider-opa
install -p -m 0755 %{gobuilddir}/bin/complyctl-provider-openscap %{buildroot}%{_libexecdir}/%{app_dir}/providers/complyctl-provider-openscap
install -p -m 0755 %{gobuilddir}/bin/complyctl-provider-ampel %{buildroot}%{_libexecdir}/%{app_dir}/providers/complyctl-provider-ampel
install -p -m 0755 %{gobuilddir}/bin/complyctl-provider-opa %{buildroot}%{_libexecdir}/%{app_dir}/providers/complyctl-provider-opa

%check
# Run unit tests
go test -mod=vendor -v ./...
%go_vendor_license_check -c %{S:2}
%if %{with check}
%gocheck2
%endif

# No main files section -- source RPM produces only sub-packages
# Main package: shared license files and documentation
%files -f %{go_vendor_license_filelist}
%doc README.md

%files openscap
%attr(0755, root, root) %{_libexecdir}/%{app_dir}/providers/complyctl-provider-openscap
%license LICENSE
%doc README.md vendor/modules.txt

%files ampel
%attr(0755, root, root) %{_libexecdir}/%{app_dir}/providers/complyctl-provider-ampel
%license LICENSE
%doc README.md vendor/modules.txt

%files opa
%attr(0755, root, root) %{_libexecdir}/%{app_dir}/providers/complyctl-provider-opa
%license LICENSE
%doc README.md vendor/modules.txt

%changelog
* Thu Jun 12 2026 Marcus Burghardt <maburgha@redhat.com> - 0.1.0-1
* Wed Aug 26 2026 Marcus Burghardt <maburgha@redhat.com> - 0.1.0-1
- Modernize spec for Fedora Go packaging guidelines
- Adopt go-vendor-tools for vendored license verification
- Fix debuginfo generation by switching to %%gobuild macro
- Use %%gocheck2 for unit tests
- Use %%autorelease for automatic release numbering
- Bump complyctl dependency to >= 1.0.0
- Add Fedora 43 Go 1.25 compatibility workaround
- Add main package for shared license files
- Add aggregated vendored license expression

* Fri Jun 12 2026 Marcus Burghardt <maburgha@redhat.com> - 0.1.0-1
- Bump to version 0.1.0
- Add OPA provider sub-package
- Add build-time version injection via ldflags
Expand Down
18 changes: 18 additions & 0 deletions go-vendor-tools.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# go-vendor-tools configuration for complytime-providers
# See: https://fedora.gitlab.io/sigs/go/go-vendor-tools/config/
#
# License overrides below are populated by:
# go_vendor_license --config go-vendor-tools.toml \
# --path complytime-providers.spec report --prompt --autofill=auto
#
# Vendor archive is generated by:
# go_vendor_archive create --config go-vendor-tools.toml complytime-providers.spec

[archive]

[licensing]
detector = "askalono"
[[licensing.licenses]]
path = "vendor/gopkg.in/yaml.v3/LICENSE"
sha256sum = "d18f6323b71b0b768bb5e9616e36da390fbd39369a81807cca352de4e4e6aa0b"
expression = "MIT AND (MIT AND Apache-2.0)"
3 changes: 3 additions & 0 deletions openspec/changes/rpm-spec-modernization/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
schema: spec-driven
created: 2026-08-26
skip_specs: true
151 changes: 151 additions & 0 deletions openspec/changes/rpm-spec-modernization/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
## Context

See proposal.md for motivation. The current `complytime-providers.spec`
was written for internal/COPR builds. Fedora Go packages must use the
`go-vendor-tools` ecosystem for vendored license handling, `%gobuild`
for hardened builds, and forge macros for source management. The
`complyctl` spec on `opsx/rpm-spec-modernization` was already modernized
and serves as the reference implementation.

Key constraints:
- complytime-providers builds **three** binaries (not one like complyctl)
- The spec produces only sub-packages (no main binary), but Fedora
needs a main package to hold shared license files
- Fedora 43 ships Go 1.25; `go.mod` requires Go 1.26.5
- Provider binaries must install to
`/usr/libexec/complytime/providers/` (owned by `complyctl` RPM)
- The `gopkg.in/yaml.v3` vendored license is a dual MIT+Apache-2.0
file that `askalono` cannot auto-detect

### Goals

- Pass Fedora package review for Go packaging compliance
- Align with the modernized `complyctl` spec patterns
- Ensure `complyctl` + `complytime-providers` install cleanly
together on Fedora and provider discovery works end-to-end
- Generate proper debuginfo packages (removing `%{nil}` override)

### Non-Goals

- Packaging `snappy`, `ampel`, or `conftest` for Fedora (external
runtime deps for ampel/opa providers remain user-managed)
- Changing provider binary behavior or code
- Creating man pages for providers (can be added later)
- Adding `go_vendor_license` checks to GitHub Actions CI
(`go-vendor-tools` is Fedora-specific tooling not available in
standard GitHub Actions runners; license drift is caught at RPM
build time via `%go_vendor_license_check`)

## Decisions

### D1: Main package as license holder (not meta-package)

The main `complytime-providers` package holds shared license files
(via `%go_vendor_license_filelist`) and `README.md`. It does NOT
pull in all sub-packages.

**Why**: Sub-packages have different runtime dependency profiles
(`openscap-scanner + scap-security-guide` vs `git` vs nothing).
A meta-package would force unnecessary dependencies on users who
only want one provider.

**Alternative considered**: Attach `%go_vendor_license_filelist` to
one arbitrary sub-package. Rejected because it creates asymmetry
between sub-packages and the chosen sub-package would need to be
installed even when the user wants a different provider.

### D2: Three `%gobuild` calls for three binaries

Each provider binary gets its own `%gobuild` invocation in `%build`.
The `%gobuild` macro supports `-o <path> <import-path>` syntax,
identical to `go build`, so three calls are straightforward.

**Why**: `%gobuild` is the Fedora-standard macro that applies PIE,
RELRO, FORTIFY, and generates proper DWARF debuginfo. No batching
mechanism exists for multiple binaries.

### D3: Single `GO_LDFLAGS` for version injection

Only `internal/version.version` is injected (unlike complyctl which
also injects `gitTreeState`, `commit`, and `buildDate`). The
providers' `internal/version` package only exposes `version`.

```
export GO_LDFLAGS="-X %{goipath}/internal/version.version=%{version}"
```

### D4: Fedora 43 Go compatibility via conditional sed

Matches the `complyctl` spec approach: conditionally lower the
`go` directive in `go.mod` and `vendor/modules.txt` from 1.26 to
1.25 when building on Fedora 43.

**Why**: Fedora 43 is supported until 2026-12-09. Using a
conditional `%if 0%{?fedora} == 43` block keeps it self-documenting
and easy to remove after EOL.

**Alternative considered**: Carrying a patch file. Rejected because
the `sed` approach is identical to the complyctl reference and
avoids maintaining a separate patch file that would need updating
on every Go version bump.

### D5: No `%gocheck2` exclusions

All 29 test files were analyzed. Every test that touches external
tools (oscap, conftest, snappy, ampel, git) uses mock/fake
implementations. The only integration test
(`cmd/openscap-provider/config/integration_test.go`) is gated by
`//go:build integration` and is automatically excluded from
`go test ./...`. Toolcheck tests use universally available commands
(`go`, `ls`).

### D6: `go-vendor-tools.toml` with yaml.v3 license override

The `askalono` detector correctly identifies all vendored licenses
except `gopkg.in/yaml.v3/LICENSE` (dual MIT + Apache-2.0 in a
single file). A manual `[[licensing.licenses]]` override is
required, matching the same override in `complyctl`'s config.

## Risks / Trade-offs

**[Risk] `%gobuild` external linker requirement** The `%gobuild`
macro uses `-linkmode=external` which requires a C compiler and
linker. This is standard in Fedora build environments but differs
from the current `CGO_ENABLED=0` approach in `.goreleaser.yaml`.
RPM builds and release builds are intentionally different
environments.
Mitigation: Fedora build roots always have `gcc` available.

**[Risk] Fedora 43 Go compat workaround fragility** The `sed`
command pattern-matches `go [0-9].*` in `go.mod`. If the format
changes in future Go versions, it could silently fail.
Mitigation: The block is conditional on `%{?fedora} == 43` only
and has a documented EOL date for removal. A `# TODO(2027-01):
remove F43 workaround` comment should be added in the spec itself
as a sunset trigger.

**[Risk] License expression drift** If vendored dependencies
change, the `License:` field and `go-vendor-tools.toml` overrides
must be updated.
Mitigation: `%go_vendor_license_check` in `%check` will fail the
build if the license config is stale. The `go_vendor_license report
--verify-spec` workflow catches drift. When vendored dependencies
change, maintainers run `go_vendor_license --config
go-vendor-tools.toml report expression` and update the spec's
`License:` field accordingly.

**[Risk] `go-vendor-tools` availability** This change makes RPM
builds dependent on the Fedora-packaged `go-vendor-tools`. This
tool is available in Fedora 43+ but is not available in CentOS
Stream or RHEL build environments.
Mitigation: The RPM spec targets Fedora submission specifically.
Non-Fedora builds (e.g., GoReleaser releases) use a separate
build pipeline that does not depend on `go-vendor-tools`.

**[Note] Provider binary permissions** The `%attr(0755, root, root)`
permission on provider binaries in `%{_libexecdir}` follows the
standard Fedora convention for executable helper programs. While
providers are invoked by `complyctl` via gRPC subprocess (not
directly by users), 0755 is the expected permission for
`%{_libexecdir}` binaries per Fedora packaging guidelines and
enables direct invocation for debugging purposes.
Loading
Loading