ci(docs-infra): test PR previews on CI (#25671)
The deployment of PR previews is triggered by the notification webhook of the `aio_preview` CircleCI job (which creates and stores the build artifacts). This commit adds a new job (`test_aio_preview`), which waits for the preview to be deployed (for PRs that do have a preview) and then runs some tests against it (currently only PWA tests). Fixes #23818 PR Close #25671
This commit is contained in:
parent
6d6b0ff1ad
commit
e42bd012f9
@ -158,6 +158,21 @@ jobs:
|
|||||||
# `AIO_ARTIFACT_PATH` in `aio/aio-builds-setup/Dockerfile`
|
# `AIO_ARTIFACT_PATH` in `aio/aio-builds-setup/Dockerfile`
|
||||||
destination: aio/dist/aio-snapshot.tgz
|
destination: aio/dist/aio-snapshot.tgz
|
||||||
|
|
||||||
|
# This job should only be run on PR builds, where `CIRCLE_PR_NUMBER` is defined.
|
||||||
|
test_aio_preview:
|
||||||
|
<<: *job_defaults
|
||||||
|
steps:
|
||||||
|
- checkout:
|
||||||
|
<<: *post_checkout
|
||||||
|
- restore_cache:
|
||||||
|
key: *cache_key
|
||||||
|
- run: yarn install --cwd aio --frozen-lockfile --non-interactive
|
||||||
|
- run:
|
||||||
|
name: Wait for preview and run tests
|
||||||
|
command: |
|
||||||
|
source "./scripts/ci/env.sh" print
|
||||||
|
xvfb-run --auto-servernum node scripts/test-preview.js $CIRCLE_PR_NUMBER $CIRCLE_SHA1 $AIO_MIN_PWA_SCORE
|
||||||
|
|
||||||
# This job exists only for backwards-compatibility with old scripts and tests
|
# This job exists only for backwards-compatibility with old scripts and tests
|
||||||
# that rely on the pre-Bazel dist/packages-dist layout.
|
# that rely on the pre-Bazel dist/packages-dist layout.
|
||||||
# It duplicates some work with the job above: we build the bazel packages
|
# It duplicates some work with the job above: we build the bazel packages
|
||||||
@ -257,6 +272,9 @@ workflows:
|
|||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
only: /pull\/\d+/
|
only: /pull\/\d+/
|
||||||
|
- test_aio_preview:
|
||||||
|
requires:
|
||||||
|
- aio_preview
|
||||||
- integration_test:
|
- integration_test:
|
||||||
requires:
|
requires:
|
||||||
- build-packages-dist
|
- build-packages-dist
|
||||||
|
@ -104,5 +104,5 @@ fi
|
|||||||
firebase deploy --message "Commit: $TRAVIS_COMMIT" --non-interactive --token "$firebaseToken"
|
firebase deploy --message "Commit: $TRAVIS_COMMIT" --non-interactive --token "$firebaseToken"
|
||||||
|
|
||||||
# Run PWA-score tests
|
# Run PWA-score tests
|
||||||
yarn test-pwa-score "$deployedUrl" "$MIN_PWA_SCORE"
|
yarn test-pwa-score "$deployedUrl" "$AIO_MIN_PWA_SCORE"
|
||||||
)
|
)
|
||||||
|
121
aio/scripts/test-preview.js
Normal file
121
aio/scripts/test-preview.js
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage:
|
||||||
|
* node scripts/test-preview <pr-number> <pr-last-sha> <min-pwa-score>
|
||||||
|
*
|
||||||
|
* Checks whether a PR will (eventually) have a (public) preview, waits for the preview to be
|
||||||
|
* available, and runs PWA tests against the preview.
|
||||||
|
*
|
||||||
|
* For PRs that are expected to have a preview, this script will fail if the preview is still not
|
||||||
|
* available after a pre-defined waiting period or if the PWA tests fail.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Imports
|
||||||
|
const {spawn} = require('child_process');
|
||||||
|
const {get: httpsGet} = require('https');
|
||||||
|
const {relative} = require('path');
|
||||||
|
|
||||||
|
// Input
|
||||||
|
const [prNumber, prLastSha, minPwaScore] = validateArgs(process.argv.slice(2));
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
const aioBuildsDomain = 'ngbuilds.io';
|
||||||
|
const previewCheckInterval = 30000;
|
||||||
|
const previewCheckAttempts = 10;
|
||||||
|
|
||||||
|
const shortSha = prLastSha && prLastSha.slice(0, 7);
|
||||||
|
const previewabilityCheckUrl = `https://${aioBuildsDomain}/can-have-public-preview/${prNumber}`;
|
||||||
|
const previewUrl = `https://pr${prNumber}-${shortSha}.${aioBuildsDomain}/`;
|
||||||
|
|
||||||
|
// Check whether the PR can have a (public) preview.
|
||||||
|
get(previewabilityCheckUrl).
|
||||||
|
then(response => JSON.parse(response)).
|
||||||
|
then(({canHavePublicPreview, reason}) => {
|
||||||
|
// Nothing to do, if this PR can have no (public) preview.
|
||||||
|
if (canHavePublicPreview === false) {
|
||||||
|
reportNoPreview(reason);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There should be a preview. Wait for it to be available.
|
||||||
|
return poll(previewCheckInterval, previewCheckAttempts, () => get(previewUrl)).
|
||||||
|
// The preview is still not available after the specified waiting period.
|
||||||
|
catch(() => {
|
||||||
|
const totalSecs = Math.round((previewCheckInterval * previewCheckAttempts) / 1000);
|
||||||
|
throw new Error(`Preview still not available after ${totalSecs}s.`);
|
||||||
|
}).
|
||||||
|
// The preview is now available. Run the PWA tests.
|
||||||
|
then(() => runPwaTests());
|
||||||
|
}).
|
||||||
|
catch(onError);
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
function get(url) {
|
||||||
|
console.log(`GET ${url}`);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const onResponse = res => {
|
||||||
|
const statusCode = res.statusCode || -1;
|
||||||
|
const isSuccess = (200 <= statusCode) && (statusCode < 400);
|
||||||
|
let responseText = '';
|
||||||
|
|
||||||
|
res.
|
||||||
|
on('error', reject).
|
||||||
|
on('data', d => responseText += d).
|
||||||
|
on('end', () => isSuccess ?
|
||||||
|
resolve(responseText) :
|
||||||
|
reject(`Request to '${url}' failed (status: ${statusCode}): ${responseText}`));
|
||||||
|
};
|
||||||
|
|
||||||
|
httpsGet(url, onResponse).
|
||||||
|
on('error', reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onError(err) {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function poll(interval, attempts, checkCondition) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!attempts) return reject();
|
||||||
|
|
||||||
|
checkCondition().
|
||||||
|
then(() => resolve()).
|
||||||
|
catch(() => wait(interval).
|
||||||
|
then(() => poll(interval, attempts - 1, checkCondition)).
|
||||||
|
then(resolve, reject));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportNoPreview(reason) {
|
||||||
|
console.log(`No (public) preview available. (Reason: ${reason})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function runPwaTests() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const spawnOptions = {cwd: __dirname, stdio: 'inherit'};
|
||||||
|
spawn('yarn', ['test-pwa-score', previewUrl, minPwaScore], spawnOptions).
|
||||||
|
on('error', reject).
|
||||||
|
on('exit', code => (code === 0 ? resolve : reject)());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateArgs(args) {
|
||||||
|
if (args.length !== 3) {
|
||||||
|
const relativeScriptPath = relative('.', __filename.replace(/\.js$/, ''));
|
||||||
|
const usageCmd = `node ${relativeScriptPath} <pr-number> <pr-last-sha> <min-pwa-score>`;
|
||||||
|
|
||||||
|
return onError(
|
||||||
|
`Invalid number of arguments (expected 3, found ${args.length}).\n` +
|
||||||
|
`Usage: ${usageCmd}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
function wait(delay) {
|
||||||
|
console.log(`Waiting ${delay}ms...`);
|
||||||
|
return new Promise(resolve => setTimeout(resolve, delay));
|
||||||
|
}
|
@ -40,6 +40,7 @@ setEnvVar CHROMIUM_VERSION 561733 # Chrome 68 linux stable, see https://www.chr
|
|||||||
setEnvVar CHROMEDRIVER_VERSION_ARG "--versions.chrome 2.41"
|
setEnvVar CHROMEDRIVER_VERSION_ARG "--versions.chrome 2.41"
|
||||||
setEnvVar SAUCE_CONNECT_VERSION 4.4.9
|
setEnvVar SAUCE_CONNECT_VERSION 4.4.9
|
||||||
setEnvVar ANGULAR_CLI_VERSION 1.6.3
|
setEnvVar ANGULAR_CLI_VERSION 1.6.3
|
||||||
|
setEnvVar AIO_MIN_PWA_SCORE 95
|
||||||
setEnvVar PROJECT_ROOT $(cd ${thisDir}/../..; pwd)
|
setEnvVar PROJECT_ROOT $(cd ${thisDir}/../..; pwd)
|
||||||
|
|
||||||
if [[ ${TRAVIS:-} ]]; then
|
if [[ ${TRAVIS:-} ]]; then
|
||||||
@ -63,8 +64,6 @@ if [[ ${TRAVIS:-} ]]; then
|
|||||||
# Determine the current stable branch.
|
# Determine the current stable branch.
|
||||||
readonly versionRe="^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$"
|
readonly versionRe="^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$"
|
||||||
setEnvVar STABLE_BRANCH `npm info @angular/core dist-tags.latest | sed -r "s/$versionRe/\1.x/"`
|
setEnvVar STABLE_BRANCH `npm info @angular/core dist-tags.latest | sed -r "s/$versionRe/\1.x/"`
|
||||||
|
|
||||||
setEnvVar MIN_PWA_SCORE 95
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user