Skip to content

Commit 5cdcaeb

Browse files
committed
dynamically build build_paths
1 parent 4bc7619 commit 5cdcaeb

3 files changed

Lines changed: 118 additions & 19 deletions

File tree

.github/workflows/build.yml

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,25 +36,8 @@ env:
3636
3737
# DEPENDENCY_CACHE_KEY: can't be set here because we don't have access to yarn.lock
3838

39-
# These are the core build paths used for most tests etc.
40-
BUILD_PATHS: |
41-
${{ github.workspace }}/packages/*/build/esm
42-
${{ github.workspace }}/packages/*/build/cjs
43-
${{ github.workspace }}/packages/*/build/npm/esm
44-
${{ github.workspace }}/packages/*/build/npm/cjs
45-
${{ github.workspace }}/packages/*/build/types
46-
${{ github.workspace }}/packages/*/build/types-ts3.8
47-
${{ github.workspace }}/packages/*/build/npm/types
48-
${{ github.workspace }}/packages/*/build/npm/types-ts3.8
49-
${{ github.workspace }}/packages/*/*.d.ts
50-
${{ github.workspace }}/packages/angular/build/esm2015
51-
${{ github.workspace }}/packages/angular/build/fesm2015
52-
${{ github.workspace }}/packages/angular/build/fesm2020
53-
${{ github.workspace }}/packages/angular/build/*.d.ts
54-
${{ github.workspace }}/packages/aws-serverless/build/lambda-extension
55-
${{ github.workspace }}/dev-packages/*/build/esm
56-
${{ github.workspace }}/dev-packages/*/build/cjs
57-
${{ github.workspace }}/dev-packages/*/build/types
39+
# BUILD_PATHS for the build-output artifact is set in job_build via
40+
# yarn ci:print-build-artifact-paths (Nx merged outputs for build:transpile, build:types, build:extension).
5841

5942
# upload-artifact globs drop the path through the first `*` (see upload-artifact
6043
# README). Tarballs therefore land in the artifact as <pkg>/*.tgz; download
@@ -128,6 +111,14 @@ jobs:
128111
- name: Build packages
129112
run: yarn build:ci
130113

114+
- name: Set BUILD_PATHS based on Nx graph
115+
run: |
116+
{
117+
echo 'BUILD_PATHS<<EOF'
118+
yarn --silent ci:print-build-artifact-paths
119+
echo 'EOF'
120+
} >> "$GITHUB_ENV"
121+
131122
- name: Store NX cache
132123
uses: actions/cache/save@v5
133124
# Only cache this per-PR to speed up CI.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"build:dev:watch": "nx run-many -t build:dev:watch",
1414
"build:tarball": "run-s clean:tarballs build:tarballs",
1515
"build:tarballs": "nx run-many -t build:tarball",
16+
"ci:print-build-artifact-paths": "node ./scripts/ci-print-build-artifact-paths.mjs",
1617
"changelog": "ts-node ./scripts/get-commit-list.ts",
1718
"generate-changelog": "ts-node ./scripts/generate-changelog.ts",
1819
"circularDepCheck": "nx run-many -t circularDepCheck",
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Prints multiline paths for actions/upload-artifact `path`, derived from the Nx project
4+
* graph: merged `outputs` of `build:transpile`, `build:types`, and `build:extension` for
5+
* every project under `packages/` and `dev-packages/`.
6+
*
7+
* Each line is an absolute path pattern suitable for @actions/glob (same style as the
8+
* previous hand-maintained BUILD_PATHS list). Uses a wildcard in the package name segment
9+
* plus a shared path suffix, except for the single-segment `build` output directory, which
10+
* must stay concrete (`packages/deno/build`) so we do not match every package's `build/` tree.
11+
*
12+
* Usage: GITHUB_WORKSPACE=<abs repo> yarn ci:print-build-artifact-paths
13+
* (defaults to cwd when GITHUB_WORKSPACE is unset)
14+
*/
15+
import { execSync } from "node:child_process";
16+
import fs from "node:fs";
17+
import path from "node:path";
18+
import { fileURLToPath } from "node:url";
19+
20+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
21+
const workspaceRoot = path.resolve(__dirname, "..");
22+
const graphPath = path.join(
23+
workspaceRoot,
24+
".nx",
25+
"ci-print-build-artifact-paths-graph.json",
26+
);
27+
28+
const TARGETS = ["build:transpile", "build:types", "build:extension"];
29+
30+
fs.mkdirSync(path.dirname(graphPath), { recursive: true });
31+
execSync(`yarn nx graph --file="${graphPath}"`, {
32+
cwd: workspaceRoot,
33+
stdio: ["ignore", "pipe", "inherit"],
34+
});
35+
36+
const { graph } = JSON.parse(fs.readFileSync(graphPath, "utf8"));
37+
try {
38+
fs.unlinkSync(graphPath);
39+
} catch {
40+
// ignore
41+
}
42+
43+
/** @type {Map<string, Set<string>>} key = `${kind}\0${suffix}` */
44+
const groups = new Map();
45+
46+
for (const node of Object.values(graph.nodes)) {
47+
const root = node.data?.root;
48+
if (
49+
!root ||
50+
(!root.startsWith("packages/") && !root.startsWith("dev-packages/"))
51+
) {
52+
continue;
53+
}
54+
55+
const [kind, pkg] = root.split("/");
56+
if (!kind || !pkg) {
57+
continue;
58+
}
59+
60+
const targets = node.data?.targets || {};
61+
for (const targetName of TARGETS) {
62+
const outputs = targets[targetName]?.outputs;
63+
if (!Array.isArray(outputs)) {
64+
continue;
65+
}
66+
67+
for (const output of outputs) {
68+
const rel = output.replace(/\{projectRoot\}/g, root).replace(/\\/g, "/");
69+
const prefix = `${kind}/${pkg}/`;
70+
if (!rel.startsWith(prefix)) {
71+
throw new Error(
72+
`Unexpected Nx output (missing project prefix): ${rel}`,
73+
);
74+
}
75+
const suffix = rel.slice(prefix.length);
76+
const key = `${kind}\0${suffix}`;
77+
if (!groups.has(key)) {
78+
groups.set(key, new Set());
79+
}
80+
groups.get(key).add(pkg);
81+
}
82+
}
83+
}
84+
85+
const ws = (process.env.GITHUB_WORKSPACE || workspaceRoot).replace(/\\/g, "/");
86+
const lines = new Set();
87+
88+
for (const [key, pkgSet] of groups) {
89+
const [kind, suffix] = key.split("\0");
90+
const needsConcretePath =
91+
pkgSet.size === 1 &&
92+
!suffix.includes("/") &&
93+
!/[?*]/.test(suffix) &&
94+
suffix === "build";
95+
96+
if (needsConcretePath) {
97+
const pkg = [...pkgSet][0];
98+
lines.add(`${ws}/${kind}/${pkg}/build`);
99+
} else {
100+
lines.add(`${ws}/${kind}/*/${suffix}`);
101+
}
102+
}
103+
104+
process.stdout.write([...lines].sort((a, b) => a.localeCompare(b)).join("\n"));
105+
if (lines.size) {
106+
process.stdout.write("\n");
107+
}

0 commit comments

Comments
 (0)