Skip to content
Closed
Changes from 1 commit
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
32 changes: 32 additions & 0 deletions scripts/rpm-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,38 @@ build_tokenless() {

local pkg_name
pkg_name=$(parse_spec_name "$spec_in")

# Component contract guard (mirrors build_cosh_ng): the RPM must publish
# the anolisa-component(<name>) capability so `anolisa install tokenless`
# can resolve the package via Provides when the component index is
# unavailable. Fail the build on spec drift instead of shipping a package
# that silently lacks the capability (GH-2836).
local component_in="${TOKEN_DIR}/.anolisa/component.toml.in"
if [ ! -f "$component_in" ]; then
err "Component contract template not found: $component_in"
return 1
fi
local component_name
component_name=$(awk '
$0 == "[component]" { in_component = 1; next }
in_component && /^\[/ { exit }
in_component && /^name = / {
value = $0
sub(/^name = "/, "", value)
sub(/"$/, "", value)
print value
exit
}
' "$component_in")
if [ "$component_name" != "$pkg_name" ]; then
err "tokenless identity mismatch: RPM name '${pkg_name}', component name '${component_name}'"
return 1
fi
if ! grep -Fqx "Provides: anolisa-component(${component_name})" "$spec_in"; then
err "tokenless spec must provide anolisa-component(${component_name})"
return 1
Comment on lines +493 to +495

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Enforce the guard in the RPM-producing workflow

When tokenless RPMs are produced by the checked-in nightly pipeline, this guard never runs: .github/workflows/docker-nightly.yaml delegates the tokenless job to _rpm-build.yaml, which processes the archived spec and invokes rpmbuild directly. Consequently, removing the Provides line still lets that pipeline publish an RPM with the original defect; move or duplicate this assertion in _rpm-build.yaml (ideally verify the built RPM's capabilities) so the production artifact path is protected.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good catch — accepted. Verified the gap: docker-nightly.yaml delegates the rpm-tokenless job to _rpm-build.yaml, which processes the archived spec and invokes rpmbuild directly, so the guard in scripts/rpm-build.sh never runs on the nightly path.

Fixed in f359ab9 by duplicating the assertion into _rpm-build.yaml (gated on inputs.component == 'tokenless', other components unaffected) and adding the artifact capability verification:

  1. New Verify tokenless component contract step before Build RPM: derives the component name from .anolisa/component.toml.in in the source archive, verifies it matches the RPM package name, and requires the exact Provides: anolisa-component(<name>) line in the processed spec — same assertions as build_tokenless.
  2. Collect RPM artifacts now verifies each built RPM actually publishes the capability via rpm -qp --provides, catching a malformed Provides line that rpmbuild would silently drop (mirrors the existing agentsight verification hook).

Local verification: simulated the nightly spec processing with the real tokenless.spec.in + component.toml.in — happy path passes; removing the Provides line (the original defect scenario), a Name/component mismatch, and a missing contract template all fail the guard; built minimal test RPMs with/without the capability to confirm the artifact check accepts/rejects correctly; actionlint clean. CI re-runs on this push.

fi

local tarball_name="${pkg_name}-${version}.tar.gz"

# Step 1: Process spec template
Expand Down
Loading