Skip to content

Commit 0162a29

Browse files
authored
Add affected packages analysis. (#2793)
1 parent af46b87 commit 0162a29

File tree

9 files changed

+104
-25
lines changed

9 files changed

+104
-25
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*.tgz
44
*.zip
55
*/diff
6+
*/run-ci
67
**/*.pyc
78
**/bundle.js
89
**/*.js.map

cloudbuild.yml

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ steps:
55
id: 'yarn'
66
args: ['install']
77

8-
# Run diff to find modified files in each folder.
8+
# Run find-affected-packages to find affected files in each folder.
99
- name: 'node:10'
1010
entrypoint: 'yarn'
11-
id: 'diff'
12-
args: ['diff']
11+
id: 'find-affected-packages'
12+
args: ['find-affected-packages']
1313
waitFor: ['yarn']
1414
env:
1515
- 'COMMIT_SHA=$COMMIT_SHA'
@@ -20,85 +20,85 @@ steps:
2020
entrypoint: 'bash'
2121
id: 'tfjs-core'
2222
args: ['./scripts/run-build.sh', 'tfjs-core']
23-
waitFor: ['diff']
23+
waitFor: ['find-affected-packages']
2424

2525
# Converter.
2626
- name: 'gcr.io/cloud-builders/gcloud'
2727
entrypoint: 'bash'
2828
id: 'tfjs-converter'
2929
args: ['./scripts/run-build.sh', 'tfjs-converter']
30-
waitFor: ['diff']
30+
waitFor: ['find-affected-packages']
3131

3232
# Data.
3333
- name: 'gcr.io/cloud-builders/gcloud'
3434
entrypoint: 'bash'
3535
id: 'tfjs-data'
3636
args: ['./scripts/run-build.sh', 'tfjs-data']
37-
waitFor: ['diff']
37+
waitFor: ['find-affected-packages']
3838

3939
# Layers.
4040
- name: 'gcr.io/cloud-builders/gcloud'
4141
entrypoint: 'bash'
4242
id: 'tfjs-layers'
4343
args: ['./scripts/run-build.sh', 'tfjs-layers']
44-
waitFor: ['diff']
44+
waitFor: ['find-affected-packages']
4545

4646
# Union.
4747
- name: 'gcr.io/cloud-builders/gcloud'
4848
entrypoint: 'bash'
4949
id: 'tfjs'
5050
args: ['./scripts/run-build.sh', 'tfjs']
51-
waitFor: ['diff']
51+
waitFor: ['find-affected-packages']
5252

5353
# Vis.
5454
- name: 'gcr.io/cloud-builders/gcloud'
5555
entrypoint: 'bash'
5656
id: 'tfjs-vis'
5757
args: ['./scripts/run-build.sh', 'tfjs-vis']
58-
waitFor: ['diff']
58+
waitFor: ['find-affected-packages']
5959

6060
# WebGPU.
6161
- name: 'gcr.io/cloud-builders/gcloud'
6262
entrypoint: 'bash'
6363
id: 'tfjs-backend-webgpu'
6464
args: ['./scripts/run-build.sh', 'tfjs-backend-webgpu']
65-
waitFor: ['diff']
65+
waitFor: ['find-affected-packages']
6666

6767
# WASM.
6868
- name: 'gcr.io/cloud-builders/gcloud'
6969
entrypoint: 'bash'
7070
id: 'tfjs-backend-wasm'
7171
args: ['./scripts/run-build.sh', 'tfjs-backend-wasm']
72-
waitFor: ['diff']
72+
waitFor: ['find-affected-packages']
7373

7474
# React Native.
7575
- name: 'gcr.io/cloud-builders/gcloud'
7676
entrypoint: 'bash'
7777
id: 'tfjs-react-native'
7878
args: ['./scripts/run-build.sh', 'tfjs-react-native']
79-
waitFor: ['diff']
79+
waitFor: ['find-affected-packages']
8080

8181
# Node CPU.
8282
- name: 'gcr.io/cloud-builders/gcloud'
8383
entrypoint: 'bash'
8484
id: 'tfjs-node'
8585
args: ['./scripts/run-build.sh', 'tfjs-node']
86-
waitFor: ['diff']
86+
waitFor: ['find-affected-packages']
8787

8888
# Node GPU.
8989
- name: 'gcr.io/cloud-builders/gcloud'
9090
entrypoint: 'bash'
9191
id: 'tfjs-node-gpu'
9292
args: ['./scripts/run-build.sh', 'tfjs-node-gpu']
93-
waitFor: ['diff']
93+
waitFor: ['find-affected-packages']
9494

9595
# Integration tests
9696
- name: 'node:10'
9797
dir: 'tfjs-core'
9898
id: 'test-integration'
9999
entrypoint: 'yarn'
100100
args: ['test-integration']
101-
waitFor: ['diff']
101+
waitFor: ['find-affected-packages']
102102
env: ['BROWSERSTACK_USERNAME=deeplearnjs1', 'NIGHTLY=$_NIGHTLY']
103103
secretEnv: ['BROWSERSTACK_KEY']
104104

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"typescript": "3.5.3"
1414
},
1515
"scripts": {
16-
"diff": "./scripts/diff.js",
16+
"find-affected-packages": "./scripts/find-affected-packages.js",
1717
"release": "ts-node ./scripts/release.ts",
1818
"release-notes": "ts-node ./scripts/release_notes/release_notes.ts",
1919
"test-release-notes": "ts-node ./scripts/release_notes/run_tests.ts"

scripts/diff.js renamed to scripts/find-affected-packages.js

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,16 @@
1414
// limitations under the License.
1515
// =============================================================================
1616

17-
const {exec} = require('./test-util');
17+
const {exec, constructDependencyGraph, computeAffectedPackages} =
18+
require('./test-util');
1819
const shell = require('shelljs');
1920
const {readdirSync, statSync, writeFileSync} = require('fs');
2021
const {join} = require('path');
2122
const fs = require('fs');
2223

2324
const filesWhitelistToTriggerBuild = [
2425
'cloudbuild.yml', 'package.json', 'tsconfig.json', 'tslint.json',
25-
'scripts/diff.js', 'scripts/run-build.sh'
26+
'scripts/find-affected-packages.js', 'scripts/run-build.sh'
2627
];
2728

2829
const CLONE_PATH = 'clone';
@@ -86,7 +87,7 @@ console.log(); // Break up the console for readability.
8687

8788
let triggeredBuilds = [];
8889
dirs.forEach(dir => {
89-
shell.rm('-f', `${dir}/diff`);
90+
shell.rm('-f', `${dir}/run-ci`);
9091
const diffOutput = diff(`${dir}/`);
9192
if (diffOutput !== '') {
9293
console.log(`${dir} has modified files.`);
@@ -97,13 +98,31 @@ dirs.forEach(dir => {
9798
const shouldDiff = diffOutput !== '' || triggerAllBuilds;
9899
if (shouldDiff) {
99100
const diffContents = whitelistDiffOutput.join('\n') + '\n' + diffOutput;
100-
writeFileSync(join(dir, 'diff'), diffContents);
101+
writeFileSync(join(dir, 'run-ci'), diffContents);
101102
triggeredBuilds.push(dir);
102103
}
103104
});
104105

105106
console.log(); // Break up the console for readability.
106107

108+
// Only add affected packages if not triggering all builds.
109+
if (!triggerAllBuilds) {
110+
console.log('Computing affected packages.');
111+
const affectedBuilds = new Set();
112+
const dependencyGraph =
113+
constructDependencyGraph('scripts/package_dependencies.json');
114+
triggeredBuilds.forEach(triggeredBuild => {
115+
const affectedPackages =
116+
computeAffectedPackages(dependencyGraph, triggeredBuild);
117+
affectedPackages.forEach(package => {
118+
writeFileSync(join(package, 'run-ci'));
119+
affectedBuilds.add(package);
120+
});
121+
});
122+
123+
triggeredBuilds.push(Array.from(affectedBuilds));
124+
}
125+
107126
// Filter the triggered builds to log by whether a cloudbuild.yml file
108127
// exists for that directory.
109128
triggeredBuilds = triggeredBuilds.filter(

scripts/package_dependencies.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
{
3+
"tfjs-core": [],
4+
"tfjs-converter": ["tfjs-core"]
5+
}

scripts/run-build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@
1717
set -e
1818

1919
DIR=$1
20-
if test -f "$DIR/diff"; then
20+
if test -f "$DIR/run-ci"; then
2121
gcloud builds submit . --config=$DIR/cloudbuild.yml
2222
fi

scripts/test-util.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// =============================================================================
1515

1616
const shell = require('shelljs');
17+
const fs = require('fs');
1718

1819
function exec(command, opt, ignoreCode) {
1920
const res = shell.exec(command, opt);
@@ -24,4 +25,57 @@ function exec(command, opt, ignoreCode) {
2425
return res;
2526
}
2627

28+
// Construct a dependency graph keyed by dependency package.
29+
// Example:
30+
// dependencyGraph = {
31+
// "tfjs-core": ["tfjs-converter", "tfjs", ...],
32+
// "tfjs": ["tfjs-node"],
33+
// ...
34+
// }
35+
function constructDependencyGraph(dependencyFilePath) {
36+
const str = fs.readFileSync(dependencyFilePath, 'utf8');
37+
const dependencyInfo = JSON.parse(str);
38+
39+
const dependencyGraph = {};
40+
41+
Object.keys(dependencyInfo)
42+
.forEach(package => dependencyInfo[package].forEach(dependency => {
43+
if (!dependencyGraph[dependency]) {
44+
dependencyGraph[dependency] = [];
45+
}
46+
dependencyGraph[dependency].push(package);
47+
}));
48+
49+
return dependencyGraph;
50+
}
51+
52+
function computeAffectedPackages(dependencyGraph, package) {
53+
const affectedPackages = new Set();
54+
traverseDependencyGraph(dependencyGraph, package, affectedPackages);
55+
56+
return Array.from(affectedPackages);
57+
}
58+
59+
// This function performs a depth-first-search to add affected packages that
60+
// transitively depend on the given package.
61+
function traverseDependencyGraph(graph, package, affectedPackages) {
62+
// Terminate early if the package has been visited.
63+
if (affectedPackages.has(package)) {
64+
return;
65+
}
66+
67+
const consumingPackages = graph[package];
68+
69+
if (!consumingPackages) {
70+
return;
71+
}
72+
73+
consumingPackages.forEach(consumingPackage => {
74+
traverseDependencyGraph(graph, consumingPackage, affectedPackages);
75+
affectedPackages.add(consumingPackage);
76+
});
77+
}
78+
2779
exports.exec = exec;
80+
exports.constructDependencyGraph = constructDependencyGraph;
81+
exports.computeAffectedPackages = computeAffectedPackages;

tfjs-layers/cloudbuild.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ steps:
3434
dir: 'tfjs-layers'
3535
entrypoint: 'bash'
3636
id: 'tfjs2keras-py'
37-
args: ['-c', './scripts/tfjs2keras-py.sh --stable && ./scripts/tfjs2keras-py.sh --stable --tfkeras && ./scripts/tfjs2keras-py.sh --dev --tfkeras']
37+
args: ['-c', './scripts/tfjs2keras-py.sh --stable && ./scripts/tfjs2keras-py.sh --stable --tfkeras']
3838
waitFor: ['tfjs2keras-js']
3939
- name: 'node:10'
4040
dir: 'tfjs-layers'

tfjs-layers/scripts/tfjs2keras-py.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ fi
4343

4444
VENV_DIR="$(mktemp -d)_venv"
4545
echo "Creating virtualenv at ${VENV_DIR} ..."
46-
virtualenv "${VENV_DIR}"
46+
virtualenv -p python3 "${VENV_DIR}"
4747
source "${VENV_DIR}/bin/activate"
4848

4949
if [[ "${DEV_VERSION}" == "stable" ]]; then
50-
pip install -r requirements-stable.txt
50+
pip3 install -r requirements-stable.txt
5151
else
52-
pip install -r requirements-dev.txt
52+
pip3 install -r requirements-dev.txt
5353
fi
5454

5555
export TFJS2KERAS_TEST_USING_TF_KERAS="${TFJS2KERAS_TEST_USING_TF_KERAS}"

0 commit comments

Comments
 (0)