Skip to content

Commit 1534284

Browse files
Copilotjamesadevine
andcommitted
fix(release): rebadge scripts bundle as ado-script
Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/eb18237a-9266-4098-bb63-db9816eb03fd Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com>
1 parent 206312b commit 1534284

11 files changed

Lines changed: 60 additions & 77 deletions

File tree

.github/workflows/release.yml

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -67,29 +67,13 @@ jobs:
6767
run: |
6868
npm ci
6969
npm run build
70-
# `npm run build` runs codegen + ncc + copies dist/gate/index.js
71-
# to ../gate.js (i.e. scripts/gate.js), which is then included in
72-
# scripts.zip by the next step.
70+
# `npm run build` runs codegen + ncc and outputs dist/gate/index.js.
7371

74-
- name: Package scripts bundle
72+
- name: Package ado-script bundle
7573
run: |
7674
set -euo pipefail
7775
cd scripts
78-
# Only ship the bundled artefacts that pipelines actually
79-
# download and execute (currently: gate.js). The TS source,
80-
# tests, and tooling under ado-script/ are excluded — they
81-
# live in the repo for development and CI, not in the release.
82-
zip -r ../scripts.zip . \
83-
-x "ado-script/node_modules/*" \
84-
-x "ado-script/dist/*" \
85-
-x "ado-script/schema/*" \
86-
-x "ado-script/src/*" \
87-
-x "ado-script/test/*" \
88-
-x "ado-script/package*.json" \
89-
-x "ado-script/tsconfig.json" \
90-
-x "ado-script/vitest.config*.ts" \
91-
-x "ado-script/README.md" \
92-
-x "ado-script/.gitignore"
76+
zip -r ../ado-script.zip ado-script/dist
9377
9478
- name: Upload release assets
9579
env:
@@ -98,7 +82,7 @@ jobs:
9882
TAG="${{ needs.release-please.outputs.tag_name || github.event.inputs.tag_name }}"
9983
gh release upload "$TAG" \
10084
target/release/ado-aw-linux-x64 \
101-
scripts.zip \
85+
ado-script.zip \
10286
--clobber
10387
10488
build-windows:
@@ -188,13 +172,13 @@ jobs:
188172
TAG="${{ needs.release-please.outputs.tag_name || github.event.inputs.tag_name }}"
189173
gh release download "$TAG" \
190174
--pattern "ado-aw-*" \
191-
--pattern "scripts.zip" \
175+
--pattern "ado-script.zip" \
192176
--repo "${{ github.repository }}"
193177
test -f ado-aw-linux-x64 || { echo "Missing ado-aw-linux-x64"; exit 1; }
194178
test -f ado-aw-windows-x64.exe || { echo "Missing ado-aw-windows-x64.exe"; exit 1; }
195179
test -f ado-aw-darwin-arm64 || { echo "Missing ado-aw-darwin-arm64"; exit 1; }
196-
test -f scripts.zip || { echo "Missing scripts.zip"; exit 1; }
197-
sha256sum ado-aw-linux-x64 ado-aw-windows-x64.exe ado-aw-darwin-arm64 scripts.zip > checksums.txt
180+
test -f ado-script.zip || { echo "Missing ado-script.zip"; exit 1; }
181+
sha256sum ado-aw-linux-x64 ado-aw-windows-x64.exe ado-aw-darwin-arm64 ado-script.zip > checksums.txt
198182
199183
- name: Upload checksums
200184
env:

docs/ado-script.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,8 @@ scripts/ado-script/ # TS workspace
6363
```
6464

6565
The release workflow (`.github/workflows/release.yml`) runs `npm ci &&
66-
npm run build` and copies `dist/gate/index.js` to `scripts/gate.js`,
67-
which is then included in the `scripts.zip` release asset that pipelines
68-
download at runtime.
66+
npm run build`, then packages `scripts/ado-script/dist/` as the
67+
`ado-script.zip` release asset that pipelines download at runtime.
6968

7069
## Schema codegen — preventing drift
7170

@@ -111,10 +110,11 @@ steps when any `filters:` block is active:
111110

