Skip to content

Commit

Permalink
build: upload release packages as job artifacts for PRs
Browse files Browse the repository at this point in the history
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 <kalpakas.g@gmail.com>
  • Loading branch information
devversion and gkalpak committed Mar 5, 2020
1 parent ef16735 commit 2c55217
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 0 deletions.
27 changes: 27 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ var_19: &skip_on_pull_requests_filter
ignore:
- /pull\/\d+/

# Filter which ensures that jobs only run for pull requests.
var_20: &only_on_pull_requests_filter
branches:
only:
- /pull\/\d+/

# -----------------------------
# Container version of CircleCI
# -----------------------------
Expand Down Expand Up @@ -342,6 +348,21 @@ jobs:
path: /tmp/cdk-umd-minified-bundles
destination: /angular_material/cdk_release_output/

upload_release_packages:
<<: *job_defaults
steps:
- *checkout_code
- *restore_cache
- *attach_release_output
- *yarn_install

# Creates package archives and passes in an appropriate meaningful archive suffix. The
# suffix consists of the pull request number and a short SHA describing the current `HEAD`.
- run: ./scripts/create-package-archives.js --suffix "$CIRCLE_PR_NUMBER-$(git rev-parse --short HEAD)"
# Upload archives to the CircleCI job artifacts.
- store_artifacts:
path: dist/release-archives

# ----------------------------------------
# Job that publishes the build snapshots
# ----------------------------------------
Expand Down Expand Up @@ -514,6 +535,12 @@ workflows:
filters: *ignore_presubmit_branch_filter
- build_release_packages:
filters: *ignore_presubmit_branch_filter
- upload_release_packages:
# We don't want to run this job on push builds because for those, the
# `publish_snapshots` runs, and publishes build artifacts.
filters: *only_on_pull_requests_filter
requires:
- build_release_packages
- lint:
filters: *ignore_presubmit_branch_filter
- ngcc_compatibility:
Expand Down
35 changes: 35 additions & 0 deletions DEV_ENVIRONMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,38 @@ and rebuild. The browser should refresh automatically when changes are made.
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`.
To run the e2e tests, run `yarn e2e`.
To run lint, run `yarn lint`.

### Getting Packages from Build Artifacts
Each CI run for a Pull Request stores the built Angular packages as
[build artifacts](https://circleci.com/docs/2.0/artifacts). The artifacts are not guaranteed to be
available as a long-term distribution mechanism, but they are guaranteed to be available around the
time of the build.

You can access the artifacts for a specific CI run by going to the workflow page, clicking on the
`upload_release_packages` job and then switching to the "Artifacts" tab.

#### Archives for each Package
On the "Artifacts" tab, there is a list of links to compressed archives for Angular packages. The
archive names are of the format `<package-name>-pr<pr-number>-<sha>.tgz` (for example
`material-pr12345-a1b2c3d.tgz`).

One can use the URL to the `.tgz` file for each package to install them as dependencies in a
project they need to test the Pull Request changes against. [Yarn](https://yarnpkg.com/lang/en/docs/cli/add)
supports installing dependencies from URLs to `.tgz` files. As an example, update the dependencies
in `package.json` to point to the artifact URLs and then run `yarn` to install the packages:

```json
"dependencies": {
"@angular/cdk": "https://<...>.circle-artifacts.com<...>/cdk-pr12345-a1b2c3d.tgz",
"@angular/material": "https://<...>.circle-artifacts.com<...>/material-pr12345-a1b2c3d.tgz",
}
```

#### Download all Packages
In addition to the individual package archives, a `.tgz` file including all packages is also
available (named `all-pr<pr-number>-<sha>.tgz`). This can be used if one prefers to download all
packages locally and test them by either of the following ways:

1. Update the dependencies in `package.json` to point to the local uncompressed package directories.
2. Directly copy the local uncompressed package directories into the `node_modules/` directory
of a project.
56 changes: 56 additions & 0 deletions scripts/create-package-archives.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env node

/**
* Script that creates tar archives of built release packages. These archives can then
* be uploaded to the CircleCI artifacts so that PRs or individual commits can be easily
* tested out without having to build the release packages manually, and packing them up.
*
* This is different to the snapshot builds repositories as those only are available for
* the primary `cdk` and `material` packages, and also don't run for pull requests.
*/

const {join} = require('path');
const {rm, mkdir, test, ls, set, exec, cd} = require('shelljs');
const {red, green} = require('chalk');
const minimist = require('minimist');

const projectDir = join(__dirname, '../');
const archivesDir = 'dist/release-archives';
const releasesDir = 'dist/releases';
let {suffix} = minimist(process.argv.slice(2), {string: ['suffix']});

if (!suffix) {
console.error(red('No suffix specified. Pass one with --suffix <text>'));
process.exit(1);
}

// Fail if any ShellJS command fails.
set('-e');

cd(projectDir);

if (!test('-e', releasesDir)) {
console.error(red('The release output has not been built.'));
process.exit(1);
}

rm('-Rf', archivesDir);
mkdir('-p', archivesDir);

const builtPackages = ls(releasesDir)
.map(name => ({name, path: join(releasesDir, name)}))
.filter(pkg => test('-d', pkg.path));

// If multiple packages should be archived, we also generate a single archive that
// contains all packages. This makes it easier to transfer the release packages.
if (builtPackages.length > 1) {
console.info('Creating archive with all packages..');
exec(`tar --create --gzip --directory ${releasesDir} --file ${archivesDir}/all-${suffix}.tgz .`);
}

for (const pkg of builtPackages) {
console.info(`Creating archive for package: ${pkg.name}`);
exec(`tar --create --gzip --directory ${pkg.path} --file ${archivesDir}/${pkg.name}-${suffix}.tgz .`);
}

console.info(green(`Created package archives in: ${archivesDir}`));

0 comments on commit 2c55217

Please sign in to comment.