Skip to content

Commit efbbae5

Browse files
gkalpakAndrewKushnir
authored andcommitted
ci: publish tarballs for all Angular packages as build artifacts on PR builds (angular#33321)
Previously, when one wanted to try out the changes from a PR before it was merged, they had to check out the PR locally and build the Angular packages themselves (which is time-consuming and wasteful given that the packages have already been built on CI). This commit persists all Angular packages on each build as `.tgz` files, which can be used to install dependencies on an project (supported by both [npm][1] and [yarn][2]). In addition to individual `.tgz` files for each package, a `.tgz` file including all packages is also stored, which can be used to test the packages locally by overwriting the ones in the `node_modules/` directory of a project. CircleCI [build artifacts][3] an be used for longer-term storage of the outputs of a build and are designed to be useful around the time of the build, which suits our needs. [1]: https://docs.npmjs.com/cli/install.html [2]: https://yarnpkg.com/lang/en/docs/cli/add [3]: https://circleci.com/docs/2.0/artifacts PR Close angular#33321
1 parent 22e4838 commit efbbae5

File tree

3 files changed

+114
-2
lines changed

3 files changed

+114
-2
lines changed

.circleci/config.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,26 @@ jobs:
559559
# amount of container nodes for this job is controlled by the "parallelism" option.
560560
- run: ./integration/run_tests.sh ${CIRCLE_NODE_INDEX} ${CIRCLE_NODE_TOTAL}
561561

562+
# This job creates compressed tarballs (`.tgz` files) for all Angular packages and stores them as
563+
# build artifacts. This makes it easy to try out changes from a PR build for testing purposes.
564+
# More info CircleCI build artifacts: https://circleci.com/docs/2.0/artifacts
565+
#
566+
# NOTE: Currently, this job only runs for PR builds. See `publish_snapshot` for non-PR builds.
567+
publish_packages_as_artifacts:
568+
executor: default-executor
569+
environment:
570+
NG_PACKAGES_DIR: &ng_packages_dir 'dist/packages-dist'
571+
NG_PACKAGES_ARCHIVES_DIR: &ng_packages_archives_dir 'dist/packages-dist-archives'
572+
steps:
573+
- custom_attach_workspace
574+
- init_environment
575+
- run:
576+
name: Create artifacts
577+
command: ./scripts/ci/create-package-archives.sh $CI_PULL_REQUEST $CI_COMMIT $NG_PACKAGES_DIR $NG_PACKAGES_ARCHIVES_DIR
578+
- store_artifacts:
579+
path: *ng_packages_archives_dir
580+
destination: angular
581+
562582
# This job updates the content of repos like github.com/angular/core-builds
563583
# for every green build on angular/angular.
564584
publish_snapshot:
@@ -823,6 +843,11 @@ workflows:
823843
- integration_test:
824844
requires:
825845
- build-npm-packages
846+
- publish_packages_as_artifacts:
847+
# Only run on PR builds. (For non-PR builds, the `publish_snapshot` job.)
848+
<<: *only_on_pull_requests
849+
requires:
850+
- build-npm-packages
826851
- publish_snapshot:
827852
# Note: no filters on this job because we want it to run for all upstream branches
828853
# We'd really like to filter out pull requests here, but not yet available:

docs/DEVELOPER.md

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,58 @@ automatically publishes build artifacts to repositories in the Angular org, eg.
139139
package is published to https://github.com/angular/core-builds.
140140

141141
You may find that your un-merged change needs some validation from external participants.
142-
Rather than requiring them to pull your Pull Request and build Angular locally, you can publish the
143-
`*-builds` snapshots just like our CircleCI build does.
142+
Rather than requiring them to pull your Pull Request and build Angular locally, they can depend on
143+
snapshots of the Angular packages created based on the code in the Pull Request.
144+
145+
### Getting Packages from Build Artifacts
146+
Each CI run for a Pull Request stores the built Angular packages as
147+
[build artifacts](https://circleci.com/docs/2.0/artifacts). The artifacts are not guaranteed to be
148+
available as a long-term distribution mechanism, but they are guaranteed to be available around the
149+
time of the build.
150+
151+
You can access the artifacts for a specific CI run by going to the workflow page, clicking on the
152+
`publish_packages_as_artifacts` job and then switching to the "Artifacts" tab.
153+
(If you happen to know the build number of the job, the URL will be something like:
154+
https://circleci.com/gh/angular/angular/<build-number>#artifacts)
155+
156+
#### Archives for each Package
157+
On the "Artifacts" tab, there is a list of links to compressed archives for Angular packages. The
158+
archive names are of the format `<package-name>-pr<pr-number>-<sha>.tgz` (for example
159+
`core-pr12345-a1b2c3d.tgz`).
160+
161+
One can use the URL to the `.tgz` file for each package to install them as dependencies in a
162+
project they need to test the Pull Request changes against. Both
163+
[npm](https://docs.npmjs.com/cli/install.html) and [yarn](https://yarnpkg.com/lang/en/docs/cli/add)
164+
support installing dependencies from URLs to `.tgz` files, for example by updating the dependencies
165+
in `package.json` to point to the artifact URLs and then running `npm/yarn install`:
166+
167+
```json
168+
"dependencies": {
169+
"@angular/common": "https://<...>.circle-artifacts.com/0/angular/common-pr12345-a1b2c3d.tgz",
170+
"@angular/core": "https://<...>.circle-artifacts.com/0/angular/core-pr12345-a1b2c3d.tgz",
171+
"...": "..."
172+
}
173+
```
174+
175+
#### Download all Packages
176+
In addition to the individual package archives, a `.tgz` file including all packages is also
177+
available (named `all-pr<pr-number>-<sha>.tgz`). This can be used if one prefers to download all
178+
packages locally and test them by either of the following ways:
179+
180+
1. Update the dependencies in `package.json` to point to the local uncompressed package directories.
181+
182+
2. Directly copy the local uncompressed package directories into the `node_modules/` directory of a
183+
project.
184+
185+
Note that (while faster) the second approach has limitations. For example:
186+
a. Any transitive dependencies of the copied packages will not be automatically updated.
187+
b. The packages need to be copied over every time `npm/yarn install` is run.
188+
c. Some package managers (such as `pnpm` or `yarn pnp`) might not work correctly.
189+
190+
### Publishing to GitHub repos
191+
You can also manually publish `*-builds` snapshots just like our CircleCI build does for upstream
192+
builds. Before being able to publish the packages, you need to build them locally by running the
193+
`./scripts/build-packages-dist.sh` script.
144194

145195
First time, you need to create the GitHub repositories:
146196

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/env bash
2+
3+
set -eu -o pipefail
4+
5+
readonly prNumber="$1"
6+
readonly prLastSha="${2:0:7}"
7+
readonly inputDir="$PROJECT_ROOT/$3"
8+
readonly outputDir="$PROJECT_ROOT/$4"
9+
readonly fileSuffix="-pr$prNumber-$prLastSha.tgz"
10+
11+
echo "Creating compressed archives for packages in '$inputDir'."
12+
13+
# Create or clean-up the output directory.
14+
echo " Preparing output directory: $outputDir"
15+
rm -rf "$outputDir"
16+
mkdir -p "$outputDir"
17+
18+
# Create a compressed archive containing all packages.
19+
# (This is useful for copying all packages into `node_modules/` (without changing `package.json`).)
20+
outputFileName=all$fileSuffix
21+
echo " Creating archive with all packages --> '$outputFileName'..."
22+
tar --create --gzip --directory "$inputDir" --file "$outputDir/$outputFileName" --transform s/^\./packages/ .
23+
24+
# Create a compressed archive for each package.
25+
# (This is useful for referencing the path/URL to the resulting archive in `package.json`.)
26+
for dir in $inputDir/*
27+
do
28+
packageName=`basename "$dir"`
29+
outputFileName="$packageName$fileSuffix"
30+
outputFilePath="$outputDir/$outputFileName"
31+
32+
echo " Processing package '$packageName' --> '$outputFileName'..."
33+
34+
tar --create --gzip --directory "$dir" --file "$outputFilePath" --transform s/^\./package/ .
35+
done
36+
37+
echo "Done creating compressed archives."

0 commit comments

Comments
 (0)