112111
1. **`NodeTool@0`** — installs Node 20.x LTS (preinstalled on
113112
Microsoft-hosted images; pinned for reproducibility on others).
114-
2. **`curl` download** — fetches `scripts.zip` from the
113+
2. **`curl` download** — fetches `ado-script.zip` from the
115114
`githubnext/ado-aw` release matching the compiler's version and
116-
extracts `gate.js` to `/tmp/ado-aw-scripts/gate.js`.
117-
3. **`bash: node '/tmp/ado-aw-scripts/gate.js'`** — runs the gate with
115+
extracts `ado-script/dist/gate/index.js` to
116+
`/tmp/ado-aw-scripts/ado-script/dist/gate/index.js`.
117+
3. **`bash: node '/tmp/ado-aw-scripts/ado-script/dist/gate/index.js'`** — runs the gate with
118118
`GATE_SPEC` (base64 JSON) plus required pipeline env vars.
119119

120120
The IR-to-bash codegen lives in `compile_gate_step_external`

docs/filter-ir.md

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ require heuristic analysis and could produce false positives.
235235

236236
Produces a complete ADO pipeline step (`- bash: |`) with a **data-driven
237237
architecture**: bash is a thin ADO-macro shim, all filter logic lives in
238-
the bundled Node.js gate evaluator (`scripts/gate.js`) that reads a JSON
238+
the bundled Node.js gate evaluator (`scripts/ado-script/dist/gate/index.js`) that reads a JSON
239239
gate spec.
240240

241241
#### Generated Step Structure
@@ -257,7 +257,7 @@ gate spec.
257257
export ADO_SYSTEM_ACCESS_TOKEN="$SYSTEM_ACCESSTOKEN"
258258
259259
# 4. Run the bundled Node evaluator (downloaded by the Setup job)
260-
node '/tmp/ado-aw-scripts/gate.js'
260+
node '/tmp/ado-aw-scripts/ado-script/dist/gate/index.js'
261261
name: prGate
262262
displayName: "Evaluate PR filters"
263263
env:
@@ -304,8 +304,8 @@ acquisition logic.
304304
#### Bundled Gate Evaluator (`scripts/ado-script/src/gate/`)
305305

306306
The evaluator is a TypeScript program ncc-bundled to a single
307-
self-contained `scripts/gate.js` (~1.1 MB) that ships as part of the
308-
`scripts.zip` release asset. See [`ado-script.md`](ado-script.md) for the
307+
self-contained `scripts/ado-script/dist/gate/index.js` (~1.1 MB) that ships as part of the
308+
`ado-script.zip` release asset. See [`ado-script.md`](ado-script.md) for the
309309
full design and codegen pipeline. It handles:
310310

311311
1. **Bypass logic** — reads `ADO_BUILD_REASON` and exits early for non-matching
@@ -358,11 +358,11 @@ When Tier 2/3 filters are configured, the `TriggerFiltersExtension`
358358

359359
1. **Node install step** — emits a `NodeTool@0` step pinned to Node 20.x
360360
LTS so `gate.js` has a runtime
361-
2. **Download step** — fetches `scripts.zip` from the ado-aw release
361+
2. **Download step** — fetches `ado-script.zip` from the ado-aw release
362362
artifacts, verifies its SHA256 checksum via `checksums.txt`, then
363-
extracts `gate.js` to `/tmp/ado-aw-scripts/gate.js`
363+
extracts `gate.js` to `/tmp/ado-aw-scripts/ado-script/dist/gate/index.js`
364364
3. **Gate step** — calls `compile_gate_step_external()` to generate a step
365-
that runs `node /tmp/ado-aw-scripts/gate.js` (no inline heredoc)
365+
that runs `node /tmp/ado-aw-scripts/ado-script/dist/gate/index.js` (no inline heredoc)
366366
4. **Validation** — runs `validate_pr_filters()` / `validate_pipeline_filters()`
367367
during compilation via the `validate()` trait method
368368

@@ -409,18 +409,18 @@ The `expression` escape hatch is also ANDed if present.
409409
### Scripts Distribution
410410

411411
The `gate.js` bundle is built from the TypeScript workspace at
412-
`scripts/ado-script/` (see [`ado-script.md`](ado-script.md)) and copied to
413-
`scripts/gate.js` by the release workflow's build step. It ships inside
414-
the `scripts.zip` release asset, alongside any future bundled helpers
412+
`scripts/ado-script/` (see [`ado-script.md`](ado-script.md)) and emitted to
413+
`scripts/ado-script/dist/gate/index.js` by the release workflow's build step. It ships inside
414+
the `ado-script.zip` release asset, alongside any future bundled helpers
415415
(e.g. `poll.js`, `stats.js`). The download URL is deterministic based on
416416
the ado-aw version:
417-
`https://github.com/githubnext/ado-aw/releases/download/v{VERSION}/scripts.zip`
417+
`https://github.com/githubnext/ado-aw/releases/download/v{VERSION}/ado-script.zip`
418418

