Skip to content

Commit a6ad6b0

Browse files
JustinBeckwithalexander-fenster
authored andcommitted
Retry npm install in CI (#148)
1 parent cdb7936 commit a6ad6b0

File tree

2 files changed

+90
-20
lines changed

2 files changed

+90
-20
lines changed

packages/google-cloud-compute/.circleci/config.yml

+30-20
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,17 @@ jobs:
5959
- image: 'node:6'
6060
user: node
6161
steps: &unit_tests_steps
62-
- checkout
62+
- checkout
6363
- run: &npm_install_and_link
6464
name: Install and link the module
6565
command: |-
6666
mkdir -p /home/node/.npm-global
67-
npm install
67+
./.circleci/npm-install-retry.js
6868
environment:
6969
NPM_CONFIG_PREFIX: /home/node/.npm-global
7070
- run: npm test
7171
- run: node_modules/.bin/codecov
72+
7273
node8:
7374
docker:
7475
- image: 'node:8'
@@ -81,7 +82,7 @@ jobs:
8182
steps: *unit_tests_steps
8283
lint:
8384
docker:
84-
- image: 'node:10'
85+
- image: 'node:8'
8586
user: node
8687
steps:
8788
- checkout
@@ -90,8 +91,8 @@ jobs:
9091
name: Link the module being tested to the samples.
9192
command: |
9293
cd samples/
93-
npm install
9494
npm link ../
95+
./../.circleci/npm-install-retry.js
9596
environment:
9697
NPM_CONFIG_PREFIX: /home/node/.npm-global
9798
- run:
@@ -101,52 +102,57 @@ jobs:
101102
NPM_CONFIG_PREFIX: /home/node/.npm-global
102103
docs:
103104
docker:
104-
- image: 'node:10'
105+
- image: 'node:8'
105106
user: node
106107
steps:
107108
- checkout
108109
- run: *npm_install_and_link
109-
- run:
110-
name: Build documentation.
111-
command: npm run docs
110+
- run: npm run docs
112111
sample_tests:
113112
docker:
114-
- image: 'node:10'
113+
- image: 'node:8'
115114
user: node
116115
steps:
117116
- checkout
118117
- run:
119118
name: Decrypt credentials.
120119
command: |
121-
openssl aes-256-cbc -d -in .circleci/key.json.enc \
120+
if ! [[ -z "${SYSTEM_TESTS_ENCRYPTION_KEY}" ]]; then
121+
openssl aes-256-cbc -d -in .circleci/key.json.enc \
122122
-out .circleci/key.json \
123123
-k "${SYSTEM_TESTS_ENCRYPTION_KEY}"
124+
fi
124125
- run: *npm_install_and_link
125126
- run: *samples_npm_install_and_link
126127
- run:
127128
name: Run sample tests.
128129
command: npm run samples-test
129130
environment:
130-
NPM_CONFIG_PREFIX: /home/node/.npm-global
131131
GCLOUD_PROJECT: long-door-651
132-
GOOGLE_APPLICATION_CREDENTIALS: /home/node/compute-samples/.circleci/key.json
132+
GOOGLE_APPLICATION_CREDENTIALS: /home/node/samples/.circleci/key.json
133+
NPM_CONFIG_PREFIX: /home/node/.npm-global
133134
- run:
134135
name: Remove unencrypted key.
135-
command: rm .circleci/key.json
136+
command: |
137+
if ! [[ -z "${SYSTEM_TESTS_ENCRYPTION_KEY}" ]]; then
138+
rm .circleci/key.json
139+
fi
136140
when: always
137-
working_directory: /home/node/compute-samples
141+
working_directory: /home/node/samples/
138142
system_tests:
139143
docker:
140-
- image: 'node:10'
144+
- image: 'node:8'
141145
user: node
142146
steps:
143147
- checkout
144148
- run:
145149
name: Decrypt credentials.
146150
command: |
147-
openssl aes-256-cbc -d -in .circleci/key.json.enc \
151+
if ! [[ -z "${SYSTEM_TESTS_ENCRYPTION_KEY}" ]]; then
152+
openssl aes-256-cbc -d -in .circleci/key.json.enc \
148153
-out .circleci/key.json \
149154
-k "${SYSTEM_TESTS_ENCRYPTION_KEY}"
155+
fi
150156
- run: *npm_install_and_link
151157
- run:
152158
name: Run system tests.
@@ -155,13 +161,17 @@ jobs:
155161
GOOGLE_APPLICATION_CREDENTIALS: .circleci/key.json
156162
- run:
157163
name: Remove unencrypted key.
158-
command: rm .circleci/key.json
164+
command: |
165+
if ! [[ -z "${SYSTEM_TESTS_ENCRYPTION_KEY}" ]]; then
166+
rm .circleci/key.json
167+
fi
159168
when: always
160169
publish_npm:
161170
docker:
162-
- image: 'node:10'
171+
- image: 'node:8'
163172
user: node
164173
steps:
165174
- checkout
166-
- run: 'echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc'
167-
- run: npm publish
175+
- run: ./.circleci/npm-install-retry.js
176+
- run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
177+
- run: npm publish --access=public
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env node
2+
3+
let spawn = require('child_process').spawn;
4+
5+
//
6+
//USE: ./index.js <ms npm can be idle> <number of attempts> [... NPM ARGS]
7+
//
8+
9+
let timeout = process.argv[2] || 60000;
10+
let attempts = process.argv[3] || 3;
11+
let args = process.argv.slice(4);
12+
if (args.length === 0) {
13+
args = ['install'];
14+
}
15+
16+
(function npm() {
17+
let timer;
18+
args.push('--verbose');
19+
let proc = spawn('npm', args);
20+
proc.stdout.pipe(process.stdout);
21+
proc.stderr.pipe(process.stderr);
22+
proc.stdin.end();
23+
proc.stdout.on('data', () => {
24+
setTimer();
25+
});
26+
proc.stderr.on('data', () => {
27+
setTimer();
28+
});
29+
30+
// side effect: this also restarts when npm exits with a bad code even if it
31+
// didnt timeout
32+
proc.on('close', (code, signal) => {
33+
clearTimeout(timer);
34+
if (code || signal) {
35+
console.log('[npm-are-you-sleeping] npm exited with code ' + code + '');
36+
37+
if (--attempts) {
38+
console.log('[npm-are-you-sleeping] restarting');
39+
npm();
40+
} else {
41+
console.log('[npm-are-you-sleeping] i tried lots of times. giving up.');
42+
throw new Error("npm install fails");
43+
}
44+
}
45+
});
46+
47+
function setTimer() {
48+
clearTimeout(timer);
49+
timer = setTimeout(() => {
50+
console.log('[npm-are-you-sleeping] killing npm with SIGTERM');
51+
proc.kill('SIGTERM');
52+
// wait a couple seconds
53+
timer = setTimeout(() => {
54+
// its it's still not closed sigkill
55+
console.log('[npm-are-you-sleeping] killing npm with SIGKILL');
56+
proc.kill('SIGKILL');
57+
}, 2000);
58+
}, timeout);
59+
}
60+
})();

0 commit comments

Comments
 (0)