{{ message }}
Repository navigation
build(docs-infra): update angular.io deployments to match new versioning/branching process #39470
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
ba3633d
build(docs-infra): switch `deploy-to-firebase.sh` script to JS
gkalpak 24fa934
test(docs-infra): ensure `deploy-to-firebase` tests pass locally
gkalpak 05de90a
refactor(docs-infra): use Sass mixin to simplify the creation of depl…
gkalpak 417e4b3
fixup! refactor(docs-infra): use Sass mixin to simplify the creation …
gkalpak e29f2a0
build(docs-infra): add new angular.io build configuration for release…
gkalpak 4dc4294
build(docs-infra): add support for RC deployments to deployment script
gkalpak 8960455
refactor(docs-infra): break up `deploy-to-firebase.js` script into fu…
gkalpak 4a70f0a
fixup! refactor(docs-infra): break up `deploy-to-firebase.js` script …
gkalpak fc9c61f
build(docs-infra): deploy angular.io to new Firebase sites
gkalpak 47904d9
build(docs-infra): upgrade `firebase-tools` to v8.14.1
gkalpak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,209 @@ | ||
| #!/bin/env node | ||
| // | ||
| // WARNING: `CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN` should NOT be printed. | ||
| // | ||
| 'use strict'; | ||
|
|
||
| const {cd, cp, exec: _exec, set} = require('shelljs'); | ||
|
|
||
| set('-e'); | ||
|
|
||
|
|
||
| // Constants | ||
| const REPO_SLUG = 'angular/angular'; | ||
| const NG_REMOTE_URL = `https://github.com/${REPO_SLUG}.git`; | ||
|
|
||
| // Exports | ||
| module.exports = { | ||
| computeDeploymentInfo, | ||
| computeInputVars, | ||
| getLatestCommit, | ||
| }; | ||
|
|
||
| // Run | ||
| if (require.main === module) { | ||
| const isDryRun = process.argv[2] === '--dry-run'; | ||
| const inputVars = computeInputVars(process.env); | ||
| const deploymentInfo = computeDeploymentInfo(inputVars); | ||
|
|
||
| if (deploymentInfo.skipped) { | ||
| console.log(deploymentInfo.reason); | ||
| } else { | ||
| console.log( | ||
| `Git branch : ${currentBranch}\n` + | ||
| `Build/deploy mode : ${deploymentInfo.deployEnv}\n` + | ||
| `Firebase project : ${deploymentInfo.projectId}\n` + | ||
| `Firebase site : ${deploymentInfo.siteId}\n` + | ||
| `Deployment URLs : ${deploymentInfo.deployedUrl}\n` + | ||
| ` https://${deploymentInfo.siteId}.web.app/`); | ||
|
|
||
| if (!isDryRun) { | ||
| deploy({...inputVars, ...deploymentInfo}); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Helpers | ||
| function computeDeploymentInfo( | ||
| {currentBranch, currentCommit, isPullRequest, repoName, repoOwner, stableBranch}) { | ||
| // Do not deploy if we are running in a fork. | ||
| if (`${repoOwner}/${repoName}` !== REPO_SLUG) { | ||
| return skipDeployment(`Skipping deploy because this is not ${REPO_SLUG}.`); | ||
| } | ||
|
|
||
| // Do not deploy if this is a PR. PRs are deployed in the `aio_preview` CircleCI job. | ||
| if (isPullRequest) { | ||
| return skipDeployment('Skipping deploy because this is a PR build.'); | ||
| } | ||
|
|
||
| // Do not deploy if the current commit is not the latest on its branch. | ||
| const latestCommit = getLatestCommit(currentBranch); | ||
| if (currentCommit !== latestCommit) { | ||
| return skipDeployment( | ||
| `Skipping deploy because ${currentCommit} is not the latest commit (${latestCommit}).`); | ||
| } | ||
|
|
||
| // The deployment mode is computed based on the branch we are building. | ||
| const currentBranchMajorVersion = computeMajorVersion(currentBranch); | ||
| const deploymentInfoPerTarget = { | ||
| next: { | ||
| deployEnv: 'next', | ||
| projectId: 'angular-io', | ||
| siteId: 'next-angular-io-site', | ||
| deployedUrl: 'https://next.angular.io/', | ||
| }, | ||
| rc: { | ||
| deployEnv: 'rc', | ||
| projectId: 'angular-io', | ||
| siteId: 'rc-angular-io-site', | ||
| deployedUrl: 'https://rc.angular.io/', | ||
| }, | ||
| stable: { | ||
| deployEnv: 'stable', | ||
| projectId: 'angular-io', | ||
| siteId: `v${currentBranchMajorVersion}-angular-io-site`, | ||
| deployedUrl: 'https://angular.io/', | ||
| }, | ||
| archive: { | ||
| deployEnv: 'archive', | ||
| projectId: 'angular-io', | ||
| siteId: `v${currentBranchMajorVersion}-angular-io-site`, | ||
| deployedUrl: `https://v${currentBranchMajorVersion}.angular.io/`, | ||
| }, | ||
| }; | ||
|
|
||
| if (currentBranch === 'master') { | ||
| return deploymentInfoPerTarget.next; | ||
| } else if (currentBranch === stableBranch) { | ||
| return deploymentInfoPerTarget.stable; | ||
| } else { | ||
| const stableBranchMajorVersion = computeMajorVersion(stableBranch); | ||
|
|
||
| // Find the branch that has highest minor version for the given `currentBranchMajorVersion`. | ||
| const mostRecentMinorVersionBranch = | ||
| // List the branches that start with the major version. | ||
| getRemoteRefs(`refs/heads/${currentBranchMajorVersion}.*.x`) | ||
| // Extract the version number. | ||
| .map(line => line.split('/')[2]) | ||
| // Sort by the minor version. | ||
| .sort((a, b) => a.split('.')[1] - b.split('.')[1]) | ||
| // Get the highest version. | ||
| .pop(); | ||
|
|
||
| // Do not deploy if it is not the latest branch for the given major version. | ||
| // NOTE: At this point, we know the current branch is not the stable branch. | ||
| if (currentBranch !== mostRecentMinorVersionBranch) { | ||
| return skipDeployment( | ||
| `Skipping deploy of branch "${currentBranch}" to Firebase.\n` + | ||
| 'There is a more recent branch with the same major version: ' + | ||
| `"${mostRecentMinorVersionBranch}"`); | ||
| } | ||
|
|
||
| return (currentBranchMajorVersion < stableBranchMajorVersion) ? | ||
| // This is the latest minor version for a major that is less than the stable major version: | ||
| // Deploy as `archive`. | ||
| deploymentInfoPerTarget.archive : | ||
| // This is the latest minor version for a major that is equal or greater than the stable | ||
| // major version, but not the stable version itself: | ||
| // Deploy as `rc`. | ||
| deploymentInfoPerTarget.rc; | ||
| } | ||
|
|
||
| // We should never get here. | ||
| throw new Error('Failed to determine deployment info.'); | ||
| } | ||
|
|
||
| function computeInputVars({ | ||
| CI_AIO_MIN_PWA_SCORE: minPwaScore, | ||
| CI_BRANCH: currentBranch, | ||
| CI_COMMIT: currentCommit, | ||
| CI_PULL_REQUEST, | ||
| CI_REPO_NAME: repoName, | ||
| CI_REPO_OWNER: repoOwner, | ||
| CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN: firebaseToken, | ||
| CI_STABLE_BRANCH: stableBranch, | ||
| }) { | ||
| return { | ||
| currentBranch, | ||
| currentCommit, | ||
| firebaseToken, | ||
| isPullRequest: CI_PULL_REQUEST !== 'false', | ||
| minPwaScore, | ||
| repoName, | ||
| repoOwner, | ||
| stableBranch, | ||
| }; | ||
| } | ||
|
|
||
| function computeMajorVersion(branchName) { | ||
| return +branchName.split('.', 1)[0]; | ||
| } | ||
|
|
||
| function deploy( | ||
| {currentCommit, deployedUrl, deployEnv, firebaseToken, minPwaScore, projectId, siteId}) { | ||
| cd(`${__dirname}/..`); | ||
|
|
||
| console.log('\n\n\n==== Build the AIO app. ====\n'); | ||
| yarn(`build --configuration=${deployEnv} --progress=false`); | ||
|
|
||
| console.log('\n\n\n==== Add any mode-specific files into the AIO distribution. ====\n'); | ||
| cp('-rf', `src/extra-files/${deployEnv}/.`, 'dist/'); | ||
|
|
||
| console.log('\n\n\n==== Update opensearch descriptor for AIO with `deployedUrl`. ====\n'); | ||
| yarn(`set-opensearch-url ${deployedUrl.replace(/[^/]$/, '$&/')}`); // The URL must end with `/`. | ||
|
|
||
| console.log('\n\n\n==== Check payload size and upload the numbers to Firebase DB. ====\n'); | ||
| yarn('payload-size'); | ||
|
|
||
| console.log('\n\n\n==== Deploy AIO to Firebase hosting. ====\n'); | ||
| yarn(`firebase use "${projectId}" --token "${firebaseToken}"`); | ||
| yarn(`firebase target:apply hosting aio "${siteId}" --token "${firebaseToken}"`); | ||
| yarn( | ||
| `firebase deploy --only hosting:aio --message "Commit: ${currentCommit}" --non-interactive ` + | ||
| `--token "${firebaseToken}"`); | ||
|
|
||
| console.log('\n\n\n==== Run PWA-score tests. ====\n'); | ||
| yarn(`test-pwa-score "${deployedUrl}" "${minPwaScore}"`); | ||
| } | ||
|
|
||
| function exec(cmd, opts) { | ||
| // Using `silent: true` to ensure no secret env variables are printed. | ||
| return _exec(cmd, {silent: true, ...opts}).trim(); | ||
| } | ||
|
|
||
| function getRemoteRefs(refOrPattern, remote = NG_REMOTE_URL) { | ||
| return exec(`git ls-remote ${remote} ${refOrPattern}`).split('\n'); | ||
| } | ||
|
|
||
| function getLatestCommit(branchName, remote = undefined) { | ||
| return getRemoteRefs(branchName, remote)[0].slice(0, 40); | ||
| } | ||
|
|
||
| function skipDeployment(reason) { | ||
| return {reason, skipped: true}; | ||
| } | ||
|
|
||
| function yarn(cmd) { | ||
| // Using `--silent` to ensure no secret env variables are printed. | ||
| return exec(`yarn --silent ${cmd}`); | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
You can’t perform that action at this time.

Uh oh!
There was an error while loading. Please reload this page.