419419
A `checksums.txt` file is also published at the same URL base and used to
420-
verify the SHA256 integrity of `scripts.zip` before extraction.
420+
verify the SHA256 integrity of `ado-script.zip` before extraction.
421421

422-
The Setup-job download step pulls the zip, extracts `gate.js`, and
423-
discards the rest. New per-use-site bundles follow the same pattern
422+
The Setup-job download step pulls the zip, extracts `ado-script/dist/gate/index.js`,
423+
and discards the rest. New per-use-site bundles follow the same pattern
424424
(per-bundle ncc entry + per-bundle download step).
425425

426426
## Adding New Filter Types
@@ -439,4 +439,3 @@ step-by-step guide. In summary:
439439
`lower_pipeline_filters`)
440440
6. Add validation rules if the new filter can conflict with existing ones
441441
7. Write tests: lowering, validation, spec serialization, and evaluator
442-

scripts/ado-script/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# @ado-aw/scripts
22

3-
Bundled TypeScript scripts shipped in `scripts.zip` alongside the ado-aw release.
3+
Bundled TypeScript scripts shipped in `ado-script.zip` alongside the ado-aw release.
44

55
## Bundles
66

@@ -20,7 +20,7 @@ This invokes `cargo run -- export-gate-schema` to write the JSON Schema, then ru
2020

2121
- `src/shared/` — modules shared across all bundles (auth, ado-client, vso-logger, env-facts, policy state machine)
2222
- `src/gate/` — gate evaluator entry point and per-concern modules
23-
- `dist/` — ncc bundle output (gitignored); `npm run build` copies the gate bundle to `../gate.js` for inclusion in `scripts.zip`
23+
- `dist/` — ncc bundle output (gitignored); `npm run build` writes `dist/gate/index.js`, which ships in `ado-script.zip`
2424

2525
## See also
2626

