mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c4b6d474f8 | |||
| 78efc406ba | |||
| c277e88b22 | |||
| 574b1c276d | |||
| 40eb5e3207 | |||
| 8ef145fa1b | |||
| 94f2daaa1c | |||
| ffc61749ff | |||
| f70d80c8c7 | |||
| a4cb2e671c | |||
| dc7882cf97 | |||
| 5f9bd59b14 | |||
| cfd466dfbb | |||
| 61ce057a09 | |||
| 8dc6c9fe22 | |||
| e71e900708 | |||
| 1168fd585f | |||
| 18ea007390 | |||
| bd23af0639 | |||
| 6b0e1c7703 | |||
| 6b89ce9e27 | |||
| 0bf724f4d4 | |||
| 7acf163f51 | |||
| 6808375e50 | |||
| 97d6781be7 | |||
| f12e8e3ea2 | |||
| f5638c25e6 | |||
| d82eb27f69 | |||
| 3b5218b768 | |||
| 5fa6ce3e61 | |||
| d88ac6db12 | |||
| 46efe02e48 | |||
| cd76360ea8 | |||
| 09ad1ef5a2 | |||
| 48f4f86835 | |||
| 183c92baed | |||
| e03ccb60ed | |||
| c402bb81f5 | |||
| 0a7a8e496e | |||
| 779e1d872f | |||
| 193a32e5c1 | |||
| 41f8584aad | |||
| 4b8e6b36ab | |||
| 4c58b2f8cf | |||
| 0e96528a70 | |||
| 1d1338fced | |||
| 1344da62ad | |||
| 0c821b28f3 | |||
| ebef1a592a | |||
| 4c97f56223 | |||
| 71e8bd8791 | |||
| fcf9edbc78 | |||
| 626d3ab586 | |||
| 3a607f51d6 | |||
| ccf0dc1884 | |||
| ebf646a9c9 | |||
| 732e45a730 | |||
| 6697d6ba2f | |||
| 399e173d8c | |||
| 05ecc619fc | |||
| 52f508ab4d | |||
| 2a61fea64b | |||
| 10c1ae5b6e | |||
| 9208e64e74 | |||
| 65d45e4919 | |||
| 080bdfa77f | |||
| 977bd97717 | |||
| a90dc4310c | |||
| 2426b2e1f1 | |||
| 912c7252f8 | |||
| 8e64d9e1d8 | |||
| 4d7b23e99e | |||
| 59d278c07c | |||
| 7e1de8cb6a | |||
| f6bda0eb4d | |||
| c7c4b9e390 | |||
| a77924ff38 | |||
| d04408d67d | |||
| f556b29d05 | |||
| a9be2b3628 | |||
| a34a479ee5 | |||
| f0c9eeceba | |||
| e737d45ad0 | |||
| c7bede629b | |||
| 992f51bc6d | |||
| f2658e34a2 | |||
| 89813aea70 | |||
| e6e5021eb9 |
@@ -6,6 +6,7 @@
|
||||
node_modules
|
||||
dist
|
||||
aio/node_modules
|
||||
aio/content/example-playground
|
||||
aio/tools/examples/shared/node_modules
|
||||
aio/tools/examples/shared/example-scaffold
|
||||
|
||||
|
||||
@@ -135,16 +135,10 @@ build:remote --platforms=@npm//@angular/build-tooling/bazel/remote-execution:pla
|
||||
|
||||
# Remote instance and caching
|
||||
build:remote --remote_instance_name=projects/internal-200822/instances/primary_instance
|
||||
build:remote --bes_instance_name=internal-200822
|
||||
build:remote --project_id=internal-200822
|
||||
build:remote --remote_cache=remotebuildexecution.googleapis.com
|
||||
build:remote --remote_executor=remotebuildexecution.googleapis.com
|
||||
|
||||
# Use HTTP remote cache
|
||||
build:remote-cache --remote_cache=https://storage.googleapis.com/angular-team-cache
|
||||
build:remote-cache --remote_accept_cached=true
|
||||
build:remote-cache --remote_upload_local_results=true
|
||||
build:remote-cache --google_default_credentials
|
||||
|
||||
# Ensure that tags like "no-remote-exec" get propagated to actions created by rules,
|
||||
# even if the rule implementation does not explicitly pass them to the execution requirements.
|
||||
# https://bazel.build/reference/command-line-reference#flag--experimental_allow_tags_propagation
|
||||
|
||||
+715
-6
@@ -1,16 +1,725 @@
|
||||
# This config is remaining in place to prevent pull requests failing because of CircleCI config missing.
|
||||
# Configuration file for https://circleci.com/gh/angular/angular
|
||||
|
||||
# Note: YAML anchors allow an object to be re-used, reducing duplication.
|
||||
# The ampersand declares an alias for an object, then later the `<<: *name`
|
||||
# syntax dereferences it.
|
||||
# See https://blog.daemonl.com/2016/02/yaml.html
|
||||
# To validate changes, use an online parser, eg.
|
||||
# https://yaml-online-parser.appspot.com/
|
||||
|
||||
# CircleCI configuration version
|
||||
# Version 2.1 allows for extra config reuse features
|
||||
# https://circleci.com/docs/2.0/reusing-config/#getting-started-with-config-reuse
|
||||
version: 2.1
|
||||
|
||||
jobs:
|
||||
pass:
|
||||
# We don't want to include the current branch name in the cache key because that would prevent
|
||||
# PRs from being able to restore the cache since the branch names are always different for PRs.
|
||||
# The cache key should only consist of dynamic values that change whenever something in the
|
||||
# cache changes. For example:
|
||||
# 1) yarn lock file changes --> cached "node_modules" are different.
|
||||
# 2) bazel repository definitions change --> cached bazel repositories are different.
|
||||
# Windows needs its own cache key because binaries in node_modules are different.
|
||||
# **NOTE 1 **: In order to avoid the cache from growing indefinitely and causing slow-downs, we invalidate the cache monthly.
|
||||
# (See https://support.circleci.com/hc/en-us/articles/360012618473-Creating-a-daily-cache.)
|
||||
# **NOTE 2 **: If you change the cache key prefix, also sync the cache_key_fallback to match.
|
||||
# **NOTE 3 **: Keep the static part of the cache key as prefix to enable correct fallbacks.
|
||||
# **NOTE 4 **: To make sure modified patches can be applied without needing to manually update the cache key,
|
||||
# the fallback cache key will not match if patches have been modified.
|
||||
# See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI.
|
||||
var_3: &cache_key v8-angular-node-16-{{ checksum "month.txt" }}-{{ checksum "patches.hash"}}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
|
||||
# We invalidate the cache if the Bazel version changes because otherwise the `bazelisk` cache
|
||||
# folder will contain all previously used versions and ultimately cause the cache restoring to
|
||||
# be slower due to its growing size.
|
||||
var_4: &cache_key_fallback v8-angular-node-16-{{ checksum "month.txt" }}-{{ checksum "patches.hash"}}-{{ checksum ".bazelversion" }}
|
||||
|
||||
# Windows needs its own cache key because binaries in node_modules are different.
|
||||
var_3_win: &cache_key_win v10-angular-win-node-16-{{ checksum "month.txt" }}-{{ checksum "patches.hash"}}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}
|
||||
var_4_win: &cache_key_win_fallback v10-angular-win-node-16-{{ checksum "month.txt" }}-{{ checksum "patches.hash"}}-{{ checksum ".bazelversion" }}
|
||||
|
||||
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages`.
|
||||
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
|
||||
# https://circleci.com/blog/deep-diving-into-circleci-workspaces/
|
||||
var_5: &workspace_location ~/
|
||||
|
||||
# Filter to run a job on builds for pull requests only.
|
||||
var_6: &only_on_pull_requests
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /pull\/\d+/
|
||||
|
||||
# Filter to skip a job on builds for pull requests.
|
||||
var_7: &skip_on_pull_requests
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /pull\/\d+/
|
||||
|
||||
# Filter to run a job on builds for the main branch only.
|
||||
var_8: &only_on_main_branch
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- main
|
||||
|
||||
# Filter to run a job on all releasable branches.
|
||||
var_9: &only_release_branches
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- main
|
||||
- /\d+\.\d+\.x/
|
||||
|
||||
# CircleCI orbs
|
||||
# https://circleci.com/developer/orbs.
|
||||
orbs:
|
||||
node: circleci/node@5.0.1
|
||||
devinfra: angular/dev-infra@1.0.8
|
||||
|
||||
# Executor Definitions
|
||||
# https://circleci.com/docs/2.0/reusing-config/#authoring-reusable-executors
|
||||
# **NOTE 1**: Pin to exact images using an ID (SHA). See https://circleci.com/docs/2.0/circleci-images/#using-a-docker-image-id-to-pin-an-image-to-a-fixed-version.
|
||||
# (Using the tag in not necessary when pinning by ID, but include it anyway for documentation purposes.)
|
||||
# **NOTE 2**: If you change the version of the docker images, also change the `cache_key` suffix.
|
||||
# **NOTE 3**: If you change the version of Node.js provided by the docker images, also update `.devcontainer/recommended-Dockerfile` to match the new version.
|
||||
executors:
|
||||
default-executor:
|
||||
parameters:
|
||||
resource_class:
|
||||
type: string
|
||||
default: medium
|
||||
docker:
|
||||
- image: cimg/base:2022.05
|
||||
- image: cimg/node:16.14.0
|
||||
resource_class: << parameters.resource_class >>
|
||||
working_directory: ~/ng
|
||||
|
||||
test-browser-executor:
|
||||
parameters:
|
||||
resource_class:
|
||||
type: string
|
||||
default: medium
|
||||
docker:
|
||||
- image: cimg/node:16.14.0-browsers
|
||||
resource_class: << parameters.resource_class >>
|
||||
working_directory: ~/ng
|
||||
|
||||
windows-executor:
|
||||
working_directory: ~/ng
|
||||
resource_class: windows.2xlarge
|
||||
shell: bash
|
||||
machine:
|
||||
image: windows-server-2019-vs2019:201908-02
|
||||
|
||||
# Command Definitions
|
||||
# https://circleci.com/docs/2.0/reusing-config/#authoring-reusable-commands
|
||||
commands:
|
||||
custom_attach_workspace:
|
||||
description: Attach workspace at a predefined location
|
||||
steps:
|
||||
- run: echo "This too shall pass (always)"
|
||||
- attach_workspace:
|
||||
at: *workspace_location
|
||||
|
||||
# Install java runtime which is required by some integration tests such as
|
||||
# //integration:hello_world__closure_test, //integration:i18n_test and
|
||||
# //integration:ng_elements_test to run the closure compiler
|
||||
install_java:
|
||||
description: Install java
|
||||
steps:
|
||||
- run:
|
||||
name: Install java
|
||||
command: |
|
||||
sudo apt-get update
|
||||
# Install java runtime
|
||||
sudo apt-get install default-jre
|
||||
|
||||
# Initializes the CI environment by setting up common environment variables.
|
||||
init_environment:
|
||||
description: Initializing environment (setting up variables)
|
||||
steps:
|
||||
- run:
|
||||
name: Set up environment
|
||||
environment:
|
||||
CIRCLE_GIT_BASE_REVISION: << pipeline.git.base_revision >>
|
||||
CIRCLE_GIT_REVISION: << pipeline.git.revision >>
|
||||
command: ./.circleci/env.sh
|
||||
- devinfra/setup-bazel-remote-exec
|
||||
- run:
|
||||
# Configure git as the CircleCI `checkout` command does.
|
||||
# This is needed because we only checkout on the setup job.
|
||||
# Add GitHub to known hosts
|
||||
name: Configure git
|
||||
command: |
|
||||
mkdir -p ~/.ssh
|
||||
echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=' >> ~/.ssh/known_hosts
|
||||
git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true
|
||||
git config --global gc.auto 0 || true
|
||||
|
||||
init_saucelabs_environment:
|
||||
description: Sets up a domain that resolves to the local host.
|
||||
steps:
|
||||
- run:
|
||||
name: Preparing environment for running tests on Sauce Labs.
|
||||
command: |
|
||||
# For SauceLabs jobs, we set up a domain which resolves to the machine which launched
|
||||
# the tunnel. We do this because devices are sometimes not able to properly resolve
|
||||
# `localhost` or `127.0.0.1` through the SauceLabs tunnel. Using a domain that does not
|
||||
# resolve to anything on SauceLabs VMs ensures that such requests are always resolved
|
||||
# through the tunnel, and resolve to the actual tunnel host machine (i.e. the CircleCI VM).
|
||||
# More context can be found in: https://github.com/angular/angular/pull/35171.
|
||||
setPublicVar SAUCE_LOCALHOST_ALIAS_DOMAIN "angular-ci.local"
|
||||
setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
|
||||
- run:
|
||||
# Sets up a local domain in the machine's host file that resolves to the local
|
||||
# host. This domain is helpful in Sauce Labs tests where devices are not able to
|
||||
# properly resolve `localhost` or `127.0.0.1` through the sauce-connect tunnel.
|
||||
name: Setting up alias domain for local host.
|
||||
command: echo "127.0.0.1 $SAUCE_LOCALHOST_ALIAS_DOMAIN" | sudo tee -a /etc/hosts
|
||||
|
||||
save_month_to_file:
|
||||
description: Store the current year and month in a file, so that it can be used for computing the cache key.
|
||||
steps:
|
||||
- run:
|
||||
name: Save month to file
|
||||
# Note: Make sure this file is excluded in the `.gitignore` as otherwise the
|
||||
# snapshot stamping would have the `-with-local-changes` suffix.
|
||||
command: date +%Y-%m > month.txt
|
||||
|
||||
capture_patches_for_cache_key:
|
||||
description: Hashes all patches so that the cache can be reset upon changes.
|
||||
steps:
|
||||
- run: |
|
||||
md5sum tools/esm-interop/patches/npm/* > patches.hash
|
||||
|
||||
yarn_install:
|
||||
description: Install dependencies
|
||||
steps:
|
||||
- run:
|
||||
name: Running Yarn install
|
||||
command: yarn install --frozen-lockfile --non-interactive --cache-folder ~/.cache/yarn
|
||||
# Yarn's requests sometimes take more than 10mins to complete (especially on Windows).
|
||||
no_output_timeout: 45m
|
||||
|
||||
notify_webhook_on_fail:
|
||||
description: Notify a webhook about failure
|
||||
parameters:
|
||||
# `webhook_url_env_var` are secret env vars defined in CircleCI project settings.
|
||||
# The URLs come from https://angular-team.slack.com/apps/A0F7VRE7N-circleci.
|
||||
webhook_url_env_var:
|
||||
type: env_var_name
|
||||
steps:
|
||||
- run:
|
||||
when: on_fail
|
||||
command: |
|
||||
notificationJson="{\"text\":\":x: \`$CIRCLE_JOB\` job for $CIRCLE_BRANCH branch failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}"
|
||||
curl --request POST --header "Content-Type: application/json" --data "$notificationJson" ${<< parameters.webhook_url_env_var >>}
|
||||
|
||||
# Job definitions
|
||||
# Jobs can include parameters that are passed in the workflow job invocation.
|
||||
# https://circleci.com/docs/2.0/reusing-config/#authoring-parameterized-jobs
|
||||
jobs:
|
||||
setup:
|
||||
executor: default-executor
|
||||
steps:
|
||||
- checkout
|
||||
- save_month_to_file
|
||||
- capture_patches_for_cache_key
|
||||
- init_environment
|
||||
- devinfra/rebase-pr-on-target-branch:
|
||||
base_revision: << pipeline.git.base_revision >>
|
||||
head_revision: << pipeline.git.revision >>
|
||||
# This cache is saved in the build-npm-packages so that Bazel cache is also included.
|
||||
- restore_cache:
|
||||
keys:
|
||||
- *cache_key
|
||||
- *cache_key_fallback
|
||||
- yarn_install
|
||||
- run: yarn --cwd aio install --frozen-lockfile --non-interactive --cache-folder ~/.cache/yarn
|
||||
# Make the bazel directories and add a file to them if they don't exist already so that
|
||||
# persist_to_workspace does not fail.
|
||||
- run: |
|
||||
if [ ! -d ~/bazel_repository_cache ]; then
|
||||
mkdir ~/bazel_repository_cache
|
||||
touch ~/bazel_repository_cache/MARKER
|
||||
fi
|
||||
# Persist any changes at this point to be reused by further jobs.
|
||||
# **NOTE**: To add new content to the workspace, always persist on the same root.
|
||||
- persist_to_workspace:
|
||||
root: *workspace_location
|
||||
paths:
|
||||
- ./ng
|
||||
- ./bazel_repository_cache
|
||||
|
||||
test:
|
||||
executor:
|
||||
name: test-browser-executor
|
||||
# Now that large integration tests are running locally in parallel (they can't run on RBE yet
|
||||
# as they require network access for yarn install), this test is running out of memory
|
||||
# consistently with the xlarge machine.
|
||||
# TODO: switch back to xlarge once integration tests are running on remote-exec
|
||||
resource_class: 2xlarge+
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- run:
|
||||
# We need to explicitly specify the --symlink_prefix option because otherwise we would
|
||||
# not be able to easily find the output bin directory when uploading artifacts for size
|
||||
# measurements.
|
||||
command: yarn test:ci
|
||||
no_output_timeout: 20m
|
||||
# Publish bundle artifacts which will be used to calculate the size change. **Note**: Make
|
||||
# sure that the size plugin from the Angular robot fetches the artifacts from this CircleCI
|
||||
# job (see .github/angular-robot.yml). Additionally any artifacts need to be stored with the
|
||||
# following path format: "{projectName}/{context}/{fileName}". This format is necessary
|
||||
# because otherwise the bot is not able to pick up the artifacts from CircleCI. See:
|
||||
# https://github.com/angular/github-robot/blob/master/functions/src/plugins/size.ts#L392-L394
|
||||
- store_artifacts:
|
||||
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js
|
||||
destination: core/hello_world/bundle
|
||||
- store_artifacts:
|
||||
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js
|
||||
destination: core/todo/bundle
|
||||
- store_artifacts:
|
||||
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js.br
|
||||
destination: core/hello_world/bundle.br
|
||||
- store_artifacts:
|
||||
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js.br
|
||||
destination: core/todo/bundle.br
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_REACTIVITY_CHANNEL_WEBHOOK_URL
|
||||
|
||||
# NOTE: This is currently limited to main builds only. See the `monitoring` configuration.
|
||||
saucelabs:
|
||||
executor:
|
||||
name: default-executor
|
||||
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
|
||||
# container for this job. This is necessary because we launch a lot of browsers concurrently
|
||||
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
|
||||
resource_class: xlarge
|
||||
environment:
|
||||
NUMBER_OF_PARALLEL_BROWSERS: 2
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- init_saucelabs_environment
|
||||
- run:
|
||||
name: Start Saucelabs daemon service
|
||||
command: yarn bazel run //tools/saucelabs-daemon/background-service -- ${NUMBER_OF_PARALLEL_BROWSERS}
|
||||
background: true
|
||||
- run:
|
||||
name: Run Bazel tests on Saucelabs
|
||||
command: |
|
||||
TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "fixme-saucelabs", ...)')
|
||||
yarn bazel test --config=saucelabs --jobs=${NUMBER_OF_PARALLEL_BROWSERS} ${TESTS}
|
||||
no_output_timeout: 40m
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
|
||||
|
||||
test_aio:
|
||||
executor:
|
||||
name: test-browser-executor
|
||||
resource_class: 2xlarge+
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
|
||||
# Run all aio tests
|
||||
- run:
|
||||
command: yarn --cwd aio test:ci
|
||||
no_output_timeout: 20m
|
||||
|
||||
# Check the bundle sizes.
|
||||
- run: yarn --cwd aio payload-size
|
||||
|
||||
deploy_aio:
|
||||
executor:
|
||||
name: test-browser-executor
|
||||
resource_class: 2xlarge+
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Deploy angular.io to production (if necessary)
|
||||
- run: setPublicVar_CI_STABLE_BRANCH
|
||||
- run: yarn --cwd aio deploy-production
|
||||
|
||||
test_aio_local:
|
||||
executor:
|
||||
name: test-browser-executor
|
||||
resource_class: 2xlarge+
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Run all aio tests (with local Angular packages)
|
||||
- run:
|
||||
command: yarn --cwd aio test-local:ci
|
||||
no_output_timeout: 20m
|
||||
|
||||
# Check the bundle sizes.
|
||||
- run: yarn --cwd aio payload-size aio-local
|
||||
|
||||
# The `build-npm-packages` tasks exist for backwards-compatibility with old scripts and
|
||||
# tests that rely on the pre-Bazel `dist/packages-dist` output structure (build.sh).
|
||||
# Having multiple jobs that independently build in this manner duplicates some work; we build
|
||||
# the bazel packages more than once. Even though we have a remote cache, these jobs will
|
||||
# typically run in parallel so up-to-date outputs will not be available at the time the build
|
||||
# starts.
|
||||
build-npm-packages:
|
||||
executor:
|
||||
name: default-executor
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- run: yarn build
|
||||
|
||||
# Save the npm packages from //packages/... for other workflow jobs to read
|
||||
- persist_to_workspace:
|
||||
root: *workspace_location
|
||||
paths:
|
||||
- ng/dist/packages-dist
|
||||
- ng/dist/angular-in-memory-web-api-dist
|
||||
- ng/dist/zone.js-dist
|
||||
|
||||
# Save dependencies and bazel repository cache to use on subsequent runs.
|
||||
- save_cache:
|
||||
key: *cache_key
|
||||
paths:
|
||||
- ~/.cache/yarn
|
||||
- ~/bazel_repository_cache
|
||||
- ~/.cache/bazelisk
|
||||
|
||||
# This job creates compressed tarballs (`.tgz` files) for all Angular packages and stores them as
|
||||
# build artifacts. This makes it easy to try out changes from a PR build for testing purposes.
|
||||
# More info CircleCI build artifacts: https://circleci.com/docs/2.0/artifacts
|
||||
#
|
||||
# NOTE: Currently, this job only runs for PR builds. See `publish_snapshot` for non-PR builds.
|
||||
publish_packages_as_artifacts:
|
||||
executor: default-executor
|
||||
environment:
|
||||
AIMWA_PACKAGES_DIR: &aimwa_packages_dir 'dist/angular-in-memory-web-api-dist'
|
||||
AIMWA_PACKAGES_ARCHIVES_DIR: &aimwa_packages_archives_dir 'dist/angular-in-memory-web-api-dist-archives'
|
||||
NG_PACKAGES_DIR: &ng_packages_dir 'dist/packages-dist'
|
||||
NG_PACKAGES_ARCHIVES_DIR: &ng_packages_archives_dir 'dist/packages-dist-archives'
|
||||
ZONEJS_PACKAGES_DIR: &zonejs_packages_dir 'dist/zone.js-dist'
|
||||
ZONEJS_PACKAGES_ARCHIVES_DIR: &zonejs_packages_archives_dir 'dist/zone.js-dist-archives'
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Publish `@angular/*` packages.
|
||||
- run:
|
||||
name: Create artifacts for @angular/* packages
|
||||
command: ./scripts/ci/create-package-archives.sh $CI_BRANCH $CI_COMMIT $NG_PACKAGES_DIR $NG_PACKAGES_ARCHIVES_DIR
|
||||
- store_artifacts:
|
||||
path: *ng_packages_archives_dir
|
||||
destination: angular
|
||||
# Publish the `angular-in-memory-web-api` package.
|
||||
- run:
|
||||
name: Create artifacts for the `angular-in-memory-web-api` package
|
||||
# Need to remove the zone.js.tgz before archive
|
||||
command: ./scripts/ci/create-package-archives.sh $CI_BRANCH $CI_COMMIT $AIMWA_PACKAGES_DIR $AIMWA_PACKAGES_ARCHIVES_DIR
|
||||
- store_artifacts:
|
||||
path: *aimwa_packages_archives_dir
|
||||
destination: angular-in-memory-web-api
|
||||
# Publish the `zone.js` package.
|
||||
- run:
|
||||
name: Create artifacts for the `zone.js` package
|
||||
# Need to remove the zone.js.tgz before archive
|
||||
command: rm -rf $ZONEJS_PACKAGES_DIR/archive && ./scripts/ci/create-package-archives.sh $CI_BRANCH $CI_COMMIT $ZONEJS_PACKAGES_DIR $ZONEJS_PACKAGES_ARCHIVES_DIR
|
||||
- store_artifacts:
|
||||
path: *zonejs_packages_archives_dir
|
||||
destination: zone.js
|
||||
|
||||
# This job updates the content of repos like github.com/angular/core-builds
|
||||
# for every green build on angular/angular.
|
||||
publish_snapshot:
|
||||
executor: default-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# CircleCI has a config setting to force SSH for all github connections
|
||||
# This is not compatible with our mechanism of using a Personal Access Token
|
||||
# Clear the global setting
|
||||
- run: git config --global --unset "url.ssh://git@github.com.insteadof"
|
||||
- run:
|
||||
name: Prepare GitHub credentials
|
||||
command: echo "https://${SNAPSHOT_BUILDS_GITHUB_TOKEN}:@github.com" > ${HOME}/.git_credentials
|
||||
- run: ./scripts/ci/publish-build-artifacts.sh
|
||||
|
||||
aio_misc:
|
||||
executor: default-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- run:
|
||||
name: Check website provided in contributors.json file
|
||||
command: yarn node aio/scripts/test-external-urls.js
|
||||
|
||||
aio_monitoring_stable:
|
||||
executor: test-browser-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- run: setPublicVar_CI_STABLE_BRANCH
|
||||
- run:
|
||||
name: Check out `aio/` and yarn from the stable branch
|
||||
command: |
|
||||
git fetch origin $CI_STABLE_BRANCH
|
||||
git checkout --force origin/$CI_STABLE_BRANCH -- aio/ .yarn/ .yarnrc
|
||||
# Ignore yarn's engines check, because we checked out `aio/package.json` from the stable
|
||||
# branch and there could be a node version skew, which is acceptable in this monitoring job.
|
||||
- run: yarn config set ignore-engines true
|
||||
- run:
|
||||
name: Run tests against https://angular.io/
|
||||
command: ./aio/scripts/test-production.sh https://angular.io/ $CI_AIO_MIN_PWA_SCORE
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_CARETAKER_WEBHOOK_URL
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
|
||||
|
||||
aio_monitoring_next:
|
||||
executor: test-browser-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- run:
|
||||
name: Run tests against https://next.angular.io/
|
||||
command: ./aio/scripts/test-production.sh https://next.angular.io/ $CI_AIO_MIN_PWA_SCORE
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_CARETAKER_WEBHOOK_URL
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
|
||||
|
||||
legacy-unit-tests-saucelabs:
|
||||
executor:
|
||||
name: default-executor
|
||||
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
|
||||
# container for this job. This is necessary because we launch a lot of browsers concurrently
|
||||
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- init_saucelabs_environment
|
||||
- run:
|
||||
name: Starting Saucelabs tunnel service
|
||||
command: ./tools/saucelabs/sauce-service.sh run
|
||||
background: true
|
||||
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
|
||||
# specific tests which are reliant on such generated fixtures is not an option as SystemJS
|
||||
# in the Saucelabs legacy job always fetches referenced files, even if the imports would be
|
||||
# guarded by an check to skip in the Saucelabs legacy job. We should be good running such
|
||||
# test in all supported browsers on Saucelabs anyway until this job can be removed.
|
||||
- run:
|
||||
name: Preparing Bazel-generated fixtures required in legacy tests
|
||||
command: |
|
||||
yarn bazel build \
|
||||
//packages/core/test:downleveled_es5_fixture \
|
||||
//packages/common/locales
|
||||
|
||||
# Needed for the ES5 downlevel reflector test in `packages/core/test/reflection`.
|
||||
mkdir -p dist/legacy-test-out/core/test/reflection/
|
||||
cp dist/bin/packages/core/test/reflection/es5_downleveled_inheritance_fixture.js \
|
||||
dist/legacy-test-out/core/test/reflection/es5_downleveled_inheritance_fixture.js
|
||||
# Locale files are needed for i18n tests running within Saucelabs. These are added
|
||||
# directly as sources so that the TypeScript compilation of `/packages/tsconfig.json`
|
||||
# can succeed. Note that the base locale and currencies files are checked-in, so
|
||||
# we do not need to re-generate those through Bazel.
|
||||
mkdir -p packages/common/locales/extra
|
||||
cp dist/bin/packages/common/locales/*.ts packages/common/locales
|
||||
cp dist/bin/packages/common/locales/extra/*.ts packages/common/locales/extra
|
||||
# Build the bundle for all tests to run within Saucelabs
|
||||
- run: node tools/legacy-saucelabs/build-saucelabs-test-bundle.mjs
|
||||
- run:
|
||||
# Waiting on ready ensures that we don't run tests too early without Saucelabs not being ready.
|
||||
name: Waiting for Saucelabs tunnel to connect
|
||||
command: ./tools/saucelabs/sauce-service.sh ready-wait
|
||||
- run:
|
||||
name: Running tests on Saucelabs.
|
||||
command: |
|
||||
KARMA_WEB_TEST_MODE=SL_REQUIRED yarn karma start ./karma-js.conf.js --single-run
|
||||
- run:
|
||||
name: Stop Saucelabs tunnel service
|
||||
command: ./tools/saucelabs/sauce-service.sh stop
|
||||
|
||||
test_zonejs:
|
||||
executor:
|
||||
name: default-executor
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- install_java
|
||||
|
||||
- run: |
|
||||
yarn bazel build -- \
|
||||
//packages/zone.js/bundles:zone.umd.js \
|
||||
//packages/zone.js:npm_package \
|
||||
//packages/zone.js/test/closure:closure_js \
|
||||
//packages/zone.js:zone_externs
|
||||
|
||||
- run: |
|
||||
mkdir -p packages/zone.js/build/
|
||||
mkdir -p packages/zone.js/build/test/
|
||||
mkdir -p packages/zone.js/test/
|
||||
|
||||
cp dist/bin/packages/zone.js/bundles/zone.umd.js packages/zone.js/build/zone.umd.js
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/
|
||||
cp dist/bin/packages/zone.js/test/closure/zone.closure.mjs ./packages/zone.js/build/test/zone.closure.mjs
|
||||
cp dist/bin/packages/zone.js/zone_externs.js ./packages/zone.js/build/zone_externs.js
|
||||
|
||||
# Install
|
||||
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive --cache-folder ~/.cache/yarn
|
||||
# Run zone.js tools tests
|
||||
- run: yarn --cwd packages/zone.js promisetest
|
||||
- run: yarn --cwd packages/zone.js promisefinallytest
|
||||
- run: yarn --cwd packages/zone.js jest:test
|
||||
- run: yarn --cwd packages/zone.js jest:nodetest
|
||||
- run: yarn --cwd packages/zone.js electrontest
|
||||
- run: yarn --cwd packages/zone.js closuretest
|
||||
- run: yarn --cwd packages/zone.js/test/typings install --frozen-lockfile --non-interactive --cache-folder ~/.cache/yarn
|
||||
- run: yarn --cwd packages/zone.js/test/typings test
|
||||
|
||||
# Windows jobs
|
||||
# Docs: https://circleci.com/docs/2.0/hello-world-windows/
|
||||
test_win:
|
||||
executor: windows-executor
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
# Setup the proper NodeJS version. The image comes pre-installed with `nvm-windows`.
|
||||
# Note: This happens immediately after checkout because environment initialization logic
|
||||
# might rely on Node and shouldn't use the older image-provided NodeJS version.
|
||||
- run:
|
||||
name: Install NodeJS version from `.nvmrc`.
|
||||
command: |
|
||||
nvm on
|
||||
nvm install $(cat .nvmrc)
|
||||
nvm use $(cat .nvmrc)
|
||||
- run:
|
||||
name: Debug information for flakiness of Windows job
|
||||
command: |
|
||||
node -v
|
||||
yarn -v
|
||||
which node
|
||||
which yarn
|
||||
echo "Path: $PATH"
|
||||
yarn node -v
|
||||
|
||||
- save_month_to_file
|
||||
- capture_patches_for_cache_key
|
||||
- init_environment
|
||||
- restore_cache:
|
||||
keys:
|
||||
- *cache_key_win
|
||||
- *cache_key_win_fallback
|
||||
|
||||
# Install project dependencies, and install Bazelisk globally. This is necessary as
|
||||
# Windows might error when `bazel` is invoked from the project node modules. The Bazel
|
||||
# invocation might modify the symlinked project `node_modules` again, causing failures.
|
||||
- yarn_install
|
||||
- run: yarn global add @bazel/bazelisk@${BAZELISK_VERSION}
|
||||
|
||||
- run:
|
||||
name: Build all windows CI targets
|
||||
command: |
|
||||
$(yarn global bin)/bazelisk build //packages/compiler-cli/...
|
||||
no_output_timeout: 15m
|
||||
- run:
|
||||
name: Test all windows CI targets
|
||||
command: |
|
||||
$(yarn global bin)/bazelisk test --test_tag_filters="-browser:chromium-local" //packages/compiler-cli/...
|
||||
no_output_timeout: 15m
|
||||
|
||||
- save_cache:
|
||||
key: *cache_key_win
|
||||
paths:
|
||||
- node_modules
|
||||
- ~/AppData/Local/bazelisk
|
||||
|
||||
test_angular_devtools:
|
||||
executor: test-browser-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- run:
|
||||
name: Run unit tests
|
||||
command: yarn devtools:test
|
||||
- run:
|
||||
name: Test production build
|
||||
command: yarn devtools:build:chrome
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
default_workflow:
|
||||
jobs:
|
||||
- pass
|
||||
- setup:
|
||||
filters:
|
||||
branches:
|
||||
ignore: g3
|
||||
- test:
|
||||
requires:
|
||||
- setup
|
||||
- build-npm-packages:
|
||||
requires:
|
||||
- setup
|
||||
- legacy-unit-tests-saucelabs:
|
||||
requires:
|
||||
- setup
|
||||
- test_aio:
|
||||
requires:
|
||||
- setup
|
||||
- deploy_aio:
|
||||
requires:
|
||||
- test_aio
|
||||
- test_aio_local:
|
||||
requires:
|
||||
- setup
|
||||
- publish_packages_as_artifacts:
|
||||
requires:
|
||||
- build-npm-packages
|
||||
- publish_snapshot:
|
||||
<<: *only_release_branches
|
||||
requires:
|
||||
# Only publish if tests and integration tests pass
|
||||
- test
|
||||
# Only publish if `aio`/`docs` tests using the locally built Angular packages pass
|
||||
- test_aio_local
|
||||
# Get the artifacts to publish from the build-packages-dist job
|
||||
# since the publishing script expects the legacy outputs layout.
|
||||
- build-npm-packages
|
||||
- legacy-unit-tests-saucelabs
|
||||
- test_zonejs:
|
||||
requires:
|
||||
- setup
|
||||
- test_win:
|
||||
requires:
|
||||
- setup
|
||||
- test_angular_devtools:
|
||||
requires:
|
||||
- setup
|
||||
|
||||
monitoring:
|
||||
jobs:
|
||||
- setup
|
||||
- aio_misc:
|
||||
requires:
|
||||
- setup
|
||||
- aio_monitoring_stable:
|
||||
requires:
|
||||
- setup
|
||||
- aio_monitoring_next:
|
||||
requires:
|
||||
- setup
|
||||
- saucelabs:
|
||||
# Testing saucelabs via Bazel currently taking longer than the legacy saucelabs job as it
|
||||
# each karma_web_test target is provisioning and tearing down browsers which is adding
|
||||
# a lot of overhead. Running once daily in the main branch to avoid wasting resources and
|
||||
# slowing down CI for PRs.
|
||||
# TODO: Run this job on all branches (including PRs) once karma_web_test targets can
|
||||
# share provisioned browsers and we can remove the legacy saucelabs job.
|
||||
requires:
|
||||
- setup
|
||||
triggers:
|
||||
- schedule:
|
||||
<<: *only_on_main_branch
|
||||
# Runs monitoring jobs at 10:00AM every day.
|
||||
cron: '0 10 * * *'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Image metadata and config.
|
||||
# Ideally, the Node.js version should match what we use on CI.
|
||||
# See `executors > default-executor` in `.circleci/config.yml`.
|
||||
FROM cimg/node:16.13-browsers@sha256:6c7a82701665dda03e92d682360fa2e4358e07dab8d1b6a7e48f7d36e3d98117
|
||||
FROM cimg/node:16.13-browsers
|
||||
|
||||
|
||||
LABEL name="Angular dev environment" \
|
||||
|
||||
@@ -4,7 +4,7 @@ description: 'Installs the dependencies using Yarn'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3
|
||||
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3
|
||||
with:
|
||||
path: |
|
||||
./node_modules/
|
||||
|
||||
@@ -22,10 +22,10 @@ jobs:
|
||||
(github.event.action == 'labeled' && github.event.label.name == 'aio: preview') ||
|
||||
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'aio: preview'))
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- uses: ./.github/actions/yarn-install
|
||||
|
||||
- uses: angular/dev-infra/github-actions/bazel/configure-remote@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- uses: angular/dev-infra/github-actions/setup-bazel-remote-exec@97cb376945b07e37671e3b38ee727ff00dc1394b
|
||||
with:
|
||||
bazelrc: ./.bazelrc.user
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
# the number of concurrent actions is determined based on the host resources.
|
||||
- run: bazel build //aio:build --jobs=32 --announce_rc --verbose_failures
|
||||
|
||||
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- uses: angular/dev-infra/github-actions/deploy-previews/pack-and-upload-artifact@97cb376945b07e37671e3b38ee727ff00dc1394b
|
||||
with:
|
||||
workflow-artifact-name: 'aio'
|
||||
pull-number: '${{github.event.pull_request.number}}'
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3
|
||||
|
||||
- name: Configure Firebase deploy target
|
||||
working-directory: aio/
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
npx -y firebase-tools@latest target:clear --project ${{env.PREVIEW_PROJECT}} hosting aio
|
||||
npx -y firebase-tools@latest target:apply --project ${{env.PREVIEW_PROJECT}} hosting aio ${{env.PREVIEW_SITE}}
|
||||
|
||||
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- uses: angular/dev-infra/github-actions/deploy-previews/upload-artifacts-to-firebase@97cb376945b07e37671e3b38ee727ff00dc1394b
|
||||
with:
|
||||
github-token: '${{secrets.GITHUB_TOKEN}}'
|
||||
workflow-artifact-name: 'aio'
|
||||
|
||||
@@ -13,9 +13,9 @@ jobs:
|
||||
assistant_to_the_branch_manager:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@97cb376945b07e37671e3b38ee727ff00dc1394b
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
exit: true
|
||||
|
||||
# Indicate that the benchmark command was received.
|
||||
- uses: peter-evans/create-or-update-comment@23ff15729ef2fc348714a3bb66d2f655ca9066f2 # v3
|
||||
- uses: peter-evans/create-or-update-comment@c6c9a1a66007646a28c153e2a8580a5bad27bcfa # v3
|
||||
with:
|
||||
comment-id: ${{github.event.comment.id}}
|
||||
token: '${{secrets.BENCHMARK_POST_RESULTS_GITHUB_TOKEN}}'
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- uses: alessbell/pull-request-comment-branch@aad01d65d6982b8eacabed5e9a684cd8ceb98da6 # v1.1
|
||||
id: comment-branch
|
||||
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
# Specify repository as the PR branch might be from a fork.
|
||||
repository: ${{steps.comment-branch.outputs.head_owner}}/${{steps.comment-branch.outputs.head_repo}}
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
|
||||
- uses: ./.github/actions/yarn-install
|
||||
|
||||
- uses: angular/dev-infra/github-actions/bazel/configure-remote@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- uses: angular/dev-infra/github-actions/setup-bazel-remote-exec@97cb376945b07e37671e3b38ee727ff00dc1394b
|
||||
with:
|
||||
bazelrc: ./.bazelrc.user
|
||||
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
id: benchmark
|
||||
name: Running benchmark
|
||||
|
||||
- uses: peter-evans/create-or-update-comment@23ff15729ef2fc348714a3bb66d2f655ca9066f2 # v3
|
||||
- uses: peter-evans/create-or-update-comment@c6c9a1a66007646a28c153e2a8580a5bad27bcfa # v3
|
||||
with:
|
||||
issue-number: ${{github.event.issue.number}}
|
||||
token: '${{secrets.BENCHMARK_POST_RESULTS_GITHUB_TOKEN}}'
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
saucelabs:
|
||||
runs-on: ubuntu-latest-4core
|
||||
env:
|
||||
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
|
||||
SAUCE_USERNAME: ${{ vars.SAUCE_USERNAME }}
|
||||
SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }}
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1befe6d24fd5cab818e7f8bada40ab364781b8a8
|
||||
with:
|
||||
cache-node-modules: true
|
||||
# Checking out the pull request commit is intended here as we need to run the changed code tests.
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1befe6d24fd5cab818e7f8bada40ab364781b8a8
|
||||
- name: Starting Saucelabs tunnel service
|
||||
run: ./tools/saucelabs/sauce-service.sh run &
|
||||
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
|
||||
# specific tests which are reliant on such generated fixtures is not an option as SystemJS
|
||||
# in the Saucelabs legacy job always fetches referenced files, even if the imports would be
|
||||
# guarded by an check to skip in the Saucelabs legacy job. We should be good running such
|
||||
# test in all supported browsers on Saucelabs anyway until this job can be removed.
|
||||
- name: Preparing Bazel-generated fixtures required in legacy tests
|
||||
run: |
|
||||
yarn bazel build //packages/core/test:downleveled_es5_fixture //packages/common/locales
|
||||
# Needed for the ES5 downlevel reflector test in `packages/core/test/reflection`.
|
||||
mkdir -p dist/legacy-test-out/core/test/reflection/
|
||||
cp dist/bin/packages/core/test/reflection/es5_downleveled_inheritance_fixture.js \
|
||||
dist/legacy-test-out/core/test/reflection/es5_downleveled_inheritance_fixture.js
|
||||
# Locale files are needed for i18n tests running within Saucelabs. These are added
|
||||
# directly as sources so that the TypeScript compilation of `/packages/tsconfig.json`
|
||||
# can succeed. Note that the base locale and currencies files are checked-in, so
|
||||
# we do not need to re-generate those through Bazel.
|
||||
mkdir -p packages/common/locales/extra
|
||||
cp dist/bin/packages/common/locales/*.ts packages/common/locales
|
||||
cp dist/bin/packages/common/locales/extra/*.ts packages/common/locales/extra
|
||||
- name: Build bundle of tests to run on Saucelabs
|
||||
run: node tools/legacy-saucelabs/build-saucelabs-test-bundle.mjs
|
||||
- name: Wait and confirm Saucelabs tunnel has connected
|
||||
run: ./tools/saucelabs/sauce-service.sh ready-wait
|
||||
timeout-minutes: 3
|
||||
- name: Running tests on Saucelabs.
|
||||
run: KARMA_WEB_TEST_MODE=SL_REQUIRED yarn karma start ./karma-js.conf.js --single-run
|
||||
- name: Stop Saucelabs tunnel service
|
||||
run: ./tools/saucelabs/sauce-service.sh stop
|
||||
|
||||
bazel-saucelabs:
|
||||
runs-on: ubuntu-latest-4core
|
||||
env:
|
||||
JOBS: 2
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1befe6d24fd5cab818e7f8bada40ab364781b8a8
|
||||
with:
|
||||
cache-node-modules: true
|
||||
# Checking out the pull request commit is intended here as we need to run the changed code tests.
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1befe6d24fd5cab818e7f8bada40ab364781b8a8
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@ba9b4487ced515e5b4d87edd681a3bd9792444d6
|
||||
- name: Set up Sauce Tunnel Daemon
|
||||
run: yarn bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
|
||||
env:
|
||||
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
|
||||
SAUCE_USERNAME: ${{ vars.SAUCE_USERNAME }}
|
||||
SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }}
|
||||
- name: Run all saucelabs bazel tests
|
||||
run: |
|
||||
TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "fixme-saucelabs", ...)')
|
||||
yarn bazel test --config=saucelabs --jobs=$JOBS ${TESTS}
|
||||
+1
-204
@@ -23,7 +23,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@852c3d1898775ec9fbc87213e519f16e78805b57
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
@@ -55,206 +55,3 @@ jobs:
|
||||
# it has been merged.
|
||||
if: github.event_name == 'pull_request'
|
||||
run: yarn ng-dev format changed --check ${{ github.event.pull_request.base.sha }}
|
||||
|
||||
devtools:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Run unit tests
|
||||
run: yarn devtools:test
|
||||
- name: Test build
|
||||
run: yarn devtools:build:chrome
|
||||
|
||||
framework-win:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile --network-timeout 100000
|
||||
- name: Test all windows CI targets
|
||||
run: bazel test --test_tag_filters="-browser:chromium-local" //packages/compiler-cli/...
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile --network-timeout 100000
|
||||
- name: Run CI tests for framework
|
||||
run: yarn test:ci
|
||||
|
||||
aio:
|
||||
runs-on: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./aio/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
- name: Install node modules for aio
|
||||
run: yarn install --cwd aio --frozen-lockfile
|
||||
- name: Run AIO tests with upstream packages
|
||||
run: yarn --cwd aio test:ci
|
||||
- name: Check generated bundle sizes
|
||||
run: yarn --cwd aio payload-size
|
||||
|
||||
aio-local:
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./aio/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
- name: Install node modules
|
||||
run: yarn install --cwd aio --frozen-lockfile
|
||||
- name: Run AIO tests with local packages
|
||||
run: yarn --cwd aio test-local:ci
|
||||
- name: Check generated bundle sizes
|
||||
run: yarn --cwd aio payload-size aio-local
|
||||
|
||||
aio-deploy:
|
||||
needs: [aio]
|
||||
if: needs.aio.result == 'success' && github.event_name == 'push'
|
||||
runs-on:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./aio/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
- name: Install node modules for aio
|
||||
run: yarn install --cwd aio --frozen-lockfile
|
||||
- name: Set the stable branch environment variable
|
||||
id: latest_version
|
||||
run: |
|
||||
echo "CI_STABLE_BRANCH=$(npm info @angular/core dist-tags.latest | sed -r 's/^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$/\1.x/')" >> $GITHUB_OUTPUT
|
||||
echo "CI_BRANCH=$(echo ${{ github.event.ref }} | cut -d '/' -f 3)" >> $GITHUB_OUTPUT
|
||||
- name: Deploy aio to production
|
||||
env:
|
||||
CI_AIO_MIN_PWA_SCORE: '95'
|
||||
CI_COMMIT: ${{ github.event.after }}
|
||||
CI_REPO_NAME: 'angular'
|
||||
CI_PULL_REQUEST: 'false'
|
||||
CI_REPO_OWNER: 'angular'
|
||||
CI_BUILD_URL: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
|
||||
CI_STABLE_BRANCH: ${{ steps.latest_version.outputs.CI_STABLE_BRANCH }}
|
||||
CI_BRANCH: ${{ steps.latest_version.outputs.CI_BRANCH }}
|
||||
CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN: ${{ secrets.AIO_DEPLOY_TOKEN }}
|
||||
CI_SECRET_PAYLOAD_FIREBASE_TOKEN: ${{ secrets.AIO_PAYLOAD_TOKEN }}
|
||||
run: yarn --cwd aio deploy-production
|
||||
- name: Notify about failed deployment
|
||||
if: ${{ failure() }}
|
||||
uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v=v1.24.0
|
||||
with:
|
||||
channel-id: 'C07DT5M6V,CKV1F72BG'
|
||||
slack-message: 'Deploy to aio job failed for ${{ github.base_ref }} branch failed on build ${{ github.event.after }}: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
|
||||
env:
|
||||
SLACK_BOT_TOKEN: ${{ secrets.ANGULAR_ROBOT_SLACK_TOKEN }}
|
||||
|
||||
publish-snapshots:
|
||||
if: github.event_name == 'push'
|
||||
runs-on:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ba9b4487ced515e5b4d87edd681a3bd9792444d6
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@ba9b4487ced515e5b4d87edd681a3bd9792444d6
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@ba9b4487ced515e5b4d87edd681a3bd9792444d6
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
|
||||
- run: yarn build
|
||||
- run: ./scripts/ci/publish-build-artifacts.sh
|
||||
|
||||
zone-js:
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./node_modules
|
||||
./packages/zone.js/node_modules
|
||||
./packages/zone.js/test/typings/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@45de46d9ba0e0689b7a846fd31ec9e241807ca71
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- run: |
|
||||
yarn bazel build \
|
||||
//packages/zone.js/bundles:zone.umd.js \
|
||||
//packages/zone.js:npm_package \
|
||||
//packages/zone.js/test/closure:closure_js \
|
||||
//packages/zone.js:zone_externs
|
||||
|
||||
- run: |
|
||||
mkdir -p packages/zone.js/build/
|
||||
mkdir -p packages/zone.js/build/test/
|
||||
mkdir -p packages/zone.js/test/
|
||||
|
||||
cp dist/bin/packages/zone.js/bundles/zone.umd.js packages/zone.js/build/zone.umd.js
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/
|
||||
cp dist/bin/packages/zone.js/test/closure/zone.closure.mjs ./packages/zone.js/build/test/zone.closure.mjs
|
||||
cp dist/bin/packages/zone.js/zone_externs.js ./packages/zone.js/build/zone_externs.js
|
||||
|
||||
# Install
|
||||
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive
|
||||
# Run zone.js tools tests
|
||||
- run: yarn --cwd packages/zone.js promisetest
|
||||
- run: yarn --cwd packages/zone.js promisefinallytest
|
||||
- run: yarn --cwd packages/zone.js jest:test
|
||||
- run: yarn --cwd packages/zone.js jest:nodetest
|
||||
- run: yarn --cwd packages/zone.js electrontest
|
||||
- run: yarn --cwd packages/zone.js closuretest
|
||||
- run: yarn --cwd packages/zone.js/test/typings install --frozen-lockfile --non-interactive
|
||||
- run: yarn --cwd packages/zone.js/test/typings test
|
||||
|
||||
@@ -12,14 +12,14 @@ jobs:
|
||||
labels:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@031962443584a0ac5cbd9d1c1b78b241453e4702
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@97cb376945b07e37671e3b38ee727ff00dc1394b
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
post_approval_changes:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@031962443584a0ac5cbd9d1c1b78b241453e4702
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@97cb376945b07e37671e3b38ee727ff00dc1394b
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -14,6 +14,6 @@ jobs:
|
||||
if: github.repository == 'angular/angular'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: angular/dev-infra/github-actions/feature-request@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- uses: angular/dev-infra/github-actions/feature-request@97cb376945b07e37671e3b38ee727ff00dc1394b
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -4,17 +4,16 @@ on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
pull-requests: read
|
||||
statuses: write
|
||||
|
||||
jobs:
|
||||
trigger:
|
||||
permissions:
|
||||
pull-requests: read
|
||||
statuses: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@031962443584a0ac5cbd9d1c1b78b241453e4702
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@97cb376945b07e37671e3b38ee727ff00dc1394b
|
||||
with:
|
||||
run-tests-guide-url: http://go/angular-g3sync-start
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -9,6 +9,6 @@ jobs:
|
||||
status:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: angular/dev-infra/github-actions/unified-status-check@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- uses: angular/dev-infra/github-actions/unified-status-check@97cb376945b07e37671e3b38ee727ff00dc1394b
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
name: Monitoring
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run at 10:00AM every day.
|
||||
- cron: '0 10 * * *'
|
||||
|
||||
permissions: {}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check_aio:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
MINIMUM_PWA_SCORE: 95
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: ['https://next.angular.io/', 'https://angular.io/']
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./aio/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
- name: Install node modules in aio
|
||||
run: yarn install --frozen-lockfile --cwd aio
|
||||
- name: Run basic e2e and deployment config tests.
|
||||
run: yarn --cwd aio test-production-url --test_env=TARGET_URL="${{ matrix.version }}"
|
||||
- name: Run PWA-score tests.
|
||||
run: yarn --cwd aio test-pwa-score "${{ matrix.version }}" "${{ env.MINIMUM_PWA_SCORE }}"
|
||||
- name: Run a11y tests.
|
||||
run: yarn --cwd aio test-a11y-score "${{ matrix.version }}"
|
||||
|
||||
check_contributor_links:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./aio/node_modules
|
||||
- name: Install node modules in aio
|
||||
run: yarn install --frozen-lockfile --cwd aio
|
||||
- name: Check website provided in contributors.json file
|
||||
run: node aio/scripts/test-external-urls.js
|
||||
@@ -25,12 +25,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 'Checkout code'
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: 'Run analysis'
|
||||
uses: ossf/scorecard-action@483ef80eb98fb506c348f7d62e28055e49fe2398 # v2.3.0
|
||||
uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031 # v2.2.0
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
|
||||
# Upload the results as artifacts.
|
||||
- name: 'Upload artifact'
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
@@ -47,6 +47,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: 'Upload to code-scanning'
|
||||
uses: github/codeql-action/upload-sarif@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3
|
||||
uses: github/codeql-action/upload-sarif@46ed16ded91731b2df79a2893d3aea8e9f03b5c4 # v2.20.3
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
# Setting `persist-credentials: false` prevents the github-action account from being the
|
||||
# account that is attempted to be used for authentication, instead the remote is set to
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
env:
|
||||
ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN: ${{ secrets.ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN }}
|
||||
- name: Create a PR (if necessary)
|
||||
uses: angular/dev-infra/github-actions/create-pr-for-changes@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
uses: angular/dev-infra/github-actions/create-pr-for-changes@97cb376945b07e37671e3b38ee727ff00dc1394b
|
||||
with:
|
||||
branch-prefix: update-cli-help
|
||||
pr-title: 'docs: update Angular CLI help [${{github.ref_name}}]'
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
# Setting `persist-credentials: false` prevents the github-action account from being the
|
||||
# account that is attempted to be used for authentication, instead the remote is set to
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
- name: Generate `events.json`
|
||||
run: node aio/scripts/generate-events/index.mjs --ignore-invalid-dates
|
||||
- name: Create a PR (if necessary)
|
||||
uses: angular/dev-infra/github-actions/create-pr-for-changes@0109d498b0f6aae418ed4924a5e5c65695f0ac61
|
||||
uses: angular/dev-infra/github-actions/create-pr-for-changes@97cb376945b07e37671e3b38ee727ff00dc1394b
|
||||
with:
|
||||
branch-prefix: docs-update-events
|
||||
pr-title: 'docs: update events'
|
||||
|
||||
+9
-5
@@ -57,7 +57,8 @@
|
||||
version: 3
|
||||
|
||||
availability:
|
||||
users_unavailable: []
|
||||
users_unavailable:
|
||||
- atscott
|
||||
|
||||
# Meta field that goes unused by PullApprove to allow for defining aliases to be
|
||||
# used throughout the config.
|
||||
@@ -167,7 +168,6 @@ groups:
|
||||
- atscott
|
||||
- crisbeto
|
||||
- JoostK
|
||||
- dylhunn
|
||||
|
||||
# =========================================================
|
||||
# Framework: Migrations
|
||||
@@ -337,8 +337,7 @@ groups:
|
||||
'aio/content/images/guide/view-encapsulation/**/{*,.*}',
|
||||
'aio/content/special-elements/**/{*,.*}',
|
||||
'aio/content/guide/hydration.md',
|
||||
'aio/content/guide/signals.md',
|
||||
'aio/content/examples/injection-token/**/{*,.*}',
|
||||
'aio/content/guide/signals.md'
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -920,7 +919,13 @@ groups:
|
||||
'aio/content/guide/releases.md',
|
||||
'aio/content/guide/updating.md',
|
||||
'aio/content/guide/deprecations.md',
|
||||
'aio/content/guide/migration-legacy-message-id.md',
|
||||
'aio/content/examples/deprecation-guide/**/{*,.*}',
|
||||
'aio/content/guide/migration-renderer.md',
|
||||
'aio/content/guide/migration-undecorated-classes.md',
|
||||
'aio/content/guide/migration-dynamic-flag.md',
|
||||
'aio/content/guide/migration-injectable.md',
|
||||
'aio/content/guide/migration-localize.md',
|
||||
'aio/content/guide/migration-module-with-providers.md',
|
||||
'aio/content/guide/static-query-migration.md',
|
||||
'aio/content/guide/update-to-latest-version.md',
|
||||
@@ -1123,7 +1128,6 @@ groups:
|
||||
users:
|
||||
- AleksanderBodurri
|
||||
- devversion
|
||||
- dgp1130
|
||||
- josephperrott
|
||||
- mgechev
|
||||
- twerske
|
||||
|
||||
Vendored
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
// List of extensions which should be recommended for users of this workspace.
|
||||
"recommendations": [
|
||||
"BazelBuild.vscode-bazel",
|
||||
"devondcarew.bazel-code",
|
||||
"gkalpak.aio-docs-utils",
|
||||
"ms-vscode.vscode-typescript-tslint-plugin",
|
||||
"xaver.clang-format",
|
||||
|
||||
+46
-186
@@ -1,207 +1,32 @@
|
||||
<a name="16.2.12"></a>
|
||||
# 16.2.12 (2023-11-02)
|
||||
<a name="16.2.0-next.2"></a>
|
||||
# 16.2.0-next.2 (2023-07-13)
|
||||
### animations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [03f4050636](https://github.com/angular/angular/commit/03f4050636a385cf2e920b06e7ec94d6b5f32383) | fix | remove `finish` listener once player is destroyed ([#51136](https://github.com/angular/angular/pull/51136)) |
|
||||
| [a14bdfe859](https://github.com/angular/angular/commit/a14bdfe8591a33d359bf4940f4efa828499a6373) | fix | Ensure elements are removed from the cache after leave animation. ([#50929](https://github.com/angular/angular/pull/50929)) |
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e092184a5c](https://github.com/angular/angular/commit/e092184a5c3d98f4be329e4037c9039c1b420d75) | fix | apply fixed_srcset_width values only to fixed srcsets ([#52486](https://github.com/angular/angular/pull/52486)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [b3b4ae4c3a](https://github.com/angular/angular/commit/b3b4ae4c3ae5f307e68e3a57f84c9e2dfc9938fb) | fix | properly emit literal types in input coercion function arguments ([#52437](https://github.com/angular/angular/pull/52437)) |
|
||||
| [873c4f2454](https://github.com/angular/angular/commit/873c4f2454716520881f9d684364bdd6ab6ef722) | fix | use originally used module specifier for transform functions ([#52437](https://github.com/angular/angular/pull/52437)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.11"></a>
|
||||
# 16.2.11 (2023-10-25)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [54ea3b65c3](https://github.com/angular/angular/commit/54ea3b65c35254b220054541f2fbc52384486156) | fix | emit provider configured event when a service is configured with `providedIn` ([#52365](https://github.com/angular/angular/pull/52365)) |
|
||||
| [78533324dc](https://github.com/angular/angular/commit/78533324dcda2e884fbe489aaa6b37fa9a6fadbc) | fix | get root and platform injector providers in special cases ([#52365](https://github.com/angular/angular/pull/52365)) |
|
||||
| [019a0f4c22](https://github.com/angular/angular/commit/019a0f4c225d6bb6f741b37bf272b62899fe1f69) | fix | load global utils before creating platform injector in the standalone case ([#52365](https://github.com/angular/angular/pull/52365)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [b79b4aca91](https://github.com/angular/angular/commit/b79b4aca914aefda1605fc8d069ac8d84283f1b3) | fix | `RouterTestingHarness` should throw if a component is expected but navigation fails ([#52357](https://github.com/angular/angular/pull/52357)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.10"></a>
|
||||
# 16.2.10 (2023-10-18)
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.9"></a>
|
||||
# 16.2.9 (2023-10-11)
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [51a5baace3](https://github.com/angular/angular/commit/51a5baace3b1eee130fa911327773066139cc68e) | fix | reset() call with null values on nested group ([#48830](https://github.com/angular/angular/pull/48830)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.8"></a>
|
||||
# 16.2.8 (2023-10-04)
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [b732961fc3](https://github.com/angular/angular/commit/b732961fc3c6eec3cf5508330cc09d6a0a2d8f9a) | fix | Retain correct language service when `ts.Project` reloads ([#51912](https://github.com/angular/angular/pull/51912)) |
|
||||
### service-worker
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [966ce9790a](https://github.com/angular/angular/commit/966ce9790aa7c9414bcd35b49621f169d67b5669) | fix | throw a critical error when handleFetch fails ([#51960](https://github.com/angular/angular/pull/51960)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.7"></a>
|
||||
# 16.2.7 (2023-09-27)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [39a3e34e03](https://github.com/angular/angular/commit/39a3e34e035b324bfa1f1a11cf452272c91011c6) | fix | allow toSignal calls in reactive context ([#51831](https://github.com/angular/angular/pull/51831)) ([#51892](https://github.com/angular/angular/pull/51892)) |
|
||||
### service-worker
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c3d901eacf](https://github.com/angular/angular/commit/c3d901eacfe8d035441e5c990f6e6b2630d592f5) | fix | throw a critical error when `handleFetch` fails ([#51885](https://github.com/angular/angular/pull/51885)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.6"></a>
|
||||
# 16.2.6 (2023-09-20)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [82712f80df](https://github.com/angular/angular/commit/82712f80dfc6aed2baf8d8f80c3552a6707c88ff) | fix | ensure a consumer drops all its stale producers ([#51722](https://github.com/angular/angular/pull/51722)) ([#51772](https://github.com/angular/angular/pull/51772)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.5"></a>
|
||||
# 16.2.5 (2023-09-13)
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.4"></a>
|
||||
# 16.2.4 (2023-09-06)
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.3"></a>
|
||||
# 16.2.3 (2023-08-30)
|
||||
### animations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [04c6574280](https://github.com/angular/angular/commit/04c65742802537c8bd725f9a7a931955a67684d9) | fix | remove unnecessary escaping in regex expressions ([#51554](https://github.com/angular/angular/pull/51554)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [dbd761f528](https://github.com/angular/angular/commit/dbd761f528a08cba0fbdd476b115e1445683cf36) | fix | correct incomplete escaping ([#51557](https://github.com/angular/angular/pull/51557)) |
|
||||
| [5c36fc784f](https://github.com/angular/angular/commit/5c36fc784f292608f7485c5513aeb98e5745d17c) | fix | remove unnecessary escaping in regex expressions ([#51554](https://github.com/angular/angular/pull/51554)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [dcd1add06f](https://github.com/angular/angular/commit/dcd1add06f9facb87de89c144967cc95a2dac27c) | fix | correct incomplete escaping ([#51557](https://github.com/angular/angular/pull/51557)) |
|
||||
| [20d62603c2](https://github.com/angular/angular/commit/20d62603c2f86c810fda0b3b503327dce232a6d3) | fix | handle hydration of view containers that use component hosts as anchors ([#51456](https://github.com/angular/angular/pull/51456)) |
|
||||
| [e6b301caa2](https://github.com/angular/angular/commit/e6b301caa25c1532a4db2e8521bdea3f911316b1) | fix | remove unnecessary escaping in regex expressions ([#51554](https://github.com/angular/angular/pull/51554)) |
|
||||
| [0c7c852ee7](https://github.com/angular/angular/commit/0c7c852ee7ba3c1943cafce4c58760eef1b0aea4) | fix | run afterRender callbacks outside of the Angular zone ([#51551](https://github.com/angular/angular/pull/51551)) |
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [8081fdd22d](https://github.com/angular/angular/commit/8081fdd22d6889f92e11cbe4c53d80bddd496a9a) | fix | correct incomplete escaping ([#51557](https://github.com/angular/angular/pull/51557)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.2"></a>
|
||||
# 16.2.2 (2023-08-23)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [a43c0772ea](https://github.com/angular/angular/commit/a43c0772ea74410b0492a178c656268a465d3b09) | fix | Allow safeUrl for ngSrc in NgOptimizedImage ([#51351](https://github.com/angular/angular/pull/51351)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [39ace8664b](https://github.com/angular/angular/commit/39ace8664b843225a75dd706236ae13e171126d3) | fix | enforce a minimum version to be used when a library uses input transform ([#51413](https://github.com/angular/angular/pull/51413)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [36f434e49d](https://github.com/angular/angular/commit/36f434e49d24f0393950299486141a121d42e044) | fix | guard the jasmine hooks ([#51394](https://github.com/angular/angular/pull/51394)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [b0396e7164](https://github.com/angular/angular/commit/b0396e7164c08e01d24d2d8411edf1ccf4b52826) | fix | Ensure `canceledNavigationResolution: 'computed'` works on first page ([#51441](https://github.com/angular/angular/pull/51441)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.1"></a>
|
||||
# 16.2.1 (2023-08-16)
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [232a8c1b8d](https://github.com/angular/angular/commit/232a8c1b8dadf3f886b4bd0142613d116c865759) | fix | Apply named outlets to children empty paths not appearing in the URL ([#51292](https://github.com/angular/angular/pull/51292)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.0"></a>
|
||||
# 16.2.0 (2023-08-09)
|
||||
### benchpress
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [dd850b2ab7](https://github.com/angular/angular/commit/dd850b2ab781f24065550f8a948ced498e0f1e99) | fix | correctly report GC memory amounts ([#50760](https://github.com/angular/angular/pull/50760)) |
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [29d358170b](https://github.com/angular/angular/commit/29d358170b046f4a6773dfdfbbd1050f54deb301) | feat | add component input binding support for NgComponentOutlet ([#51148](https://github.com/angular/angular/pull/51148)) |
|
||||
| [1837efb9da](https://github.com/angular/angular/commit/1837efb9daf5c8e86a99a06ecc77bb42bc60dbb0) | feat | Allow ngSrc to be changed post-init ([#50683](https://github.com/angular/angular/pull/50683)) |
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c27a1e61d6](https://github.com/angular/angular/commit/c27a1e61d64a67aa169086f7db11bcfd5bb7d2fc) | feat | scope selectors in @scope queries ([#50747](https://github.com/angular/angular/pull/50747)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [12bad6576d](https://github.com/angular/angular/commit/12bad6576d2ffe4667118b214d9c7598ed3d8edb) | fix | libraries compiled with v16.1+ breaking with Angular framework v16.0.x ([#50714](https://github.com/angular/angular/pull/50714)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e53d4ecf4c](https://github.com/angular/angular/commit/e53d4ecf4cfd9e64d6ba8c8b19adbb7df9cfc047) | feat | add afterRender and afterNextRender ([#50607](https://github.com/angular/angular/pull/50607)) |
|
||||
| [98d262fd27](https://github.com/angular/angular/commit/98d262fd27795014ee3988b08d3c48a0dfb63c40) | feat | create injector debugging APIs ([#48639](https://github.com/angular/angular/pull/48639)) |
|
||||
| [cdaa2a8a9e](https://github.com/angular/angular/commit/cdaa2a8a9eab490b55bbb841ede4f54a2656df30) | feat | support Provider type in Injector.create ([#49587](https://github.com/angular/angular/pull/49587)) |
|
||||
| [9f490da7e2](https://github.com/angular/angular/commit/9f490da7e27e495cb45d2064af9091731422a6b1) | fix | handle hydration of view containers for root components ([#51247](https://github.com/angular/angular/pull/51247)) |
|
||||
### router
|
||||
| [031b599a55](https://github.com/angular/angular/commit/031b599a5528e1df5779695eb75b738a5a3076fe) | fix | ensure that standalone components get correct injector instances ([#50954](https://github.com/angular/angular/pull/50954)) |
|
||||
| [5d6ec0336b](https://github.com/angular/angular/commit/5d6ec0336bdea22735d0ca2bbd7cfad958efbdda) | fix | handle `deref` returning `null` on `RefactiveNode`. ([#50992](https://github.com/angular/angular/pull/50992)) |
|
||||
| [b66a16ec4c](https://github.com/angular/angular/commit/b66a16ec4cf42f47efeafa711ec301efeda272be) | fix | use `setTimeout` when coalescing tasks in Node.js ([#50820](https://github.com/angular/angular/pull/50820)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [0b14e4ef74](https://github.com/angular/angular/commit/0b14e4ef742b1c0f73d873e2c337683b60f46845) | feat | exposes the `fixture` of the `RouterTestingHarness` ([#50280](https://github.com/angular/angular/pull/50280)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.1.8"></a>
|
||||
# 16.1.8 (2023-08-02)
|
||||
### compiler
|
||||
| [f1b629961f](https://github.com/angular/angular/commit/f1b629961f75d535982a6196e70b82f177587ebf) | perf | do not remove renderer from cache when `REMOVE_STYLES_ON_COMPONENT_DESTROY` is enabled. ([#51005](https://github.com/angular/angular/pull/51005)) |
|
||||
### upgrade
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [cc722ea1f5](https://github.com/angular/angular/commit/cc722ea1f5b16f5a4fddc1ecd91b21b3005242ae) | fix | return full spans for Comment nodes ([#50855](https://github.com/angular/angular/pull/50855)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.1.7"></a>
|
||||
# 16.1.7 (2023-07-26)
|
||||
### http
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [916916d835](https://github.com/angular/angular/commit/916916d8357a3b045cbe6ec1b850c980be1bdb12) | fix | check whether `Zone` is defined ([#51119](https://github.com/angular/angular/pull/51119)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.1.6"></a>
|
||||
# 16.1.6 (2023-07-19)
|
||||
### http
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [dea8dc0378](https://github.com/angular/angular/commit/dea8dc0378c5b777b1879f22189fe32cbe61b36b) | fix | Run fetch request out the angular zone ([#50981](https://github.com/angular/angular/pull/50981)) |
|
||||
| [a19a87df6c](https://github.com/angular/angular/commit/a19a87df6c30a60ca997083b979a8e1e185e5b43) | fix | allow for downgraded components to work with component-router ([#50871](https://github.com/angular/angular/pull/50871)) |
|
||||
| [253d756464](https://github.com/angular/angular/commit/253d7564647607804d45404152d1253993177aea) | fix | Use `takeUntil` on leaky subscription. ([#50901](https://github.com/angular/angular/pull/50901)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
@@ -240,6 +65,28 @@
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.0-next.1"></a>
|
||||
# 16.2.0-next.1 (2023-06-28)
|
||||
### benchpress
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [dd850b2ab7](https://github.com/angular/angular/commit/dd850b2ab781f24065550f8a948ced498e0f1e99) | fix | correctly report GC memory amounts ([#50760](https://github.com/angular/angular/pull/50760)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [29340a0678](https://github.com/angular/angular/commit/29340a06789652e359e61b32f1814dcd20d9bd26) | fix | expose input transform function on ComponentFactory and ComponentMirror ([#50713](https://github.com/angular/angular/pull/50713)) |
|
||||
### elements
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d64864e95e](https://github.com/angular/angular/commit/d64864e95e193e46180aeaf0d634152327650871) | fix | support input transform functions ([#50713](https://github.com/angular/angular/pull/50713)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [2b55103e94](https://github.com/angular/angular/commit/2b55103e94578ab1cb765147077e82e1228b0dbb) | fix | wait until animation completion before destroying renderer ([#50677](https://github.com/angular/angular/pull/50677)) |
|
||||
| [0380564f85](https://github.com/angular/angular/commit/0380564f8562f5971cff671319439ad0f2b40a7e) | fix | wait until animation completion before destroying renderer ([#50860](https://github.com/angular/angular/pull/50860)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.1.3"></a>
|
||||
# 16.1.3 (2023-06-28)
|
||||
### core
|
||||
@@ -258,6 +105,19 @@
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.2.0-next.0"></a>
|
||||
# 16.2.0-next.0 (2023-06-21)
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [12bad6576d](https://github.com/angular/angular/commit/12bad6576d2ffe4667118b214d9c7598ed3d8edb) | fix | libraries compiled with v16.1+ breaking with Angular framework v16.0.x ([#50714](https://github.com/angular/angular/pull/50714)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [0b14e4ef74](https://github.com/angular/angular/commit/0b14e4ef742b1c0f73d873e2c337683b60f46845) | feat | exposes the `fixture` of the `RouterTestingHarness` ([#50280](https://github.com/angular/angular/pull/50280)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="16.1.2"></a>
|
||||
# 16.1.2 (2023-06-21)
|
||||
### http
|
||||
|
||||
+1
-1
@@ -109,7 +109,7 @@ Before you submit your Pull Request (PR) consider the following guidelines:
|
||||
```shell
|
||||
git commit --all
|
||||
```
|
||||
Note: the optional commit `--all` command line option will automatically "add" and "rm" edited files.
|
||||
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
|
||||
|
||||
10. Push your branch to GitHub:
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ Help us keep Angular open and inclusive. Please read and follow our [Code of Con
|
||||
|
||||
Join the conversation and help the community.
|
||||
|
||||
- [X (formerly Twitter)][X (formerly Twitter)]
|
||||
- [Twitter][twitter]
|
||||
- [Discord][discord]
|
||||
- [Gitter][gitter]
|
||||
- [YouTube][youtube]
|
||||
@@ -158,7 +158,7 @@ Join the conversation and help the community.
|
||||
[node.js]: https://nodejs.org/
|
||||
[npm]: https://www.npmjs.com/get-npm
|
||||
[codeofconduct]: CODE_OF_CONDUCT.md
|
||||
[X (formerly Twitter)]: https://www.twitter.com/angular
|
||||
[twitter]: https://www.twitter.com/angular
|
||||
[discord]: https://discord.gg/angular
|
||||
[gitter]: https://gitter.im/angular/angular
|
||||
[stackoverflow]: https://stackoverflow.com/questions/tagged/angular
|
||||
|
||||
@@ -64,7 +64,12 @@ load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")
|
||||
|
||||
nodejs_register_toolchains(
|
||||
name = "nodejs",
|
||||
node_version = "18.13.0",
|
||||
node_version = "16.14.0",
|
||||
)
|
||||
|
||||
nodejs_register_toolchains(
|
||||
name = "node18",
|
||||
node_version = "18.10.0",
|
||||
)
|
||||
|
||||
# Download npm dependencies.
|
||||
@@ -194,10 +199,10 @@ cldr_xml_data_repository(
|
||||
# sass rules
|
||||
http_archive(
|
||||
name = "io_bazel_rules_sass",
|
||||
sha256 = "7a90567717c3417a23ff4b21963a698a6e9aa669ac9e682121ea33f218a2816a",
|
||||
strip_prefix = "rules_sass-425ecafa8268bc013d684216363fe75bc802323e",
|
||||
sha256 = "4bb36a654166e1b629717e55a9c0cc30590f6615c122c054f38409c20ee5ec6f",
|
||||
strip_prefix = "rules_sass-f89fc59345a5074cf184ec215e9858152b7258e7",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/rules_sass/archive/425ecafa8268bc013d684216363fe75bc802323e.zip",
|
||||
"https://github.com/bazelbuild/rules_sass/archive/f89fc59345a5074cf184ec215e9858152b7258e7.zip",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -215,6 +215,7 @@
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": ["zone.js", "zone.js/testing"],
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"webWorkerTsConfig": "tsconfig.worker.json",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"branchName": "refs/heads/16.2.x",
|
||||
"sha": "36adedc25c729e418ce3984b9f94bc32a1ff8a38"
|
||||
"branchName": "refs/heads/main",
|
||||
"sha": "d29cbad7e25ed9114be351b9582eb8723db14773"
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"command": "ng build [project]",
|
||||
"shortDescription": "Compiles an Angular application or library into an output directory named dist/ at the given output path.",
|
||||
"longDescriptionRelativePath": "@angular/cli/src/commands/build/long-description.md",
|
||||
"longDescription": "The command can be used to build a project of type \"application\" or \"library\".\nWhen used to build a library, a different builder is invoked, and only the `ts-config`, `configuration`, and `watch` options are applied.\nAll other options apply only to building applications.\n\nThe application builder uses the [webpack](https://webpack.js.org/) build tool, with default configuration options specified in the workspace configuration file (`angular.json`) or with a named alternative configuration.\nA \"development\" configuration is created by default when you use the CLI to create the project, and you can use that configuration by specifying the `--configuration development`.\n\nThe configuration options generally correspond to the command options.\nYou can override individual configuration defaults by specifying the corresponding options on the command line.\nThe command can accept option names given in dash-case.\nNote that in the configuration file, you must specify names in camelCase.\n\nSome additional options can only be set through the configuration file,\neither by direct editing or with the `ng config` command.\nThese include `assets`, `styles`, and `scripts` objects that provide runtime-global resources to include in the project.\nResources in CSS, such as images and fonts, are automatically written and fingerprinted at the root of the output folder.\n\nFor further details, see [Workspace Configuration](guide/workspace-config).\n",
|
||||
"longDescription": "The command can be used to build a project of type \"application\" or \"library\".\nWhen used to build a library, a different builder is invoked, and only the `ts-config`, `configuration`, and `watch` options are applied.\nAll other options apply only to building applications.\n\nThe application builder uses the [webpack](https://webpack.js.org/) build tool, with default configuration options specified in the workspace configuration file (`angular.json`) or with a named alternative configuration.\nA \"development\" configuration is created by default when you use the CLI to create the project, and you can use that configuration by specifying the `--configuration development`.\n\nThe configuration options generally correspond to the command options.\nYou can override individual configuration defaults by specifying the corresponding options on the command line.\nThe command can accept option names given in either dash-case or camelCase.\nNote that in the configuration file, you must specify names in camelCase.\n\nSome additional options can only be set through the configuration file,\neither by direct editing or with the `ng config` command.\nThese include `assets`, `styles`, and `scripts` objects that provide runtime-global resources to include in the project.\nResources in CSS, such as images and fonts, are automatically written and fingerprinted at the root of the output folder.\n\nFor further details, see [Workspace Configuration](guide/workspace-config).\n",
|
||||
"aliases": [
|
||||
"b"
|
||||
],
|
||||
@@ -160,7 +160,7 @@
|
||||
{
|
||||
"name": "output-path",
|
||||
"type": "string",
|
||||
"description": "The full path for the new output directory, relative to the current workspace."
|
||||
"description": "The full path for the new output directory, relative to the current workspace.\nBy default, writes output to a folder named dist/ in the current project."
|
||||
},
|
||||
{
|
||||
"name": "poll",
|
||||
|
||||
@@ -19,4 +19,4 @@
|
||||
"positional": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
{
|
||||
"name": "from",
|
||||
"type": "string",
|
||||
"description": "Version from which to migrate from. Only available when a single package is updated, and only with 'migrate-only'."
|
||||
"description": "Version from which to migrate from. Only available with a single package being updated, and only with 'migrate-only'."
|
||||
},
|
||||
{
|
||||
"name": "help",
|
||||
@@ -46,7 +46,7 @@
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"description": "The name of the migration to run. Only available when a single package is updated."
|
||||
"description": "The name of the migration to run. Only available with a single package being updated, and only with 'migrate-only' option."
|
||||
},
|
||||
{
|
||||
"name": "next",
|
||||
@@ -71,7 +71,7 @@
|
||||
{
|
||||
"name": "to",
|
||||
"type": "string",
|
||||
"description": "Version up to which to apply migrations. Only available when a single package is updated, and only with 'migrate-only' option. Requires 'from' to be specified. Default to the installed version detected."
|
||||
"description": "Version up to which to apply migrations. Only available with a single package being updated, and only with 'migrate-only' option. Requires 'from' to be specified. Default to the installed version detected."
|
||||
},
|
||||
{
|
||||
"name": "verbose",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<title>Your first Angular app</title>
|
||||
</head>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
@name HTML content was altered after server-side rendering
|
||||
@category runtime
|
||||
@shortDescription HTML content was altered after server-side rendering
|
||||
|
||||
@description
|
||||
Angular throws this error when it detects that the content generated by server-side rendering (SSR) was altered after the rendering. The process of hydration relies on the content to be untouched after SSR, which also includes whitespaces and comment nodes. Those whitespaces and comment nodes must be retained in the HTML generated by the SSR process. Learn more in the [Hydration guide](guide/hydration#constraints).
|
||||
|
||||
@debugging
|
||||
|
||||
Typically this happens in the following cases:
|
||||
* Some CDN providers have a built-in feature to remove whitespaces and comment nodes from HTML as an optimization. Please verify if there is such an option in CDN configuration and turn it off.
|
||||
* If you use custom post-processing of HTML generated by SSR (as a build step), make sure that this process doesn't remove whitespaces and comment nodes.
|
||||
@@ -3,9 +3,9 @@
|
||||
@shortDescription Root element was not found during bootstrap.
|
||||
|
||||
@description
|
||||
Bootstrapped components are defined in the `bootstrap` property of an `@NgModule` decorator or as the first parameter of `bootstrapApplication` for standalone components.
|
||||
Boostraped components are defined in the `bootstrap` property of an `@NgModule` decorator or as the first parameter of `boopstrapApplication` for standalone components.
|
||||
|
||||
This error happens when Angular tries to bootstrap one of these components but cannot find its corresponding node in the DOM.
|
||||
This error happens when Angular tries to boostrap one of these components but cannot find its corresponing node in the DOM.
|
||||
|
||||
@debugging
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<h1>Accessibility Example</h1>
|
||||
<!-- #docregion template -->
|
||||
<label for="progress-value">
|
||||
<label>
|
||||
Enter an example progress value
|
||||
<input id="progress-value" type="number" min="0" max="100"
|
||||
<input type="number" min="0" max="100"
|
||||
[value]="progress" (input)="setProgress($event)">
|
||||
</label>
|
||||
|
||||
|
||||
Executable → Regular
Executable → Regular
-1
@@ -1,7 +1,6 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-about',
|
||||
templateUrl: './about.component.html',
|
||||
styleUrls: ['./about.component.css']
|
||||
|
||||
Executable → Regular
+10
-10
@@ -31,15 +31,15 @@ export const slideInAnimation =
|
||||
// #docregion query
|
||||
query(':enter', [
|
||||
style({ left: '-100%' })
|
||||
], { optional: true }),
|
||||
query(':leave', animateChild(), { optional: true }),
|
||||
]),
|
||||
query(':leave', animateChild()),
|
||||
group([
|
||||
query(':leave', [
|
||||
animate('300ms ease-out', style({ left: '100%' }))
|
||||
], { optional: true }),
|
||||
]),
|
||||
query(':enter', [
|
||||
animate('300ms ease-out', style({ left: '0%' }))
|
||||
], { optional: true }),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
transition('* <=> *', [
|
||||
@@ -51,19 +51,19 @@ export const slideInAnimation =
|
||||
left: 0,
|
||||
width: '100%'
|
||||
})
|
||||
], { optional: true }),
|
||||
]),
|
||||
query(':enter', [
|
||||
style({ left: '-100%' })
|
||||
], { optional: true }),
|
||||
query(':leave', animateChild(), { optional: true }),
|
||||
]),
|
||||
query(':leave', animateChild()),
|
||||
group([
|
||||
query(':leave', [
|
||||
animate('200ms ease-out', style({ left: '100%', opacity: 0 }))
|
||||
], { optional: true }),
|
||||
]),
|
||||
query(':enter', [
|
||||
animate('300ms ease-out', style({ left: '0%' }))
|
||||
], { optional: true }),
|
||||
query('@*', animateChild(), { optional: true })
|
||||
]),
|
||||
query('@*', animateChild())
|
||||
]),
|
||||
])
|
||||
// #enddocregion query
|
||||
|
||||
Executable → Regular
-1
@@ -2,7 +2,6 @@
|
||||
import { Component, HostBinding } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-root',
|
||||
templateUrl: 'app.component.html',
|
||||
styleUrls: ['app.component.css'],
|
||||
|
||||
Executable → Regular
+1
-3
@@ -11,16 +11,14 @@ import {
|
||||
} from '@angular/animations';
|
||||
|
||||
// #enddocregion imports
|
||||
import { ChildrenOutletContexts, RouterLink, RouterOutlet } from '@angular/router';
|
||||
import { ChildrenOutletContexts, RouterOutlet } from '@angular/router';
|
||||
import { slideInAnimation } from './animations';
|
||||
|
||||
// #docregion decorator, toggle-app-animations, define
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-root',
|
||||
templateUrl: 'app.component.html',
|
||||
styleUrls: ['app.component.css'],
|
||||
imports: [RouterLink, RouterOutlet],
|
||||
animations: [
|
||||
// #enddocregion decorator
|
||||
slideInAnimation
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import { ApplicationConfig } from '@angular/core';
|
||||
import { routes } from './app.routes';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { provideProtractorTestingSupport } from '@angular/platform-browser';
|
||||
import { provideAnimations } from '@angular/platform-browser/animations';
|
||||
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
// needed for supporting e2e tests
|
||||
provideProtractorTestingSupport(),
|
||||
provideRouter(routes),
|
||||
provideAnimations(),
|
||||
]
|
||||
};
|
||||
+70
-31
@@ -1,73 +1,112 @@
|
||||
import { Routes } from '@angular/router';
|
||||
// #docregion route-animation-data
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { AppComponent } from './app.component';
|
||||
import { OpenCloseComponent } from './open-close.component';
|
||||
import { OpenClosePageComponent } from './open-close-page.component';
|
||||
import { StatusSliderPageComponent } from './status-slider-page.component';
|
||||
import { OpenCloseChildComponent } from './open-close.component.4';
|
||||
import { ToggleAnimationsPageComponent } from './toggle-animations-page.component';
|
||||
import { StatusSliderComponent } from './status-slider.component';
|
||||
import { StatusSliderPageComponent } from './status-slider-page.component';
|
||||
import { HeroListPageComponent } from './hero-list-page.component';
|
||||
import { HeroListGroupPageComponent } from './hero-list-group-page.component';
|
||||
import { HeroListGroupsComponent } from './hero-list-groups.component';
|
||||
import { HeroListEnterLeavePageComponent } from './hero-list-enter-leave-page.component';
|
||||
import { HeroListEnterLeaveComponent } from './hero-list-enter-leave.component';
|
||||
import { HeroListAutoCalcPageComponent } from './hero-list-auto-page.component';
|
||||
import { InsertRemoveComponent } from './insert-remove.component';
|
||||
import { QueryingComponent } from './querying.component';
|
||||
import { HeroListAutoComponent } from './hero-list-auto.component';
|
||||
import { HomeComponent } from './home.component';
|
||||
import { AboutComponent } from './about.component';
|
||||
import { InsertRemoveComponent } from './insert-remove.component';
|
||||
import { QueryingComponent } from './querying.component';
|
||||
|
||||
// #docregion route-animation-data
|
||||
export const routes: Routes = [
|
||||
{ path: '', pathMatch: 'full', redirectTo: '/enter-leave' },
|
||||
{
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
RouterModule.forRoot([
|
||||
{ path: '', pathMatch: 'full', redirectTo: '/enter-leave' },
|
||||
{
|
||||
path: 'open-close',
|
||||
component: OpenClosePageComponent,
|
||||
data: { animation: 'openClosePage' }
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
path: 'status',
|
||||
component: StatusSliderPageComponent,
|
||||
data: { animation: 'statusPage' }
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
path: 'toggle',
|
||||
component: ToggleAnimationsPageComponent,
|
||||
data: { animation: 'togglePage' }
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
path: 'heroes',
|
||||
component: HeroListPageComponent,
|
||||
data: { animation: 'filterPage' }
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
path: 'hero-groups',
|
||||
component: HeroListGroupPageComponent,
|
||||
data: { animation: 'heroGroupPage' }
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
path: 'enter-leave',
|
||||
component: HeroListEnterLeavePageComponent,
|
||||
data: { animation: 'enterLeavePage' }
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
path: 'auto',
|
||||
component: HeroListAutoCalcPageComponent,
|
||||
data: { animation: 'autoPage' }
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
path: 'insert-remove',
|
||||
component: InsertRemoveComponent,
|
||||
data: { animation: 'insertRemovePage' }
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
path: 'querying',
|
||||
component: QueryingComponent,
|
||||
data: { animation: 'queryingPage' }
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
path: 'home',
|
||||
component: HomeComponent,
|
||||
data: { animation: 'HomePage' }
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
path: 'about',
|
||||
component: AboutComponent,
|
||||
data: { animation: 'AboutPage' }
|
||||
},
|
||||
];
|
||||
// #enddocregion route-animation-data
|
||||
},
|
||||
])
|
||||
],
|
||||
// #enddocregion route-animation-data
|
||||
declarations: [
|
||||
AppComponent,
|
||||
StatusSliderComponent,
|
||||
OpenCloseComponent,
|
||||
OpenCloseChildComponent,
|
||||
OpenClosePageComponent,
|
||||
StatusSliderPageComponent,
|
||||
ToggleAnimationsPageComponent,
|
||||
HeroListPageComponent,
|
||||
HeroListGroupsComponent,
|
||||
HeroListGroupPageComponent,
|
||||
HeroListEnterLeavePageComponent,
|
||||
HeroListEnterLeaveComponent,
|
||||
HeroListAutoCalcPageComponent,
|
||||
HeroListAutoComponent,
|
||||
HomeComponent,
|
||||
InsertRemoveComponent,
|
||||
QueryingComponent,
|
||||
AboutComponent
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
Executable → Regular
+1
-4
@@ -1,9 +1,7 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { HEROES } from './mock-heroes';
|
||||
import { HeroListAutoComponent } from './hero-list-auto.component';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-hero-list-auto-page',
|
||||
template: `
|
||||
<section>
|
||||
@@ -11,8 +9,7 @@ import { HeroListAutoComponent } from './hero-list-auto.component';
|
||||
|
||||
<app-hero-list-auto [heroes]="heroes" (remove)="onRemove($event)"></app-hero-list-auto>
|
||||
</section>
|
||||
`,
|
||||
imports: [HeroListAutoComponent]
|
||||
`
|
||||
})
|
||||
export class HeroListAutoCalcPageComponent {
|
||||
heroes = HEROES.slice();
|
||||
|
||||
Executable → Regular
-3
@@ -13,14 +13,11 @@ import {
|
||||
} from '@angular/animations';
|
||||
|
||||
import { Hero } from './hero';
|
||||
import { NgFor } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-hero-list-auto',
|
||||
templateUrl: 'hero-list-auto.component.html',
|
||||
styleUrls: ['./hero-list-page.component.css'],
|
||||
imports: [NgFor],
|
||||
// #docregion auto-calc
|
||||
animations: [
|
||||
trigger('shrinkOut', [
|
||||
|
||||
Executable → Regular
+1
-4
@@ -1,9 +1,7 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { HEROES } from './mock-heroes';
|
||||
import { HeroListEnterLeaveComponent } from './hero-list-enter-leave.component';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-hero-list-enter-leave-page',
|
||||
template: `
|
||||
<section>
|
||||
@@ -11,8 +9,7 @@ import { HeroListEnterLeaveComponent } from './hero-list-enter-leave.component';
|
||||
|
||||
<app-hero-list-enter-leave [heroes]="heroes" (remove)="onRemove($event)"></app-hero-list-enter-leave>
|
||||
</section>
|
||||
`,
|
||||
imports: [HeroListEnterLeaveComponent]
|
||||
`
|
||||
})
|
||||
export class HeroListEnterLeavePageComponent {
|
||||
heroes = HEROES.slice();
|
||||
|
||||
Executable → Regular
-3
@@ -13,10 +13,8 @@ import {
|
||||
} from '@angular/animations';
|
||||
|
||||
import { Hero } from './hero';
|
||||
import { NgFor } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-hero-list-enter-leave',
|
||||
template: `
|
||||
<ul class="heroes">
|
||||
@@ -30,7 +28,6 @@ import { NgFor } from '@angular/common';
|
||||
</ul>
|
||||
`,
|
||||
styleUrls: ['./hero-list-page.component.css'],
|
||||
imports: [NgFor],
|
||||
// #docregion animationdef
|
||||
animations: [
|
||||
trigger('flyInOut', [
|
||||
|
||||
Executable → Regular
+1
-4
@@ -1,9 +1,7 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { HEROES } from './mock-heroes';
|
||||
import { HeroListGroupsComponent } from './hero-list-groups.component';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-hero-list-groups-page',
|
||||
template: `
|
||||
<section>
|
||||
@@ -11,8 +9,7 @@ import { HeroListGroupsComponent } from './hero-list-groups.component';
|
||||
|
||||
<app-hero-list-groups [heroes]="heroes" (remove)="onRemove($event)"></app-hero-list-groups>
|
||||
</section>
|
||||
`,
|
||||
imports: [HeroListGroupsComponent]
|
||||
`
|
||||
})
|
||||
export class HeroListGroupPageComponent {
|
||||
heroes = HEROES.slice();
|
||||
|
||||
Executable → Regular
-3
@@ -14,10 +14,8 @@ import {
|
||||
} from '@angular/animations';
|
||||
|
||||
import { Hero } from './hero';
|
||||
import { NgFor } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-hero-list-groups',
|
||||
template: `
|
||||
<ul class="heroes">
|
||||
@@ -30,7 +28,6 @@ import { NgFor } from '@angular/common';
|
||||
</ul>
|
||||
`,
|
||||
styleUrls: ['./hero-list-page.component.css'],
|
||||
imports: [NgFor],
|
||||
// #docregion animationdef
|
||||
animations: [
|
||||
trigger('flyInOut', [
|
||||
|
||||
Executable → Regular
-3
@@ -4,13 +4,10 @@ import { Component, HostBinding, OnInit } from '@angular/core';
|
||||
import { trigger, transition, animate, style, query, stagger } from '@angular/animations';
|
||||
import { HEROES } from './mock-heroes';
|
||||
import { Hero } from './hero';
|
||||
import { NgFor } from '@angular/common';
|
||||
|
||||
// #docregion filter-animations
|
||||
@Component({
|
||||
// #enddocregion filter-animations
|
||||
standalone: true,
|
||||
imports: [NgFor],
|
||||
selector: 'app-hero-list-page',
|
||||
templateUrl: 'hero-list-page.component.html',
|
||||
styleUrls: ['hero-list-page.component.css'],
|
||||
|
||||
Executable → Regular
-1
@@ -1,7 +1,6 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-home',
|
||||
templateUrl: './home.component.html',
|
||||
styleUrls: ['./home.component.css']
|
||||
|
||||
Executable → Regular
-3
@@ -1,12 +1,9 @@
|
||||
// #docplaster
|
||||
import { Component } from '@angular/core';
|
||||
import { trigger, transition, animate, style } from '@angular/animations';
|
||||
import { NgIf } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-insert-remove',
|
||||
imports: [NgIf],
|
||||
animations: [
|
||||
// #docregion enter-leave-trigger
|
||||
trigger('myInsertRemoveTrigger', [
|
||||
|
||||
Executable → Regular
+1
-4
@@ -1,8 +1,6 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { OpenCloseComponent } from './open-close.component';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-open-close-page',
|
||||
template: `
|
||||
<section>
|
||||
@@ -12,8 +10,7 @@ import { OpenCloseComponent } from './open-close.component';
|
||||
|
||||
<app-open-close [logging]="logging"></app-open-close>
|
||||
</section>
|
||||
`,
|
||||
imports: [OpenCloseComponent]
|
||||
`
|
||||
})
|
||||
export class OpenClosePageComponent {
|
||||
logging = false;
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Component } from '@angular/core';
|
||||
import { trigger, transition, state, animate, style, keyframes } from '@angular/animations';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-open-close',
|
||||
animations: [
|
||||
// #docregion trigger
|
||||
@@ -12,7 +11,7 @@ import { trigger, transition, state, animate, style, keyframes } from '@angular/
|
||||
opacity: 1,
|
||||
backgroundColor: 'yellow'
|
||||
})),
|
||||
state('closed', style({
|
||||
state('close', style({
|
||||
height: '100px',
|
||||
opacity: 0.5,
|
||||
backgroundColor: 'green'
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Component } from '@angular/core';
|
||||
import { trigger, transition, state, animate, style } from '@angular/animations';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-open-close-boolean',
|
||||
// #docregion trigger-boolean
|
||||
animations: [
|
||||
|
||||
Executable → Regular
-1
@@ -5,7 +5,6 @@ import { transition, trigger, useAnimation } from '@angular/animations';
|
||||
import { transitionAnimation } from './animations';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-open-close-reusable',
|
||||
animations: [
|
||||
trigger('openClose', [
|
||||
|
||||
Executable → Regular
-1
@@ -6,7 +6,6 @@ import { trigger, transition, state, animate, style } from '@angular/animations'
|
||||
// #docregion toggle-animation
|
||||
@Component({
|
||||
// #enddocregion toggle-animation
|
||||
standalone: true,
|
||||
selector: 'app-open-close-toggle',
|
||||
templateUrl: 'open-close.component.4.html',
|
||||
styleUrls: ['open-close.component.css'],
|
||||
|
||||
Executable → Regular
-1
@@ -4,7 +4,6 @@ import { trigger, transition, state, animate, style, AnimationEvent } from '@ang
|
||||
|
||||
// #docregion component, events1
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-open-close',
|
||||
// #docregion trigger-wildcard1, trigger-transition
|
||||
animations: [
|
||||
|
||||
Executable → Regular
-3
@@ -13,10 +13,8 @@ import {
|
||||
} from '@angular/animations';
|
||||
|
||||
import { HEROES } from './mock-heroes';
|
||||
import { NgIf } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-querying',
|
||||
template: `
|
||||
<nav>
|
||||
@@ -33,7 +31,6 @@ import { NgIf } from '@angular/common';
|
||||
</section>
|
||||
`,
|
||||
styleUrls: ['./querying.component.css'],
|
||||
imports: [NgIf],
|
||||
animations: [
|
||||
trigger('query', [
|
||||
transition(':enter', [
|
||||
|
||||
Executable → Regular
+1
-4
@@ -1,15 +1,12 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { StatusSliderComponent } from './status-slider.component';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-status-slider-page',
|
||||
template: `
|
||||
<section>
|
||||
<h2>Status Slider</h2>
|
||||
<app-status-slider></app-status-slider>
|
||||
</section>
|
||||
`,
|
||||
imports: [StatusSliderComponent]
|
||||
`
|
||||
})
|
||||
export class StatusSliderPageComponent {}
|
||||
|
||||
Executable → Regular
-1
@@ -2,7 +2,6 @@ import { Component } from '@angular/core';
|
||||
import { trigger, transition, state, animate, style, keyframes } from '@angular/animations';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-status-slider',
|
||||
templateUrl: 'status-slider.component.html',
|
||||
styleUrls: ['status-slider.component.css'],
|
||||
|
||||
Executable → Regular
+1
-4
@@ -1,8 +1,6 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { OpenCloseChildComponent } from './open-close.component.4';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-toggle-animations-child-page',
|
||||
template: `
|
||||
<section>
|
||||
@@ -10,7 +8,6 @@ import { OpenCloseChildComponent } from './open-close.component.4';
|
||||
|
||||
<app-open-close-toggle></app-open-close-toggle>
|
||||
</section>
|
||||
`,
|
||||
imports: [OpenCloseChildComponent]
|
||||
`
|
||||
})
|
||||
export class ToggleAnimationsPageComponent {}
|
||||
|
||||
Executable → Regular
+5
-4
@@ -1,5 +1,6 @@
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { appConfig } from './app/app.config';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
bootstrapApplication(AppComponent, appConfig);
|
||||
import { AppModule } from './app/app.module';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
.catch(err => console.error(err));
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
<h2>HTML attributes and DOM properties</h2>
|
||||
<p>1. Use the inspector to see the HTML attribute and DOM property values. Click the buttons to log values to the console.</p>
|
||||
|
||||
<label for="html-attr">HTML Attribute Initializes to "Sarah":
|
||||
<input id="html-attr" type="text" value="Sarah" #bindingInput></label>
|
||||
<label>HTML Attribute Initializes to "Sarah":
|
||||
<input type="text" value="Sarah" #bindingInput></label>
|
||||
<div>
|
||||
<button type="button" (click)="getHTMLAttributeValue()">Get HTML attribute value</button> Won't change.
|
||||
</div>
|
||||
|
||||
@@ -83,9 +83,9 @@
|
||||
|
||||
|
||||
<br>
|
||||
<label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |
|
||||
<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |
|
||||
<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label>
|
||||
<label>italic: <input type="checkbox" [(ngModel)]="canSave"></label> |
|
||||
<label>normal: <input type="checkbox" [(ngModel)]="isUnchanged"></label> |
|
||||
<label>xlarge: <input type="checkbox" [(ngModel)]="isSpecial"></label>
|
||||
<button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button>
|
||||
<br><br>
|
||||
<div [ngStyle]="currentStyles">
|
||||
@@ -215,8 +215,8 @@
|
||||
|
||||
<p>Pick your favorite item</p>
|
||||
<div>
|
||||
<label for="item-{{i}}" *ngFor="let i of items">
|
||||
<div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{i.name}}
|
||||
<label *ngFor="let i of items">
|
||||
<div><input type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{i.name}}
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,22 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { SubmitButtonComponent } from './submit-button/submit-button.component';
|
||||
|
||||
// #docregion lazyload-syntax, lazyload-deprecated-syntax
|
||||
const routes: Routes = [{
|
||||
path: 'lazy',
|
||||
// #enddocregion lazyload-deprecated-syntax
|
||||
// The new import() syntax
|
||||
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
|
||||
// #enddocregion lazyload-syntax
|
||||
/*
|
||||
// #docregion lazyload-deprecated-syntax
|
||||
// The following string syntax for loadChildren is deprecated
|
||||
loadChildren: './lazy/lazy.module#LazyModule',
|
||||
// #enddocregion lazyload-deprecated-syntax
|
||||
*/
|
||||
// #docregion lazyload-syntax, lazyload-deprecated-syntax
|
||||
}];
|
||||
// #enddocregion lazyload-syntax, lazyload-deprecated-syntax
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
@@ -15,6 +31,7 @@ import { SubmitButtonComponent } from './submit-button/submit-button.component';
|
||||
// #docregion reactive-form-no-warning
|
||||
imports: [
|
||||
// #enddocregion reactive-form-no-warning
|
||||
RouterModule.forChild(routes),
|
||||
FormsModule,
|
||||
BrowserModule,
|
||||
// #docregion reactive-form-no-warning
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
<h2>{{selectedHero.name}} details!</h2>
|
||||
<div>id: {{selectedHero.id}}</div>
|
||||
<div>
|
||||
<label for="name">
|
||||
name: <input id="name" [(ngModel)]="selectedHero.name" placeholder="name"/>
|
||||
<label>
|
||||
name: <input [(ngModel)]="selectedHero.name" placeholder="name"/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -67,7 +67,6 @@ EXAMPLES = {
|
||||
"http": {"stackblitz": True, "zip": True},
|
||||
"i18n": {"stackblitz": True, "zip": True},
|
||||
"inputs-outputs": {"stackblitz": True, "zip": True},
|
||||
"injection-token": {"stackblitz": False, "zip": False},
|
||||
"interpolation": {"stackblitz": True, "zip": True},
|
||||
"lazy-loading-ngmodules": {"stackblitz": True, "zip": True},
|
||||
"lifecycle-hooks": {"stackblitz": True, "zip": True},
|
||||
@@ -132,6 +131,7 @@ def docs_example(name, test = True, test_tags = [], test_exec_properties = {}, f
|
||||
native.filegroup(
|
||||
name = "files",
|
||||
srcs = native.glob(["**"], exclude = [
|
||||
"BUILD.bazel",
|
||||
"**/node_modules/**", # Node modules may exist from the legacy setup.
|
||||
]),
|
||||
)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Hero Form with Validation</title>
|
||||
|
||||
@@ -3,18 +3,9 @@ import { Component } from '@angular/core';
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
template: `
|
||||
<label for="showHeroes">
|
||||
<input id="showHeroes" type="checkbox" [checked]="showHeroes" (change)="showHeroes=!showHeroes">
|
||||
Heroes
|
||||
</label>
|
||||
<label for="showVillains">
|
||||
<input id="showVillains" type="checkbox" [checked]="showVillains" (change)="showVillains=!showVillains">
|
||||
Villains
|
||||
</label>
|
||||
<label for="showCars">
|
||||
<input id="showCars" type="checkbox" [checked]="showCars" (change)="showCars=!showCars">
|
||||
Cars
|
||||
</label>
|
||||
<label><input type="checkbox" [checked]="showHeroes" (change)="showHeroes=!showHeroes">Heroes</label>
|
||||
<label><input type="checkbox" [checked]="showVillains" (change)="showVillains=!showVillains">Villains</label>
|
||||
<label><input type="checkbox" [checked]="showCars" (change)="showCars=!showCars">Cars</label>
|
||||
|
||||
<h1>Hierarchical Dependency Injection</h1>
|
||||
|
||||
|
||||
+2
-6
@@ -1,22 +1,18 @@
|
||||
<div class="tax-return">
|
||||
<div class="msg" [class.canceled]="message==='Canceled'">{{message}}</div>
|
||||
<fieldset>
|
||||
<legend>Tax Return</legend>
|
||||
<span id=name>{{taxReturn.name}}</span>
|
||||
<span id=tid>TID: {{taxReturn.tid}}</span>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Tax Return</legend>
|
||||
<label for="income">
|
||||
Income: <input id="income" [(ngModel)]="taxReturn.income" class="num">
|
||||
<label>
|
||||
Income: <input [(ngModel)]="taxReturn.income" class="num">
|
||||
</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Tax Return</legend>
|
||||
<span>Tax: {{taxReturn.tax}}</span>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Tax Return</legend>
|
||||
<button type="button" (click)="onSaved()">Save</button>
|
||||
<button type="button" (click)="onCanceled()">Cancel</button>
|
||||
<button type="button" (click)="onClose()">Close</button>
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
<h1>HttpClient Example</h1>
|
||||
<div class="checkboxes">
|
||||
<label for="showHeroes">
|
||||
<input id="showHeroes" type="checkbox" [checked]="showHeroes" (click)="toggleHeroes()">
|
||||
<label>
|
||||
<input type="checkbox" [checked]="showHeroes" (click)="toggleHeroes()">
|
||||
Heroes
|
||||
</label>
|
||||
|
||||
<label for="showConfig">
|
||||
<input id="showConfig" type="checkbox" [checked]="showConfig" (click)="toggleConfig()">
|
||||
<label>
|
||||
<input type="checkbox" [checked]="showConfig" (click)="toggleConfig()">
|
||||
Config
|
||||
</label>
|
||||
|
||||
<label for="showDownloader">
|
||||
<input id="showDownloader" type="checkbox" [checked]="showDownloader" (click)="toggleDownloader()">
|
||||
<label>
|
||||
<input type="checkbox" [checked]="showDownloader" (click)="toggleDownloader()">
|
||||
Downloader
|
||||
</label>
|
||||
|
||||
<label for="showUploader">
|
||||
<input id="showUploader" type="checkbox" [checked]="showUploader" (click)="toggleUploader()">
|
||||
<label>
|
||||
<input type="checkbox" [checked]="showUploader" (click)="toggleUploader()">
|
||||
Uploader
|
||||
</label>
|
||||
|
||||
<label for="showSearch">
|
||||
<input id="showSearch" type="checkbox" id="search" [checked]="showSearch" (click)="toggleSearch()">
|
||||
<label>
|
||||
<input type="checkbox" id="search" [checked]="showSearch" (click)="toggleSearch()">
|
||||
Search
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!-- #docregion -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>Angular i18n example</title>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
load("//aio/content/examples:examples.bzl", "docs_example")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
docs_example(
|
||||
name = "injection-token",
|
||||
)
|
||||
@@ -1,9 +0,0 @@
|
||||
/*
|
||||
* This example project is special in that it is not a cli app. To run tests appropriate for this
|
||||
* project, the test command is overwritten in `aio/content/examples/injection-token/example-config.json`.
|
||||
*
|
||||
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.mjs` runs
|
||||
* tests for this project.
|
||||
*
|
||||
* TODO: Fix our infrastructure/tooling, so that this hack is not necessary.
|
||||
*/
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"tests": [
|
||||
{
|
||||
"cmd": "yarn",
|
||||
"args": [ "tsc", "--project", "./tsconfig.app.json" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
// TODO: Add unit tests for this file.
|
||||
/* eslint-disable @angular-eslint/no-output-native */
|
||||
// #docregion
|
||||
import {Injector, InjectionToken} from '@angular/core';
|
||||
|
||||
interface MyInterface {
|
||||
someProperty: string;
|
||||
}
|
||||
|
||||
// #docregion InjectionToken
|
||||
|
||||
const TOKEN = new InjectionToken<MyInterface>('SomeToken');
|
||||
|
||||
// Setting up the provider using the same token instance
|
||||
const providers = [
|
||||
{provide: TOKEN, useValue: {someProperty: 'exampleValue'}}, // Mock value for MyInterface
|
||||
];
|
||||
|
||||
// Creating the injector with the provider
|
||||
const injector = Injector.create({providers});
|
||||
|
||||
// Retrieving the value using the same token instance
|
||||
const myInterface = injector.get(TOKEN);
|
||||
// myInterface is inferred to be MyInterface.
|
||||
|
||||
// #enddocregion InjectionToken
|
||||
@@ -3,11 +3,6 @@
|
||||
<!-- #docregion input-parent -->
|
||||
<app-item-detail [item]="currentItem"></app-item-detail>
|
||||
<!-- #enddocregion input-parent -->
|
||||
|
||||
<!-- #docregion input-parent-metadata -->
|
||||
<app-item-detail-metadata [item]="currentItem" [itemAvailability]="true"></app-item-detail-metadata>
|
||||
<!-- #enddocregion input-parent-metadata -->
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- #docregion output-parent -->
|
||||
|
||||
@@ -8,7 +8,6 @@ import { ItemOutputComponent } from './item-output/item-output.component';
|
||||
import { InputOutputComponent } from './input-output/input-output.component';
|
||||
import { InTheMetadataComponent } from './in-the-metadata/in-the-metadata.component';
|
||||
import { AliasingComponent } from './aliasing/aliasing.component';
|
||||
import { ItemDetailMetadataComponent } from './item-details-metadata/item-details-metadata.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
@@ -18,8 +17,7 @@ import { ItemDetailMetadataComponent } from './item-details-metadata/item-detail
|
||||
ItemOutputComponent,
|
||||
InputOutputComponent,
|
||||
InTheMetadataComponent,
|
||||
AliasingComponent,
|
||||
ItemDetailMetadataComponent
|
||||
AliasingComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule
|
||||
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
<h2>Child component with @Input() metadata configurations</h2>
|
||||
|
||||
<p>
|
||||
Today's item: {{item}}
|
||||
Item's Availability: {{itemAvailability}}
|
||||
</p>
|
||||
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion use-input-metadata-required
|
||||
import { Component, Input } from '@angular/core'; // First, import Input
|
||||
// #enddocregion use-input-metadata-required
|
||||
// #docregion use-input-metadata-boolean-transform
|
||||
import { booleanAttribute } from '@angular/core'; // First, import booleanAttribute
|
||||
// #enddocregion use-input-metadata-boolean-transform
|
||||
@Component({
|
||||
selector: 'app-item-detail-metadata',
|
||||
templateUrl: './item-details-metadata.component.html'
|
||||
})
|
||||
|
||||
|
||||
export class ItemDetailMetadataComponent {
|
||||
// #docregion use-input-metadata-required
|
||||
@Input({required: true}) item!: string; // Second, decorate the property with required metadata
|
||||
// #enddocregion use-input-metadata-required
|
||||
|
||||
// #docregion use-input-metadata-boolean-transform
|
||||
@Input({transform: booleanAttribute}) itemAvailability!: boolean; // Second, decorate the property with transform
|
||||
// #enddocregion use-input-metadata-boolean-transform
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@
|
||||
<div (keyup)="0">
|
||||
<h4>Template context: template reference variables (#customerInput):</h4>
|
||||
<!-- #docregion template-reference-variable -->
|
||||
<label for="customer-input">Type something:
|
||||
<input id="customer-input" #customerInput>{{customerInput.value}}
|
||||
<label>Type something:
|
||||
<input #customerInput>{{customerInput.value}}
|
||||
</label>
|
||||
<!-- #enddocregion template-reference-variable -->
|
||||
</div>
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
<h4>#3 <ng-container> and <p></h4>
|
||||
<p>
|
||||
<label for="showId"><input id="showId" type="checkbox" [checked]="showId" (change)="showId=!showId">Show ID</label>
|
||||
<label><input type="checkbox" [checked]="showId" (change)="showId=!showId">Show ID</label>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
@@ -113,10 +113,7 @@
|
||||
<p><em><select> with <span></em></p>
|
||||
<div>
|
||||
Pick your favorite hero
|
||||
(<label for="favorite-hero">
|
||||
<input id="favorite-hero" type="checkbox" checked (change)="showSad=!showSad">
|
||||
show sad
|
||||
</label>)
|
||||
(<label><input type="checkbox" checked (change)="showSad=!showSad">show sad</label>)
|
||||
</div>
|
||||
<select [(ngModel)]="hero">
|
||||
<span *ngFor="let h of heroes">
|
||||
@@ -129,7 +126,7 @@
|
||||
<p><em><select> with <ng-container></em></p>
|
||||
<div>
|
||||
Pick your favorite hero
|
||||
(<label for="show-sad"><input id="show-sad" type="checkbox" checked (change)="showSad=!showSad">show sad</label>)
|
||||
(<label><input type="checkbox" checked (change)="showSad=!showSad">show sad</label>)
|
||||
</div>
|
||||
<select [(ngModel)]="hero">
|
||||
<ng-container *ngFor="let h of heroes">
|
||||
@@ -143,8 +140,8 @@
|
||||
|
||||
<h4>#2 <ng-container> and <options></h4>
|
||||
<p>
|
||||
<label for="default-traits" (change)="traitPicker.value=showDefaultTraits ? 'loyal' : heroTraits[0]">
|
||||
<input id="default-traits" type="checkbox"
|
||||
<label (change)="traitPicker.value=showDefaultTraits ? 'loyal' : heroTraits[0]">
|
||||
<input type="checkbox"
|
||||
[checked]="showDefaultTraits"
|
||||
(change)="showDefaultTraits=!showDefaultTraits">Show default traits
|
||||
</label>
|
||||
@@ -182,18 +179,9 @@
|
||||
|
||||
<h4><ng-container> and <table></h4>
|
||||
<p>
|
||||
<label for="attrDirs">
|
||||
<input id="attrDirs" type="checkbox" checked (change)="attrDirs=!attrDirs">
|
||||
Attribute directives
|
||||
</label>
|
||||
<label for="strucDirs">
|
||||
<input id="strucDirs" type="checkbox" checked (change)="strucDirs=!strucDirs">
|
||||
Structural directives
|
||||
</label>
|
||||
<label for="divNgIf">
|
||||
<input id="divNgIf" type="checkbox" (change)="divNgIf=!divNgIf">
|
||||
div with *ngIf
|
||||
</label>
|
||||
<label><input type="checkbox" checked (change)="attrDirs=!attrDirs">Attribute directives</label>
|
||||
<label><input type="checkbox" checked (change)="strucDirs=!strucDirs">Structural directives</label>
|
||||
<label><input type="checkbox" (change)="divNgIf=!divNgIf">div with *ngIf</label>
|
||||
</p>
|
||||
|
||||
<table>
|
||||
|
||||
@@ -9,8 +9,8 @@ import { Customer,
|
||||
<h3 highlight>Customer Detail</h3>
|
||||
<div *ngIf="customer">
|
||||
<div>Id: {{customer.id}}</div><br>
|
||||
<label for="name">Name:
|
||||
<input id="name" [(ngModel)]="customer.name">
|
||||
<label>Name:
|
||||
<input [(ngModel)]="customer.name">
|
||||
</label>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>NgmodulesExample</title>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Providers</title>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>DI Resolution Modifiers Example</title>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-compose-message',
|
||||
@@ -12,7 +12,7 @@ export class ComposeMessageComponent {
|
||||
message = '';
|
||||
sending = false;
|
||||
|
||||
constructor(private router: Router, private route: ActivatedRoute) {}
|
||||
constructor(private router: Router) {}
|
||||
|
||||
send() {
|
||||
this.sending = true;
|
||||
@@ -32,7 +32,7 @@ export class ComposeMessageComponent {
|
||||
closePopup() {
|
||||
// Providing a `null` value to the named outlet
|
||||
// clears the contents of the named outlet
|
||||
this.router.navigate([{outlets: {popup: null}}], {relativeTo: this.route.parent});
|
||||
this.router.navigate([{ outlets: { popup: null }}]);
|
||||
}
|
||||
// #enddocregion closePopup
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>Angular App</title>
|
||||
@@ -7,4 +6,4 @@
|
||||
<body>
|
||||
<app-root>loading</app-root>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -30,6 +30,6 @@ describe('Security E2E Tests', () => {
|
||||
|
||||
it('binds trusted resource URLs', async () => {
|
||||
const iframe = element(By.className('e2e-iframe-trusted-src'));
|
||||
expect(await iframe.getAttribute('src')).toMatch(/^https:\/\/www\.youtube\.com\//);
|
||||
expect(await iframe.getAttribute('src')).toMatch(/^https:\/\/www.youtube.com\//);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<title>Angular Quickstart Seed</title>
|
||||
<base href="/">
|
||||
|
||||
@@ -72,11 +72,11 @@
|
||||
and continued on my way.
|
||||
</p>
|
||||
|
||||
<p><em><select> with <span></em></p>
|
||||
<p><i><select> with <span></i></p>
|
||||
|
||||
<div>
|
||||
Pick your favorite hero
|
||||
(<label for="show-sad"><input id="show-sad" type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
|
||||
(<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
|
||||
</div>
|
||||
<select [(ngModel)]="hero">
|
||||
<span *ngFor="let h of heroes">
|
||||
@@ -86,11 +86,11 @@
|
||||
</span>
|
||||
</select>
|
||||
|
||||
<p><em><select> with <ng-container></em></p>
|
||||
<p><i><select> with <ng-container></i></p>
|
||||
<!-- #docregion select-ngcontainer -->
|
||||
<div>
|
||||
Pick your favorite hero
|
||||
(<label for="showSad"><input id="showSad" type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
|
||||
(<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
|
||||
</div>
|
||||
<select [(ngModel)]="hero">
|
||||
<ng-container *ngFor="let h of heroes">
|
||||
@@ -134,10 +134,10 @@
|
||||
|
||||
<div>Pick your favorite hero</div>
|
||||
<p>
|
||||
<label for="hero-{{h}}" *ngFor="let h of heroes">
|
||||
<input id="hero-{{h}}" type="radio" name="heroes" [(ngModel)]="hero" [value]="h">{{h.name}}
|
||||
<label *ngFor="let h of heroes">
|
||||
<input type="radio" name="heroes" [(ngModel)]="hero" [value]="h">{{h.name}}
|
||||
</label>
|
||||
<label for="none-of-the-above"><input id="none-of-the-above" type="radio" name="heroes" (click)="hero = null">None of the above</label>
|
||||
<label><input type="radio" name="heroes" (click)="hero = null">None of the above</label>
|
||||
</p>
|
||||
|
||||
<h4>NgSwitch</h4>
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
|
||||
// #enddocregion no-docs
|
||||
*
|
||||
* If the expression assigned to `appUnless` evaluates to a truthy value
|
||||
* then the templated elements are removed from the DOM,
|
||||
* then the templated elements are removed removed from the DOM,
|
||||
* the templated elements are (re)inserted into the DOM.
|
||||
*
|
||||
* <div *appUnless="errorCount" class="success">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Template Expression Operators Example</title>
|
||||
|
||||
@@ -350,7 +350,7 @@ button</button>
|
||||
<div id="two-way-1">
|
||||
<app-sizer [(size)]="fontSizePx"></app-sizer>
|
||||
<div [style.font-size.px]="fontSizePx">Resizable Text</div>
|
||||
<label for="font-size">FontSize (px): <input id="font-size" [(ngModel)]="fontSizePx"></label>
|
||||
<label>FontSize (px): <input [(ngModel)]="fontSizePx"></label>
|
||||
</div>
|
||||
<br>
|
||||
<div id="two-way-2">
|
||||
@@ -393,9 +393,9 @@ without NgModel
|
||||
|
||||
<!-- not used in chapter -->
|
||||
<br>
|
||||
<label for="canSave">saveable <input type="checkbox" id="canSave" [(ngModel)]="canSave"></label> |
|
||||
<label for="isUnchanged">modified: <input type="checkbox" id="isUnchanged" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged"></label> |
|
||||
<label for="isSpecial">special: <input type="checkbox" id="isSpecial" [(ngModel)]="isSpecial"></label>
|
||||
<label>saveable <input type="checkbox" [(ngModel)]="canSave"></label> |
|
||||
<label>modified: <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged"></label> |
|
||||
<label>special: <input type="checkbox" [(ngModel)]="isSpecial"></label>
|
||||
<button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button>
|
||||
<br><br>
|
||||
<div [ngClass]="currentClasses">
|
||||
@@ -426,9 +426,9 @@ without NgModel
|
||||
|
||||
<!-- not used in chapter -->
|
||||
<br>
|
||||
<label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |
|
||||
<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |
|
||||
<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label>
|
||||
<label>italic: <input type="checkbox" [(ngModel)]="canSave"></label> |
|
||||
<label>normal: <input type="checkbox" [(ngModel)]="isUnchanged"></label> |
|
||||
<label>xlarge: <input type="checkbox" [(ngModel)]="isSpecial"></label>
|
||||
<button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button>
|
||||
<br><br>
|
||||
<div [ngStyle]="currentStyles">
|
||||
@@ -551,8 +551,8 @@ without NgModel
|
||||
|
||||
<p>Pick your favorite hero</p>
|
||||
<div>
|
||||
<label for="hero-{{h}}" *ngFor="let h of heroes">
|
||||
<input id="hero-{{h}}" type="radio" name="heroes" [(ngModel)]="currentHero" [value]="h">{{h.name}}
|
||||
<label *ngFor="let h of heroes">
|
||||
<input type="radio" name="heroes" [(ngModel)]="currentHero" [value]="h">{{h.name}}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -273,7 +273,7 @@ export class NeedsContentComponent {
|
||||
template: `
|
||||
<h4>MyIfChildComp</h4>
|
||||
<div>
|
||||
<label for="child-value">Child value: <input id="child-value" [(ngModel)]="childValue"> </label>
|
||||
<label>Child value: <input [(ngModel)]="childValue"> </label>
|
||||
</div>
|
||||
<p><i>Change log:</i></p>
|
||||
<div *ngFor="let log of changeLog; let i=index">{{i + 1}} - {{log}}</div>`
|
||||
@@ -322,8 +322,8 @@ export class MyIfChildComponent implements OnInit, OnChanges, OnDestroy {
|
||||
selector: 'my-if-parent-comp',
|
||||
template: `
|
||||
<h3>MyIfParentComp</h3>
|
||||
<label for="parent">Parent value:
|
||||
<input id="parent" [(ngModel)]="parentValue">
|
||||
<label>Parent value:
|
||||
<input [(ngModel)]="parentValue">
|
||||
</label>
|
||||
<button type="button" (click)="clicked()">{{toggleLabel}} Child</button><br>
|
||||
<div *ngIf="showChild"
|
||||
|
||||
@@ -74,7 +74,7 @@ function selectHeroTests() {
|
||||
it(`has selected ${targetHero.name}`, async () => {
|
||||
const page = getPageElts();
|
||||
const expectedText = `${targetHero.id} ${targetHero.name}`;
|
||||
expect((await page.selected.getText()).replace(/\n/g, ' ')).toBe(expectedText);
|
||||
expect((await page.selected.getText()).replace('\n', ' ')).toBe(expectedText);
|
||||
});
|
||||
|
||||
it('shows selected hero details', async () => {
|
||||
@@ -101,7 +101,7 @@ function updateHeroTests() {
|
||||
|
||||
it(`shows updated hero name in list`, async () => {
|
||||
const page = getPageElts();
|
||||
const hero = Hero.fromString((await page.selected.getText()).replace(/\n/g, ' '));
|
||||
const hero = Hero.fromString((await page.selected.getText()).replace('\n', ' '));
|
||||
const newName = targetHero.name + nameSuffix;
|
||||
expect(hero.id).toEqual(targetHero.id);
|
||||
expect(hero.name).toEqual(newName);
|
||||
|
||||
@@ -74,7 +74,7 @@ function selectHeroTests() {
|
||||
it(`has selected ${targetHero.name}`, async () => {
|
||||
const page = getPageElts();
|
||||
const expectedText = `${targetHero.id} ${targetHero.name}`;
|
||||
expect((await page.selected.getText()).replace(/\n/g, ' ')).toBe(expectedText);
|
||||
expect((await page.selected.getText()).replace('\n', ' ')).toBe(expectedText);
|
||||
});
|
||||
|
||||
it('shows selected hero details', async () => {
|
||||
@@ -101,7 +101,7 @@ function updateHeroTests() {
|
||||
|
||||
it(`shows updated hero name in list`, async () => {
|
||||
const page = getPageElts();
|
||||
const hero = Hero.fromString(await (await page.selected.getText()).replace(/\n/g, ' '));
|
||||
const hero = Hero.fromString(await (await page.selected.getText()).replace('\n', ' '));
|
||||
const newName = targetHero.name + nameSuffix;
|
||||
expect(hero.id).toEqual(targetHero.id);
|
||||
expect(hero.name).toEqual(newName);
|
||||
|
||||
@@ -74,7 +74,7 @@ function selectHeroTests() {
|
||||
it(`has selected ${targetHero.name}`, async () => {
|
||||
const page = getPageElts();
|
||||
const expectedText = `${targetHero.id} ${targetHero.name}`;
|
||||
expect((await page.selected.getText()).replace(/\n/g, ' ')).toBe(expectedText);
|
||||
expect((await page.selected.getText()).replace('\n', ' ')).toBe(expectedText);
|
||||
});
|
||||
|
||||
it('shows selected hero details', async () => {
|
||||
@@ -106,7 +106,7 @@ function updateHeroTests() {
|
||||
|
||||
it(`shows updated hero name in list`, async () => {
|
||||
const page = getPageElts();
|
||||
const hero = Hero.fromString((await page.selected.getText()).replace(/\n/g, ' '));
|
||||
const hero = Hero.fromString((await page.selected.getText()).replace('\n', ' '));
|
||||
const newName = targetHero.name + nameSuffix;
|
||||
expect(hero.id).toEqual(targetHero.id);
|
||||
expect(hero.name).toEqual(newName);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<!-- #enddocregion two-way-syntax-->
|
||||
<div [style.font-size.px]="fontSizePx">Resizable Text</div>
|
||||
<!-- #enddocregion two-way-1 -->
|
||||
<label for="font-size">FontSize (px): <input id="font-size" [(ngModel)]="fontSizePx"></label>
|
||||
<label>FontSize (px): <input [(ngModel)]="fontSizePx"></label>
|
||||
</div>
|
||||
<br>
|
||||
<div id="two-way-2">
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<h2>{{hero.name | uppercase}} Details</h2>
|
||||
<div><span>id: </span>{{hero.id}}</div>
|
||||
<div>
|
||||
<label for="name">name:
|
||||
<input id="name" [(ngModel)]="hero.name" placeholder="name"/>
|
||||
<label>name:
|
||||
<input [(ngModel)]="hero.name" placeholder="name"/>
|
||||
</label>
|
||||
</div>
|
||||
<button type="button" (click)="goBack()">go back</button>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user