Skip to content

Commit 7bd157e

Browse files
[Fixed] Run CI on a single machine by generating cloudbuild files (#4186)
* Run CI on a single machine by generating cloudbuild files Instead of running each CI test on a separate Google Cloud machine, generate a cloudbuild.yml file to test all affected packages on a single machine. The benifits of this strategy include the following: * Fewer machines are required for a single test (2 instead of up to 12), so queuing should happen much less often. * Packages only need to be built once, instead of once per machine. * Multithreaded steps have access to more cores. When CI is run, the root cloudbuild.yml is launched on Google Cloud. This file has only three steps: Install yarn dependencies, run `yarn generate-cloudbuild-for-packages`, and run `run-build.sh`. The second step finds what packages were affected by the change and combines their cloudbuild.yml files into a single `cloudbuild_generated.yml` file, and the third step launches the generated build on Google Cloud. The steps in the generated build are set to `waitFor` each other according to the dependency tree `scripts/package_dependencies.json`, and each package's `build-deps` step is removed in favor of waiting for its dependencies to be built. Each package's cloudbuild file still works as expected, and there are two new yarn commands at the root: * `yarn test-packages` tests all packages affected by a change. It performs the same steps as CI. * `yarn generate-cloudbuild-for-packages [PACKAGE]...` generates the cloudbuild file to test each `PACKAGE` and packages it might affect. If given no packages, it detects what packages have been changed in the current PR. * Verify the dependency graph is a valid graph * Add dependencies to e2e * Use the node:12 docker image for tfjs-node CI tfjs-node builds N-API bindings that end-to-end tests need to use. End-to-end uses our custom docker image (gcr.io/learnjs-174218/release) since it has to build tfjs-backend-wasm when it's run by itself (which requires emscripten). Our custom image uses node 12, and is incompatible with node 10 N-API bindings. Eventually, we'll want to move everything that's using node:10 to node:12, but that's out of the scope of this commit. * Remove TODO and allow changes to generate_cloudbuild.js to trigger a full rebuild * Add tfjs-backend-cpu to tfjs-data in package_dependencies.json tfjs-backend-cpu is listed in tfjs-data's package.json as a linked dependency, but was missing form package_dependencies.json. * Don't have tfjs-backend-webgpu build its dependencies in CI Move tfjs-backend-webgpu's dependency building to the 'build-deps' step so it can be removed during CI. This commit also updates the test cloudbuild files that should have been updated in f9c1fdd. It would probably be best to amend that commit, but last time I tried force-pushing in GitHub, I broke the PR I was working on. * Revert changes in tfjs-backend-webgpu to master tfjs-backend-webgpu is now pinned at v2.7.0 for all its tfjs dependencies. * Add the update-cloudbuild-tests script to package.json update-cloudbuild-tests updates the change detection tests for scripts/generate_cloudbuild.js. It should be run iff a change affects cloudbuild files or the dependency tree. * Make tfjs-backend-webgpu tests wait for yarn to run * Add a destination argument to generate_cloudbuild_for_packages.js Co-authored-by: Ping Yu <[email protected]>
1 parent c9808f1 commit 7bd157e

23 files changed

+2262
-301
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,4 @@ tfjs-backend-wasm/wasm-out/*.js
5959
tfjs-backend-wasm/wasm-out/*.wasm
6060
yalc.lock
6161
yarn-error.log
62+
cloudbuild_generated.yml

cloudbuild.yml

+9-122
Original file line numberDiff line numberDiff line change
@@ -5,138 +5,25 @@ steps:
55
id: 'yarn'
66
args: ['install']
77

8-
# Run find-affected-packages to find affected files in each folder.
8+
# Generate cloudbuild_generated.yml,
9+
# which builds and tests all affected packages.
910
- name: 'node:10'
1011
entrypoint: 'yarn'
11-
id: 'find-affected-packages'
12-
args: ['find-affected-packages']
12+
id: 'generate-cloudbuild-for-packages'
13+
args: ['generate-cloudbuild-for-packages']
1314
waitFor: ['yarn']
1415
env:
1516
- 'COMMIT_SHA=$COMMIT_SHA'
1617
- 'BRANCH_NAME=$BRANCH_NAME'
1718
- 'BASE_BRANCH=$_BASE_BRANCH'
19+
- 'NIGHTLY=$_NIGHTLY'
1820

19-
# Core.
21+
# Run the generated cloudbuild file
2022
- name: 'gcr.io/cloud-builders/gcloud'
2123
entrypoint: 'bash'
22-
id: 'tfjs-core'
23-
args: ['./scripts/run-build.sh', 'tfjs-core']
24-
waitFor: ['find-affected-packages']
25-
env: ['NIGHTLY=$_NIGHTLY']
26-
27-
# CPU backend.
28-
- name: 'gcr.io/cloud-builders/gcloud'
29-
entrypoint: 'bash'
30-
id: 'tfjs-backend-cpu'
31-
args: ['./scripts/run-build.sh', 'tfjs-backend-cpu']
32-
waitFor: ['find-affected-packages']
33-
env: ['NIGHTLY=$_NIGHTLY']
34-
35-
# Webgl backend.
36-
- name: 'gcr.io/cloud-builders/gcloud'
37-
entrypoint: 'bash'
38-
id: 'tfjs-backend-webgl'
39-
args: ['./scripts/run-build.sh', 'tfjs-backend-webgl']
40-
waitFor: ['find-affected-packages']
41-
env: ['NIGHTLY=$_NIGHTLY']
42-
43-
# Converter.
44-
- name: 'gcr.io/cloud-builders/gcloud'
45-
entrypoint: 'bash'
46-
id: 'tfjs-converter'
47-
args: ['./scripts/run-build.sh', 'tfjs-converter']
48-
waitFor: ['find-affected-packages']
49-
env: ['NIGHTLY=$_NIGHTLY']
50-
51-
# Data.
52-
- name: 'gcr.io/cloud-builders/gcloud'
53-
entrypoint: 'bash'
54-
id: 'tfjs-data'
55-
args: ['./scripts/run-build.sh', 'tfjs-data']
56-
waitFor: ['find-affected-packages']
57-
env: ['NIGHTLY=$_NIGHTLY']
58-
59-
# Layers.
60-
- name: 'gcr.io/cloud-builders/gcloud'
61-
entrypoint: 'bash'
62-
id: 'tfjs-layers'
63-
args: ['./scripts/run-build.sh', 'tfjs-layers']
64-
waitFor: ['find-affected-packages']
65-
env: ['NIGHTLY=$_NIGHTLY']
66-
67-
# Union.
68-
- name: 'gcr.io/cloud-builders/gcloud'
69-
entrypoint: 'bash'
70-
id: 'tfjs'
71-
args: ['./scripts/run-build.sh', 'tfjs']
72-
waitFor: ['find-affected-packages']
73-
74-
# Vis.
75-
- name: 'gcr.io/cloud-builders/gcloud'
76-
entrypoint: 'bash'
77-
id: 'tfjs-vis'
78-
args: ['./scripts/run-build.sh', 'tfjs-vis']
79-
waitFor: ['find-affected-packages']
80-
81-
# WebGPU.
82-
- name: 'gcr.io/cloud-builders/gcloud'
83-
entrypoint: 'bash'
84-
id: 'tfjs-backend-webgpu'
85-
args: ['./scripts/run-build.sh', 'tfjs-backend-webgpu']
86-
waitFor: ['find-affected-packages']
87-
88-
# WASM.
89-
- name: 'gcr.io/cloud-builders/gcloud'
90-
entrypoint: 'bash'
91-
id: 'tfjs-backend-wasm'
92-
args: ['./scripts/run-build.sh', 'tfjs-backend-wasm']
93-
waitFor: ['find-affected-packages']
94-
env: ['NIGHTLY=$_NIGHTLY']
95-
96-
# React Native.
97-
- name: 'gcr.io/cloud-builders/gcloud'
98-
entrypoint: 'bash'
99-
id: 'tfjs-react-native'
100-
args: ['./scripts/run-build.sh', 'tfjs-react-native']
101-
waitFor: ['find-affected-packages']
102-
103-
# Node CPU.
104-
- name: 'gcr.io/cloud-builders/gcloud'
105-
entrypoint: 'bash'
106-
id: 'tfjs-node'
107-
args: ['./scripts/run-build.sh', 'tfjs-node']
108-
waitFor: ['find-affected-packages']
109-
env: ['NIGHTLY=$_NIGHTLY']
110-
111-
# Node GPU.
112-
- name: 'gcr.io/cloud-builders/gcloud'
113-
entrypoint: 'bash'
114-
id: 'tfjs-node-gpu'
115-
args: ['./scripts/run-build.sh', 'tfjs-node-gpu']
116-
waitFor: ['find-affected-packages']
117-
env: ['NIGHTLY=$_NIGHTLY']
118-
119-
# Release notes test
120-
- name: 'node:10'
121-
id: 'test-monorepo'
122-
entrypoint: 'yarn'
123-
args: ['test-release-notes']
124-
waitFor: ['yarn']
125-
126-
# E2E test
127-
- name: 'gcr.io/cloud-builders/gcloud'
128-
entrypoint: 'bash'
129-
id: 'e2e'
130-
args: ['./scripts/run-build.sh', 'e2e']
131-
waitFor: ['find-affected-packages']
132-
env: ['NIGHTLY=$_NIGHTLY']
133-
134-
# Inference API
135-
- name: 'gcr.io/cloud-builders/gcloud'
136-
entrypoint: 'bash'
137-
id: 'tfjs-inference'
138-
args: ['scripts/run-build.sh', 'tfjs-inference']
139-
waitFor: ['find-affected-packages']
24+
id: 'run-cloudbuild'
25+
args: ['./scripts/run-build.sh']
26+
waitFor: ['generate-cloudbuild-for-packages']
14027
env: ['NIGHTLY=$_NIGHTLY']
14128

14229
# General settings.

e2e/cloudbuild.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ steps:
2121
id: 'test'
2222
args: ['test-ci']
2323
env: ['BROWSERSTACK_USERNAME=deeplearnjs1', 'NIGHTLY=$_NIGHTLY']
24-
2524
secretEnv: ['BROWSERSTACK_KEY']
25+
waitFor: ['yarn', 'build-deps']
2626

2727
secrets:
2828
- kmsKeyName: projects/learnjs-174218/locations/global/keyRings/tfjs/cryptoKeys/enc

package.json

+9-4
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,31 @@
33
"@octokit/rest": "15.17.0",
44
"@types/argparse": "^1.0.38",
55
"@types/jasmine": "2.8.7",
6-
"@types/node": "^12.7.5",
76
"@types/mkdirp": "^0.5.2",
7+
"@types/node": "^12.7.5",
88
"@types/shelljs": "^0.8.7",
99
"argparse": "^1.0.10",
1010
"chalk": "~2.4.2",
1111
"clang-format": "~1.2.4",
12+
"console-table-printer": "^2.4.32",
1213
"jasmine": "3.1.0",
13-
"shelljs": "~0.8.3",
14+
"js-yaml": "^3.14.0",
1415
"mkdirp": "~0.5.1",
16+
"shelljs": "~0.8.3",
1517
"ts-node": "~8.8.2",
1618
"tslint": "~5.20.0",
1719
"typescript": "3.5.3"
1820
},
1921
"scripts": {
20-
"find-affected-packages": "./scripts/find-affected-packages.js",
22+
"test-packages-ci": "yarn generate-cloudbuild-for-packages && ./scripts/run-build.sh",
23+
"generate-cloudbuild-for-packages": "./scripts/generate_cloudbuild_for_packages.js",
24+
"test-generate-cloudbuild": "jasmine run scripts/generate_cloudbuild_test.js",
2125
"release": "ts-node -s ./scripts/release.ts",
2226
"release-tfjs": "ts-node -s ./scripts/release-tfjs.ts",
2327
"publish-npm": "ts-node -s ./scripts/publish-npm.ts",
2428
"release-notes": "ts-node -s ./scripts/release_notes/release_notes.ts",
2529
"test-release-notes": "ts-node -s ./scripts/release_notes/run_tests.ts",
26-
"update-tfjs-lockfiles": "ts-node -s ./scripts/update-tfjs-lockfiles"
30+
"update-tfjs-lockfiles": "ts-node -s ./scripts/update-tfjs-lockfiles",
31+
"update-cloudbuild-tests": "yarn generate-cloudbuild-for-packages tfjs-node -o scripts/cloudbuild_tfjs_node_expected.yml && yarn generate-cloudbuild-for-packages tfjs-core -o scripts/cloudbuild_tfjs_core_expected.yml"
2732
}
2833
}

scripts/cloudbuild.yml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
steps:
2+
# Install common dependencies.
3+
- name: 'node:10'
4+
id: 'yarn-common'
5+
entrypoint: 'yarn'
6+
args: ['install']
7+
8+
# Test generate_cloudbuild.js
9+
- name: 'node:10'
10+
dir: 'scripts'
11+
id: 'test-generate-cloudbuild'
12+
entrypoint: 'yarn'
13+
args: ['test-generate-cloudbuild']
14+
waitFor: ['yarn-common']

scripts/cloudbuild_general_config.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
steps:
2+
# Install top-level deps.
3+
- name: 'node:10'
4+
entrypoint: 'yarn'
5+
id: 'yarn-common'
6+
args: ['install']
7+
8+
# General configuration
9+
secrets:
10+
- kmsKeyName: projects/learnjs-174218/locations/global/keyRings/tfjs/cryptoKeys/enc
11+
secretEnv:
12+
BROWSERSTACK_KEY: CiQAkwyoIW0LcnxymzotLwaH4udVTQFBEN4AEA5CA+a3+yflL2ASPQAD8BdZnGARf78MhH5T9rQqyz9HNODwVjVIj64CTkFlUCGrP1B2HX9LXHWHLmtKutEGTeFFX9XhuBzNExA=
13+
FIREBASE_KEY: CiQAkwyoIXmET39jOD3ywloCIa6+WUpu3w49twpMmkMqy0vS+YsSUAAD8BdZQGOL8FKEBxr/1jl0G78OigwlNVHjD3usZobNtlOp8tV/9iacb8zPFqy0SwIO1gvz3HRr+VU7c7LS2qqaTCdacZF+dx3VJNewvdZu
14+
timeout: 3600s
15+
logsBucket: 'gs://tfjs-build-logs'
16+
substitutions:
17+
_NIGHTLY: ''
18+
options:
19+
logStreamingOption: 'STREAM_ON'
20+
machineType: 'N1_HIGHCPU_32'
21+
substitution_option: 'ALLOW_LOOSE'

0 commit comments

Comments
 (0)