Skip to content

Commit

Permalink
Retry npm install in CI (#184)
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinBeckwith authored and alexander-fenster committed Sep 4, 2018
1 parent 963f98e commit 6416a1d
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 15 deletions.
41 changes: 26 additions & 15 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,17 @@ jobs:
- image: 'node:6'
user: node
steps: &unit_tests_steps
- checkout
- checkout
- run: &npm_install_and_link
name: Install and link the module
command: |-
mkdir -p /home/node/.npm-global
npm install
./.circleci/npm-install-retry.js
environment:
NPM_CONFIG_PREFIX: /home/node/.npm-global
- run: npm test
- run: node_modules/.bin/codecov

node8:
docker:
- image: 'node:8'
Expand All @@ -90,23 +91,23 @@ jobs:
name: Link the module being tested to the samples.
command: |
cd samples/
npm install
npm link ../
./../.circleci/npm-install-retry.js
environment:
NPM_CONFIG_PREFIX: /home/node/.npm-global
- run:
name: Run linting.
command: npm run lint
environment:
NPM_CONFIG_PREFIX: /home/node/.npm-global
docs:
docker:
- image: 'node:8'
user: node
steps:
- checkout
- run: *npm_install_and_link
- run:
name: Build documentation.
command: npm run docs
- run: npm run docs
sample_tests:
docker:
- image: 'node:8'
Expand All @@ -116,23 +117,28 @@ jobs:
- run:
name: Decrypt credentials.
command: |
openssl aes-256-cbc -d -in .circleci/key.json.enc \
if ! [[ -z "${SYSTEM_TESTS_ENCRYPTION_KEY}" ]]; then
openssl aes-256-cbc -d -in .circleci/key.json.enc \
-out .circleci/key.json \
-k "${SYSTEM_TESTS_ENCRYPTION_KEY}"
fi
- run: *npm_install_and_link
- run: *samples_npm_install_and_link
- run:
name: Run sample tests.
command: npm run samples-test
environment:
GCLOUD_PROJECT: long-door-651
GOOGLE_APPLICATION_CREDENTIALS: /home/node/bigquery-samples/.circleci/key.json
GOOGLE_APPLICATION_CREDENTIALS: /home/node/samples/.circleci/key.json
NPM_CONFIG_PREFIX: /home/node/.npm-global
- run:
name: Remove unencrypted key.
command: rm .circleci/key.json
command: |
if ! [[ -z "${SYSTEM_TESTS_ENCRYPTION_KEY}" ]]; then
rm .circleci/key.json
fi
when: always
working_directory: /home/node/bigquery-samples/
working_directory: /home/node/samples/
system_tests:
docker:
- image: 'node:8'
Expand All @@ -142,25 +148,30 @@ jobs:
- run:
name: Decrypt credentials.
command: |
openssl aes-256-cbc -d -in .circleci/key.json.enc \
if ! [[ -z "${SYSTEM_TESTS_ENCRYPTION_KEY}" ]]; then
openssl aes-256-cbc -d -in .circleci/key.json.enc \
-out .circleci/key.json \
-k "${SYSTEM_TESTS_ENCRYPTION_KEY}"
fi
- run: *npm_install_and_link
- run:
name: Run system tests.
command: npm run system-test
environment:
GCLOUD_PROJECT: long-door-651
GOOGLE_APPLICATION_CREDENTIALS: .circleci/key.json
- run:
name: Remove unencrypted key.
command: rm .circleci/key.json
command: |
if ! [[ -z "${SYSTEM_TESTS_ENCRYPTION_KEY}" ]]; then
rm .circleci/key.json
fi
when: always
publish_npm:
docker:
- image: 'node:8'
user: node
steps:
- checkout
- run: 'echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc'
- run: npm publish
- run: ./.circleci/npm-install-retry.js
- run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
- run: npm publish --access=public
60 changes: 60 additions & 0 deletions .circleci/npm-install-retry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env node

let spawn = require('child_process').spawn;

//
//USE: ./index.js <ms npm can be idle> <number of attempts> [... NPM ARGS]
//

let timeout = process.argv[2] || 60000;
let attempts = process.argv[3] || 3;
let args = process.argv.slice(4);
if (args.length === 0) {
args = ['install'];
}

(function npm() {
let timer;
args.push('--verbose');
let proc = spawn('npm', args);
proc.stdout.pipe(process.stdout);
proc.stderr.pipe(process.stderr);
proc.stdin.end();
proc.stdout.on('data', () => {
setTimer();
});
proc.stderr.on('data', () => {
setTimer();
});

// side effect: this also restarts when npm exits with a bad code even if it
// didnt timeout
proc.on('close', (code, signal) => {
clearTimeout(timer);
if (code || signal) {
console.log('[npm-are-you-sleeping] npm exited with code ' + code + '');

if (--attempts) {
console.log('[npm-are-you-sleeping] restarting');
npm();
} else {
console.log('[npm-are-you-sleeping] i tried lots of times. giving up.');
throw new Error("npm install fails");
}
}
});

function setTimer() {
clearTimeout(timer);
timer = setTimeout(() => {
console.log('[npm-are-you-sleeping] killing npm with SIGTERM');
proc.kill('SIGTERM');
// wait a couple seconds
timer = setTimeout(() => {
// its it's still not closed sigkill
console.log('[npm-are-you-sleeping] killing npm with SIGKILL');
proc.kill('SIGKILL');
}, 2000);
}, timeout);
}
})();

0 comments on commit 6416a1d

Please sign in to comment.