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
30 changes: 28 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,19 @@ jobs:
git -C source check-ref-format --branch "$D2B_BRANCH" >/dev/null 2>&1 ||
fail "branch metadata is not an approved ref"

validate_optional_reusable_workflow() {
if [ -n "$D2B_JOB_WORKFLOW_REF" ] || [ -n "$D2B_JOB_WORKFLOW_SHA" ]; then
[ "$D2B_JOB_WORKFLOW_REF" = "vicondoa/d2b/.github/workflows/build.yaml@refs/heads/main" ] ||
fail "reusable build controls must be sourced from protected main"
is_sha "$D2B_JOB_WORKFLOW_SHA" ||
fail "reusable workflow SHA is not a full immutable commit SHA"
fi
}

if [ "$D2B_EVENT_NAME" = "pull_request_target" ]; then
[ "$D2B_CALLER_WORKFLOW_REF" = "vicondoa/d2b/.github/workflows/pr.yml@refs/heads/main" ] ||
fail "PR workflow controls must be sourced from protected main"
[ "$D2B_JOB_WORKFLOW_REF" = "vicondoa/d2b/.github/workflows/build.yaml@refs/heads/main" ] ||
fail "reusable build controls must be sourced from protected main"
validate_optional_reusable_workflow
case "$D2B_BASE_REF" in
main|v3) ;;
*) fail "pull request target is not main or v3" ;;
Expand All @@ -110,6 +118,7 @@ jobs:
elif [ "$D2B_EVENT_NAME" = "push" ]; then
[ "$D2B_CALLER_WORKFLOW_REF" = "vicondoa/d2b/.github/workflows/build.yaml@refs/heads/main" ] ||
fail "push workflow controls must be sourced from protected main"
validate_optional_reusable_workflow
[ "$D2B_REF" = "refs/heads/main" ] ||
fail "trusted build pushes are restricted to main"
[ -z "$D2B_BASE_REF" ] || fail "push events must not carry a base ref"
Expand Down Expand Up @@ -202,6 +211,23 @@ jobs:
set -euo pipefail
test "$(git -C trusted rev-parse HEAD)" = "$D2B_TRUSTED_SHA"
test "$(git -C workspace rev-parse HEAD)" = "$D2B_TESTED_SHA"
- name: Prepare pinned Rust toolchain for parallel Layer-1 gates
working-directory: workspace
run: |
set -euo pipefail
if ! command -v rustup >/dev/null 2>&1; then
echo "rustup is unavailable; Rust gates will use their Nix fallback."
exit 0
fi
pinned_channel="$(
sed -n 's/^[[:space:]]*channel[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' \
packages/rust-toolchain.toml | head -1
)"
[ -n "$pinned_channel" ] || {
echo "::error::could not read the pinned Rust channel" >&2
exit 76
}
rustup toolchain install "$pinned_channel" --profile minimal --component rustfmt --component clippy
- name: Run credential-free local Layer-1 gate
working-directory: workspace
run: |
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ deprecations ship one minor release before removal.
- Fixed trusted `main` push validation and reusable workflow resolution so the
BuildBuddy seed workflow executes its metadata checks instead of failing on
shell test parsing.
- Accepted GitHub runs that omit `job_workflow_ref` and `job_workflow_sha` for
same-repository reusable workflows while still validating those immutable
identifiers whenever GitHub provides them.
- Prepared the pinned Rust toolchain before parallel local Layer-1 gates so
concurrent Rust and proof jobs do not race during rustup installation.

## [1.4.1] - 2026-07-12

Expand Down
61 changes: 61 additions & 0 deletions packages/xtask/tests/policy_ci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,43 @@ fn main_controlled_buildbuddy_workflows_preserve_trust_contract() {
&& build.contains("merge_sha"),
"build workflow must bind trusted and tested immutable OIDs"
);
assert!(
build.contains("trusted_sha=\"${D2B_JOB_WORKFLOW_SHA:-$D2B_CALLER_WORKFLOW_SHA}\""),
"trusted workflow SHA must fall back to the caller SHA when job metadata is absent"
);
let helper_start = build
.find(" validate_optional_reusable_workflow() {")
.expect("build workflow must define optional reusable-workflow validation");
let pr_validation_start = build
.find(" if [ \"$D2B_EVENT_NAME\" = \"pull_request_target\" ]")
.expect("build workflow must validate pull_request_target metadata");
let push_validation_start = build
.find(" elif [ \"$D2B_EVENT_NAME\" = \"push\" ]")
.expect("build workflow must validate push metadata");
let helper_end = helper_start
+ build[helper_start..pr_validation_start]
.find("\n }\n\n")
.expect("optional reusable-workflow validator must end before event validation");
let helper = &build[helper_start..helper_end];
assert!(
helper.contains(
"if [ -n \"$D2B_JOB_WORKFLOW_REF\" ] || [ -n \"$D2B_JOB_WORKFLOW_SHA\" ]; then"
) && helper.contains(
"[ \"$D2B_JOB_WORKFLOW_REF\" = \"vicondoa/d2b/.github/workflows/build.yaml@refs/heads/main\" ]"
) && helper.contains("is_sha \"$D2B_JOB_WORKFLOW_SHA\""),
"optional reusable-workflow metadata checks must stay inside their validator"
);
let push_validation_end = push_validation_start
+ build[push_validation_start..]
.find("\n else\n fail \"only pull_request_target and push events are accepted\"")
.expect("build workflow event validation must have a bounded fallback branch");
assert!(
build[pr_validation_start..push_validation_start]
.contains(" validate_optional_reusable_workflow\n")
&& build[push_validation_start..push_validation_end]
.contains(" validate_optional_reusable_workflow\n"),
"optional reusable-workflow metadata validation must bind to both event paths"
);
assert!(
build.matches("persist-credentials: false").count() >= 4,
"trusted and source checkouts must not persist credentials"
Expand Down Expand Up @@ -211,6 +248,30 @@ fn main_controlled_buildbuddy_workflows_preserve_trust_contract() {
&& build.contains("D2B_BAZEL_UNTRUSTED: \"1\""),
"full PR coverage must retain a credential-free local Layer-1 gate"
);
let local_job_start = build
.find("\n local:\n")
.expect("build workflow must define a local job");
let local_job_end = local_job_start
+ build[local_job_start..]
.find("\n remote:\n")
.expect("build workflow must define a remote job");
let local_job = &build[local_job_start..local_job_end];
let rust_bootstrap = local_job
.find(" - name: Prepare pinned Rust toolchain for parallel Layer-1 gates")
.expect("local Layer-1 gate must prepare the shared Rust toolchain");
let local_gate = local_job
.find(" - name: Run credential-free local Layer-1 gate")
.expect("local Layer-1 gate step must be present");
let rust_bootstrap_step = &local_job[rust_bootstrap..local_gate];
assert!(
rust_bootstrap < local_gate
&& rust_bootstrap_step.contains("working-directory: workspace")
&& rust_bootstrap_step.contains("packages/rust-toolchain.toml")
&& rust_bootstrap_step
.contains("rustup toolchain install \"$pinned_channel\" --profile minimal")
&& rust_bootstrap_step.contains("--component rustfmt --component clippy"),
"parallel local Layer-1 jobs must share a preinstalled pinned Rust toolchain"
);
assert!(
build.contains("github.event_name == 'push'")
&& build.contains("github.event_name == 'push' }}"),
Expand Down
Loading