Validation pipeline foundation (P1+P2): validate floor + trusted lane as shadow checks - #866
Merged
Merged
Conversation
…ness Re-home validate-sample.sh into public .github/scripts/ — a verbatim logic port of .azure-pipelines/validation.yml Stage 2, whose 5 duplicated per-language bash jobs collapse into one function set. Net-new vs. ADO: the 3-way classifier (pass=0 / fail=1 / error=2, ERROR never quarantines) and --results-dir / $GITHUB_OUTPUT emit. Adds real per-language good/broken fixtures, a generalized 5-language exit gate (run-tests.sh, with a scrubbed-PATH ERROR proof), and an inert contents:read workflow that runs the gate on a real runner. The harness triggers only on workflow_dispatch (inert stub) + pull_request into the integration branch — never on public main traffic. Credential-free: no secrets, no OIDC. ADO Task 5015439 (P1.1): https://msdata.visualstudio.com/Vienna/_workitems/edit/5015439 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: b970b82c-3e04-4c0a-970c-e2aef97c714b
…lf-test Ports the private ADO DetectChanges stage to a GH-Actions-native detector: changed files under samples/ resolve to their nearest ancestor sample.yaml dir, deduped into a set exposed as job outputs (has_changes/count/samples) for needs.*.outputs consumption. Fail-loud on git diff error (ADO 5247751); empty set = docs-only short-circuit. Single deduped set instead of per-language has_<lang> booleans (language derived from path at fan-out). Sibling hermetic harness (git-only) + inert selftest workflow (contents:read, no secrets/OIDC, no on:paths). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 441d830f-ce1e-4ebf-bdbf-cdf84cafef1f
…s the step's output file The unit harness invokes the detector ~10x and asserts on stdout; on a runner each call was appending has_changes/count/samples to the real \, which GitHub then rejected. Unset it in the harness — the GITHUB_OUTPUT emission is proven separately by the detect->consume plumbing job. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 441d830f-ce1e-4ebf-bdbf-cdf84cafef1f
grep -c on an empty file prints 0 AND exits 1, so the '|| echo 0' fallback double-printed, making COUNT=\
…est-effort fetch) Non-behavioral: adds a Known-limitations comment block above resolve_base_ref capturing the three faithful-port characteristics surfaced in the P1.2 Chapter-1 walkthrough (two-dot PR diff, HEAD~1 final-transition-only on push, best-effort fetch staleness). No logic change to the frozen DetectChanges port. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 441d830f-ce1e-4ebf-bdbf-cdf84cafef1f
One-page companion to detect-changed-samples.sh: the five-move flow, the fail-loud rule, the input/output contract, the needs.*.outputs wiring note, and the two tracked known-characteristics follow-ups (ADO 5473511, 5473651). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 441d830f-ce1e-4ebf-bdbf-cdf84cafef1f
pip/npm install failures with positive transport evidence (DNS / connection refused-reset / timeout / registry 5xx) now classify as error (exit 2) instead of failure (exit 1); unaccompanied resolution errors stay failure. Transport evidence wins even when pip prints its misleading 'No matching distribution' line after exhausting retries against an unreachable index. - dep_infra_signature() narrow transport allow-list, routed on the two dedicated install steps only (merged build tools stay failure - documented limit) - CLASSIFICATION.md: exit contract, taxonomy, ambiguity-bias, honest limits - run-tests.sh: real-runner blackhole cases (pip/npm -> error) + hermetic no-index resolution failure (-> fail); new python-deps / typescript-deps fixtures ADO 5449687: https://msdata.visualstudio.com/Vienna/_workitems/edit/5449687 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6b0ffec6-9f36-4309-80ef-adb79f1de81a
npm install --silent suppresses error output too, so the captured log was empty and dep_infra_signature saw no transport evidence -> blackhole misclassified as fail. Real-runner proof (run 30309241864) caught this: pip cases passed, npm registry-unreachable got fail instead of error. Switch to --no-audit --no-fund --loglevel=error: quiet on success, ECONNREFUSED still emitted and captured. ADO 5449687: https://msdata.visualstudio.com/Vienna/_workitems/edit/5449687 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6b0ffec6-9f36-4309-80ef-adb79f1de81a
Microsoft Security is blocking direct public-npm access on managed devices (CFS-protected feed); a held package can return 403/blocked, which the 5xx-only allow-list doesn't promote to error. Documented as a v1 honest limit + deferred follow-up. Doc-only; no classifier change (runner-proven behavior is commit 391ba22). ADO 5449687: https://msdata.visualstudio.com/Vienna/_workitems/edit/5449687 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6b0ffec6-9f36-4309-80ef-adb79f1de81a
Documents that the public-first validation path is already fully GitHub-Actions-native (zero ADO-isms): every UseDotNet@2/UsePythonVersion@0/NodeTool@0/JavaToolInstaller@0/GoTool@0 setup task maps to a pinned setup-* action; cross-job data flows via needs.*.outputs; CheckMailmap + Report/status-posting intentionally dropped; artifact fan-out + aggregation deferred to P2. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a7d3b36b-7970-4500-888e-af959a5a5066
Real PR-triggered floor lane (distinct from the inert self-tests): on: pull_request (never pull_request_target), permissions contents:read only, no environment/secrets. detect-changed-samples.sh finds changed samples in-job; a matrix fans out one runner per sample and validates to L3 via validate-sample.sh, deriving --language from the samples/<dir>/ path. Untrusted fork code runs on a barren runner by design. ADO 5449695 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: c4e21e67-bf10-42a8-9e21-98dde95aa89f
Adds the credentialed trusted counterpart to the P2.1 floor lane as a third job (trusted) in validate.yml, producing required-check context 'validate / trusted'. Single job (no matrix); fork+draft gated via job-level if; docs-only short-circuit before any secret step; in-job parallel L3; L4 via warm project (SKIP_PROVISION=true) with OIDC login to env L4-validation. Reuses shared detect + validate-sample.sh scripts unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 446e89c2-fad1-4300-bdc7-fcd2599deb24
Replace the two inert *-selftest.yml dev harnesses (which only fired on PRs based on a throwaway dev branch, so never on real traffic) with one lean .github/workflows/scripts-selftest.yml that triggers on pull_request + paths: ['.github/scripts/**'] (plus workflow_dispatch). Jobs (contents:read only, non-required, separate from validate.yml): - detect-harness: hermetic run-detect-tests.sh - validate-harness: 5 toolchain setups + yq, run-tests.sh (must reach exit 0) - detect -> consume: trimmed needs.*.outputs isolation proof (non-empty case; docs-only empty-result contract already pinned by run-detect-tests.sh case h) Repoint now-dangling references to the deleted workflows in CLASSIFICATION.md and detect-changed-samples.README.md; add a post-consolidation banner to the historical P1.4 WRAPPER-MAPPING.md audit. Validated: actionlint + shellcheck clean; hermetic detect harness 23/23 GREEN locally; validate harness PARTIAL locally with 0 failures (toolchain-gated cases skip, provided by the runner).
…ADO 5449688 + git history) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3417ac9a-6d98-4124-b452-44410f3c3960
Merge-forward to bring public main into the P1+P2 validation-pipeline stack ahead of the shadow go-live PR (ADO 5486308). Stack is purely additive vs merge-base; no .github changes on main since merge-base.
Contributor
|
👋 Thanks for your contribution, @brandom-msft! This repository is read-only. If you are contributing on behalf of Microsoft, please submit your PR to the private staging repository instead: See CONTRIBUTING.md for full instructions. |
brandom-msft
temporarily deployed
to
L4-validation
July 31, 2026 16:46 — with
GitHub Actions
Inactive
brandom-msft
temporarily deployed
to
L4-validation
July 31, 2026 16:49 — with
GitHub Actions
Inactive
brandom-msft
changed the base branch from
brandom-msft-scripts-selftest-ci
to
main
July 31, 2026 16:56
Comment/doc-only cleanup on the composed P1+P2 change set. No YAML logic, script behavior, or trust/gate/fork logic changed. - validate.yml: scope the fork-safety 'no environment/no secrets' bullet to the fork-reachable detect/validate jobs so it no longer contradicts the trusted L4 lane described below; name scripts-selftest.yml directly instead of the stale *-selftest.yml glob. - run-detect-tests.sh: header case list now documents case (h) (GITHUB_OUTPUT hygiene) plus the --output-dir artifact assertion. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 348d520e-aad2-4b98-ba83-7c157597212d
brandom-msft
temporarily deployed
to
L4-validation
July 31, 2026 17:30 — with
GitHub Actions
Inactive
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.
Context
This merges the P1+P2 foundation of the public-first validation pipeline into
main. The whole stack was built as a linear feature-branch stack and has never landed on publicmain. Merging it here turns on the two PR checks —validate(the L3 "floor" matrix) andvalidate / trusted(the fork-gated L4 lane) — so they start running against real incoming PRs.These go live as SHADOW / non-required checks. Nothing in this PR marks any check as required and no branch ruleset is touched. Flipping to a required gate is a later, separate step (P3). Tracked as ADO 5486308 — https://msdata.visualstudio.com/Vienna/_workitems/edit/5486308 (under Feature 5449671).
What changed
.github/workflows/validate.yml(detect→validatefloor matrix → singletrustedjob) and.github/workflows/scripts-selftest.yml(script self-test harness, real-triggered).validate-sample.sh(single-sample L3 validator),detect-changed-samples.sh(in-job, data-driven change detection), plusCLASSIFICATION.mdanddetect-changed-samples.README.md..github/scripts/test/(go / python / typescript / csharp / java / csharp-yaml — good, broken, and deps variants).mainwas merged into this branch (merge commit2ab3c5c) to bring it current; the merge was clean (ort, no conflicts) becausemainhas zero changes under.github/since the merge-base. The stack's.github/tree is byte-identical to its pre-merge tip.Why this matters
Turning these on as shadow checks lets us observe real signal (pass/fail/error classification) on live PRs — including fork PRs — with zero risk of blocking contributors, and establishes the precondition for making the floor a required gate in P3.
Design properties (frozen — unchanged by this PR)
validate.ymlison: pull_request(neverpull_request_target) withpermissions: contents: read— fork-safe by construction: fork code executes on a barren, secret-less runner.trustedL4 lane is a single job (never a matrix), so its check context is exactlyvalidate / trusted; it is draft-skipped and fork-gated.redirect-pull-requests.yml,mirror-back.yml,run-setup.yml,mirror-back.sh) are untouched by this merge.Static-analysis notes (for reviewer transparency)
Local actionlint + shellcheck are clean apart from two pre-existing, benign false positives that predate this merge (the
.github/tree is byte-identical to the pre-merge tip) and are intentionally left as-is under the merge-only scope:validate.yml:270— SC1007: theGITHUB_OUTPUT=prefix is an intentional per-invocation empty-env assignment (documented inline).validate-sample.sh:349— SC2329:cleanup_python_venvis invoked indirectly viatrap ... EXIT(line 393).Notes & links
foundry-samples). Authoritative validation is the PR's own check runs, once they trigger.