mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
build: convert release package build scripts to typescript (#46456)
Follow-up to: cce395a928.
PR Close #46456
This commit is contained in:
committed by
Andrew Kushnir
parent
2d713f5847
commit
d248d83c17
@@ -53,8 +53,8 @@ build:release --workspace_status_command="yarn -s ng-dev release build-env-stamp
|
||||
build:release --stamp
|
||||
|
||||
# Snapshots should also be stamped with version control information.
|
||||
build:snapshot --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=snapshot"
|
||||
build:snapshot --stamp
|
||||
build:snapshot-build --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=snapshot"
|
||||
build:snapshot-build --stamp
|
||||
|
||||
###############################
|
||||
# Output #
|
||||
|
||||
@@ -442,7 +442,7 @@ jobs:
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- run: node scripts/build/build-packages-dist.js
|
||||
- run: yarn build
|
||||
|
||||
# Save the npm packages from //packages/... for other workflow jobs to read
|
||||
- persist_to_workspace:
|
||||
|
||||
+4
-7
@@ -1,5 +1,4 @@
|
||||
import {ReleaseConfig} from '@angular/dev-infra-private/ng-dev';
|
||||
import {join} from 'path';
|
||||
|
||||
/** Configuration for the `ng-dev release` command. */
|
||||
export const release: ReleaseConfig = {
|
||||
@@ -24,12 +23,10 @@ export const release: ReleaseConfig = {
|
||||
{name: '@angular/upgrade'},
|
||||
],
|
||||
buildPackages: async () => {
|
||||
// The buildTargetPackages function is loaded at runtime as the loading the script causes an
|
||||
// invocation of bazel.
|
||||
const packageBuilder = await import('../scripts/build/package-builder.js');
|
||||
|
||||
return packageBuilder.default.buildTargetPackages(
|
||||
'dist/release-output', 'Release', /* isRelease */ true);
|
||||
// The buildTargetPackages function is loaded at runtime as the loading the script
|
||||
// causes an invocation of Bazel.
|
||||
const {performNpmReleaseBuild} = await import('../scripts/build/package-builder.mjs');
|
||||
return performNpmReleaseBuild();
|
||||
},
|
||||
releaseNotes: {
|
||||
hiddenScopes: ['aio', 'bazel', 'dev-infra', 'docs-infra', 'zone.js', 'devtools'],
|
||||
|
||||
@@ -16,8 +16,7 @@ const ANGULAR_ROOT_DIR = path.resolve(__dirname, '../../..');
|
||||
const ANGULAR_DIST_PACKAGES_DIR = path.join(ANGULAR_ROOT_DIR, 'dist/packages-dist');
|
||||
const AIMWA_DIST_PACKAGES_DIR = path.join(ANGULAR_ROOT_DIR, 'dist/angular-in-memory-web-api-dist');
|
||||
const ZONEJS_DIST_PACKAGES_DIR = path.join(ANGULAR_ROOT_DIR, 'dist/zone.js-dist');
|
||||
const DIST_PACKAGES_BUILD_SCRIPT = path.join(ANGULAR_ROOT_DIR, 'scripts/build/build-packages-dist.js');
|
||||
const DIST_PACKAGES_BUILD_CMD = `"${process.execPath}" "${DIST_PACKAGES_BUILD_SCRIPT}"`;
|
||||
const DIST_PACKAGES_BUILD_CMD = 'yarn -s build';
|
||||
|
||||
/**
|
||||
* A tool that can install Angular/Zone.js dependencies for a project from NPM or from the
|
||||
@@ -181,14 +180,14 @@ class NgPackagesInstaller {
|
||||
const canBuild = process.platform !== 'win32';
|
||||
|
||||
if (canBuild) {
|
||||
this._log(`Building the local packages with: ${DIST_PACKAGES_BUILD_SCRIPT}`);
|
||||
shelljs.exec(DIST_PACKAGES_BUILD_CMD);
|
||||
this._log(`Building the local packages with: ${DIST_PACKAGES_BUILD_CMD} in ${ANGULAR_ROOT_DIR}`);
|
||||
shelljs.exec(DIST_PACKAGES_BUILD_CMD, {cwd: ANGULAR_ROOT_DIR});
|
||||
} else {
|
||||
this._warn([
|
||||
'Automatically building the local Angular/angular-in-memory-web-api/zone.js packages is currently not ' +
|
||||
'supported on Windows.',
|
||||
`Please, ensure '${ANGULAR_DIST_PACKAGES_DIR}', '${AIMWA_DIST_PACKAGES_DIR}' and ` +
|
||||
`'${ZONEJS_DIST_PACKAGES_DIR}' exist and are up-to-date (e.g. by running '${DIST_PACKAGES_BUILD_SCRIPT}' ` +
|
||||
`'${ZONEJS_DIST_PACKAGES_DIR}' exist and are up-to-date (e.g. by running "${DIST_PACKAGES_BUILD_CMD}" ` +
|
||||
'in Git Bash for Windows, Windows Subsystem for Linux or a Linux docker container or VM).',
|
||||
'',
|
||||
'Proceeding anyway...',
|
||||
|
||||
@@ -305,25 +305,20 @@ describe('NgPackagesInstaller', () => {
|
||||
};
|
||||
|
||||
it('should build the local packages, when not on Windows', () => {
|
||||
const buildScript = path.join(ngRootDir, 'scripts/build/build-packages-dist.js');
|
||||
const buildCmd = `"${process.execPath}" "${buildScript}"`;
|
||||
const buildCmd = 'yarn -s build';
|
||||
|
||||
buildDistPackagesOnPlatform('linux');
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildCmd);
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildCmd, {cwd: ngRootDir});
|
||||
|
||||
shelljs.exec.calls.reset();
|
||||
|
||||
buildDistPackagesOnPlatform('darwin');
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildCmd);
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildCmd, {cwd: ngRootDir});
|
||||
|
||||
shelljs.exec.calls.reset();
|
||||
|
||||
buildDistPackagesOnPlatform('anythingButWindows :(');
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildCmd);
|
||||
|
||||
// Ensure that the script does actually exist (e.g. it was not renamed/moved).
|
||||
fs.existsSync.and.callThrough();
|
||||
expect(fs.existsSync(buildScript)).toBe(true);
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildCmd, {cwd: ngRootDir});
|
||||
});
|
||||
|
||||
it('should print a warning, when on Windows', () => {
|
||||
|
||||
@@ -283,7 +283,7 @@ pkg_web(
|
||||
"@npm//:node_modules/tslib/tslib.js",
|
||||
],
|
||||
# Currently, ibazel doesn't allow passing in flags to bazel run.
|
||||
# This means we are not able to use --config snapshot
|
||||
# This means we are not able to use --config snapshot-build
|
||||
# to access the current commit SHA.
|
||||
# Since we still want to be able to use ibazel to speed up
|
||||
# local development, we supply an empty string for the SHA substitution.
|
||||
|
||||
+1
-1
@@ -297,7 +297,7 @@ The `msys64` library and associated tools (like `mkdir`) are required to build A
|
||||
|
||||
Make sure you have `C:\msys64\usr\bin` in the "system" `PATH` rather than the "user" `PATH`.
|
||||
|
||||
After that, a `git clean -xfd`, `yarn`, and `node scripts\build\build-packages-dist.js` should resolve this issue.
|
||||
After that, a `git clean -xfd`, `yarn`, and `yarn build` should resolve this issue.
|
||||
|
||||
### Xcode
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@ Currently all changes to Ivy are validated against the test suite of the
|
||||
`angular/components` repository. In order to debug the `components-repo-unit-tests` CI
|
||||
job, the following steps can be used:
|
||||
|
||||
1\) Build the Ivy package output by running `node ./scripts/build/build-packages-dist.js` in
|
||||
the `angular/angular` repo.
|
||||
1\) Build the Ivy package output by running `yarn build` in the `angular/angular` repo.
|
||||
|
||||
2\) Clone the `angular/components` repository if not done yet ([quick link to repo](https://github.com/angular/components)).
|
||||
|
||||
|
||||
+2
-2
@@ -67,7 +67,7 @@ yarn install
|
||||
To build Angular run:
|
||||
|
||||
```shell
|
||||
node ./scripts/build/build-packages-dist.js
|
||||
yarn build
|
||||
```
|
||||
|
||||
* Results are put in the `dist/packages-dist` folder.
|
||||
@@ -197,7 +197,7 @@ c. Some package managers (such as `pnpm` or `yarn pnp`) might not work correctly
|
||||
### Publishing to GitHub Repos
|
||||
You can also manually publish `*-builds` snapshots just like our CircleCI build does for upstream
|
||||
builds. Before being able to publish the packages, you need to build them locally by running the
|
||||
`./scripts/build/build-packages-dist.js` script.
|
||||
`yarn build` command.
|
||||
|
||||
First time, you need to create the GitHub repositories:
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ This directory contains end-to-end tests for Angular. Each directory is a self-c
|
||||
that exactly mimics how a user might expect Angular to work, so they allow high-fidelity
|
||||
reproductions of real-world issues.
|
||||
|
||||
For this to work, we first build the Angular distribution via `./scripts/build/build-packages-dist.js`, then
|
||||
For this to work, we first build the Angular distribution via `yarn build`, then
|
||||
install the distribution into each app.
|
||||
|
||||
To test Angular CLI applications, we use the `cli-hello-world-*` integration tests.
|
||||
|
||||
@@ -11,7 +11,8 @@ set -u -e -o pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
node $(pwd)/../../scripts/build/build-packages-dist.js
|
||||
# Go to the project directory and build the release packages.
|
||||
(cd $(pwd)/../../ && yarn build)
|
||||
|
||||
# Workaround https://github.com/yarnpkg/yarn/issues/2165
|
||||
# Yarn will cache file://dist URIs and not update Angular code
|
||||
|
||||
@@ -11,7 +11,8 @@ set -u -e -o pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
node $(pwd)/../../scripts/build/build-packages-dist.js
|
||||
# Go to the project directory and build the release packages.
|
||||
(cd $(pwd)/../../ && yarn build)
|
||||
|
||||
# Workaround https://github.com/yarnpkg/yarn/issues/2165
|
||||
# Yarn will cache file://dist URIs and not update Angular code
|
||||
|
||||
@@ -11,7 +11,8 @@ set -u -e -o pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
node $(pwd)/../../scripts/build/build-packages-dist.js
|
||||
# Go to the project directory and build the release packages.
|
||||
(cd $(pwd)/../../ && yarn build)
|
||||
|
||||
# Workaround https://github.com/yarnpkg/yarn/issues/2165
|
||||
# Yarn will cache file://dist URIs and not update Angular code
|
||||
|
||||
@@ -11,7 +11,8 @@ set -u -e -o pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
node $(pwd)/../../scripts/build/build-packages-dist.js
|
||||
# Go to the project directory and build the release packages.
|
||||
(cd $(pwd)/../../ && yarn build)
|
||||
|
||||
# Workaround https://github.com/yarnpkg/yarn/issues/2165
|
||||
# Yarn will cache file://dist URIs and not update Angular code
|
||||
|
||||
@@ -20,7 +20,7 @@ echo ${RUN_TESTS}
|
||||
|
||||
# Build the packages-dist directory.
|
||||
# This should be fast on incremental re-build.
|
||||
node ../scripts/build/build-packages-dist.js
|
||||
yarn build
|
||||
|
||||
# Workaround https://github.com/yarnpkg/yarn/issues/2165
|
||||
# Yarn will cache file://dist URIs and not update Angular code
|
||||
|
||||
+5
-4
@@ -25,6 +25,7 @@
|
||||
"postinstall": "node scripts/webdriver-manager-update.js && node --preserve-symlinks --preserve-symlinks-main ./tools/postinstall-patches.js",
|
||||
"prepare": "husky install",
|
||||
"ng-dev": "ts-node --esm --project .ng-dev/tsconfig.json node_modules/@angular/dev-infra-private/ng-dev/bundles/cli.mjs",
|
||||
"build": "ts-node --esm --project scripts/tsconfig.json scripts/build/build-packages-dist.mts",
|
||||
"test": "bazelisk test",
|
||||
"test:ci": "bazelisk test -- //... -//devtools/... -//aio/...",
|
||||
"test-tsec": "bazelisk test //... --build_tag_filters=tsec --test_tag_filters=tsec",
|
||||
@@ -36,11 +37,11 @@
|
||||
"symbol-extractor:update": "node tools/symbol-extractor/run_all_symbols_extractor_tests.js accept",
|
||||
"ts-circular-deps:check": "yarn -s ng-dev ts-circular-deps check --config ./packages/circular-deps-test.conf.js",
|
||||
"ts-circular-deps:approve": "yarn -s ng-dev ts-circular-deps approve --config ./packages/circular-deps-test.conf.js",
|
||||
"check-tooling-setup": "yarn tsc --project .ng-dev/tsconfig.json",
|
||||
"check-tooling-setup": "yarn tsc --project .ng-dev/tsconfig.json && yarn tsc --project scripts/tsconfig.json",
|
||||
"devtools:devserver": "ibazel run //devtools/src:devserver",
|
||||
"devtools:build:chrome": "bazelisk build --config snapshot --//devtools/projects/shell-browser/src:flag_browser=chrome -- devtools/projects/shell-browser/src:prodapp",
|
||||
"devtools:build:firefox": "bazelisk build --config snapshot --//devtools/projects/shell-browser/src:flag_browser=firefox -- devtools/projects/shell-browser/src:prodapp",
|
||||
"devtools:test": "bazelisk test --config snapshot --//devtools/projects/shell-browser/src:flag_browser=chrome -- //devtools/..."
|
||||
"devtools:build:chrome": "bazelisk build --config snapshot-build --//devtools/projects/shell-browser/src:flag_browser=chrome -- devtools/projects/shell-browser/src:prodapp",
|
||||
"devtools:build:firefox": "bazelisk build --config snapshot-build --//devtools/projects/shell-browser/src:flag_browser=firefox -- devtools/projects/shell-browser/src:prodapp",
|
||||
"devtools:test": "bazelisk test --config snapshot-build --//devtools/projects/shell-browser/src:flag_browser=chrome -- //devtools/..."
|
||||
},
|
||||
"// 1": "dependencies are used locally and by bazel",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
// The build script used to be here but has been moved to `scripts/build/` in PR
|
||||
// https://github.com/angular/angular/pull/35780. This is a temporary placeholder script for people
|
||||
// that are not aware of the change and expect to find the script here.
|
||||
//
|
||||
// TODO: This script can be removed early May 2020.
|
||||
'use strict';
|
||||
|
||||
const {red} = require('chalk');
|
||||
const {relative, resolve} = require('path');
|
||||
|
||||
|
||||
const absoluteScriptPath = resolve(`${__dirname}/build/build-packages-dist.js`);
|
||||
const relativeScriptPath = relative(process.cwd(), absoluteScriptPath);
|
||||
|
||||
console.error(red('ERROR: The build script has been moved to \'scripts/build/\'.'));
|
||||
console.error(red(` Run: node ${relativeScriptPath}`));
|
||||
|
||||
process.exit(1);
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const {resolve} = require('path');
|
||||
const {chmod, cp, mkdir, rm, test} = require('shelljs');
|
||||
const {baseDir, bazelBin, bazelCmd, exec, scriptPath} = require('./package-builder');
|
||||
|
||||
|
||||
module.exports = {
|
||||
buildAngularInMemoryWebApiPackage,
|
||||
};
|
||||
|
||||
/**
|
||||
* Build the `angular-in-memory-web-api` npm package and copy it to `destDir` for other
|
||||
* scripts/tests to use.
|
||||
*
|
||||
* NOTE: The `angular-in-memory-web-api` package is not built as part of `package-builder`'s
|
||||
* `buildTargetPackages()` nor is it copied into the same directory as the Angular packages
|
||||
* (e.g. `dist/packages-dist/`) despite its source's being inside `packages/`, because it is
|
||||
* not published to npm under the `@angular` scope (as happens for the rest of the packages).
|
||||
*
|
||||
* @param {string} destDir Path to the output directory into which we copy the npm package.
|
||||
* This path should either be absolute or relative to the project root.
|
||||
*/
|
||||
function buildAngularInMemoryWebApiPackage(destDir) {
|
||||
console.info('##############################');
|
||||
console.info(`${scriptPath}:`);
|
||||
console.info(' Building angular-in-memory-web-api npm package');
|
||||
console.info('##############################');
|
||||
exec(`${bazelCmd} build //packages/misc/angular-in-memory-web-api:npm_package`);
|
||||
|
||||
// Create the output directory.
|
||||
const absDestDir = resolve(baseDir, destDir);
|
||||
if (!test('-d', absDestDir)) {
|
||||
mkdir('-p', absDestDir);
|
||||
}
|
||||
|
||||
const buildOutputDir = `${bazelBin}/packages/misc/angular-in-memory-web-api/npm_package`;
|
||||
const distTargetDir = `${absDestDir}/angular-in-memory-web-api`;
|
||||
|
||||
console.info(`# Copy artifacts to ${distTargetDir}`);
|
||||
rm('-rf', distTargetDir);
|
||||
cp('-R', buildOutputDir, distTargetDir);
|
||||
chmod('-R', 'u+w', distTargetDir);
|
||||
|
||||
console.info('');
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {join} from 'path';
|
||||
import sh from 'shelljs';
|
||||
|
||||
import {projectDir, bazelCmd, exec} from './package-builder.mjs';
|
||||
|
||||
/**
|
||||
* Build the `angular-in-memory-web-api` npm package and copies it into the release
|
||||
* distribution directory.
|
||||
*
|
||||
* NOTE: The `angular-in-memory-web-api` package is not built as part of `package-builder`'s
|
||||
* `buildTargetPackages()` nor is it copied into the same directory as the Angular packages (e.g.
|
||||
* `dist/packages-dist/`) despite its source's being inside `packages/`, because it is not
|
||||
* published to npm under the `@angular` scope (as happens for the rest of the packages).
|
||||
*
|
||||
* @param {string} destDir Path to the output directory into which we copy the npm package.
|
||||
* This path should either be absolute or relative to the project root.
|
||||
*/
|
||||
export function buildAngularInMemoryWebApiPackage(destDir: string): void {
|
||||
console.info('##############################');
|
||||
console.info(' Building angular-in-memory-web-api npm package');
|
||||
console.info('##############################');
|
||||
|
||||
exec(`${bazelCmd} build //packages/misc/angular-in-memory-web-api:npm_package`);
|
||||
|
||||
// Create the output directory.
|
||||
if (!sh.test('-d', destDir)) {
|
||||
sh.mkdir('-p', destDir);
|
||||
}
|
||||
|
||||
const bazelBinPath = exec(`${bazelCmd} info bazel-bin`, true);
|
||||
|
||||
// Copy artifacts to `destDir`, so they can be easier persisted on CI and used by non-bazel
|
||||
// scripts/tests.
|
||||
const buildOutputDir = join(bazelBinPath, 'packages/misc/angular-in-memory-web-api/npm_package');
|
||||
const distTargetDir = join(destDir, 'angular-in-memory-web-api');
|
||||
|
||||
console.info(`# Copy npm_package artifacts to ${distTargetDir}`);
|
||||
|
||||
sh.rm('-rf', distTargetDir);
|
||||
sh.cp('-R', buildOutputDir, distTargetDir);
|
||||
sh.chmod('-R', 'u+w', distTargetDir);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
@@ -7,15 +8,13 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const {buildAngularInMemoryWebApiPackage} = require('./angular-in-memory-web-api');
|
||||
const {buildTargetPackages} = require('./package-builder');
|
||||
const {buildZoneJsPackage} = require('./zone-js-builder');
|
||||
import {buildAngularInMemoryWebApiPackage} from './angular-in-memory-web-api.mjs';
|
||||
import {performDefaultSnapshotBuild} from './package-builder.mjs';
|
||||
import {buildZoneJsPackage} from './zone-js-builder.mjs';
|
||||
|
||||
|
||||
// Build the legacy (view engine) npm packages into `dist/packages-dist/`.
|
||||
buildTargetPackages('dist/packages-dist', 'Production');
|
||||
performDefaultSnapshotBuild();
|
||||
|
||||
// Build the `angular-in-memory-web-api` npm package into `dist/angular-in-memory-web-api-dist/`,
|
||||
// because it might be needed by other scripts/targets.
|
||||
Vendored
-18
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Build the Angular packages.
|
||||
*
|
||||
* @param {string} destDir Path to the output directory into which we copy the npm packages.
|
||||
* This path should either be absolute or relative to the project root.
|
||||
* @param {string} description Human-readable description of the build.
|
||||
* @param {boolean?} isRelease True, if the build should be stamped for a release.
|
||||
* @returns {Array<{name: string, outputPath: string}} A list of packages built.
|
||||
*/
|
||||
export declare function buildTargetPackages(destDir, description, isRelease: boolean): {name: string, outputPath: string}[];
|
||||
@@ -1,153 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// Build the dist/packages-dist directory in the same fashion as the legacy
|
||||
// /build.sh script, by building the npm packages with Bazel and copying files.
|
||||
// This is needed for scripts and tests which are not updated to the Bazel output
|
||||
// layout (which always matches the input layout).
|
||||
// Do not add new dependencies on this script, instead adapt scripts to use the
|
||||
// new layout, and write new tests as Bazel targets.
|
||||
//
|
||||
// Ideally integration tests should run under bazel, and just consume the npm
|
||||
// packages via `deps`. Until that works, we manually build the npm packages and then
|
||||
// copy the results to the appropriate `dist` location.
|
||||
|
||||
// NOTE: this script may be run from any directory. The actions should be written to be independent
|
||||
// of the current working directory. For example, use absolute paths wherever possible, and pass a
|
||||
// working directory to tools like `yarn`.
|
||||
|
||||
const {execSync} = require('child_process');
|
||||
const {resolve, relative} = require('path');
|
||||
const {chmod, cp, mkdir, rm, set, test} = require('shelljs');
|
||||
|
||||
set('-e');
|
||||
|
||||
|
||||
/** @type {string} The absolute path to the project root directory. */
|
||||
const baseDir = resolve(`${__dirname}/../..`);
|
||||
|
||||
/** @type {string} The command to use for running bazel. */
|
||||
const bazelCmd = process.env.BAZEL ?? `yarn --cwd "${baseDir}" --silent bazel`;
|
||||
|
||||
/** @type {string} The absolute path to the bazel-bin directory. */
|
||||
const bazelBin = exec(`${bazelCmd} info bazel-bin`, true);
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* The relative path to the entry script (i.e. the one loaded when the Node.js process launched).
|
||||
* It is relative to `baseDir`.
|
||||
*/
|
||||
const scriptPath = relative(baseDir, require.main.filename);
|
||||
|
||||
module.exports = {
|
||||
baseDir,
|
||||
bazelBin,
|
||||
bazelCmd,
|
||||
buildTargetPackages,
|
||||
exec,
|
||||
scriptPath,
|
||||
};
|
||||
|
||||
/**
|
||||
* Build the Angular packages.
|
||||
*
|
||||
* @param {string} destDir Path to the output directory into which we copy the npm packages.
|
||||
* This path should either be absolute or relative to the project root.
|
||||
* @param {string} description Human-readable description of the build.
|
||||
* @param {boolean?} isRelease True, if the build should be stamped for a release.
|
||||
* @returns {Array<{name: string, outputPath: string}} A list of packages built.
|
||||
*/
|
||||
function buildTargetPackages(destDir, description, isRelease = false) {
|
||||
console.info('##################################');
|
||||
console.info(`${scriptPath}:`);
|
||||
console.info(' Building @angular/* npm packages');
|
||||
console.info(` Mode: ${description}`);
|
||||
console.info('##################################');
|
||||
|
||||
/** The list of packages which were built. */
|
||||
const builtPackages = [];
|
||||
// List of targets to build, e.g. core, common, compiler, etc. Note that we want to also remove
|
||||
// all carriage return (`\r`) characters form the query output, because otherwise the carriage
|
||||
// return is part of the bazel target name and bazel will complain.
|
||||
const getTargetsCmd = `${
|
||||
bazelCmd} query --output=label "attr('tags', '\\[.*release-with-framework.*\\]', //packages/...) intersect kind('ng_package|pkg_npm', //packages/...)"`;
|
||||
const targets = exec(getTargetsCmd, true).split(/\r?\n/);
|
||||
|
||||
// If we are in release mode, run `bazel clean` to ensure the execroot and action cache
|
||||
// are not populated. This is necessary because targets using `npm_package` rely on
|
||||
// workspace status variables for the package version. Such NPM package targets are not
|
||||
// rebuilt if only the workspace status variables change. This could result in accidental
|
||||
// re-use of previously built package output with a different `version` in the `package.json`.
|
||||
if (isRelease) {
|
||||
console.info('Building in release mode. Resetting the Bazel execroot and action cache..');
|
||||
exec(`${bazelCmd} clean`);
|
||||
}
|
||||
|
||||
// Use either `--config=snapshot` or `--config=release` so that builds are created with the
|
||||
// correct embedded version info.
|
||||
exec(`${bazelCmd} build --config=${isRelease ? 'release' : 'snapshot'} ${targets.join(' ')}`);
|
||||
|
||||
// Create the output directory.
|
||||
const absDestDir = resolve(baseDir, destDir);
|
||||
if (!test('-d', absDestDir)) {
|
||||
mkdir('-p', absDestDir);
|
||||
}
|
||||
|
||||
targets.forEach(target => {
|
||||
const pkg = target.replace(/\/\/packages\/(.*):npm_package/, '$1');
|
||||
|
||||
// Skip any that don't have an "npm_package" target.
|
||||
const srcDir = `${bazelBin}/packages/${pkg}/npm_package`;
|
||||
const destDir = `${absDestDir}/${pkg}`;
|
||||
|
||||
if (test('-d', srcDir)) {
|
||||
console.info(`# Copy artifacts to ${destDir}`);
|
||||
rm('-rf', destDir);
|
||||
cp('-R', srcDir, destDir);
|
||||
chmod('-R', 'u+w', destDir);
|
||||
builtPackages.push({name: `@angular/${pkg}`, outputPath: destDir});
|
||||
}
|
||||
});
|
||||
|
||||
console.info('');
|
||||
return builtPackages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a command synchronously.
|
||||
*
|
||||
* By default, the current process' stdout is used (and thus the output is not captured and returned
|
||||
* to the caller). This is necessary for showing colors and modifying already printed output, for
|
||||
* example to show progress.
|
||||
*
|
||||
* If the caller requests the output (via `captureStdout: true`), the command is run without
|
||||
* printing anything to stdout and then (once the command has completed) the whole output is printed
|
||||
* to stdout and returned to the caller.
|
||||
*
|
||||
* @param {string} cmd The command to run.
|
||||
* @param {boolean} [captureStdout=false] Whether to return the output of the command.
|
||||
* @param {import('child_process').ExecSyncOptions} [options] The options to pass to `execSync()`.
|
||||
* @return {string | undefined} The captured stdout output if `captureStdout: true` or `undefined`.
|
||||
*/
|
||||
function exec(cmd, captureStdout, options) {
|
||||
const output = execSync(cmd, {
|
||||
stdio: [
|
||||
/* stdin */ 'inherit',
|
||||
/* stdout */ captureStdout ? 'pipe' : 'inherit',
|
||||
/* stderr */ 'inherit',
|
||||
],
|
||||
...options,
|
||||
});
|
||||
|
||||
if (captureStdout) {
|
||||
process.stdout.write(output);
|
||||
return output.toString().trim();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {execSync} from 'child_process';
|
||||
import {join, dirname} from 'path';
|
||||
import {BuiltPackage} from '@angular/dev-infra-private/ng-dev';
|
||||
import {fileURLToPath} from 'url';
|
||||
import sh from 'shelljs';
|
||||
|
||||
// ShellJS should exit if a command fails.
|
||||
sh.set('-e');
|
||||
|
||||
/** Path to the project directory. */
|
||||
export const projectDir = join(dirname(fileURLToPath(import.meta.url)), '../..');
|
||||
|
||||
/** Command that runs Bazel. */
|
||||
export const bazelCmd = process.env.BAZEL || `yarn -s bazel`;
|
||||
|
||||
/** Name of the Bazel tag that will be used to find release package targets. */
|
||||
const releaseTargetTag = 'release-with-framework';
|
||||
|
||||
/** Command that queries Bazel for all release package targets. */
|
||||
const queryPackagesCmd =
|
||||
`${bazelCmd} query --output=label "attr('tags', '\\[.*${releaseTargetTag}.*\\]', //packages/...) ` +
|
||||
`intersect kind('ng_package|pkg_npm', //packages/...)"`;
|
||||
|
||||
/** Path for the default distribution output directory. */
|
||||
const defaultDistPath = join(projectDir, 'dist/packages-dist');
|
||||
|
||||
/** Builds the release packages for NPM. */
|
||||
export function performNpmReleaseBuild(): BuiltPackage[] {
|
||||
return buildReleasePackages(defaultDistPath, /* isSnapshotBuild */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the release packages as snapshot build. This means that the current
|
||||
* Git HEAD SHA is included in the version (for easier debugging and back tracing).
|
||||
*/
|
||||
export function performDefaultSnapshotBuild(): BuiltPackage[] {
|
||||
return buildReleasePackages(defaultDistPath, /* isSnapshotBuild */ true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the release packages with the given compile mode and copies
|
||||
* the package output into the given directory.
|
||||
*/
|
||||
function buildReleasePackages(distPath: string, isSnapshotBuild: boolean): BuiltPackage[] {
|
||||
console.info('######################################');
|
||||
console.info(' Building release packages...');
|
||||
console.info('######################################');
|
||||
|
||||
// List of targets to build. e.g. "packages/core:npm_package", or "packages/forms:npm_package".
|
||||
const targets = exec(queryPackagesCmd, true).split(/\r?\n/);
|
||||
const packageNames = getPackageNamesOfTargets(targets);
|
||||
const bazelBinPath = exec(`${bazelCmd} info bazel-bin`, true);
|
||||
const getBazelOutputPath = (pkgName: string) => join(bazelBinPath, 'packages', pkgName, 'npm_package');
|
||||
const getDistPath = (pkgName: string) => join(distPath, pkgName);
|
||||
|
||||
// Build with "--config=release" or `--config=snapshot-build` so that Bazel
|
||||
// runs the workspace stamping script. The stamping script ensures that the
|
||||
// version placeholder is populated in the release output.
|
||||
const stampConfigArg = `--config=${isSnapshotBuild ? 'snapshot-build' : 'release'}`;
|
||||
|
||||
// Walk through each release package and clear previous "npm_package" outputs. This is
|
||||
// a workaround for: https://github.com/bazelbuild/rules_nodejs/issues/1219. We need to
|
||||
// do this to ensure that the version placeholders are properly populated.
|
||||
packageNames.forEach((pkgName) => {
|
||||
const outputPath = getBazelOutputPath(pkgName);
|
||||
if (sh.test('-d', outputPath)) {
|
||||
sh.chmod('-R', 'u+w', outputPath);
|
||||
sh.rm('-rf', outputPath);
|
||||
}
|
||||
});
|
||||
|
||||
exec(`${bazelCmd} build ${stampConfigArg} ${targets.join(' ')}`);
|
||||
|
||||
// Delete the distribution directory so that the output is guaranteed to be clean. Re-create
|
||||
// the empty directory so that we can copy the release packages into it later.
|
||||
sh.rm('-rf', distPath);
|
||||
sh.mkdir('-p', distPath);
|
||||
|
||||
// Copy the package output into the specified distribution folder.
|
||||
packageNames.forEach((pkgName) => {
|
||||
const outputPath = getBazelOutputPath(pkgName);
|
||||
const targetFolder = getDistPath(pkgName);
|
||||
console.info(`> Copying package output to "${targetFolder}"`);
|
||||
sh.cp('-R', outputPath, targetFolder);
|
||||
sh.chmod('-R', 'u+w', targetFolder);
|
||||
});
|
||||
|
||||
return packageNames.map((pkg) => {
|
||||
return {
|
||||
name: `@angular/${pkg}`,
|
||||
outputPath: getDistPath(pkg),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the package names of the specified Bazel targets.
|
||||
* e.g. //packages/core:npm_package => core
|
||||
*/
|
||||
function getPackageNamesOfTargets(targets: string[]): string[] {
|
||||
return targets.map((targetName) => {
|
||||
const matches = targetName.match(/\/\/packages\/(.*):npm_package/);
|
||||
if (matches === null) {
|
||||
throw Error(
|
||||
`Found Bazel target with "${releaseTargetTag}" tag, but could not ` +
|
||||
`determine release output name: ${targetName}`
|
||||
);
|
||||
}
|
||||
return matches[1];
|
||||
});
|
||||
}
|
||||
|
||||
/** Executes the given command in the project directory. */
|
||||
export function exec(command: string): void;
|
||||
/** Executes the given command in the project directory and returns its stdout. */
|
||||
export function exec(command: string, captureStdout: true): string;
|
||||
export function exec(command: string, captureStdout?: true) {
|
||||
const stdout = execSync(command, {
|
||||
cwd: projectDir,
|
||||
stdio: ['inherit', captureStdout ? 'pipe' : 'inherit', 'inherit'],
|
||||
});
|
||||
|
||||
if (captureStdout) {
|
||||
process.stdout.write(stdout);
|
||||
return stdout.toString().trim();
|
||||
}
|
||||
}
|
||||
@@ -6,17 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
import {join} from 'path';
|
||||
import sh from 'shelljs';
|
||||
|
||||
const {resolve} = require('path');
|
||||
const {chmod, cp, mkdir, mv, rm, test} = require('shelljs');
|
||||
const zonePackageJson = require('../../packages/zone.js/package.json');
|
||||
const {baseDir, bazelBin, bazelCmd, exec, scriptPath} = require('./package-builder');
|
||||
|
||||
|
||||
module.exports = {
|
||||
buildZoneJsPackage,
|
||||
};
|
||||
import {projectDir, bazelCmd, exec} from './package-builder.mjs';
|
||||
|
||||
/**
|
||||
* Build the `zone.js` npm package into `dist/bin/packages/zone.js/npm_package/` and copy it to
|
||||
@@ -30,36 +23,36 @@ module.exports = {
|
||||
* @param {string} destDir Path to the output directory into which we copy the npm package.
|
||||
* This path should either be absolute or relative to the project root.
|
||||
*/
|
||||
function buildZoneJsPackage(destDir) {
|
||||
export function buildZoneJsPackage(destDir: string): void {
|
||||
console.info('##############################');
|
||||
console.info(`${scriptPath}:`);
|
||||
console.info(' Building zone.js npm package');
|
||||
console.info('##############################');
|
||||
|
||||
exec(`${bazelCmd} run //packages/zone.js:npm_package.pack`);
|
||||
|
||||
// Create the output directory.
|
||||
const absDestDir = resolve(baseDir, destDir);
|
||||
if (!test('-d', absDestDir)) {
|
||||
mkdir('-p', absDestDir);
|
||||
if (!sh.test('-d', destDir)) {
|
||||
sh.mkdir('-p', destDir);
|
||||
}
|
||||
|
||||
const bazelBinPath = exec(`${bazelCmd} info bazel-bin`, true);
|
||||
|
||||
// Copy artifacts to `destDir`, so they can be easier persisted on CI and used by non-bazel
|
||||
// scripts/tests.
|
||||
const buildOutputDir = `${bazelBin}/packages/zone.js/npm_package`;
|
||||
const distTargetDir = `${absDestDir}/zone.js`;
|
||||
const buildOutputDir = join(bazelBinPath, 'packages/zone.js/npm_package');
|
||||
const distTargetDir = join(destDir, 'zone.js');
|
||||
|
||||
console.info(`# Copy npm_package artifacts to ${distTargetDir}`);
|
||||
rm('-rf', distTargetDir);
|
||||
cp('-R', buildOutputDir, distTargetDir);
|
||||
chmod('-R', 'u+w', distTargetDir);
|
||||
|
||||
sh.rm('-rf', distTargetDir);
|
||||
sh.cp('-R', buildOutputDir, distTargetDir);
|
||||
sh.chmod('-R', 'u+w', distTargetDir);
|
||||
|
||||
// Copy `zone.js.tgz` to `destDir`, so we can test
|
||||
// the archive generated by the `npm_package.pack` rule.
|
||||
const distArchiveTargetDir = `${absDestDir}/archive`;
|
||||
const distArchiveTargetDir = `${destDir}/archive`;
|
||||
console.info(`# Copy npm_package archive file to ${distArchiveTargetDir}`);
|
||||
rm('-rf', distArchiveTargetDir);
|
||||
mkdir('-p', distArchiveTargetDir);
|
||||
mv(`${baseDir}/zone.js-${zonePackageJson.version}.tgz`, `${distArchiveTargetDir}/zone.js.tgz`);
|
||||
|
||||
console.info('');
|
||||
sh.rm('-rf', distArchiveTargetDir);
|
||||
sh.mkdir('-p', distArchiveTargetDir);
|
||||
sh.mv(`${projectDir}/zone.js-*.tgz`, `${distArchiveTargetDir}/zone.js.tgz`);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "../dist/dev-infra-scripts",
|
||||
"target": "es2020",
|
||||
"lib": ["es2020"],
|
||||
"module": "Node16",
|
||||
"types": ["node"],
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"skipLibCheck": true,
|
||||
"downlevelIteration": true,
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user