scripts/ado-script/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
"node": ">=20.0.0"
88
},
99
"scripts": {
10-
"build": "npm run codegen && npm run build:gate && cp dist/gate/index.js ../gate.js",
10+
"build": "npm run codegen && npm run build:gate",
1111
"build:gate": "ncc build src/gate/index.ts -o dist/gate -m -t",
12-
"build:check": "ls -lh ../gate.js && wc -c ../gate.js",
12+
"build:check": "ls -lh dist/gate/index.js && wc -c dist/gate/index.js",
1313
"codegen": "mkdir -p schema && cargo run --quiet --manifest-path ../../Cargo.toml -- export-gate-schema --output schema/gate-spec.schema.json && npx json2ts schema/gate-spec.schema.json -o src/shared/types.gen.ts --bannerComment \"// AUTO-GENERATED from Rust IR via cargo run -- export-gate-schema. Do not edit; run npm run codegen.\"",
1414
"test": "vitest run",
1515
"test:smoke": "npm run build && vitest run -c vitest.config.smoke.ts",

scripts/ado-script/src/gate/predicates.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ export function evaluatePredicate(p: PredicateSpec, facts: Map<string, unknown>)
149149
const unknownType = (p as { type?: unknown }).type;
150150
logWarning(
151151
`Unknown predicate type '${String(unknownType)}'; failing closed. ` +
152-
"Update scripts/gate.js (or the bundled scripts.zip) to a " +
152+
"Update scripts/ado-script/dist/gate/index.js (or the bundled ado-script.zip) to a " +
153153
"release that supports this predicate.",
154154
);
155155
return false;

scripts/ado-script/src/shared/types.gen.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export type PredicateSpec =
7676

7777
/**
7878
* Serializable gate specification — the JSON document consumed by the
79-
* Node gate evaluator (`scripts/gate.js`) at pipeline runtime.
79+
* Node gate evaluator (`scripts/ado-script/dist/gate/index.js`) at pipeline runtime.
8080
*/
8181
export interface GateSpec {
8282
checks: CheckSpec[];

src/compile/extensions/trigger_filters.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::compile::filter_ir::{
1818
use crate::compile::types::{PipelineFilters, PrFilters};
1919

2020
/// The path where the gate evaluator is downloaded at pipeline runtime.
21-
const GATE_EVAL_PATH: &str = "/tmp/ado-aw-scripts/gate.js";
21+
const GATE_EVAL_PATH: &str = "/tmp/ado-aw-scripts/ado-script/dist/gate/index.js";
2222

2323
/// Base URL for ado-aw release artifacts.
2424
const RELEASE_BASE_URL: &str = "https://github.com/githubnext/ado-aw/releases/download";
@@ -115,9 +115,9 @@ impl CompilerExtension for TriggerFiltersExtension {
115115
set -eo pipefail
116116
mkdir -p /tmp/ado-aw-scripts
117117
curl -fsSL "{RELEASE_BASE_URL}/v{version}/checksums.txt" -o /tmp/ado-aw-scripts/checksums.txt
118-
curl -fsSL "{RELEASE_BASE_URL}/v{version}/scripts.zip" -o /tmp/ado-aw-scripts/scripts.zip
119-
cd /tmp/ado-aw-scripts && grep "scripts.zip" checksums.txt | sha256sum -c -
120-
cd /tmp/ado-aw-scripts && unzip -jo scripts.zip gate-eval.py
118+
curl -fsSL "{RELEASE_BASE_URL}/v{version}/ado-script.zip" -o /tmp/ado-aw-scripts/ado-script.zip
119+
cd /tmp/ado-aw-scripts && grep "ado-script.zip" checksums.txt | sha256sum -c -
120+
cd /tmp/ado-aw-scripts && unzip -o ado-script.zip
121121
displayName: "Download ado-aw scripts (v{version})"
122122
condition: succeeded()"#,
123123
));
@@ -241,24 +241,24 @@ mod tests {
241241
assert!(steps[0].contains("20.x"), "should install Node 20.x");
242242
assert!(steps[1].contains("curl"), "second step should download");
243243
assert!(
244-
steps[1].contains("scripts.zip"),
245-
"should download scripts.zip"
244+
steps[1].contains("ado-script.zip"),
245+
"should download ado-script.zip"
246246
);
247247
assert!(
248248
steps[1].contains("checksums.txt"),
249249
"should download checksums.txt"
250250
);
251251
assert!(
252252
steps[1].contains("sha256sum -c -"),
253-
"should verify scripts.zip checksum"
253+
"should verify ado-script.zip checksum"
254254
);
255255
assert!(
256-
steps[1].contains("unzip -jo scripts.zip gate-eval.py"),
257-
"should extract only gate-eval.py"
256+
steps[1].contains("unzip -o ado-script.zip"),
257+
"should extract ado-script.zip"
258258
);
259259
assert!(steps[2].contains("prGate"), "third step should be PR gate");
260260
assert!(
261-
steps[2].contains("node '/tmp/ado-aw-scripts/gate.js'"),
261+
steps[2].contains("node '/tmp/ado-aw-scripts/ado-script/dist/gate/index.js'"),
262262
"gate step should reference external script"
263263
);
264264
}

src/compile/filter_ir.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ use schemars::JsonSchema;
814814
use serde::Serialize;
815815

816816
/// Serializable gate specification — the JSON document consumed by the
817-
/// Node gate evaluator (`scripts/gate.js`) at pipeline runtime.
817+
/// Node gate evaluator (`scripts/ado-script/dist/gate/index.js`) at pipeline runtime.
818818
#[derive(Debug, Clone, Serialize, JsonSchema)]
819819
pub struct GateSpec {
820820
pub context: GateContextSpec,
@@ -1519,7 +1519,7 @@ mod tests {
15191519
let result = compile_gate_step_external(
15201520
GateContext::PullRequest,
15211521
&[],
1522-
"/tmp/ado-aw-scripts/gate.js",
1522+
"/tmp/ado-aw-scripts/ado-script/dist/gate/index.js",
15231523
)
15241524
.unwrap();
15251525
assert!(result.is_empty());
@@ -1538,7 +1538,7 @@ mod tests {
15381538
let result = compile_gate_step_external(
15391539
GateContext::PullRequest,
15401540
&checks,
1541-
"/tmp/ado-aw-scripts/gate.js",
1541+
"/tmp/ado-aw-scripts/ado-script/dist/gate/index.js",
15421542
)
15431543
.unwrap();
15441544
assert!(result.contains("- bash:"), "should be a bash step");
@@ -1547,7 +1547,7 @@ mod tests {
15471547
"should include base64 spec in env"
15481548
);
15491549
assert!(
1550-
result.contains("node '/tmp/ado-aw-scripts/gate.js'"),
1550+
result.contains("node '/tmp/ado-aw-scripts/ado-script/dist/gate/index.js'"),
15511551
"should reference external evaluator script"
15521552
);
15531553
assert!(result.contains("name: prGate"), "should set step name");
@@ -1570,7 +1570,7 @@ mod tests {
15701570
let result = compile_gate_step_external(
15711571
GateContext::PullRequest,
15721572
&checks,
1573-
"/tmp/ado-aw-scripts/gate.js",
1573+
"/tmp/ado-aw-scripts/ado-script/dist/gate/index.js",
15741574
)
15751575
.unwrap();
15761576
assert!(
@@ -1597,7 +1597,7 @@ mod tests {
15971597
let result = compile_gate_step_external(
15981598
GateContext::PipelineCompletion,
15991599
&checks,
1600-
"/tmp/ado-aw-scripts/gate.js",
1600+
"/tmp/ado-aw-scripts/ado-script/dist/gate/index.js",
16011601
)
16021602
.unwrap();
16031603
assert!(
@@ -1627,7 +1627,7 @@ mod tests {
16271627
let result = compile_gate_step_external(
16281628
GateContext::PullRequest,
16291629
&checks,
1630-
"/tmp/ado-aw-scripts/gate.js",
1630+
"/tmp/ado-aw-scripts/ado-script/dist/gate/index.js",
16311631
)
16321632
.unwrap();
16331633
assert!(
@@ -1653,7 +1653,7 @@ mod tests {
16531653
let result = compile_gate_step_external(
16541654
GateContext::PullRequest,
16551655
&checks,
1656-
"/tmp/ado-aw-scripts/gate.js",
1656+
"/tmp/ado-aw-scripts/ado-script/dist/gate/index.js",
16571657
)
16581658
.unwrap();
16591659
// Check export lines only (evaluator script always contains these strings)
@@ -1746,7 +1746,7 @@ mod tests {
17461746
let step = compile_gate_step_external(
17471747
GateContext::PullRequest,
17481748
&checks,
1749-
"/tmp/ado-aw-scripts/gate.js",
1749+
"/tmp/ado-aw-scripts/ado-script/dist/gate/index.js",
17501750
)
17511751
.unwrap();
17521752
// Step structure

tests/compiler_tests.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3972,7 +3972,7 @@ fn test_pr_filter_tier1_compiled_output_is_valid_yaml() {
39723972
assert_valid_yaml(&compiled, "pr-filter-tier1-agent.md");
39733973
}
39743974

3975-
/// Tier 1 PR filters now also use the Python evaluator via extension.
3975+
/// Tier 1 PR filters use the bundled Node evaluator via extension.
39763976
#[test]
39773977
fn test_pr_filter_tier1_has_evaluator_gate() {
39783978
let compiled = compile_fixture("pr-filter-tier1-agent.md");
@@ -3990,11 +3990,11 @@ fn test_pr_filter_tier1_has_evaluator_gate() {
39903990
"Should include base64-encoded spec"
39913991
);
39923992
assert!(
3993-
compiled.contains("node '/tmp/ado-aw-scripts/gate.js'"),
3993+
compiled.contains("node '/tmp/ado-aw-scripts/ado-script/dist/gate/index.js'"),
39943994
"Should invoke node gate evaluator"
39953995
);
39963996
assert!(
3997-
compiled.contains("scripts.zip"),
3997+
compiled.contains("ado-script.zip"),
39983998
"Should download scripts bundle"
39993999
);
40004000
assert!(
@@ -4020,15 +4020,15 @@ fn test_pr_filter_tier2_has_extension_gate() {
40204020
"Should create Setup job for PR filters"
40214021
);
40224022
assert!(
4023-
compiled.contains("scripts.zip"),
4023+
compiled.contains("ado-script.zip"),
40244024
"Tier 2 should download scripts bundle"
40254025
);
40264026
assert!(
40274027
compiled.contains("GATE_SPEC"),
40284028
"Tier 2 should include base64-encoded spec"
40294029
);
40304030
assert!(
4031-
compiled.contains("node '/tmp/ado-aw-scripts/gate.js'"),
4031+
compiled.contains("node '/tmp/ado-aw-scripts/ado-script/dist/gate/index.js'"),
40324032
"Tier 2 should invoke node gate evaluator"
40334033
);
40344034
assert!(compiled.contains("name: prGate"), "Should have prGate step");

0 commit comments

Comments
 (0)