fix(product): capture products on traced builds (workdir-anchored, absolute glob)#21
Open
colek42 wants to merge 5 commits into
Open
fix(product): capture products on traced builds (workdir-anchored, absolute glob)#21colek42 wants to merge 5 commits into
colek42 wants to merge 5 commits into
Conversation
…ild) rookery split the eBPF code into its own Go submodule at plugins/attestors/commandrun/ebpf. cilock-action's go.mod had no require/ replace for it, so any Linux build (tracing_ebpf_linux.go is build-tagged linux) failed with "missing go.sum entry for .../commandrun/ebpf" — this is why main's Build (linux/amd64, linux/arm64) checks are currently red. Add the require + local replace (matching every other rookery sibling) and run go mod tidy so go.sum gains the submodule's transitive deps (github.com/cilium/ebpf and friends). Linux build now resolves. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Three changes that fix the conceptual model surfaced by the gh CLI
smoke (which classified 9281 compiler intermediates as "products"):
1. New \`products\` input — newline-separated list of paths/globs
the build is expected to produce. Joined as a {a,b,c} brace
pattern for the rookery product attestor.
2. Default = workingDir/** when \`products\` is empty. Idiomatic
builds that write under the workspace just work. Builds that
write to /tmp or ~/.local/bin/ must explicitly list those paths.
3. \`::warning::no products detected\` when the resolved glob
matched nothing. Surfaces the active glob and tells the user
exactly where + how to override it in their workflow YAML.
Legacy \`product-include-glob\` input still honoured (no default,
opt-in). \`product-exclude-glob\` unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
resolveProductIncludeGlob compiled relative entries (e.g.,
\`products: bin/gh\`) as-is, but rookery's trace mode emits absolute
paths in TraceOutputs (e.g., /home/runner/work/cli/cli/bin/gh).
The relative glob matched zero paths → empty products map even when
the summary classifier saw 2.
Now: relative entries get filepath.Join'd against cfg.WorkingDir
(falling back to os.Getwd if WorkingDir is empty) before compiling
into the {a,b,c} brace glob.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Trace mode emits ABSOLUTE product paths (the kernel read-tap/path-hash resolves fds via /proc/<pid>/fd). resolveProductIncludeGlob anchored the include-glob to cfg.WorkingDir via filepath.Join, but WorkingDir is typically RELATIVE (the common `workingdir: yq-src` input). A relative glob (e.g. "yq-src/**") never matches an absolute product path, so every traced build with a relative workingdir silently recorded zero products (treeSize=0) while trace evidence captured thousands of files. Resolve WorkingDir to an absolute path before anchoring, and pass the same absolute path to attestation.WithWorkingDir so relative trace paths resolve into the same namespace the glob lives in. Adds TDD coverage for default/legacy/products-list globs + absolute-workingdir passthrough. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…atforms) e210ec8 deprecated `product-include-glob` in favor of `products` and made the GitHub parser return the raw (empty) input, but left the DefaultProductIncludeGlob constant at "*". That broke TestParseGitHub_Defaults and, worse, left GitLab still applying a "*" default via glEnvDefault — so the two platforms disagreed on the default product surface. A non-empty "*" default also defeats trace mode: it never matches the absolute product paths trace mode emits. Set the constant to "" so an unset glob falls through to the workingDir/** default in resolveProductIncludeGlob, consistently on GitHub and GitLab. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
151c281 to
f8177dd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Trace-mode builds through cilock-action silently recorded zero products
(
treeSize=0) while trace evidence captured thousands of files. This PR fixesthat and gives the product attestation a coherent, workdir-anchored model.
Root cause: trace mode emits absolute product paths (the kernel
read-tap / path-hash resolves fds via
/proc/<pid>/fd). The productinclude-glob was anchored to
cfg.WorkingDirviafilepath.Join, butWorkingDiris typically relative (the commonworkingdir: yq-srcinput),so the glob stayed relative (
yq-src/**) and a relative glob never matches anabsolute path → nothing captured.
What changed
productsinput + workdir default + no-products warning — newline list ofpaths/globs; default is
workingDir/**so the build's outputs count asproducts without matching every compiler intermediate.
WorkingDirbefore anchoring the glob and forattestation.WithWorkingDir, so the glob and the resolved trace paths live inone absolute namespace. Adds TDD coverage (default / legacy / products-list /
absolute-passthrough).
product-include-globon both GitHub andGitLab (the constant was stale at
"*", which brokeTestParseGitHub_Defaultsand left the platforms inconsistent;
"*"also can't match trace-modeabsolute paths).
Evidence
Validated end-to-end on a real
ubuntu-24.04eBPF runner buildingmikefarah/yq:yq-src/**):tree:products= empty-tree roote3b0c442…,treeSize: 0.makes automatic):
tree:productsroot7ee52167…,treeSize: 1— theyqbinary captured — alongside 9.7k traced files / 1.3k processes.Notes
setcap/eBPF PR feat(shim): setcap cap_bpf+cap_perfmon to enable eBPF tracing on hosted runners #19 so they can be reviewed (and shipped) on their own. feat(shim): setcap cap_bpf+cap_perfmon to enable eBPF tracing on hosted runners #19
should be rebased to drop them once this lands.
shim downloads releases).
Test plan
go test ./...(GOWORK=off) greenTestResolveProductIncludeGlob_*unit teststree:products(treeSize=1)workingdirpath through a released binary🤖 Generated with Claude Code