mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(docs-infra): convert deploy-to-firebase script to ESM (#43963)
Convert the `deploy-to-firebase` script (and corresponding tests) from CommonJS format to ESM. PR Close #43963
This commit is contained in:
committed by
Alex Rickabaugh
parent
80d8eb87bb
commit
4f4b2b5ac9
@@ -6,4 +6,4 @@ TODO (gkalpak): Add docs. Mention:
|
|||||||
Relevant files: `aio/aio-builds-setup/scripts/test.sh`
|
Relevant files: `aio/aio-builds-setup/scripts/test.sh`
|
||||||
- Deploying from CI.
|
- Deploying from CI.
|
||||||
Relevant files: `.circleci/config.yml`, `scripts/ci/deploy.sh`, `aio/scripts/build-artifacts.sh`,
|
Relevant files: `.circleci/config.yml`, `scripts/ci/deploy.sh`, `aio/scripts/build-artifacts.sh`,
|
||||||
`aio/scripts/deploy-to-firebase/index.js`
|
`aio/scripts/deploy-to-firebase/index.mjs`
|
||||||
|
|||||||
+3
-3
@@ -44,7 +44,7 @@
|
|||||||
"example-use-local": "node tools/ng-packages-installer overwrite ./tools/examples/shared --debug --force",
|
"example-use-local": "node tools/ng-packages-installer overwrite ./tools/examples/shared --debug --force",
|
||||||
"example-use-npm": "node tools/ng-packages-installer restore ./tools/examples/shared",
|
"example-use-npm": "node tools/ng-packages-installer restore ./tools/examples/shared",
|
||||||
"example-check-local": "node tools/ng-packages-installer check ./tools/examples/shared",
|
"example-check-local": "node tools/ng-packages-installer check ./tools/examples/shared",
|
||||||
"deploy-production": "node scripts/deploy-to-firebase",
|
"deploy-production": "node scripts/deploy-to-firebase/index.mjs",
|
||||||
"check-env": "yarn ~~check-env",
|
"check-env": "yarn ~~check-env",
|
||||||
"postcheck-env": "yarn aio-check-local",
|
"postcheck-env": "yarn aio-check-local",
|
||||||
"payload-size": "scripts/payload.sh",
|
"payload-size": "scripts/payload.sh",
|
||||||
@@ -56,8 +56,8 @@
|
|||||||
"docs-test": "node tools/transforms/test.js",
|
"docs-test": "node tools/transforms/test.js",
|
||||||
"redirects-test": "node tests/deployment/unit/test",
|
"redirects-test": "node tests/deployment/unit/test",
|
||||||
"firebase-utils-test": "node tools/firebase-test-utils/test",
|
"firebase-utils-test": "node tools/firebase-test-utils/test",
|
||||||
"tools-lint": "eslint scripts/deploy-to-firebase && eslint tools/firebase-test-utils && eslint tools/ng-packages-installer",
|
"tools-lint": "eslint --ext=.mjs scripts/deploy-to-firebase && eslint tools/firebase-test-utils && eslint tools/ng-packages-installer",
|
||||||
"tools-test": "yarn docs-test && yarn boilerplate:test && jasmine tools/ng-packages-installer/index.spec.js && jasmine scripts/deploy-to-firebase/**/*.spec.js && yarn firebase-utils-test",
|
"tools-test": "yarn docs-test && yarn boilerplate:test && jasmine tools/ng-packages-installer/index.spec.js && jasmine scripts/deploy-to-firebase/**/*.spec.mjs && yarn firebase-utils-test",
|
||||||
"preserve-and-sync": "yarn docs",
|
"preserve-and-sync": "yarn docs",
|
||||||
"serve-and-sync": "run-p \"docs-watch --watch-only\" \"start {@}\" --",
|
"serve-and-sync": "run-p \"docs-watch --watch-only\" \"start {@}\" --",
|
||||||
"boilerplate:add": "node ./tools/examples/example-boilerplate add",
|
"boilerplate:add": "node ./tools/examples/example-boilerplate add",
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ module.exports = {
|
|||||||
jasmine: true,
|
jasmine: true,
|
||||||
node: true,
|
node: true,
|
||||||
},
|
},
|
||||||
|
parserOptions: {
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
'jasmine',
|
'jasmine',
|
||||||
],
|
],
|
||||||
|
|||||||
+24
-13
@@ -2,11 +2,12 @@
|
|||||||
//
|
//
|
||||||
// WARNING: `CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN` should NOT be printed.
|
// WARNING: `CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN` should NOT be printed.
|
||||||
//
|
//
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const {cd, cp, exec, mv, sed, set} = require('shelljs');
|
import {dirname} from 'path';
|
||||||
|
import sh from 'shelljs';
|
||||||
|
import {fileURLToPath} from 'url';
|
||||||
|
|
||||||
set('-e');
|
sh.set('-e');
|
||||||
|
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
@@ -15,10 +16,11 @@ const NG_REMOTE_URL = `https://github.com/${REPO_SLUG}.git`;
|
|||||||
const GIT_REMOTE_REFS_CACHE = new Map();
|
const GIT_REMOTE_REFS_CACHE = new Map();
|
||||||
|
|
||||||
// Exports
|
// Exports
|
||||||
module.exports = {
|
export {
|
||||||
computeDeploymentsInfo,
|
computeDeploymentsInfo,
|
||||||
computeInputVars,
|
computeInputVars,
|
||||||
computeMajorVersion,
|
computeMajorVersion,
|
||||||
|
getDirname,
|
||||||
getLatestCommit,
|
getLatestCommit,
|
||||||
getMostRecentMinorBranch,
|
getMostRecentMinorBranch,
|
||||||
skipDeployment,
|
skipDeployment,
|
||||||
@@ -26,7 +28,11 @@ module.exports = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Run
|
// Run
|
||||||
if (require.main === module) {
|
// ESM alternative for CommonJS' `require.main === module`. For simplicity, we assume command
|
||||||
|
// references the full file path (including the file extension).
|
||||||
|
// See https://stackoverflow.com/questions/45136831/node-js-require-main-module#answer-60309682 for
|
||||||
|
// more details.
|
||||||
|
if (fileURLToPath(import.meta.url) === process.argv[1]) {
|
||||||
const isDryRun = process.argv[2] === '--dry-run';
|
const isDryRun = process.argv[2] === '--dry-run';
|
||||||
const inputVars = computeInputVars(process.env);
|
const inputVars = computeInputVars(process.env);
|
||||||
const deploymentsInfo = computeDeploymentsInfo(inputVars);
|
const deploymentsInfo = computeDeploymentsInfo(inputVars);
|
||||||
@@ -67,7 +73,7 @@ function build({deployedUrl, deployEnv}) {
|
|||||||
yarn(`build --configuration=${deployEnv} --progress=false`);
|
yarn(`build --configuration=${deployEnv} --progress=false`);
|
||||||
|
|
||||||
console.log('\n\n\n==== Add any mode-specific files into the AIO distribution. ====\n');
|
console.log('\n\n\n==== Add any mode-specific files into the AIO distribution. ====\n');
|
||||||
cp('-rf', `src/extra-files/${deployEnv}/.`, 'dist/');
|
sh.cp('-rf', `src/extra-files/${deployEnv}/.`, 'dist/');
|
||||||
|
|
||||||
console.log('\n\n\n==== Update opensearch descriptor for AIO with `deployedUrl`. ====\n');
|
console.log('\n\n\n==== Update opensearch descriptor for AIO with `deployedUrl`. ====\n');
|
||||||
yarn(`set-opensearch-url ${deployedUrl.replace(/[^/]$/, '$&/')}`); // The URL must end with `/`.
|
yarn(`set-opensearch-url ${deployedUrl.replace(/[^/]$/, '$&/')}`); // The URL must end with `/`.
|
||||||
@@ -270,7 +276,7 @@ function deploy(data) {
|
|||||||
siteId,
|
siteId,
|
||||||
} = data;
|
} = data;
|
||||||
|
|
||||||
cd(`${__dirname}/../..`);
|
sh.cd(`${getDirname(import.meta.url)}/../..`);
|
||||||
|
|
||||||
console.log('\n\n\n==== Run pre-deploy actions. ====\n');
|
console.log('\n\n\n==== Run pre-deploy actions. ====\n');
|
||||||
preDeployActions.forEach(fn => fn(data));
|
preDeployActions.forEach(fn => fn(data));
|
||||||
@@ -286,6 +292,10 @@ function deploy(data) {
|
|||||||
postDeployActions.forEach(fn => fn(data));
|
postDeployActions.forEach(fn => fn(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDirname(fileUrl) {
|
||||||
|
return dirname(fileURLToPath(fileUrl));
|
||||||
|
}
|
||||||
|
|
||||||
function getRemoteRefs(refOrPattern, {remote = NG_REMOTE_URL, retrieveFromCache = true} = {}) {
|
function getRemoteRefs(refOrPattern, {remote = NG_REMOTE_URL, retrieveFromCache = true} = {}) {
|
||||||
// If remote refs for the same `refOrPattern` and `remote` have been requested before, return the
|
// If remote refs for the same `refOrPattern` and `remote` have been requested before, return the
|
||||||
// cached results. This improves the performance and ensures a more stable behavior.
|
// cached results. This improves the performance and ensures a more stable behavior.
|
||||||
@@ -298,7 +308,7 @@ function getRemoteRefs(refOrPattern, {remote = NG_REMOTE_URL, retrieveFromCache
|
|||||||
const cmd = `git ls-remote ${remote} ${refOrPattern}`;
|
const cmd = `git ls-remote ${remote} ${refOrPattern}`;
|
||||||
const result = (retrieveFromCache && GIT_REMOTE_REFS_CACHE.has(cmd)) ?
|
const result = (retrieveFromCache && GIT_REMOTE_REFS_CACHE.has(cmd)) ?
|
||||||
GIT_REMOTE_REFS_CACHE.get(cmd) :
|
GIT_REMOTE_REFS_CACHE.get(cmd) :
|
||||||
exec(cmd, {silent: true}).trim().split('\n');
|
sh.exec(cmd, {silent: true}).trim().split('\n');
|
||||||
|
|
||||||
// Cache the result for future use (regardless of the value of `retrieveFromCache`).
|
// Cache the result for future use (regardless of the value of `retrieveFromCache`).
|
||||||
GIT_REMOTE_REFS_CACHE.set(cmd, result);
|
GIT_REMOTE_REFS_CACHE.set(cmd, result);
|
||||||
@@ -337,13 +347,13 @@ function redirectToAngularIo() {
|
|||||||
// See https://firebase.google.com/docs/hosting/full-config#redirects.
|
// See https://firebase.google.com/docs/hosting/full-config#redirects.
|
||||||
const redirectRule =
|
const redirectRule =
|
||||||
'{"type": 302, "regex": "^(.*/[^./]*)$", "destination": "https://angular.io:1"}';
|
'{"type": 302, "regex": "^(.*/[^./]*)$", "destination": "https://angular.io:1"}';
|
||||||
sed('-i', /(\s*)"redirects": \[/, `$&\n$1 ${redirectRule},\n`, 'firebase.json');
|
sh.sed('-i', /(\s*)"redirects": \[/, `$&\n$1 ${redirectRule},\n`, 'firebase.json');
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeServiceWorker() {
|
function removeServiceWorker() {
|
||||||
// Rename the SW manifest (`ngsw.json`). This will cause the ServiceWorker to unregister itself.
|
// Rename the SW manifest (`ngsw.json`). This will cause the ServiceWorker to unregister itself.
|
||||||
// See https://angular.io/guide/service-worker-devops#fail-safe.
|
// See https://angular.io/guide/service-worker-devops#fail-safe.
|
||||||
mv('dist/ngsw.json', 'dist/ngsw.json.bak');
|
sh.mv('dist/ngsw.json', 'dist/ngsw.json.bak');
|
||||||
}
|
}
|
||||||
|
|
||||||
function serializeActions(actions) {
|
function serializeActions(actions) {
|
||||||
@@ -360,7 +370,8 @@ function testNoActiveRcDeployment({deployedUrl}) {
|
|||||||
// Ensure a request for `ngsw.json` returns 404.
|
// Ensure a request for `ngsw.json` returns 404.
|
||||||
const ngswJsonUrl = `${deployedOrigin}/ngsw.json`;
|
const ngswJsonUrl = `${deployedOrigin}/ngsw.json`;
|
||||||
const ngswJsonScript = `https.get('${ngswJsonUrl}', res => console.log(res.statusCode))`;
|
const ngswJsonScript = `https.get('${ngswJsonUrl}', res => console.log(res.statusCode))`;
|
||||||
const ngswJsonActualStatusCode = exec(`node --eval "${ngswJsonScript}"`, {silent: true}).trim();
|
const ngswJsonActualStatusCode =
|
||||||
|
sh.exec(`node --eval "${ngswJsonScript}"`, {silent: true}).trim();
|
||||||
const ngswJsonExpectedStatusCode = '404';
|
const ngswJsonExpectedStatusCode = '404';
|
||||||
|
|
||||||
if (ngswJsonActualStatusCode !== ngswJsonExpectedStatusCode) {
|
if (ngswJsonActualStatusCode !== ngswJsonExpectedStatusCode) {
|
||||||
@@ -374,7 +385,7 @@ function testNoActiveRcDeployment({deployedUrl}) {
|
|||||||
const fooBarScript =
|
const fooBarScript =
|
||||||
`https.get('${fooBarUrl}', res => console.log(res.statusCode, res.headers.location))`;
|
`https.get('${fooBarUrl}', res => console.log(res.statusCode, res.headers.location))`;
|
||||||
const [fooBarActualStatusCode, fooBarActualRedirectUrl] =
|
const [fooBarActualStatusCode, fooBarActualRedirectUrl] =
|
||||||
exec(`node --eval "${fooBarScript}"`, {silent: true}).trim().split(' ');
|
sh.exec(`node --eval "${fooBarScript}"`, {silent: true}).trim().split(' ');
|
||||||
const fooBarExpectedStatusCode = '302';
|
const fooBarExpectedStatusCode = '302';
|
||||||
const fooBarExpectedRedirectUrl = 'https://angular.io/foo/bar?baz=qux';
|
const fooBarExpectedRedirectUrl = 'https://angular.io/foo/bar?baz=qux';
|
||||||
|
|
||||||
@@ -480,5 +491,5 @@ function yarn(cmd) {
|
|||||||
// This is not strictly necessary, since CircleCI will mask secret environment variables in the
|
// This is not strictly necessary, since CircleCI will mask secret environment variables in the
|
||||||
// output (see https://circleci.com/docs/2.0/env-vars/#secrets-masking), but is an extra
|
// output (see https://circleci.com/docs/2.0/env-vars/#secrets-masking), but is an extra
|
||||||
// precaution.
|
// precaution.
|
||||||
return exec(`yarn --silent ${cmd}`);
|
return sh.exec(`yarn --silent ${cmd}`);
|
||||||
}
|
}
|
||||||
+6
-7
@@ -1,16 +1,14 @@
|
|||||||
#!/usr/bin/env node
|
import {execSync} from 'child_process';
|
||||||
'use strict';
|
import {
|
||||||
|
|
||||||
const {execSync} = require('child_process');
|
|
||||||
const {
|
|
||||||
computeDeploymentsInfo,
|
computeDeploymentsInfo,
|
||||||
computeInputVars,
|
computeInputVars,
|
||||||
computeMajorVersion,
|
computeMajorVersion,
|
||||||
|
getDirname,
|
||||||
getLatestCommit,
|
getLatestCommit,
|
||||||
getMostRecentMinorBranch,
|
getMostRecentMinorBranch,
|
||||||
skipDeployment,
|
skipDeployment,
|
||||||
validateDeploymentsInfo,
|
validateDeploymentsInfo,
|
||||||
} = require('./index');
|
} from './index.mjs';
|
||||||
|
|
||||||
|
|
||||||
describe('deploy-to-firebase:', () => {
|
describe('deploy-to-firebase:', () => {
|
||||||
@@ -424,7 +422,8 @@ describe('deploy-to-firebase:', () => {
|
|||||||
// and thus does not share the `getRemoteRefs()` cache. To improve stability, we retrieve the
|
// and thus does not share the `getRemoteRefs()` cache. To improve stability, we retrieve the
|
||||||
// latest commit from master ignoring any cached entries.
|
// latest commit from master ignoring any cached entries.
|
||||||
const latestCommitOnMaster = getLatestCommit('master', {retrieveFromCache: false});
|
const latestCommitOnMaster = getLatestCommit('master', {retrieveFromCache: false});
|
||||||
const cmd = `"${process.execPath}" "${__dirname}" --dry-run`;
|
const scriptPath = `${getDirname(import.meta.url)}/index.mjs`;
|
||||||
|
const cmd = `"${process.execPath}" "${scriptPath}" --dry-run`;
|
||||||
const env = {
|
const env = {
|
||||||
CI_REPO_OWNER: 'angular',
|
CI_REPO_OWNER: 'angular',
|
||||||
CI_REPO_NAME: 'angular',
|
CI_REPO_NAME: 'angular',
|
||||||
@@ -4,7 +4,7 @@ This folder is used for extra files that should be included in deployments to fi
|
|||||||
|
|
||||||
After the AIO application had been built and before it is deployed all files and folders inside the folder with the same name as the current deployment mode (next, stable, archive) will be copied to the `dist` folder.
|
After the AIO application had been built and before it is deployed all files and folders inside the folder with the same name as the current deployment mode (next, stable, archive) will be copied to the `dist` folder.
|
||||||
|
|
||||||
See the `scripts/deploy-to-firebase/index.js` script for more details.
|
See the `scripts/deploy-to-firebase/index.mjs` script for more details.
|
||||||
|
|
||||||
**Note:**
|
**Note:**
|
||||||
The script always expects there to be a folder for the current deployment mode (even if it is empty).
|
The script always expects there to be a folder for the current deployment mode (even if it is empty).
|
||||||
|
|||||||
Reference in New Issue
Block a user