Skip to content

Commit f6fb2fb

Browse files
mmalerbagkalpak
andcommitted
build: upload release packages as job artifacts for PRs (#18710)
* build: upload release packages as job artifacts for PRs Upload release packages as job artifacts for PRs. This allows us to easily check out changes from a PR locally, without having to manually check-out the branch, and building the release output. Co-authored-by: George Kalpakas <[email protected]> * fixup! build: upload release packages as job artifacts for PRs Suffix should match docs Co-authored-by: George Kalpakas <[email protected]>
1 parent e0f8f84 commit f6fb2fb

File tree

3 files changed

+118
-0
lines changed

3 files changed

+118
-0
lines changed

.circleci/config.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ var_19: &skip_on_pull_requests_filter
132132
ignore:
133133
- /pull\/\d+/
134134

135+
# Filter which ensures that jobs only run for pull requests.
136+
var_20: &only_on_pull_requests_filter
137+
branches:
138+
only:
139+
- /pull\/\d+/
140+
135141
# -----------------------------
136142
# Container version of CircleCI
137143
# -----------------------------
@@ -342,6 +348,21 @@ jobs:
342348
path: /tmp/cdk-umd-minified-bundles
343349
destination: /angular_material/cdk_release_output/
344350

351+
upload_release_packages:
352+
<<: *job_defaults
353+
steps:
354+
- *checkout_code
355+
- *restore_cache
356+
- *attach_release_output
357+
- *yarn_install
358+
359+
# Creates package archives and passes in an appropriate meaningful archive suffix. The
360+
# suffix consists of the pull request number and a short SHA describing the current `HEAD`.
361+
- run: ./scripts/create-package-archives.js --suffix "pr$CIRCLE_PR_NUMBER-$(git rev-parse --short HEAD)"
362+
# Upload archives to the CircleCI job artifacts.
363+
- store_artifacts:
364+
path: dist/release-archives
365+
345366
# ----------------------------------------
346367
# Job that publishes the build snapshots
347368
# ----------------------------------------
@@ -514,6 +535,12 @@ workflows:
514535
filters: *ignore_presubmit_branch_filter
515536
- build_release_packages:
516537
filters: *ignore_presubmit_branch_filter
538+
- upload_release_packages:
539+
# We don't want to run this job on push builds because for those, the
540+
# `publish_snapshots` runs, and publishes build artifacts.
541+
filters: *only_on_pull_requests_filter
542+
requires:
543+
- build_release_packages
517544
- lint:
518545
filters: *ignore_presubmit_branch_filter
519546
- ngcc_compatibility:

DEV_ENVIRONMENT.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,38 @@ and rebuild. The browser should refresh automatically when changes are made.
2323
To run unit tests, run `yarn test <target>`. The `target` can be either a short name (e.g. `yarn test button`) or an explicit path `yarn test src/cdk/stepper`.
2424
To run the e2e tests, run `yarn e2e`.
2525
To run lint, run `yarn lint`.
26+
27+
### Getting Packages from Build Artifacts
28+
Each CI run for a Pull Request stores the built Angular packages as
29+
[build artifacts](https://circleci.com/docs/2.0/artifacts). The artifacts are not guaranteed to be
30+
available as a long-term distribution mechanism, but they are guaranteed to be available around the
31+
time of the build.
32+
33+
You can access the artifacts for a specific CI run by going to the workflow page, clicking on the
34+
`upload_release_packages` job and then switching to the "Artifacts" tab.
35+
36+
#### Archives for each Package
37+
On the "Artifacts" tab, there is a list of links to compressed archives for Angular packages. The
38+
archive names are of the format `<package-name>-pr<pr-number>-<sha>.tgz` (for example
39+
`material-pr12345-a1b2c3d.tgz`).
40+
41+
One can use the URL to the `.tgz` file for each package to install them as dependencies in a
42+
project they need to test the Pull Request changes against. [Yarn](https://yarnpkg.com/lang/en/docs/cli/add)
43+
supports installing dependencies from URLs to `.tgz` files. As an example, update the dependencies
44+
in `package.json` to point to the artifact URLs and then run `yarn` to install the packages:
45+
46+
```json
47+
"dependencies": {
48+
"@angular/cdk": "https://<...>.circle-artifacts.com<...>/cdk-pr12345-a1b2c3d.tgz",
49+
"@angular/material": "https://<...>.circle-artifacts.com<...>/material-pr12345-a1b2c3d.tgz",
50+
}
51+
```
52+
53+
#### Download all Packages
54+
In addition to the individual package archives, a `.tgz` file including all packages is also
55+
available (named `all-pr<pr-number>-<sha>.tgz`). This can be used if one prefers to download all
56+
packages locally and test them by either of the following ways:
57+
58+
1. Update the dependencies in `package.json` to point to the local uncompressed package directories.
59+
2. Directly copy the local uncompressed package directories into the `node_modules/` directory
60+
of a project.

scripts/create-package-archives.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Script that creates tar archives of built release packages. These archives can then
5+
* be uploaded to the CircleCI artifacts so that PRs or individual commits can be easily
6+
* tested out without having to build the release packages manually, and packing them up.
7+
*
8+
* This is different to the snapshot builds repositories as those only are available for
9+
* the primary `cdk` and `material` packages, and also don't run for pull requests.
10+
*/
11+
12+
const {join} = require('path');
13+
const {rm, mkdir, test, ls, set, exec, cd} = require('shelljs');
14+
const {red, green} = require('chalk');
15+
const minimist = require('minimist');
16+
17+
const projectDir = join(__dirname, '../');
18+
const archivesDir = 'dist/release-archives';
19+
const releasesDir = 'dist/releases';
20+
let {suffix} = minimist(process.argv.slice(2), {string: ['suffix']});
21+
22+
if (!suffix) {
23+
console.error(red('No suffix specified. Pass one with --suffix <text>'));
24+
process.exit(1);
25+
}
26+
27+
// Fail if any ShellJS command fails.
28+
set('-e');
29+
30+
cd(projectDir);
31+
32+
if (!test('-e', releasesDir)) {
33+
console.error(red('The release output has not been built.'));
34+
process.exit(1);
35+
}
36+
37+
rm('-Rf', archivesDir);
38+
mkdir('-p', archivesDir);
39+
40+
const builtPackages = ls(releasesDir)
41+
.map(name => ({name, path: join(releasesDir, name)}))
42+
.filter(pkg => test('-d', pkg.path));
43+
44+
// If multiple packages should be archived, we also generate a single archive that
45+
// contains all packages. This makes it easier to transfer the release packages.
46+
if (builtPackages.length > 1) {
47+
console.info('Creating archive with all packages..');
48+
exec(`tar --create --gzip --directory ${releasesDir} --file ${archivesDir}/all-${suffix}.tgz .`);
49+
}
50+
51+
for (const pkg of builtPackages) {
52+
console.info(`Creating archive for package: ${pkg.name}`);
53+
exec(`tar --create --gzip --directory ${pkg.path} --file ${archivesDir}/${pkg.name}-${suffix}.tgz .`);
54+
}
55+
56+
console.info(green(`Created package archives in: ${archivesDir}`));

0 commit comments

Comments
 (0)