mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
Compare commits
229 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f6c229f755 | |||
| 9361f091cc | |||
| eac94f0945 | |||
| b0892c0cfa | |||
| 16eda01be0 | |||
| b09686923b | |||
| 78781a998d | |||
| 6336b8e5b3 | |||
| 10de52887b | |||
| 6f1c941dfe | |||
| 9bce9ce89e | |||
| 8227eb914e | |||
| 23003f817f | |||
| d98ce5ed4f | |||
| cff1c5622f | |||
| 6efa366e2c | |||
| ad9d98146e | |||
| 8390e12bdd | |||
| 43bbaf810d | |||
| 6842bf0515 | |||
| f261fa7c08 | |||
| d29883adff | |||
| de67c9fd01 | |||
| 9a8ef7cc28 | |||
| 4e1d825d83 | |||
| 356c521195 | |||
| 9a7eba2352 | |||
| e16dab82a1 | |||
| 913bbba42b | |||
| c7e5cb0371 | |||
| aa616db24f | |||
| de9290096c | |||
| 2c7d96afcb | |||
| 8bf3b53a1d | |||
| 56ca7d385b | |||
| e8fd452bd2 | |||
| 71ff12c1cc | |||
| 82d772857c | |||
| 2bebaa99cf | |||
| 8907fbbfed | |||
| 84b4ad812b | |||
| 76c6dca93f | |||
| 85546594a5 | |||
| 55b8c4f701 | |||
| 1e6f700b7d | |||
| 01fde59dd9 | |||
| a4debf14e3 | |||
| c6e64aa8ad | |||
| 7379d75782 | |||
| 21a51fb6a4 | |||
| b39db80f91 | |||
| 3b86dda068 | |||
| 64da1daa78 | |||
| d388522745 | |||
| 4f1870362e | |||
| 6c906a5bb9 | |||
| 6c61d20476 | |||
| e914da145b | |||
| 6550c59df5 | |||
| 032276253f | |||
| d607d0b93c | |||
| c02e4d72bc | |||
| 4d2ef0f5df | |||
| 1a4b489692 | |||
| cbd23ee0de | |||
| 5d08390584 | |||
| 9b1d3d2fce | |||
| f71eb58036 | |||
| f7a2dd88aa | |||
| 031e23b06a | |||
| 5b0980f050 | |||
| 54d09a6bc0 | |||
| 782f678236 | |||
| 62cec95981 | |||
| 2ec696a50f | |||
| 119fbddb83 | |||
| e8e09d3455 | |||
| d7c20c8886 | |||
| 3e1fad406a | |||
| aeeb1b55d3 | |||
| 331383b39b | |||
| 0050b01b62 | |||
| e632fd1f0f | |||
| 128038e486 | |||
| 42c8533f42 | |||
| 2cc8fb0a08 | |||
| 4013db6fd2 | |||
| 95ee74a66c | |||
| a782be62e9 | |||
| dc4115d7ed | |||
| d8a18717da | |||
| dd177e2c18 | |||
| 0b8208690c | |||
| 7af1f0a265 | |||
| d0b88a6810 | |||
| fd860e3ef7 | |||
| a01ae487d7 | |||
| 3769de2caa | |||
| 835b326759 | |||
| 92cf9fbebe | |||
| 09f0254bdd | |||
| 7b9490ad64 | |||
| f0e82c8af4 | |||
| 7a47add255 | |||
| 7bc4dbd7ff | |||
| d40ac2056e | |||
| 1368f58b49 | |||
| b75e90f809 | |||
| 3919ee37cf | |||
| 37af6abb49 | |||
| 604a67f0a1 | |||
| baf0c7a11a | |||
| cd97d8793f | |||
| 3fae6637e7 | |||
| 30d1c34384 | |||
| 1384013a00 | |||
| 9327e97500 | |||
| 59a6ec4396 | |||
| 1b216297f4 | |||
| a89805c3ae | |||
| f092badb9c | |||
| d27015a43c | |||
| b9aee9070c | |||
| 5fdd8ae3ba | |||
| b2f474c4c9 | |||
| 38b042b6d0 | |||
| 48262bcb70 | |||
| fb3c0b2605 | |||
| fecd4f8eab | |||
| 9cce12cbf5 | |||
| b9aab0c87b | |||
| 123f42c744 | |||
| 64adfc9150 | |||
| 7924a2e497 | |||
| 98a1da9382 | |||
| 165aa4f164 | |||
| 4a5ad1793f | |||
| d65a42b183 | |||
| dee108b67c | |||
| 5a75721835 | |||
| ec49796807 | |||
| b4e4617807 | |||
| 812c1ba971 | |||
| 1cc1588c29 | |||
| b6d2212ce5 | |||
| a432ad65c7 | |||
| 96b3b774c3 | |||
| 365962948a | |||
| 577d97f757 | |||
| 36b16e667a | |||
| 2916ac9e1a | |||
| 4644886aaf | |||
| f5ce6cfa1e | |||
| 7ec482d9c2 | |||
| 98ba48eedf | |||
| 1aebbf8714 | |||
| 250dc40a46 | |||
| 8fb2e3b71f | |||
| 626980f3eb | |||
| 5400a3d88a | |||
| e07014f3d9 | |||
| 85b889e6fb | |||
| 881d4696a2 | |||
| 07185f4ed1 | |||
| 0778e6f7d7 | |||
| 25f8305195 | |||
| b51d111d72 | |||
| 72cdd1403b | |||
| c1fc425cd1 | |||
| e62c98f2aa | |||
| 47c02caa29 | |||
| 94c9e47dbe | |||
| 6b7fffcbeb | |||
| 641f27a9c9 | |||
| ab63ed3448 | |||
| b89ee0819b | |||
| 553c8d1366 | |||
| f398717502 | |||
| c9abf34d88 | |||
| 96d2c58647 | |||
| 49ca5bb1d8 | |||
| f6c2934f5b | |||
| 1169fae366 | |||
| 522b845bec | |||
| 2fa2f7d34a | |||
| af19c440e2 | |||
| 9f7157e560 | |||
| 30ddeabca6 | |||
| 4a91d9b0a0 | |||
| fcc6528159 | |||
| dc0cac235f | |||
| de1e35b944 | |||
| a38ae0aefa | |||
| fe3e4d6865 | |||
| 6cb7c3ebe3 | |||
| 966343bb92 | |||
| 7e93513425 | |||
| 7c7a1a1724 | |||
| 62217efb7e | |||
| 1fa14e0c84 | |||
| a71eb4c18e | |||
| ffd62b9f11 | |||
| e545dd8130 | |||
| 4883b7d9c7 | |||
| 8eb1f76341 | |||
| 37bbd97d6e | |||
| 9e9e82d7c7 | |||
| e12dfa535b | |||
| fa7c7afbe9 | |||
| a4aa9b3c28 | |||
| 40f27a31d2 | |||
| 94bfcdd9de | |||
| f0a8303abe | |||
| abd1bc8039 | |||
| 7316e72ec5 | |||
| ac2f262e9a | |||
| f2fa67eb0b | |||
| 9bee561956 | |||
| fce521e4d2 | |||
| ade305757b | |||
| ed67a074ce | |||
| 43eb934e6b | |||
| d2ae96f742 | |||
| 5626b34264 | |||
| 1671212a55 | |||
| 100091ebf0 | |||
| b7ff6f06de | |||
| 6b75263303 | |||
| caeb162513 |
+43
-15
@@ -5,37 +5,65 @@
|
||||
.git
|
||||
node_modules
|
||||
dist
|
||||
aio/content
|
||||
aio/node_modules
|
||||
aio/tools/examples/shared/node_modules
|
||||
aio/tools/examples/shared/example-scaffold
|
||||
packages/bazel/node_modules
|
||||
|
||||
# All integration test node_modules folders
|
||||
integration/animations/node_modules
|
||||
integration/bazel_workspace_tests/bazel_ngtsc_plugin/node_modules
|
||||
integration/cli-elements-universal/node_modules
|
||||
integration/cli-hello-world/node_modules
|
||||
integration/cli-hello-world-ivy-compat/node_modules
|
||||
integration/cli-hello-world-ivy-i18n/node_modules
|
||||
integration/cli-hello-world-ivy-minimal/node_modules
|
||||
integration/cli-hello-world-lazy/node_modules
|
||||
integration/cli-hello-world-mocha/node_modules
|
||||
integration/cli-signal-inputs/node_modules
|
||||
integration/defer/node_modules
|
||||
integration/dynamic-compiler/node_modules
|
||||
integration/forms/node_modules
|
||||
integration/hello_world__closure/node_modules
|
||||
integration/hello_world__systemjs_umd/node_modules
|
||||
integration/i18n/node_modules
|
||||
integration/injectable-def/node_modules
|
||||
integration/ivy-i18n/node_modules
|
||||
integration/ng-add-localize/node_modules
|
||||
integration/trusted-types/node_modules
|
||||
integration/forms/node_modules
|
||||
integration/ng_elements/node_modules
|
||||
integration/ng_elements_schematics/node_modules
|
||||
integration/ng_update/node_modules
|
||||
integration/ng_update_migrations/node_modules
|
||||
integration/nodenext_resolution/node_modules
|
||||
integration/npm_package_archives.bzl/node_modules
|
||||
integration/ngcc/node_modules
|
||||
integration/platform-server/node_modules
|
||||
integration/service-worker-schema/node_modules
|
||||
integration/side-effects/node_modules
|
||||
integration/standalone-bootstrap/node_modules
|
||||
integration/terser/node_modules
|
||||
integration/trusted-types/node_modules
|
||||
integration/typings_test_rxjs7/node_modules
|
||||
integration/typings_test_ts49/node_modules
|
||||
integration/typings_test_ts50/node_modules
|
||||
integration/typings_test_ts51/node_modules
|
||||
integration/typings_test_ts52/node_modules
|
||||
integration/typings_test_ts36/node_modules
|
||||
integration/typings_test_ts37/node_modules
|
||||
|
||||
# All integration test .yarn_local_cache folders
|
||||
integration/bazel_workspace_tests/bazel_ngtsc_plugin/.yarn_local_cache
|
||||
integration/cli-elements-universal/.yarn_local_cache
|
||||
integration/cli-hello-world/.yarn_local_cache
|
||||
integration/cli-hello-world-ivy-compat/.yarn_local_cache
|
||||
integration/cli-hello-world-ivy-i18n/.yarn_local_cache
|
||||
integration/cli-hello-world-ivy-minimal/.yarn_local_cache
|
||||
integration/cli-hello-world-lazy/.yarn_local_cache
|
||||
integration/dynamic-compiler/.yarn_local_cache
|
||||
integration/hello_world__closure/.yarn_local_cache
|
||||
integration/hello_world__systemjs_umd/.yarn_local_cache
|
||||
integration/i18n/.yarn_local_cache
|
||||
integration/injectable-def/.yarn_local_cache
|
||||
integration/ivy-i18n/.yarn_local_cache
|
||||
integration/ng-add-localize/.yarn_local_cache
|
||||
integration/trusted-types/.yarn_local_cache
|
||||
integration/forms/.yarn_local_cache
|
||||
integration/ng_elements/.yarn_local_cache
|
||||
integration/ng_elements_schematics/.yarn_local_cache
|
||||
integration/ng_update/.yarn_local_cache
|
||||
integration/ng_update_migrations/.yarn_local_cache
|
||||
integration/ngcc/.yarn_local_cache
|
||||
integration/platform-server/.yarn_local_cache
|
||||
integration/service-worker-schema/.yarn_local_cache
|
||||
integration/side-effects/.yarn_local_cache
|
||||
integration/terser/.yarn_local_cache
|
||||
integration/typings_test_ts36/.yarn_local_cache
|
||||
integration/typings_test_ts37/.yarn_local_cache
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
# Enable debugging tests with --config=debug
|
||||
test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test_strategy=exclusive --test_timeout=9999 --nocache_test_results --spawn_strategy=local
|
||||
|
||||
# Do not attempt to de-flake locally.
|
||||
# On CI we might set this to `3` to run with deflaking.
|
||||
test --flaky_test_attempts=1
|
||||
test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test_strategy=exclusive --test_timeout=9999 --nocache_test_results
|
||||
|
||||
###############################
|
||||
# Filesystem interactions #
|
||||
@@ -42,8 +38,6 @@ test --incompatible_strict_action_env
|
||||
# and https://github.com/bazelbuild/bazel/commit/03246077f948f2790a83520e7dccc2625650e6df
|
||||
build --nobuild_runfile_links
|
||||
|
||||
build --enable_runfiles
|
||||
|
||||
###############################
|
||||
# Release support #
|
||||
# Turn on these settings with #
|
||||
@@ -56,31 +50,9 @@ build --enable_runfiles
|
||||
build:release --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=release"
|
||||
build:release --stamp
|
||||
|
||||
# Building AIO against local Angular deps requires stamping
|
||||
# versions in Angular packages due to CLI version checks.
|
||||
build:aio_local_deps --stamp
|
||||
build:aio_local_deps --workspace_status_command="yarn -s --cwd aio local-workspace-status"
|
||||
|
||||
# Snapshots should also be stamped with version control information.
|
||||
build:snapshot-build --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=snapshot"
|
||||
build:snapshot-build --stamp
|
||||
|
||||
##########################################################
|
||||
# AIO architect build configuration #
|
||||
# See aio/angular.json for available configurations. #
|
||||
# To build with a partiular configuration: #
|
||||
# bazel build //aio:build --aio_build_config=<config> #
|
||||
# Default config is `stable``. #
|
||||
##########################################################
|
||||
build --flag_alias=aio_build_config=//aio:flag_aio_build_config
|
||||
|
||||
####################################
|
||||
# AIO first party dep substitution #
|
||||
# Turn on with #
|
||||
# --config=aio_local_deps #
|
||||
####################################
|
||||
|
||||
build:aio_local_deps --//aio:flag_aio_local_deps
|
||||
build:snapshot --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=snapshot"
|
||||
build:snapshot --stamp
|
||||
|
||||
###############################
|
||||
# Output #
|
||||
@@ -112,55 +84,28 @@ build:remote --define=EXECUTOR=remote
|
||||
# Set a higher timeout value, just in case.
|
||||
build:remote --remote_timeout=600
|
||||
|
||||
# Bazel detects maximum number of jobs based on host resources.
|
||||
# Since we run remotely, we can increase this number significantly.
|
||||
common:remote --jobs=200
|
||||
|
||||
# Increase the default number of jobs by 50% because our build has lots of
|
||||
# parallelism
|
||||
build:remote --jobs=150
|
||||
build:remote --google_default_credentials
|
||||
|
||||
# Limit the number of test jobs for on an AIO local deps build. The example tests running
|
||||
# concurrently pushes the circleci executor RAM usage to its limits.
|
||||
test:aio_local_deps --jobs=24
|
||||
|
||||
# Force remote exeuctions to consider the entire run as linux
|
||||
build:remote --cpu=k8
|
||||
build:remote --host_cpu=k8
|
||||
|
||||
# Toolchain and platform related flags
|
||||
build:remote --crosstool_top=@npm//@angular/build-tooling/bazel/remote-execution/cpp:cc_toolchain_suite
|
||||
build:remote --extra_toolchains=@npm//@angular/build-tooling/bazel/remote-execution/cpp:cc_toolchain
|
||||
build:remote --extra_execution_platforms=@npm//@angular/build-tooling/bazel/remote-execution:platform
|
||||
build:remote --host_platform=@npm//@angular/build-tooling/bazel/remote-execution:platform
|
||||
build:remote --platforms=@npm//@angular/build-tooling/bazel/remote-execution:platform
|
||||
build:remote --crosstool_top=@npm//@angular/dev-infra-private/bazel/remote-execution/cpp:cc_toolchain_suite
|
||||
build:remote --extra_toolchains=@npm//@angular/dev-infra-private/bazel/remote-execution/cpp:cc_toolchain
|
||||
build:remote --extra_execution_platforms=@npm//@angular/dev-infra-private/bazel/remote-execution:platform
|
||||
build:remote --host_platform=@npm//@angular/dev-infra-private/bazel/remote-execution:platform
|
||||
build:remote --platforms=@npm//@angular/dev-infra-private/bazel/remote-execution:platform
|
||||
|
||||
# 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
|
||||
common --experimental_allow_tags_propagation
|
||||
|
||||
# Disable network access in the sandbox by default. To enable network access
|
||||
# for a particular target, use:
|
||||
#
|
||||
# load("@npm//@angular/build-tooling/bazel/remote-execution:index.bzl", "ENABLE_NETWORK")
|
||||
# my_target(
|
||||
# ...,
|
||||
# exec_properties = ENABLE_NETWORK, # Enables network in remote exec
|
||||
# tags = ["requires-network"] # Enables network in sandbox
|
||||
# )
|
||||
build --nosandbox_default_allow_network
|
||||
|
||||
##################################
|
||||
# Saucelabs tests settings #
|
||||
# Turn on these settings with #
|
||||
@@ -177,9 +122,16 @@ test:saucelabs --flaky_test_attempts=1
|
||||
|
||||
# --ng_perf will ask the Ivy compiler to produce performance results for each build.
|
||||
build --flag_alias=ng_perf=//packages/compiler-cli:ng_perf
|
||||
# --adev_fast will run adev build/serve in a faster mode, skipping things like prerendering
|
||||
# for local development.
|
||||
build --flag_alias=fast_adev=//adev:fast_build_mode
|
||||
|
||||
#####################################################################
|
||||
# Folders to ignore for integration tests (nested Bazel workspaces) #
|
||||
#####################################################################
|
||||
|
||||
# The nested Bazel integration test workspace should not be analysed as part of
|
||||
# Skyframe, but should also not be ignored in order to be able to glob for its files.
|
||||
# TODO: Simplify this once https://github.com/bazelbuild/bazel/issues/12034 is fixed
|
||||
build --deleted_packages=integration/bazel_workspace_tests/bazel_ngtsc_plugin,integration/bazel_workspace_tests/bazel_ngtsc_plugin/src,integration/bazel_workspace_tests/bazel_ngtsc_plugin/src/hello-world,integration/bazel_workspace_tests/bazel_ngtsc_plugin/test,integration/bazel_workspace_tests/bazel_ngtsc_plugin/test/e2e,integration/bazel_workspace_tests/bazel_ngtsc_plugin/tools,integration/bazel_workspace_tests/bazel_ngtsc_plugin/tools/angular
|
||||
query --deleted_packages=integration/bazel_workspace_tests/bazel_ngtsc_plugin,integration/bazel_workspace_tests/bazel_ngtsc_plugin/src,integration/bazel_workspace_tests/bazel_ngtsc_plugin/src/hello-world,integration/bazel_workspace_tests/bazel_ngtsc_plugin/test,integration/bazel_workspace_tests/bazel_ngtsc_plugin/test/e2e,integration/bazel_workspace_tests/bazel_ngtsc_plugin/tools,integration/bazel_workspace_tests/bazel_ngtsc_plugin/tools/angular
|
||||
|
||||
####################################################
|
||||
# User bazel configuration
|
||||
@@ -188,4 +140,4 @@ build --flag_alias=fast_adev=//adev:fast_build_mode
|
||||
|
||||
# Load any settings which are specific to the current user. Needs to be *last* statement
|
||||
# in this config, as the user configuration should be able to overwrite flags from this file.
|
||||
try-import %workspace%/.bazelrc.user
|
||||
try-import .bazelrc.user
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
5.0.0
|
||||
4.2.2
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
# Settings in this file should be OS agnostic. Use the bazel.<OS>.rc files for OS specific settings.
|
||||
|
||||
# Don't be spammy in the logs
|
||||
build --noshow_progress
|
||||
|
||||
# Print all the options that apply to the build.
|
||||
# This helps us diagnose which options override others
|
||||
# (e.g. /etc/bazel.bazelrc vs. tools/bazel.rc)
|
||||
build --announce_rc
|
||||
|
||||
# Retry in the event of flakes, eg. https://circleci.com/gh/angular/angular/31309
|
||||
# By default this is set in the project `.bazelrc` to `1`.
|
||||
test --flaky_test_attempts=3
|
||||
test --flaky_test_attempts=2
|
||||
|
||||
# More details on failures
|
||||
build --verbose_failures=true
|
||||
|
||||
# CI supports colors but Bazel does not detect it.
|
||||
common --color=yes
|
||||
|
||||
@@ -12,10 +12,10 @@ build --repository_cache=/home/circleci/bazel_repository_cache
|
||||
|
||||
# Workaround https://github.com/bazelbuild/bazel/issues/3645
|
||||
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
|
||||
# Limit Bazel to consuming resources that fit in CircleCI "2xlarge+" class
|
||||
# Limit Bazel to consuming resources that fit in CircleCI "xlarge" class
|
||||
# https://circleci.com/docs/2.0/configuration-reference/#resource_class
|
||||
build --local_cpu_resources=20
|
||||
build --local_ram_resources=40960
|
||||
build --local_ram_resources=32768
|
||||
|
||||
# All build executed remotely should be done using our RBE configuration.
|
||||
build:remote --google_default_credentials
|
||||
|
||||
+820
-6
@@ -1,16 +1,830 @@
|
||||
# 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.
|
||||
# See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI.
|
||||
var_3: &cache_key v6-angular-node-14-{{ checksum "month.txt" }}-{{ 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 v6-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
|
||||
# Windows needs its own cache key because binaries in node_modules are different.
|
||||
var_3_win: &cache_key_win v6-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
|
||||
var_4_win: &cache_key_win_fallback v6-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
|
||||
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
|
||||
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
|
||||
var_5: &components_repo_unit_tests_cache_key v1-angular-components-{{ checksum "month.txt" }}-e0b76ed029939a7bb8246410b0170cfdbf35da25
|
||||
var_6: &components_repo_unit_tests_cache_key_fallback v1-angular-components-{{ checksum "month.txt" }}
|
||||
|
||||
# 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_7: &workspace_location ~/
|
||||
|
||||
# Filter to run a job on builds for pull requests only.
|
||||
var_8: &only_on_pull_requests
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /pull\/\d+/
|
||||
|
||||
# Filter to skip a job on builds for pull requests.
|
||||
var_9: &skip_on_pull_requests
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /pull\/\d+/
|
||||
|
||||
# Filter to run a job on builds for the master branch only.
|
||||
var_10: &only_on_master
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
# Filter to run a job on all releasable branches.
|
||||
var_11: &only_release_branches
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /\d+\.\d+\.x/
|
||||
|
||||
# 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.10.0
|
||||
resource_class: << parameters.resource_class >>
|
||||
working_directory: ~/ng
|
||||
|
||||
test-browser-executor:
|
||||
parameters:
|
||||
resource_class:
|
||||
type: string
|
||||
default: medium
|
||||
docker:
|
||||
- image: cimg/node:16.10.0-browsers
|
||||
resource_class: << parameters.resource_class >>
|
||||
working_directory: ~/ng
|
||||
|
||||
windows-executor:
|
||||
working_directory: ~/ng
|
||||
resource_class: windows.2xlarge
|
||||
# CircleCI windows VMs do have the GitBash shell available:
|
||||
# https://github.com/CircleCI-Public/windows-preview-docs#shells
|
||||
# But in this specific case we really should not use it because Bazel must not be ran from
|
||||
# GitBash. These issues discuss why:
|
||||
# https://github.com/bazelbuild/bazel/issues/5751
|
||||
# https://github.com/bazelbuild/bazel/issues/5724#issuecomment-410194038
|
||||
# https://github.com/bazelbuild/bazel/issues/6339#issuecomment-441600879
|
||||
shell: powershell.exe -ExecutionPolicy Bypass
|
||||
machine:
|
||||
# Windows preview image that includes the following:
|
||||
# - Visual Studio 2019 build tools
|
||||
# - Node 14
|
||||
# - yarn 1.17
|
||||
# - Python 3 3.7.4
|
||||
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
|
||||
- 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 AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.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
|
||||
|
||||
# Normally this would be an individual job instead of a command.
|
||||
# But startup and setup time for each individual windows job are high enough to discourage
|
||||
# many small jobs, so instead we use a command for setup unless the gain becomes significant.
|
||||
setup_win:
|
||||
description: Setup windows node environment
|
||||
steps:
|
||||
- checkout
|
||||
- save_month_to_file
|
||||
# Install Bazel pre-requisites that aren't in the preconfigured CircleCI Windows VM.
|
||||
- run: ./.circleci/windows-env.ps1
|
||||
- run: node --version
|
||||
- run: yarn --version
|
||||
- restore_cache:
|
||||
keys:
|
||||
- *cache_key_win
|
||||
- *cache_key_win_fallback
|
||||
# Install @bazel/bazelisk globally and use that for the first run.
|
||||
# Workaround for https://github.com/bazelbuild/rules_nodejs/issues/894
|
||||
# NB: the issue was for @bazel/bazel but the same problem applies to @bazel/bazelisk
|
||||
- run: yarn global add @bazel/bazelisk@$env:BAZELISK_VERSION
|
||||
# On Windows `~/` is not resolved when using as a CLI value. `../` results in the same path.
|
||||
- run: yarn install --frozen-lockfile --non-interactive --cache-folder ../.cache/yarn
|
||||
|
||||
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
|
||||
- init_environment
|
||||
- run:
|
||||
name: Rebase PR on target branch
|
||||
# After checkout, rebase on top of target branch.
|
||||
command: >
|
||||
if [[ -n "${CIRCLE_PR_NUMBER}" ]]; then
|
||||
# User is required for rebase.
|
||||
git config user.name "angular-ci"
|
||||
git config user.email "angular-ci"
|
||||
# Rebase PR on top of target branch.
|
||||
node .circleci/rebase-pr.js
|
||||
else
|
||||
echo "This build is not over a PR, nothing to do."
|
||||
fi
|
||||
# This cache is saved in the build-npm-packages so that Bazel cache is also included.
|
||||
- restore_cache:
|
||||
keys:
|
||||
- *cache_key
|
||||
- *cache_key_fallback
|
||||
- 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.
|
||||
no_output_timeout: 45m
|
||||
- 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
|
||||
|
||||
lint:
|
||||
executor: default-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
|
||||
- run: yarn -s tslint
|
||||
- run: yarn -s ng-dev format changed $CI_GIT_BASE_REVISION --check
|
||||
- run: yarn -s ts-circular-deps:check
|
||||
- run: yarn -s ng-dev pullapprove verify
|
||||
- run: yarn -s ng-dev ngbot verify
|
||||
- run: yarn -s ng-dev commit-message validate-range $CI_GIT_BASE_REVISION $CI_GIT_REVISION
|
||||
- run: yarn -s check-tooling-setup
|
||||
|
||||
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
|
||||
- install_java
|
||||
- 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 --symlink_prefix=dist/ -- //...
|
||||
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
|
||||
|
||||
# NOTE: This is currently limited to master 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
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- init_saucelabs_environment
|
||||
- run:
|
||||
name: Run Bazel tests on Saucelabs
|
||||
# See /tools/saucelabs/README.md for more info
|
||||
command: |
|
||||
yarn bazel run //tools/saucelabs:sauce_service_setup
|
||||
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 ${TESTS}
|
||||
yarn bazel run //tools/saucelabs:sauce_service_stop
|
||||
no_output_timeout: 40m
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
|
||||
|
||||
test_aio:
|
||||
executor: test-browser-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Build aio
|
||||
- run: yarn --cwd aio build --progress=false
|
||||
# Lint the code
|
||||
- run: yarn --cwd aio lint
|
||||
# Run unit tests
|
||||
- run: yarn --cwd aio test --progress=false --watch=false
|
||||
# Run e2e tests
|
||||
- run: yarn --cwd aio e2e --configuration=ci
|
||||
# Run PWA-score tests
|
||||
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
|
||||
# Run accessibility tests
|
||||
- run: yarn --cwd aio test-a11y-score-localhost
|
||||
# Check the bundle sizes.
|
||||
- run: yarn --cwd aio payload-size
|
||||
# Run unit tests for Firebase redirects
|
||||
- run: yarn --cwd aio redirects-test
|
||||
|
||||
deploy_aio:
|
||||
executor: test-browser-executor
|
||||
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: test-browser-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Build aio (with local Angular packages)
|
||||
- run: yarn --cwd aio build-local-ci
|
||||
# Run unit tests
|
||||
- run: yarn --cwd aio test --progress=false --watch=false
|
||||
# Run e2e tests
|
||||
- run: yarn --cwd aio e2e --configuration=ci
|
||||
# Run PWA-score tests
|
||||
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
|
||||
# Check the bundle sizes.
|
||||
- run: yarn --cwd aio payload-size aio-local
|
||||
|
||||
test_aio_tools:
|
||||
executor: default-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Install
|
||||
- run: yarn --cwd aio install --frozen-lockfile --non-interactive --cache-folder ~/.cache/yarn
|
||||
- run: yarn --cwd aio extract-cli-command-docs
|
||||
# Run tools tests
|
||||
- run: yarn --cwd aio tools-test
|
||||
- run: ./aio/aio-builds-setup/scripts/test.sh
|
||||
|
||||
test_docs_examples:
|
||||
executor:
|
||||
name: test-browser-executor
|
||||
resource_class: xlarge
|
||||
parallelism: 5
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Install aio
|
||||
- run: yarn --cwd aio install --frozen-lockfile --non-interactive --cache-folder ~/.cache/yarn
|
||||
# Run examples tests. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
|
||||
# Since the parallelism is set to "5", there will be five parallel CircleCI containers.
|
||||
# with either "0", "1", etc as node index. This can be passed to the "--shard" argument.
|
||||
- run: yarn --cwd aio example-e2e --setup --local --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
|
||||
|
||||
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
|
||||
aio_preview:
|
||||
executor: default-executor
|
||||
environment:
|
||||
AIO_SNAPSHOT_ARTIFACT_PATH: &aio_preview_artifact_path 'aio/tmp/snapshot.tgz'
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- run: ./aio/scripts/build-artifacts.sh $AIO_SNAPSHOT_ARTIFACT_PATH $CI_PULL_REQUEST $CI_COMMIT
|
||||
- store_artifacts:
|
||||
path: *aio_preview_artifact_path
|
||||
# The `destination` needs to be kept in sync with the value of
|
||||
# `AIO_ARTIFACT_PATH` in `aio/aio-builds-setup/Dockerfile`
|
||||
destination: aio/dist/aio-snapshot.tgz
|
||||
- run: node ./aio/scripts/create-preview $CIRCLE_BUILD_NUM
|
||||
|
||||
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
|
||||
test_aio_preview:
|
||||
executor: test-browser-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- run: yarn --cwd aio install --frozen-lockfile --non-interactive --cache-folder ~/.cache/yarn
|
||||
- run:
|
||||
name: Wait for preview and run tests
|
||||
command: node aio/scripts/test-preview.js $CI_PULL_REQUEST $CI_COMMIT $CI_AIO_MIN_PWA_SCORE
|
||||
|
||||
# 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: node scripts/build/build-packages-dist.js
|
||||
|
||||
# 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: Decrypt github credentials
|
||||
# We need ensure that the same default digest is used for encoding and decoding with
|
||||
# OpenSSL. OpenSSL versions might have different default digests which can cause
|
||||
# decryption failures based on the installed OpenSSL version. https://stackoverflow.com/a/39641378/4317734
|
||||
command: 'openssl aes-256-cbc -d -in .circleci/github_token -md md5 -k "${KEY}" -out ~/.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 ZoneJS so that it can be loaded globally in the Karma tests.
|
||||
- run: yarn bazel build //packages/zone.js:npm_package
|
||||
# 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
|
||||
|
||||
# Job that runs all unit tests of the `angular/components` repository.
|
||||
components-repo-unit-tests:
|
||||
executor:
|
||||
name: default-executor
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Restore the cache before cloning the repository because the clone script re-uses
|
||||
# the restored repository if present. This reduces the amount of times the components
|
||||
# repository needs to be cloned (this is slow and increases based on commits in the repo).
|
||||
- restore_cache:
|
||||
keys:
|
||||
- *components_repo_unit_tests_cache_key
|
||||
# Whenever the `angular/components` SHA is updated, the cache key will no longer
|
||||
# match. The fallback cache will still match, and CircleCI will restore the most
|
||||
# recently cached repository folder. Without the fallback cache, we'd need to download
|
||||
# the repository from scratch and it would slow down the job. This is because we can't
|
||||
# clone the repository with reduced `--depth`, but rather need to clone the whole
|
||||
# repository to be able to support arbitrary SHAs.
|
||||
- *components_repo_unit_tests_cache_key_fallback
|
||||
- run:
|
||||
name: 'Fetching angular/components repository'
|
||||
command: ./scripts/ci/clone_angular_components_repo.sh
|
||||
- run:
|
||||
# Run yarn install to fetch the Bazel binaries as used in the components repo.
|
||||
name: Installing dependencies.
|
||||
command: yarn --cwd ${COMPONENTS_REPO_TMP_DIR} install --frozen-lockfile --non-interactive --cache-folder ~/.cache/yarn
|
||||
- save_cache:
|
||||
key: *components_repo_unit_tests_cache_key
|
||||
paths:
|
||||
# Temporary directory must be kept in sync with the `$COMPONENTS_REPO_TMP_DIR` env
|
||||
# variable. It needs to be hardcoded here, because env variables interpolation is
|
||||
# not supported.
|
||||
- '/tmp/angular-components-repo'
|
||||
- run:
|
||||
# Copy zone.js package to dist/packages-dist, so `angular/components` can also use the local zone.js build.
|
||||
name: Setting up zone.js release packages.
|
||||
command: cp -r dist/zone.js-dist/zone.js dist/packages-dist/
|
||||
- run:
|
||||
# Updates the `angular/components` `package.json` file to refer to the release output
|
||||
# inside the `packages-dist` directory.
|
||||
name: Setting up framework release packages.
|
||||
command: node scripts/ci/update-framework-deps-to-dist-packages.js ${COMPONENTS_REPO_TMP_DIR}/package.json dist/packages-dist/
|
||||
- run:
|
||||
# Run `yarn install` again to install the Angular packages from `packages-dist/` and update the lockfile.
|
||||
# NOTE: We cannot rely on Bazel to run `yarn install`, because it uses the `--frozen-lockfile` flag and fails.
|
||||
name: Installing local Angular packages.
|
||||
command: yarn --cwd ${COMPONENTS_REPO_TMP_DIR} install --non-interactive --cache-folder ~/.cache/yarn
|
||||
- run:
|
||||
name: 'Running `angular/components` unit tests'
|
||||
command: ./scripts/ci/run_angular_components_unit_tests.sh
|
||||
|
||||
test_zonejs:
|
||||
executor:
|
||||
name: default-executor
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- install_java
|
||||
# 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 bazel build //packages/zone.js:npm_package &&
|
||||
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/npm_package/bundles/zone.umd.js ./packages/zone.js/build/test/closure/zone.js
|
||||
- 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:
|
||||
- setup_win
|
||||
- run:
|
||||
name: Build all windows CI targets
|
||||
command: bazel build //packages/compiler-cli/...
|
||||
no_output_timeout: 15m
|
||||
- run:
|
||||
name: Test all windows CI targets
|
||||
command: bazel test --test_tag_filters="-browser:chromium-local" //packages/compiler-cli/...
|
||||
no_output_timeout: 15m
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
default_workflow:
|
||||
jobs:
|
||||
- pass
|
||||
- setup:
|
||||
filters:
|
||||
branches:
|
||||
ignore: g3
|
||||
- lint:
|
||||
requires:
|
||||
- setup
|
||||
- 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:
|
||||
- build-npm-packages
|
||||
- test_aio_tools:
|
||||
requires:
|
||||
- build-npm-packages
|
||||
- test_docs_examples:
|
||||
requires:
|
||||
- build-npm-packages
|
||||
- aio_preview:
|
||||
# Only run on PR builds. (There can be no previews for non-PR builds.)
|
||||
<<: *only_on_pull_requests
|
||||
requires:
|
||||
- setup
|
||||
- test_aio_preview:
|
||||
requires:
|
||||
- aio_preview
|
||||
- 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
|
||||
- test_docs_examples
|
||||
# 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
|
||||
- components-repo-unit-tests:
|
||||
requires:
|
||||
- build-npm-packages
|
||||
- test_zonejs:
|
||||
requires:
|
||||
- setup
|
||||
- test_win:
|
||||
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 on master only 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_master
|
||||
# Runs monitoring jobs at 10:00AM every day.
|
||||
cron: '0 10 * * *'
|
||||
|
||||
@@ -31,10 +31,7 @@ function setSecretVar() {
|
||||
local -r originalShellOptions=$(set +o);
|
||||
set +x -eu -o pipefail;
|
||||
|
||||
local assignmentStatement="export $1=\"${2:-}\";"
|
||||
|
||||
echo "${assignmentStatement}" >> $BASH_ENV;
|
||||
eval "${assignmentStatement}"
|
||||
echo "export $1=\"${2:-}\";" >> $BASH_ENV;
|
||||
|
||||
# Restore original shell options.
|
||||
eval "$originalShellOptions";
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
####################################################################################################
|
||||
# Set bazel configuration for CircleCI runs.
|
||||
####################################################################################################
|
||||
cp "${PROJECT_ROOT}/.circleci/bazel.linux.rc" ".bazelrc.user";
|
||||
+33
-10
@@ -51,7 +51,7 @@ setSecretVar CI_SECRET_PAYLOAD_FIREBASE_TOKEN "$ANGULAR_PAYLOAD_TOKEN";
|
||||
# Define SauceLabs environment variables for CircleCI.
|
||||
####################################################################################################
|
||||
setPublicVar SAUCE_USERNAME "angular-framework";
|
||||
setSecretVar SAUCE_ACCESS_KEY "f4bf7c639c5a-c6bb-d6a4-a4b5-800aa111";
|
||||
setSecretVar SAUCE_ACCESS_KEY "0c731274ed5f-cbc9-16f4-021a-9835e39f";
|
||||
# TODO(josephperrott): Remove environment variables once all saucelabs tests are via bazel method.
|
||||
setPublicVar SAUCE_LOG_FILE /tmp/angular/sauce-connect.log
|
||||
setPublicVar SAUCE_READY_FILE /tmp/angular/sauce-connect-ready-file.lock
|
||||
@@ -61,6 +61,32 @@ setPublicVar SAUCE_TUNNEL_IDENTIFIER "angular-framework-${CIRCLE_BUILD_NUM}-${CI
|
||||
# acquire CircleCI instances for too long if sauceconnect failed, we need a connect timeout.
|
||||
setPublicVar SAUCE_READY_FILE_TIMEOUT 120
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Define environment variables for the `angular/components` repo unit tests job.
|
||||
####################################################################################################
|
||||
# We specifically use a directory within "/tmp" here because we want the cloned repo to be
|
||||
# completely isolated from angular/angular in order to avoid any bad interactions between
|
||||
# their separate build setups. **NOTE**: When updating the temporary directory, also update
|
||||
# the `save_cache` path configuration in `config.yml`
|
||||
setPublicVar COMPONENTS_REPO_TMP_DIR "/tmp/angular-components-repo"
|
||||
setPublicVar COMPONENTS_REPO_URL "https://github.com/angular/components.git"
|
||||
setPublicVar COMPONENTS_REPO_BRANCH "master"
|
||||
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI `config.yml`.
|
||||
setPublicVar COMPONENTS_REPO_COMMIT "e0b76ed029939a7bb8246410b0170cfdbf35da25"
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Decrypt GCP Credentials and store them as the Google default credentials.
|
||||
####################################################################################################
|
||||
mkdir -p "$HOME/.config/gcloud";
|
||||
openssl aes-256-cbc -d -in "${projectDir}/.circleci/gcp_token" \
|
||||
-md md5 -k "$CIRCLE_PROJECT_REPONAME" -out "$HOME/.config/gcloud/application_default_credentials.json"
|
||||
####################################################################################################
|
||||
# Set bazel configuration for CircleCI runs.
|
||||
####################################################################################################
|
||||
cp "${projectDir}/.circleci/bazel.linux.rc" "$HOME/.bazelrc";
|
||||
|
||||
####################################################################################################
|
||||
# Create shell script in /tmp for Bazel actions to access CI envs without
|
||||
# busting the cache. Used by payload-size.sh script in integration tests.
|
||||
@@ -71,19 +97,16 @@ echo "export PROJECT_ROOT=\"${PROJECT_ROOT}\";" >> $bazelVarEnv
|
||||
echo "export CI_BRANCH=\"${CI_BRANCH}\";" >> $bazelVarEnv
|
||||
echo "export CI_BUILD_URL=\"${CI_BUILD_URL}\";" >> $bazelVarEnv
|
||||
echo "export CI_COMMIT=\"${CI_COMMIT}\";" >> $bazelVarEnv
|
||||
echo "export CI_COMMIT_RANGE=\"${CI_COMMIT_RANGE}\";" >> $bazelVarEnv
|
||||
echo "export CI_PULL_REQUEST=\"${CI_PULL_REQUEST}\";" >> $bazelVarEnv
|
||||
echo "export CI_REPO_NAME=\"${CI_REPO_NAME}\";" >> $bazelVarEnv
|
||||
echo "export CI_REPO_OWNER=\"${CI_REPO_OWNER}\";" >> $bazelVarEnv
|
||||
echo "export CI_SECRET_PAYLOAD_FIREBASE_TOKEN=\"${CI_SECRET_PAYLOAD_FIREBASE_TOKEN}\";" >> $bazelVarEnv
|
||||
|
||||
####################################################################################################
|
||||
# Platform-specific environment setup (which can leverage the base variables from here)
|
||||
####################################################################################################
|
||||
|
||||
# Conditionally, load additional environment settings based on the current VM
|
||||
# operating system running. We detect Windows by checking for `%AppData%`.
|
||||
if [[ -n "${APPDATA}" ]]; then
|
||||
source ${projectDir}/.circleci/env.windows.sh
|
||||
else
|
||||
source ${projectDir}/.circleci/env.linux.sh
|
||||
fi
|
||||
## Source `$BASH_ENV` to make the variables available immediately. ##
|
||||
## ***NOTE: This must remain the last action in this script*** ##
|
||||
####################################################################################################
|
||||
####################################################################################################
|
||||
source $BASH_ENV;
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
####################################################################################################
|
||||
# Set bazel configuration for CircleCI runs.
|
||||
####################################################################################################
|
||||
cp "${PROJECT_ROOT}/.circleci/bazel.windows.rc" ".bazelrc.user";
|
||||
|
||||
# Override the `PATH` environment variable so that the windows-nvm NodeJS version
|
||||
# always has precedence over potential existing NodeJS versions from the image.
|
||||
setPublicVar PATH "/c/Program Files/nodejs/:$PATH"
|
||||
|
||||
# Expose the Bazelisk version. We need to run Bazelisk globally since Windows has problems launching
|
||||
# Bazel from a node modules directoy that might be modified by the Bazel Yarn install then.
|
||||
setPublicVar BAZELISK_VERSION \
|
||||
"$(cd ${PROJECT_ROOT}; node -p 'require("./package.json").devDependencies["@bazel/bazelisk"]')"
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Rebases the current branch on top of the GitHub PR target branch.
|
||||
*
|
||||
* **Context:**
|
||||
* Since a GitHub PR is not necessarily up to date with its target branch, it is useful to rebase
|
||||
* prior to testing it on CI to ensure more up to date test results.
|
||||
*
|
||||
* **NOTE:**
|
||||
* This script cannot use external dependencies or be compiled because it needs to run before the
|
||||
* environment is setup.
|
||||
* Use only features supported by the NodeJS versions used in the environment.
|
||||
*/
|
||||
// tslint:disable:no-console
|
||||
const {execSync} = require('child_process');
|
||||
|
||||
|
||||
/** A regex to select a ref that matches our semver refs. */
|
||||
const semverRegex = /^(\d+)\.(\d+)\.x$/;
|
||||
|
||||
// Run
|
||||
_main().catch(err => {
|
||||
console.log('Failed to rebase on top of target branch.\n');
|
||||
console.error(err);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
|
||||
// Helpers
|
||||
async function _main() {
|
||||
const refs = await getRefsAndShasForChange();
|
||||
|
||||
// Log known refs and shas
|
||||
console.log(`--------------------------------`);
|
||||
console.log(` Target Branch: ${refs.base.ref}`);
|
||||
console.log(` Latest Commit for Target Branch: ${refs.target.latestSha}`);
|
||||
console.log(` Latest Commit for PR: ${refs.base.latestSha}`);
|
||||
console.log(` First Common Ancestor SHA: ${refs.commonAncestorSha}`);
|
||||
console.log(`--------------------------------`);
|
||||
console.log();
|
||||
|
||||
// Get the count of commits between the latest commit from origin and the common ancestor SHA.
|
||||
const commitCount =
|
||||
exec(`git rev-list --count origin/${refs.base.ref}...${refs.commonAncestorSha}`);
|
||||
console.log(`Checking ${commitCount} commits for changes in the CircleCI config file.`);
|
||||
|
||||
// Check if the files changed between the latest commit from origin and the common ancestor SHA
|
||||
// includes the CircleCI config.
|
||||
const circleCIConfigChanged = exec(`git diff --name-only origin/${refs.base.ref} ${
|
||||
refs.commonAncestorSha} -- .circleci/config.yml`);
|
||||
|
||||
if (!!circleCIConfigChanged) {
|
||||
throw Error(`
|
||||
CircleCI config on ${refs.base.ref} has been modified since commit
|
||||
${refs.commonAncestorSha.slice(0, 7)}, which this PR is based on.
|
||||
|
||||
Please rebase the PR on ${refs.base.ref} after fetching from upstream.
|
||||
|
||||
Rebase instructions for PR Author, please run the following commands:
|
||||
|
||||
git fetch upstream ${refs.base.ref};
|
||||
git checkout ${refs.target.ref};
|
||||
git rebase upstream/${refs.base.ref};
|
||||
git push --force-with-lease;
|
||||
`);
|
||||
} else {
|
||||
console.log('No change found in the CircleCI config file, continuing.');
|
||||
}
|
||||
console.log();
|
||||
|
||||
// Rebase the PR.
|
||||
exec(`git rebase origin/${refs.base.ref}`);
|
||||
console.log(`Rebased current branch onto ${refs.base.ref}.`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sort a list of fullpath refs into a list and then provide the first entry.
|
||||
*
|
||||
* The sort order will first find master ref, and then any semver ref, followed
|
||||
* by the rest of the refs in the order provided.
|
||||
*
|
||||
* Branches are sorted in this order as work is primarily done on master, and
|
||||
* otherwise on a semver branch. If neither of those were to match, the most
|
||||
* likely correct branch will be the first one encountered in the list.
|
||||
*/
|
||||
function getRefFromBranchList(gitOutput) {
|
||||
const branches = gitOutput.split('\n').map(b => b.split('/').slice(1).join('/').trim());
|
||||
return branches.sort((a, b) => {
|
||||
if (a === 'master') {
|
||||
return -1;
|
||||
}
|
||||
if (b === 'master') {
|
||||
return 1;
|
||||
}
|
||||
const aIsSemver = semverRegex.test(a);
|
||||
const bIsSemver = semverRegex.test(b);
|
||||
if (aIsSemver && bIsSemver) {
|
||||
const [, aMajor, aMinor] = a.match(semverRegex);
|
||||
const [, bMajor, bMinor] = b.match(semverRegex);
|
||||
return parseInt(bMajor, 10) - parseInt(aMajor, 10) ||
|
||||
parseInt(aMinor, 10) - parseInt(bMinor, 10) || 0;
|
||||
}
|
||||
if (aIsSemver) {
|
||||
return -1;
|
||||
}
|
||||
if (bIsSemver) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
})[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full sha of the ref provided.
|
||||
*
|
||||
* example: 1bc0c1a6c01ede7168f22fa9b3508ba51f1f464e
|
||||
*/
|
||||
function getShaFromRef(ref) {
|
||||
return exec(`git rev-parse ${ref}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of branches which contain the provided sha, sorted in descending order
|
||||
* by committerdate.
|
||||
*
|
||||
* example:
|
||||
* upstream/master
|
||||
* upstream/9.0.x
|
||||
* upstream/test
|
||||
* upstream/1.1.x
|
||||
*/
|
||||
function getBranchListForSha(sha, remote) {
|
||||
return exec(`git branch -r '${remote}/*' --sort=-committerdate --contains ${sha}`);
|
||||
}
|
||||
|
||||
/** Get the common ancestor sha of the two provided shas. */
|
||||
function getCommonAncestorSha(sha1, sha2) {
|
||||
return exec(`git merge-base ${sha1} ${sha2}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the remote to git, if it doesn't already exist. Returns a boolean indicating
|
||||
* whether the remote was added by the command.
|
||||
*/
|
||||
function addAndFetchRemote(owner, name) {
|
||||
const remoteName = `${owner}_${name}`;
|
||||
exec(`git remote add ${remoteName} https://github.com/${owner}/${name}.git`, true);
|
||||
exec(`git fetch ${remoteName}`);
|
||||
return remoteName;
|
||||
}
|
||||
|
||||
|
||||
/** Get the ref and latest shas for the provided sha on a specific remote. */
|
||||
function getRefAndShas(sha, owner, name) {
|
||||
const remoteName = addAndFetchRemote(owner, name);
|
||||
|
||||
// Get the ref on the remote for the sha provided.
|
||||
const branches = getBranchListForSha(sha, remoteName);
|
||||
const ref = getRefFromBranchList(branches);
|
||||
|
||||
// Get the latest sha on the discovered remote ref.
|
||||
const latestSha = getShaFromRef(`${remoteName}/${ref}`);
|
||||
|
||||
return {remote: remoteName, ref, latestSha, sha};
|
||||
}
|
||||
|
||||
|
||||
/** Gets the refs and shas for the base and target of the current environment. */
|
||||
function getRefsAndShasForChange() {
|
||||
const base = getRefAndShas(
|
||||
process.env['CI_GIT_BASE_REVISION'], process.env['CI_REPO_OWNER'],
|
||||
process.env['CI_REPO_NAME']);
|
||||
const target = getRefAndShas(
|
||||
process.env['CI_GIT_REVISION'], process.env['CI_PR_USERNAME'], process.env['CI_PR_REPONAME']);
|
||||
const commonAncestorSha = getCommonAncestorSha(base.sha, target.sha);
|
||||
return {
|
||||
base,
|
||||
target,
|
||||
commonAncestorSha,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Synchronously executes the command.
|
||||
*
|
||||
* Return the trimmed stdout as a string, with an added attribute of the exit code.
|
||||
*/
|
||||
function exec(command, ignoreError = false) {
|
||||
try {
|
||||
return execSync(command, {stdio: 'pipe'}).toString().trim();
|
||||
} catch (err) {
|
||||
if (ignoreError) {
|
||||
return '';
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Usage (cli):
|
||||
* ```
|
||||
* node create-preview <build-number> <job-name> <webhook-url>
|
||||
* ```
|
||||
*
|
||||
* Usage (JS):
|
||||
* ```js
|
||||
* require('./trigger-webhook').
|
||||
* triggerWebhook(buildNumber, jobName, webhookUrl).
|
||||
* then(...);
|
||||
* ```
|
||||
*
|
||||
* Triggers a notification webhook with CircleCI specific info.
|
||||
*
|
||||
* It can be used for notifying external servers and trigger operations based on CircleCI job status
|
||||
* (e.g. triggering the creation of a preview based on previously stored build atrifacts).
|
||||
*
|
||||
* The body of the sent payload is of the form:
|
||||
* ```json
|
||||
* {
|
||||
* "payload": {
|
||||
* "build_num": ${buildNumber}
|
||||
* "build_parameters": {
|
||||
* "CIRCLE_JOB": "${jobName}"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* When used from JS, it returns a promise which resolves to an object of the form:
|
||||
* ```json
|
||||
* {
|
||||
* "statucCode": ${statusCode},
|
||||
* "responseText": "${responseText}"
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* NOTE:
|
||||
* - When used from the cli, the command will exit with an error code if the response's status code
|
||||
* is outside the [200, 400) range.
|
||||
* - When used from JS, the returned promise will be resolved, even if the response's status code is
|
||||
* outside the [200, 400) range. It is up to the caller to decide how this should be handled.
|
||||
*/
|
||||
|
||||
// Imports
|
||||
const {request} = require('https');
|
||||
|
||||
// Exports
|
||||
module.exports = {
|
||||
triggerWebhook,
|
||||
};
|
||||
|
||||
// Run
|
||||
if (require.resolve === module) {
|
||||
_main(process.argv.slice(2));
|
||||
}
|
||||
|
||||
// Helpers
|
||||
function _main(args) {
|
||||
triggerWebhook(...args)
|
||||
.then(
|
||||
({statusCode, responseText}) => (200 <= statusCode && statusCode < 400) ?
|
||||
console.log(`Status: ${statusCode}\n${responseText}`) :
|
||||
Promise.reject(new Error(`Request failed (status: ${statusCode}): ${responseText}`)))
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
function postJson(url, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const opts = {method: 'post', headers: {'Content-Type': 'application/json'}};
|
||||
const onResponse = res => {
|
||||
const statusCode = res.statusCode || -1;
|
||||
let responseText = '';
|
||||
|
||||
res.on('error', reject)
|
||||
.on('data', d => responseText += d)
|
||||
.on('end', () => resolve({statusCode, responseText}));
|
||||
};
|
||||
|
||||
request(url, opts, onResponse).on('error', reject).end(JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
async function triggerWebhook(buildNumber, jobName, webhookUrl) {
|
||||
if (!buildNumber || !jobName || !webhookUrl || isNaN(buildNumber)) {
|
||||
throw new Error(
|
||||
'Missing or invalid arguments.\n' +
|
||||
'Expected: buildNumber (number), jobName (string), webhookUrl (string)');
|
||||
}
|
||||
|
||||
const data = {
|
||||
payload: {
|
||||
build_num: +buildNumber,
|
||||
build_parameters: {CIRCLE_JOB: jobName},
|
||||
},
|
||||
};
|
||||
|
||||
return postJson(webhookUrl, data);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
# Install Bazel pre-reqs on Windows
|
||||
# https://docs.bazel.build/versions/master/install-windows.html
|
||||
# https://docs.bazel.build/versions/master/windows.html
|
||||
# Install MSYS2 and packages
|
||||
choco install msys2 --version 20200903.0.0 --no-progress --package-parameters "/NoUpdate"
|
||||
C:\tools\msys64\usr\bin\bash.exe -l -c "pacman --needed --noconfirm -S zip unzip patch diffutils"
|
||||
|
||||
# Add PATH modifications to the Powershell profile. This is the win equivalent of .bash_profile.
|
||||
# https://docs.microsoft.com/en-us/previous-versions//bb613488(v=vs.85)
|
||||
new-item -path $profile -itemtype file -force
|
||||
# Paths for nodejs, npm, yarn, and msys2. Use single quotes to prevent interpolation.
|
||||
# Add before the original path to use msys2 instead of the installed gitbash.
|
||||
Add-Content $profile '$Env:path = "${Env:ProgramFiles}\nodejs\;C:\Users\circleci\AppData\Roaming\npm\;${Env:ProgramFiles(x86)}\Yarn\bin\;C:\Users\circleci\AppData\Local\Yarn\bin\;C:\tools\msys64\usr\bin\;" + $Env:path'
|
||||
# Environment variables for Bazel
|
||||
Add-Content $profile '$Env:BAZEL_SH = "C:\tools\msys64\usr\bin\bash.exe"'
|
||||
|
||||
# Get the bazelisk version devdep and store it in a global var for use in the circleci job.
|
||||
$bazeliskVersion = & ${Env:ProgramFiles}\nodejs\node.exe -e "console.log(require('./package.json').devDependencies['@bazel/bazelisk'])"
|
||||
# This is a tricky situation: we want $bazeliskVersion to be evaluated but not $Env:BAZELISK_VERSION.
|
||||
# Formatting works https://stackoverflow.com/questions/32127583/expand-variable-inside-single-quotes
|
||||
$bazeliskVersionGlobalVar = '$Env:BAZELISK_VERSION = "{0}"' -f $bazeliskVersion
|
||||
Add-Content $profile $bazeliskVersionGlobalVar
|
||||
|
||||
# Remove the CircleCI checkout SSH override, because it breaks cloning repositories through Bazel.
|
||||
# See https://circleci.com/gh/angular/angular/401454 for an example.
|
||||
# TODO: is this really needed? Maybe there's a better way. It doesn't happen on Linux or on Codefresh.
|
||||
git config --global --unset url.ssh://git@github.com.insteadOf
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Decrypt GCP Credentials and store them as the Google default credentials.
|
||||
####################################################################################################
|
||||
mkdir ${env:APPDATA}\gcloud
|
||||
openssl aes-256-cbc -d -in .circleci\gcp_token -md md5 -out "$env:APPDATA\gcloud\application_default_credentials.json" -k "$env:CIRCLE_PROJECT_REPONAME"
|
||||
|
||||
####################################################################################################
|
||||
# Set bazel configuration for CircleCI runs.
|
||||
####################################################################################################
|
||||
copy .circleci\bazel.windows.rc ${Env:USERPROFILE}\.bazelrc
|
||||
|
||||
####################################################################################################
|
||||
# Install specific version of node.
|
||||
####################################################################################################
|
||||
nvm install 16.10.0
|
||||
nvm use 16.10.0
|
||||
|
||||
# These Bazel prereqs aren't needed because the CircleCI image already includes them.
|
||||
# choco install yarn --version 1.16.0 --no-progress
|
||||
# choco install vcredist2015 --version 14.0.24215.20170201
|
||||
|
||||
# We don't need VS Build Tools for the tested bazel targets.
|
||||
# If it's needed again, uncomment these lines.
|
||||
# VS Build Tools are needed for Bazel C++ targets (like com_google_protobuf)
|
||||
# choco install visualstudio2019buildtools --version 16.1.2.0 --no-progress --package-parameters "--add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.Component.VC.Runtime.UCRTSDK --add Microsoft.VisualStudio.Component.Windows10SDK.17763"
|
||||
# Add-Content $profile '$Env:BAZEL_VC = "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\BuildTools\VC\"'
|
||||
# Python is needed for Bazel Python targets
|
||||
# choco install python --version 3.5.1 --no-progress
|
||||
@@ -12,7 +12,7 @@ Info on remote development and developing inside a container with VSCode:
|
||||
|
||||
_Prerequisite: [Install Docker](https://docs.docker.com/install) on your local environment._
|
||||
|
||||
To get started, read and follow the instructions in [Developing inside a Container](https://code.visualstudio.com/docs/remote/containers). The [.devcontainer/](.) directory contains pre-configured `devcontainer.json` and `Dockerfile` files, which you can use to set up remote development with a docker container.
|
||||
To get started, read and follow the instuctions in [Developing inside a Container](https://code.visualstudio.com/docs/remote/containers). The [.devcontainer/](.) directory contains pre-configured `devcontainer.json` and `Dockerfile` files, which you can use to set up remote development with a docker container.
|
||||
|
||||
In a nutshell, you need to:
|
||||
- Install the [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension.
|
||||
|
||||
@@ -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:18.13.0@sha256:45d0ee279f522c4562a464df71108104cc9b2187205333ffd0707d4f05589731
|
||||
FROM cimg/node:14-browsers
|
||||
|
||||
|
||||
LABEL name="Angular dev environment" \
|
||||
|
||||
@@ -4,3 +4,6 @@
|
||||
# JS and TS files must always use LF for tools to work
|
||||
*.js eol=lf
|
||||
*.ts eol=lf
|
||||
|
||||
# Must keep Windows line ending to be parsed correctly
|
||||
scripts/windows/packages.txt eol=crlf
|
||||
|
||||
@@ -23,7 +23,6 @@ body:
|
||||
- router
|
||||
- service-worker
|
||||
- upgrade
|
||||
- zone.js
|
||||
- Don't known / other
|
||||
multiple: true
|
||||
validations:
|
||||
|
||||
@@ -5,54 +5,38 @@ body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the problem that you experienced
|
||||
label: Description
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: affected-url
|
||||
attributes:
|
||||
label: Enter the URL of the topic with the problem
|
||||
|
||||
- type: textarea
|
||||
id: documentation-goal
|
||||
attributes:
|
||||
label: Describe what you were looking for in the documentation
|
||||
label: What is the affected URL?
|
||||
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Describe the actions that led you to experience the problem
|
||||
label: Please provide the steps to reproduce the issue
|
||||
|
||||
- type: textarea
|
||||
id: expected-vs-actual-behavior
|
||||
attributes:
|
||||
label: Describe what you want to experience that would fix the problem
|
||||
label: Please provide the expected behavior vs the actual behavior you encountered
|
||||
|
||||
- type: textarea
|
||||
id: screenshot
|
||||
attributes:
|
||||
label: Add a screenshot if that helps illustrate the problem
|
||||
label: Please provide a screenshot if possible
|
||||
|
||||
- type: textarea
|
||||
id: exception-or-error
|
||||
attributes:
|
||||
label: If this problem caused an exception or error, please paste it here
|
||||
label: Please provide the exception or error you saw
|
||||
render: true
|
||||
placeholder: |
|
||||
```
|
||||
Paste the exception or error here inside a markdown code block,
|
||||
which is annotated by three grave \(`\) characters before and after the text block.
|
||||
```
|
||||
|
||||
- type: textarea
|
||||
id: browser-info
|
||||
attributes:
|
||||
label: If the problem is browser-specific, please specify the device, OS, browser, and version
|
||||
render: true
|
||||
|
||||
- type: textarea
|
||||
id: additional-info
|
||||
attributes:
|
||||
label: Provide any additional information here in as much as detail as you can
|
||||
label: Is this a browser-specific issue? If so, please specify the device, browser, and version.
|
||||
render: true
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
name: 'Angular DevTools'
|
||||
description: Report an issue or suggest a feature for Angular DevTools
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: bug-report-or-feature-request
|
||||
attributes:
|
||||
label: Is this a bug report or a feature request?
|
||||
description: Select one.
|
||||
options:
|
||||
- label: Bug Report
|
||||
- label: Feature Request
|
||||
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Please provide the steps to reproduce the issue [Bug Report only]
|
||||
|
||||
- type: textarea
|
||||
id: expected-vs-actual-behavior
|
||||
attributes:
|
||||
label: Please provide the expected behavior vs the actual behavior you encountered [Bug Report only]
|
||||
|
||||
- type: textarea
|
||||
id: screenshot
|
||||
attributes:
|
||||
label: Please provide a screenshot if possible [Bug Report only]
|
||||
|
||||
- type: textarea
|
||||
id: exception-or-error
|
||||
attributes:
|
||||
label: Please provide the exception or error you saw [Bug Report only]
|
||||
render: true
|
||||
|
||||
- type: textarea
|
||||
id: browser-info
|
||||
attributes:
|
||||
label: Is this a browser-specific issue? If so, please specify the device, browser, and version. [Bug Report only]
|
||||
render: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description [Feature Request only]
|
||||
|
||||
- type: textarea
|
||||
id: proposed-solution
|
||||
attributes:
|
||||
label: Proposed solution [Feature Request only]
|
||||
|
||||
- type: textarea
|
||||
id: alternatives-considered
|
||||
attributes:
|
||||
label: Alternatives considered [Feature Request only]
|
||||
@@ -4,11 +4,11 @@ contact_links:
|
||||
url: https://angular.io/guide/security#report-issues
|
||||
about: Report a security issue in Angular Framework, CDK, Material, or CLI
|
||||
- name: Angular CLI
|
||||
url: https://github.com/angular/angular-cli/issues/new/choose
|
||||
url: https://github.com/angular/angular/issues/new/choose
|
||||
about: Issues and feature requests for Angular CLI
|
||||
- name: Angular Material and Components Development Kit (CDK)
|
||||
url: https://github.com/angular/components/issues/new/choose
|
||||
about: Issues and feature requests for Angular Material
|
||||
- name: Support Request
|
||||
url: https://github.com/angular/angular/blob/main/CONTRIBUTING.md#question
|
||||
url: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
|
||||
about: Questions and requests for support
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## PR Checklist
|
||||
Please check if your PR fulfills the following requirements:
|
||||
|
||||
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit
|
||||
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit
|
||||
- [ ] Tests for the changes have been added (for bug fixes / features)
|
||||
- [ ] Docs have been added / updated (for bug fixes / features)
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
name: 'Installing Yarn dependencies'
|
||||
description: 'Installs the dependencies using Yarn'
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4
|
||||
with:
|
||||
path: |
|
||||
./node_modules/
|
||||
# If just `WORKSPACE` or `yarn.lock` is changed, the most recent cache can be restored.
|
||||
# See: https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows#example-using-the-cache-action.
|
||||
key: v1-angular-main-deps-${{hashFiles('WORKSPACE')}}-${{hashFiles('yarn.lock')}}
|
||||
restore-keys: v1-angular-main-deps-
|
||||
|
||||
- run: yarn install --frozen-lockfile --non-interactive
|
||||
shell: bash
|
||||
+64
-19
@@ -1,8 +1,8 @@
|
||||
# Configuration for angular-robot
|
||||
|
||||
# options for the size plugin
|
||||
#options for the size plugin
|
||||
size:
|
||||
disabled: true
|
||||
disabled: false
|
||||
maxSizeIncrease: 2000
|
||||
circleCiStatusName: 'ci/circleci: test'
|
||||
|
||||
@@ -22,7 +22,7 @@ merge:
|
||||
# the g3 status will be added to your pull requests if they include files that match the patterns
|
||||
g3Status:
|
||||
# set to true to disable
|
||||
disabled: true
|
||||
disabled: false
|
||||
# the name of the status
|
||||
context: 'google3'
|
||||
# text to show when the status is pending, {{PRNumber}} will be replaced by the PR number
|
||||
@@ -32,8 +32,50 @@ merge:
|
||||
# link to use for the details
|
||||
url: 'http://go/angular/g3sync'
|
||||
# list of patterns to check for the files changed by the PR
|
||||
# this list must be manually kept in sync with google3/third_party/javascript/angular2/copy.bara.sky
|
||||
include:
|
||||
- 'LICENSE'
|
||||
- 'modules/benchmarks/**'
|
||||
- 'modules/system.d.ts'
|
||||
- 'packages/**'
|
||||
# list of patterns to ignore for the files changed by the PR
|
||||
exclude:
|
||||
- 'packages/*'
|
||||
- 'packages/bazel/*'
|
||||
- 'packages/bazel/src/api-extractor/**'
|
||||
- 'packages/bazel/src/ng_package/**'
|
||||
- 'packages/bazel/src/ng_module/**'
|
||||
- 'packages/compiler-cli/src/ngcc/**'
|
||||
- 'packages/compiler-cli/linker/**'
|
||||
- 'packages/compiler-cli/ngcc/**'
|
||||
- 'packages/compiler-cli/src/ngtsc/sourcemaps/**'
|
||||
- 'packages/docs/**'
|
||||
- 'packages/elements/schematics/**'
|
||||
- 'packages/examples/**'
|
||||
- 'packages/language-service/**'
|
||||
- 'packages/localize/**'
|
||||
- 'packages/private/**'
|
||||
- 'packages/service-worker/**'
|
||||
- 'packages/common/locales/**'
|
||||
- 'packages/http/**'
|
||||
- '**/.gitignore'
|
||||
- '**/.gitkeep'
|
||||
- '**/yarn.lock'
|
||||
- '**/package.json'
|
||||
- '**/third_party/**'
|
||||
- '**/tsconfig-build.json'
|
||||
- '**/tsconfig-tsec.json'
|
||||
- '**/tsconfig.json'
|
||||
- '**/rollup.config.js'
|
||||
- '**/BUILD.bazel'
|
||||
- '**/*.md'
|
||||
- 'packages/**/integrationtest/**'
|
||||
- 'packages/**/test/**'
|
||||
- 'packages/zone.js/*'
|
||||
- 'packages/zone.js/dist/**'
|
||||
- 'packages/zone.js/doc/**'
|
||||
- 'packages/zone.js/example/**'
|
||||
- 'packages/zone.js/scripts/**'
|
||||
|
||||
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable
|
||||
mergeConflictComment: "Hi @{{PRAuthor}}! This PR has merge conflicts due to recent upstream merges.\nPlease help to unblock it by resolving these conflicts. Thanks!"
|
||||
@@ -55,7 +97,7 @@ merge:
|
||||
|
||||
# whether the PR shouldn't have a conflict with the base branch
|
||||
noConflict: true
|
||||
# list of labels that a PR needs to have, checked with a regexp.
|
||||
# list of labels that a PR needs to have, checked with a regexp (e.g. "target:" will work for the label "target: master")
|
||||
requiredLabels:
|
||||
- 'target: *'
|
||||
|
||||
@@ -68,13 +110,16 @@ merge:
|
||||
|
||||
# list of PR statuses that need to be successful
|
||||
requiredStatuses:
|
||||
- 'google-internal-tests'
|
||||
- 'ci/circleci: build'
|
||||
- 'ci/circleci: lint'
|
||||
- 'ci/angular: size'
|
||||
- 'google3'
|
||||
- 'pullapprove'
|
||||
|
||||
# the comment that will be added when the merge label is added despite failing checks, leave empty or set to false to disable
|
||||
# {{MERGE_LABEL}} will be replaced by the value of the mergeLabel option
|
||||
# {{PLACEHOLDER}} will be replaced by the list of failing checks
|
||||
mergeRemovedComment: "I see that you just added the `{{MERGE_LABEL}}` label, but the following checks are still failing:\n{{PLACEHOLDER}}\n\n**If you want your PR to be merged, it has to pass all the CI checks.**\n\nIf you can't get the PR to a green state due to flakes or broken `main`, please try rebasing to `main` and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help."
|
||||
mergeRemovedComment: "I see that you just added the `{{MERGE_LABEL}}` label, but the following checks are still failing:\n{{PLACEHOLDER}}\n\n**If you want your PR to be merged, it has to pass all the CI checks.**\n\nIf you can't get the PR to a green state due to flakes or broken master, please try rebasing to master and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help."
|
||||
|
||||
# options for the triage plugin
|
||||
triage:
|
||||
@@ -84,29 +129,29 @@ triage:
|
||||
defaultMilestone: 82,
|
||||
# arrays of labels that determine if an issue has been triaged by the caretaker
|
||||
l1TriageLabels:
|
||||
- - 'area: *'
|
||||
- - 'comp: *'
|
||||
# arrays of labels that determine if an issue has been fully triaged
|
||||
l2TriageLabels:
|
||||
- - 'P0'
|
||||
- 'area: *'
|
||||
- 'comp: *'
|
||||
- - 'P1'
|
||||
- 'area: *'
|
||||
- 'comp: *'
|
||||
- - 'P2'
|
||||
- 'area: *'
|
||||
- 'comp: *'
|
||||
- - 'P3'
|
||||
- 'area: *'
|
||||
- 'comp: *'
|
||||
- - 'P4'
|
||||
- 'area: *'
|
||||
- 'comp: *'
|
||||
- - 'P5'
|
||||
- 'area: *'
|
||||
- 'comp: *'
|
||||
- - 'feature'
|
||||
- 'area: *'
|
||||
- 'comp: *'
|
||||
- - 'discussion'
|
||||
- 'area: *'
|
||||
- 'comp: *'
|
||||
- - 'needs clarification'
|
||||
- 'area: *'
|
||||
- 'comp: *'
|
||||
- - 'needs reproduction'
|
||||
- 'area: *'
|
||||
- 'comp: *'
|
||||
|
||||
# options for the triage PR plugin
|
||||
triagePR:
|
||||
@@ -118,10 +163,10 @@ triagePR:
|
||||
defaultMilestone: 82,
|
||||
# arrays of labels that determine if a PR has been triaged by the caretaker
|
||||
l1TriageLabels:
|
||||
- - 'area: *'
|
||||
- - 'comp: *'
|
||||
# arrays of labels that determine if a PR has been fully triaged
|
||||
l2TriageLabels:
|
||||
- - 'area: *'
|
||||
- - 'comp: *'
|
||||
|
||||
# options for rerunning CI
|
||||
rerunCircleCI:
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
# This workflow builds the previews for pull requests when a certain label is applied.
|
||||
# The actual deployment happens as part of a dedicated second workflow to avoid security
|
||||
# issues where the building would otherwise occur in an authorized context where secrets
|
||||
# could be leaked. More details can be found here:
|
||||
|
||||
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/.
|
||||
|
||||
name: Build adev for preview deployment
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [synchronize, labeled]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
adev-build:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
(github.event.action == 'labeled' && github.event.label.name == 'adev: preview') ||
|
||||
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'adev: preview'))
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev to ensure it continues to work
|
||||
run: yarn bazel build --config=aio_local_deps //adev:build
|
||||
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
with:
|
||||
workflow-artifact-name: 'adev-preview'
|
||||
pull-number: '${{github.event.pull_request.number}}'
|
||||
artifact-build-revision: '${{github.event.pull_request.head.sha}}'
|
||||
deploy-directory: './dist/bin/adev/build/browser'
|
||||
@@ -1,50 +0,0 @@
|
||||
# This workflow runs whenever the ADEV build workflow has completed. Deployment happens
|
||||
# as part of a dedicated second workflow to avoid security issues where the building would
|
||||
# otherwise occur in an authorized context where secrets could be leaked.
|
||||
#
|
||||
# More details can be found here:
|
||||
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/.
|
||||
|
||||
name: Deploying adev preview to Firebase
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ['Build adev for preview deployment']
|
||||
types: [completed]
|
||||
|
||||
permissions:
|
||||
# Needed in order to be able to comment on the pull request.
|
||||
pull-requests: write
|
||||
# Needed in order to checkout the repository
|
||||
contents: read
|
||||
# Needed in order to retrieve the artifacts from the previous job
|
||||
actions: read
|
||||
|
||||
env:
|
||||
PREVIEW_PROJECT: ng-dev-previews
|
||||
PREVIEW_SITE: ng-dev-previews-fw
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
|
||||
with:
|
||||
token: '${{secrets.GITHUB_TOKEN}}'
|
||||
|
||||
- name: Configure Firebase deploy target
|
||||
working-directory: ./
|
||||
run: |
|
||||
# We can use `npx` as the Firebase deploy actions uses it too.
|
||||
npx -y firebase-tools@latest target:clear --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs
|
||||
npx -y firebase-tools@latest target:apply --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs ${{env.PREVIEW_SITE}}
|
||||
|
||||
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
with:
|
||||
github-token: '${{secrets.GITHUB_TOKEN}}'
|
||||
workflow-artifact-name: 'adev-preview'
|
||||
firebase-config-dir: './adev'
|
||||
firebase-public-dir: './adev/build/browser'
|
||||
firebase-project-id: '${{env.PREVIEW_PROJECT}}'
|
||||
firebase-service-key: '${{secrets.FIREBASE_PREVIEW_SERVICE_TOKEN}}'
|
||||
@@ -1,21 +0,0 @@
|
||||
name: DevInfra
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened, ready_for_review, labeled]
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
assistant_to_the_branch_manager:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
@@ -1,68 +0,0 @@
|
||||
name: Run benchmark comparison
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
benchmark-compare:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.issue.pull_request && startsWith(github.event.comment.body, '/benchmark-compare ')}}
|
||||
steps:
|
||||
- uses: TheModdingInquisition/actions-team-membership@a69636a92bc927f32c3910baac06bacc949c984c # v1.0
|
||||
with:
|
||||
team: 'team'
|
||||
organization: angular
|
||||
token: ${{secrets.BENCHMARK_COMPARE_MEMBERSHIP_GITHUB_TOKEN}}
|
||||
exit: true
|
||||
|
||||
# Indicate that the benchmark command was received.
|
||||
- uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4
|
||||
with:
|
||||
comment-id: ${{github.event.comment.id}}
|
||||
token: '${{secrets.BENCHMARK_POST_RESULTS_GITHUB_TOKEN}}'
|
||||
reactions: 'rocket'
|
||||
|
||||
- uses: alessbell/pull-request-comment-branch@aad01d65d6982b8eacabed5e9a684cd8ceb98da6 # v1.1
|
||||
id: comment-branch
|
||||
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
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}}
|
||||
# Checkout the pull request and assume it being trusted given we've checked
|
||||
# that the action was triggered by a team member.
|
||||
ref: ${{steps.comment-branch.outputs.head_ref}}
|
||||
|
||||
- uses: ./.github/actions/yarn-install
|
||||
|
||||
- uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
with:
|
||||
bazelrc: ./.bazelrc.user
|
||||
|
||||
- name: Preparing benchmark for GitHub action
|
||||
id: info
|
||||
env:
|
||||
# Untrusted input used in an executable code, must be wrapped as an env var to prevent injections
|
||||
COMMENT_BODY: ${{ github.event.comment.body }}
|
||||
run: yarn benchmarks prepare-for-github-action "$COMMENT_BODY"
|
||||
|
||||
- run: yarn benchmarks run-compare ${{steps.info.outputs.compareSha}} ${{steps.info.outputs.benchmarkTarget}}
|
||||
id: benchmark
|
||||
name: Running benchmark
|
||||
|
||||
- uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4
|
||||
with:
|
||||
issue-number: ${{github.event.issue.number}}
|
||||
token: '${{secrets.BENCHMARK_POST_RESULTS_GITHUB_TOKEN}}'
|
||||
body: |
|
||||
## Benchmark Test Results
|
||||
**Test**: `${{steps.info.outputs.benchmarkTarget}}`
|
||||
|
||||
### PR (${{steps.info.outputs.prHeadSha}})
|
||||
${{steps.benchmark.outputs.workingStageResultsText}}
|
||||
|
||||
### Compare Ref (${{steps.info.outputs.compareSha}})
|
||||
${{steps.benchmark.outputs.comparisonResultsText}}
|
||||
@@ -1,277 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- '[0-9]+.[0-9]+.x'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./node_modules
|
||||
./aio/node_modules
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Install node modules in aio
|
||||
run: yarn install --frozen-lockfile --cwd aio
|
||||
- name: Check code lint
|
||||
run: yarn -s tslint
|
||||
- name: Check for circular dependencies
|
||||
run: yarn -s ts-circular-deps:check
|
||||
- name: Validate pull approve configuration
|
||||
run: yarn -s ng-dev pullapprove verify
|
||||
- name: Validate angular robot configuration
|
||||
run: yarn -s ng-dev ngbot verify
|
||||
- name: Confirm code builds with typescript as expected
|
||||
run: yarn -s check-tooling-setup
|
||||
- name: Check commit message
|
||||
# Commit message validation is only done on pull requests as its too late to validate once
|
||||
# it has been merged.
|
||||
if: github.event_name == 'pull_request'
|
||||
run: yarn ng-dev commit-message validate-range ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}
|
||||
- name: Check code format
|
||||
# Code formatting checks are only done on pull requests as its too late to validate once
|
||||
# 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@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- 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
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile --network-timeout 100000
|
||||
- name: Run CI tests for framework
|
||||
run: yarn test:ci
|
||||
|
||||
adev:
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev to ensure it continues to work
|
||||
run: yarn bazel test --config=aio_local_deps //adev:test
|
||||
|
||||
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@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- 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@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
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@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- 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 \
|
||||
|
||||
- run: |
|
||||
rm -Rf packages/zone.js/build
|
||||
rm -Rf packages/zone.js/test/extra/*.umd.js
|
||||
|
||||
mkdir -p packages/zone.js/build/
|
||||
mkdir -p packages/zone.js/build/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
|
||||
|
||||
# Install
|
||||
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive
|
||||
# Run zone.js tools tests
|
||||
- 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/test/typings install --frozen-lockfile --non-interactive
|
||||
- run: yarn --cwd packages/zone.js/test/typings test
|
||||
|
||||
bazel-saucelabs:
|
||||
# TODO: Replace legacy job with Bazel saucelabs job.
|
||||
if: github.event_name == 'push'
|
||||
runs-on: ubuntu-latest-4core
|
||||
env:
|
||||
JOBS: 2
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
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@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@50bb71e51d3372ca2e359adb9069f89beeac4ae7
|
||||
- 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 }}
|
||||
- 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}
|
||||
|
||||
saucelabs:
|
||||
runs-on: ubuntu-latest-4core
|
||||
env:
|
||||
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@50bb71e51d3372ca2e359adb9069f89beeac4ae7
|
||||
- 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
|
||||
|
||||
adev-deploy:
|
||||
needs: [adev]
|
||||
if: needs.adev.result == 'success' && github.event_name == 'push' && github.ref_name == 'main'
|
||||
env:
|
||||
DEPLOY_PROJECT: angular-dev-site
|
||||
DEPLOY_SITE: angular-dev-site
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev to ensure it continues to work
|
||||
run: yarn bazel build --config=aio_local_deps //adev:build
|
||||
- name: Move generated project files into deployment directory
|
||||
run: cp -r dist/bin/adev/build adev/build
|
||||
- name: Setup firebase context
|
||||
run: |
|
||||
npx -y firebase-tools@latest target:clear --config adev/firebase.json --project ${{ env.DEPLOY_PROJECT }} hosting angular-docs
|
||||
npx -y firebase-tools@latest target:apply --config adev/firebase.json --project ${{ env.DEPLOY_PROJECT }} hosting angular-docs ${{ env.DEPLOY_SITE }}
|
||||
- name: Deploy to firebase
|
||||
uses: FirebaseExtended/action-hosting-deploy@120e124148ab7016bec2374e5050f15051255ba2 # v0.7.1
|
||||
with:
|
||||
entryPoint: './adev'
|
||||
firebaseServiceAccount: ${{ secrets.ANGULAR_DEV_SITE_DEPLOY }}
|
||||
projectId: ${{ env.DEPLOY_PROJECT }}
|
||||
channelId: live
|
||||
@@ -12,14 +12,7 @@ jobs:
|
||||
labels:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
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@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 # tag=v3.0.0
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@ff24a8ca7be9066fc9a7ece62c1b62d064c3dfff
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
name: Feature request triage bot
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run at 14:00 every day
|
||||
- cron: '0 14 * * *'
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
feature_triage:
|
||||
if: github.repository == 'angular/angular'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: angular/dev-infra/github-actions/feature-request@ff24a8ca7be9066fc9a7ece62c1b62d064c3dfff
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
@@ -1,21 +0,0 @@
|
||||
name: Google Internal Tests Enforcement
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
permissions: {}
|
||||
|
||||
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@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
with:
|
||||
run-tests-guide-url: http://go/angular-g3sync-start
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
sync-config: ./.ng-dev/google-sync-config.json
|
||||
@@ -0,0 +1,19 @@
|
||||
name: Lock closed inactive issues
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run at 16:00 every day
|
||||
- cron: '0 16 * * *'
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lock_closed:
|
||||
if: github.repository == 'angular/angular'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: angular/dev-infra/github-actions/lock-closed@ff24a8ca7be9066fc9a7ece62c1b62d064c3dfff
|
||||
with:
|
||||
lock-bot-key: ${{ secrets.LOCK_BOT_PRIVATE_KEY }}
|
||||
@@ -1,14 +0,0 @@
|
||||
name: Merge Ready
|
||||
|
||||
on: pull_request_target
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
status:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: angular/dev-infra/github-actions/unified-status-check@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
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@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./aio/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
- 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@5774b71c01a55c4c998f858ee37d3b77ae704c31
|
||||
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
|
||||
@@ -4,7 +4,7 @@ on:
|
||||
schedule:
|
||||
- cron: '0 0 * * 0'
|
||||
push:
|
||||
branches: [main]
|
||||
branches: [master]
|
||||
workflow_dispatch:
|
||||
|
||||
# Declare default permissions as read only.
|
||||
@@ -18,19 +18,17 @@ jobs:
|
||||
permissions:
|
||||
# Needed to upload the results to code-scanning dashboard.
|
||||
security-events: write
|
||||
# Needed to publish results
|
||||
id-token: write
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: 'Checkout code'
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@230611dbd0eb52da1e1f4f7bc8bb0c3a339fc8b7
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: 'Run analysis'
|
||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
|
||||
uses: ossf/scorecard-action@3662744abc9b750123cb8965fef31e3802d52da5
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -39,7 +37,7 @@ jobs:
|
||||
|
||||
# Upload the results as artifacts.
|
||||
- name: 'Upload artifact'
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@2244c8200304ec9588bf9399eac622d9fadc28c4
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
@@ -47,6 +45,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: 'Upload to code-scanning'
|
||||
uses: github/codeql-action/upload-sarif@05963f47d870e2cb19a537396c1f668a348c7d8f # v3.24.8
|
||||
uses: github/codeql-action/upload-sarif@040feefecff4ae0fc15c110822a5f96516b0629e
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
name: Update AIO Angular CLI help
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- '[0-9]+.[0-9]+.x'
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
update_cli_help:
|
||||
name: Update Angular CLI help (if necessary)
|
||||
if: github.repository == 'angular/angular'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
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
|
||||
# an authenticated URL.
|
||||
persist-credentials: false
|
||||
# This is needed as otherwise the PR creation will fail with `shallow update not allowed` when the forked branch is not in sync.
|
||||
fetch-depth: 0
|
||||
- name: Generate CLI help
|
||||
run: node aio/scripts/update-cli-help/index.mjs
|
||||
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@1421ff04811ecb45812930c5d1f61d912880e75f
|
||||
with:
|
||||
branch-prefix: update-cli-help
|
||||
pr-title: 'docs: update Angular CLI help [${{github.ref_name}}]'
|
||||
pr-description: |
|
||||
Updated Angular CLI help contents.
|
||||
pr-labels: |
|
||||
action: review
|
||||
area: docs
|
||||
angular-robot-token: ${{ secrets.ANGULAR_ROBOT_ACCESS_TOKEN }}
|
||||
+1
-6
@@ -4,7 +4,7 @@
|
||||
/bazel-out
|
||||
/integration/bazel/bazel-*
|
||||
*.log
|
||||
/node_modules/
|
||||
node_modules
|
||||
|
||||
# CircleCI temporary file for cache key computation.
|
||||
# See `save_month_to_file` in `.circleci/config.yml`.
|
||||
@@ -56,8 +56,3 @@ baseline.json
|
||||
|
||||
# Husky
|
||||
.husky/_
|
||||
aio/content/examples/.DS_Store
|
||||
|
||||
|
||||
# Ignore cache created with the Angular CLI.
|
||||
.angular/
|
||||
+4
-5
@@ -74,7 +74,7 @@ Fixes #<issue number>
|
||||
# =============================
|
||||
#
|
||||
# The full specification of the Angular Commit Message Format can be found at
|
||||
# https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit
|
||||
# https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit
|
||||
#
|
||||
# The following is an excerpt of the specification with the most commonly needed info.
|
||||
#
|
||||
@@ -106,12 +106,11 @@ Fixes #<issue number>
|
||||
# │ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
||||
# │ elements|forms|http|language-service|localize|platform-browser|
|
||||
# │ platform-browser-dynamic|platform-server|router|service-worker|
|
||||
# │ upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve|
|
||||
# │ devtools
|
||||
# │ https://github.com/angular/angular/blob/main/CONTRIBUTING.md#scope
|
||||
# │ upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve
|
||||
# │ https://github.com/angular/angular/blob/master/CONTRIBUTING.md#scope
|
||||
# │
|
||||
# └─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test
|
||||
# https://github.com/angular/angular/blob/main/CONTRIBUTING.md#type
|
||||
# https://github.com/angular/angular/blob/master/CONTRIBUTING.md#type
|
||||
#
|
||||
#
|
||||
# Commit Message Body
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname $0)/_/husky.sh"
|
||||
|
||||
set +e
|
||||
|
||||
yarn -s ng-dev commit-message pre-commit-validate --file $1 2>/dev/null
|
||||
|
||||
+4
-1
@@ -1,8 +1,11 @@
|
||||
set +e
|
||||
#!/bin/sh
|
||||
. "$(dirname $0)/_/husky.sh"
|
||||
|
||||
set +e
|
||||
yarn -s ng-dev format staged 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "WARNING: failed to run file formatting (ng-dev format staged)"
|
||||
fi
|
||||
|
||||
|
||||
exit 0;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname $0)/_/husky.sh"
|
||||
|
||||
set +e
|
||||
|
||||
yarn -s ng-dev commit-message restore-commit-message-draft $1 $2 2>/dev/null
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import {CaretakerConfig} from '@angular/ng-dev';
|
||||
|
||||
/** The configuration for `ng-dev caretaker` commands. */
|
||||
export const caretaker: CaretakerConfig = {
|
||||
g3SyncConfigPath: './.ng-dev/google-sync-config.json',
|
||||
githubQueries: [
|
||||
{
|
||||
name: 'Merge Queue',
|
||||
query: `is:pr is:open status:success label:"action: merge"`,
|
||||
},
|
||||
{
|
||||
name: 'Merge Assistance Queue',
|
||||
query: `is:pr is:open label:"merge: caretaker note" label:"action: merge"`,
|
||||
},
|
||||
{
|
||||
name: 'Initial Triage Queue',
|
||||
query: `is:open no:milestone -draft:true`,
|
||||
},
|
||||
],
|
||||
caretakerGroup: 'angular-caretaker',
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import {CaretakerConfig} from '@angular/dev-infra-private/ng-dev';
|
||||
|
||||
/** The configuration for `ng-dev caretaker` commands. */
|
||||
export const caretaker: CaretakerConfig = {
|
||||
githubQueries: [
|
||||
{
|
||||
name: 'Merge Queue',
|
||||
query: `is:pr is:open status:success label:"action: merge"`,
|
||||
},
|
||||
{
|
||||
name: 'Merge Assistance Queue',
|
||||
query: `is:pr is:open label:"action: merge-assistance"`,
|
||||
},
|
||||
{
|
||||
name: 'Initial Triage Queue',
|
||||
query: `is:open no:milestone`,
|
||||
},
|
||||
],
|
||||
caretakerGroup: 'angular-caretaker',
|
||||
};
|
||||
@@ -1,38 +0,0 @@
|
||||
import {CommitMessageConfig} from '@angular/ng-dev';
|
||||
|
||||
/**
|
||||
* The configuration for `ng-dev commit-message` commands.
|
||||
*/
|
||||
export const commitMessage: CommitMessageConfig = {
|
||||
maxLineLength: Infinity,
|
||||
minBodyLength: 20,
|
||||
minBodyLengthTypeExcludes: ['docs'],
|
||||
scopes: [
|
||||
'animations',
|
||||
'bazel',
|
||||
'benchpress',
|
||||
'changelog',
|
||||
'common',
|
||||
'compiler',
|
||||
'compiler-cli',
|
||||
'core',
|
||||
'dev-infra',
|
||||
'devtools',
|
||||
'docs-infra',
|
||||
'elements',
|
||||
'forms',
|
||||
'http',
|
||||
'language-service',
|
||||
'localize',
|
||||
'migrations',
|
||||
'packaging',
|
||||
'platform-browser',
|
||||
'platform-browser-dynamic',
|
||||
'platform-server',
|
||||
'router',
|
||||
'service-worker',
|
||||
'upgrade',
|
||||
've',
|
||||
'zone.js',
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
import {CommitMessageConfig} from '@angular/dev-infra-private/ng-dev';
|
||||
|
||||
/**
|
||||
* The configuration for `ng-dev commit-message` commands.
|
||||
*/
|
||||
export const commitMessage: CommitMessageConfig = {
|
||||
maxLineLength: Infinity,
|
||||
minBodyLength: 20,
|
||||
minBodyLengthTypeExcludes: ['docs'],
|
||||
scopes: [
|
||||
'animations',
|
||||
'bazel',
|
||||
'benchpress',
|
||||
'changelog',
|
||||
'common',
|
||||
'compiler',
|
||||
'compiler-cli',
|
||||
'core',
|
||||
'dev-infra',
|
||||
'docs-infra',
|
||||
'elements',
|
||||
'forms',
|
||||
'http',
|
||||
'language-service',
|
||||
'localize',
|
||||
'migrations',
|
||||
'ngcc',
|
||||
'packaging',
|
||||
'platform-browser',
|
||||
'platform-browser-dynamic',
|
||||
'platform-server',
|
||||
'platform-webworker',
|
||||
'platform-webworker-dynamic',
|
||||
'router',
|
||||
'service-worker',
|
||||
'upgrade',
|
||||
've',
|
||||
'zone.js',
|
||||
],
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
import {caretaker} from './caretaker.mjs';
|
||||
import {commitMessage} from './commit-message.mjs';
|
||||
import {format} from './format.mjs';
|
||||
import {github} from './github.mjs';
|
||||
import {pullRequest} from './pull-request.mjs';
|
||||
import {release} from './release.mjs';
|
||||
|
||||
export {
|
||||
commitMessage,
|
||||
format,
|
||||
github,
|
||||
pullRequest,
|
||||
caretaker,
|
||||
release,
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import {caretaker} from './caretaker';
|
||||
import {commitMessage} from './commit-message';
|
||||
import {format} from './format';
|
||||
import {github} from './github';
|
||||
import {pullRequest} from './pullRequest';
|
||||
import {release} from './release';
|
||||
|
||||
module.exports = {
|
||||
commitMessage,
|
||||
format,
|
||||
github,
|
||||
pullRequest,
|
||||
caretaker,
|
||||
release,
|
||||
};
|
||||
@@ -1,81 +0,0 @@
|
||||
import {FormatConfig} from '@angular/ng-dev';
|
||||
|
||||
/**
|
||||
* Configuration for the `ng-dev format` command.
|
||||
*/
|
||||
export const format: FormatConfig = {
|
||||
'prettier': {
|
||||
'matchers': [
|
||||
'**/*.{yaml,yml}',
|
||||
'adev/**/*.{js,ts}',
|
||||
'devtools/**/*.{js,ts}',
|
||||
'tools/**/*.{js,ts}',
|
||||
'modules/**/*.{js,ts}',
|
||||
'scripts/**/*.{js,ts}',
|
||||
'packages/animations/**/*.{js,ts}',
|
||||
'packages/bazel/**/*.{js,ts}',
|
||||
'packages/benchpress/**/*.{js,ts}',
|
||||
'packages/common/**/*.{js,ts}',
|
||||
'packages/docs/**/*.{js,ts}',
|
||||
'packages/elements/**/*.{js,ts}',
|
||||
'packages/examples/**/*.{js,ts}',
|
||||
'packages/misc/**/*.{js,ts}',
|
||||
'packages/private/**/*.{js,ts}',
|
||||
'packages/router/**/*.{js,ts}',
|
||||
'packages/service-worker/**/*.{js,ts}',
|
||||
'packages/upgrade/**/*.{js,ts}',
|
||||
|
||||
// Do not format d.ts files as they are generated
|
||||
'!**/*.d.ts',
|
||||
// Both third_party and .yarn are directories containing copied code which should
|
||||
// not be modified.
|
||||
'!third_party/**',
|
||||
'!.yarn/**',
|
||||
],
|
||||
},
|
||||
'clang-format': {
|
||||
'matchers': [
|
||||
'**/*.{js,ts}',
|
||||
// TODO: burn down format failures and remove aio and integration exceptions.
|
||||
'!aio/**',
|
||||
'!integration/**',
|
||||
// Both third_party and .yarn are directories containing copied code which should
|
||||
// not be modified.
|
||||
'!third_party/**',
|
||||
'!.yarn/**',
|
||||
// Do not format d.ts files as they are generated
|
||||
'!**/*.d.ts',
|
||||
// Do not format generated ng-dev script
|
||||
'!dev-infra/ng-dev.js',
|
||||
'!dev-infra/build-worker.js',
|
||||
// Do not format compliance test-cases since they must match generated code
|
||||
'!packages/compiler-cli/test/compliance/test_cases/**/*.js',
|
||||
// Do not format the locale files which are checked-in for Google3, but generated using
|
||||
// the `generate-locales-tool` from `packages/common/locales`.
|
||||
'!packages/core/src/i18n/locale_en.ts',
|
||||
'!packages/common/locales/closure-locale.ts',
|
||||
'!packages/common/src/i18n/currencies.ts',
|
||||
// Temporarily disable formatting for adev
|
||||
'!adev/**',
|
||||
|
||||
// Migrated to prettier
|
||||
'!devtools/**/*.{js,ts}',
|
||||
'!tools/**/*.{js,ts}',
|
||||
'!modules/**/*.{js,ts}',
|
||||
'!scripts/**/*.{js,ts}',
|
||||
'!packages/animations/**/*.{js,ts}',
|
||||
'!packages/bazel/**/*.{js,ts}',
|
||||
'!packages/benchpress/**/*.{js,ts}',
|
||||
'!packages/common/**/*.{js,ts}',
|
||||
'!packages/docs/**/*.{js,ts}',
|
||||
'!packages/elements/**/*.{js,ts}',
|
||||
'!packages/examples/**/*.{js,ts}',
|
||||
'!packages/misc/**/*.{js,ts}',
|
||||
'!packages/private/**/*.{js,ts}',
|
||||
'!packages/router/**/*.{js,ts}',
|
||||
'!packages/service-worker/**/*.{js,ts}',
|
||||
'!packages/upgrade/**/*.{js,ts}',
|
||||
],
|
||||
},
|
||||
'buildifier': true,
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
import {FormatConfig} from '@angular/dev-infra-private/ng-dev';
|
||||
|
||||
/**
|
||||
* Configuration for the `ng-dev format` command.
|
||||
*/
|
||||
export const format: FormatConfig = {
|
||||
'prettier': {
|
||||
'matchers': ['**/*.{yaml,yml}'],
|
||||
},
|
||||
'clang-format': {
|
||||
'matchers': [
|
||||
'**/*.{js,ts}',
|
||||
// TODO: burn down format failures and remove aio and integration exceptions.
|
||||
'!aio/**',
|
||||
'!integration/**',
|
||||
// Both third_party and .yarn are directories containing copied code which should
|
||||
// not be modified.
|
||||
'!third_party/**',
|
||||
'!.yarn/**',
|
||||
// Do not format d.ts files as they are generated
|
||||
'!**/*.d.ts',
|
||||
// Do not format generated ng-dev script
|
||||
'!dev-infra/ng-dev.js',
|
||||
'!dev-infra/build-worker.js',
|
||||
// Do not format compliance test-cases since they must match generated code
|
||||
'!packages/compiler-cli/test/compliance/test_cases/**/*.js',
|
||||
// Do not format the locale files which are checked-in for Google3, but generated using
|
||||
// the `generate-locales-tool` from `packages/common/locales`.
|
||||
'!packages/core/src/i18n/locale_en.ts',
|
||||
'!packages/common/locales/closure-locale.ts',
|
||||
'!packages/common/src/i18n/currencies.ts',
|
||||
],
|
||||
},
|
||||
'buildifier': true,
|
||||
};
|
||||
@@ -1,12 +0,0 @@
|
||||
import {GithubConfig} from '@angular/ng-dev';
|
||||
|
||||
/**
|
||||
* Github configuration for the `ng-dev` command. This repository is used as
|
||||
* remote for the merge script and other utilities like `ng-dev pr rebase`.
|
||||
*/
|
||||
export const github: GithubConfig = {
|
||||
owner: 'angular',
|
||||
name: 'angular',
|
||||
mainBranchName: 'main',
|
||||
useNgDevAuthService: true,
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
import {GithubConfig} from '@angular/dev-infra-private/ng-dev';
|
||||
|
||||
/**
|
||||
* Github configuration for the `ng-dev` command. This repository is used as
|
||||
* remote for the merge script and other utilities like `ng-dev pr rebase`.
|
||||
*/
|
||||
export const github: GithubConfig = {
|
||||
owner: 'angular',
|
||||
name: 'angular',
|
||||
mainBranchName: 'master',
|
||||
};
|
||||
@@ -1,55 +0,0 @@
|
||||
{
|
||||
"syncedFilePatterns": [
|
||||
"LICENSE",
|
||||
"modules/benchmarks/**",
|
||||
"packages/**"
|
||||
],
|
||||
"separateFilePatterns": [
|
||||
"packages/core/primitives/**"
|
||||
],
|
||||
"alwaysExternalFilePatterns": [
|
||||
"packages/*",
|
||||
"packages/bazel/*",
|
||||
"packages/bazel/src/*",
|
||||
"packages/bazel/src/api-extractor/**",
|
||||
"packages/bazel/src/builders/**",
|
||||
"packages/bazel/src/ng_module/**",
|
||||
"packages/bazel/src/ng_package/**",
|
||||
"packages/bazel/src/protractor/**",
|
||||
"packages/bazel/src/schematics/**",
|
||||
"packages/bazel/src/types_bundle/**",
|
||||
"packages/compiler-cli/linker/**",
|
||||
"packages/compiler-cli/src/ngtsc/sourcemaps/**",
|
||||
"packages/compiler-cli/src/ngtsc/testing/**",
|
||||
"packages/compiler-cli/private/bazel.ts",
|
||||
"packages/compiler-cli/private/localize.ts",
|
||||
"packages/compiler-cli/private/tooling.ts",
|
||||
"packages/compiler-cli/private/babel.d.ts",
|
||||
"packages/compiler-cli/src/bin/**",
|
||||
"packages/docs/**",
|
||||
"packages/elements/schematics/**",
|
||||
"packages/examples/**",
|
||||
"packages/localize/**",
|
||||
"packages/private/**",
|
||||
"packages/service-worker/**",
|
||||
"packages/common/locales/generate-locales-tool/**",
|
||||
"packages/common/locales/index.bzl",
|
||||
"packages/http/**",
|
||||
"**/.gitignore",
|
||||
"**/.gitkeep",
|
||||
"**/third_party/**",
|
||||
"**/tsconfig-build.json",
|
||||
"**/tsconfig-tsec.json",
|
||||
"**/tsconfig.json",
|
||||
"**/rollup.config.js",
|
||||
"**/BUILD.bazel",
|
||||
"**/*.md",
|
||||
"packages/**/integrationtest/**",
|
||||
"packages/**/test/**",
|
||||
"packages/zone.js/*",
|
||||
"packages/zone.js/dist/**",
|
||||
"packages/zone.js/doc/**",
|
||||
"packages/zone.js/example/**",
|
||||
"packages/zone.js/scripts/**"
|
||||
]
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import {PullRequestConfig} from '@angular/ng-dev';
|
||||
|
||||
/**
|
||||
* Configuration for the merge tool in `ng-dev`. This sets up the labels which
|
||||
* are respected by the merge script (e.g. the target labels).
|
||||
*/
|
||||
export const pullRequest: PullRequestConfig = {
|
||||
githubApiMerge: false,
|
||||
requiredBaseCommits: {
|
||||
// PRs that target either `main` or the patch branch, need to be rebased
|
||||
// on top of the latest commit message validation fix.
|
||||
// These SHAs are the commits that update the required license text in the header.
|
||||
'main': '5aeb9a4124922d8ac08eb73b8f322905a32b0b3a',
|
||||
'10.0.x': '27b95ba64a5d99757f4042073fd1860e20e3ed24',
|
||||
},
|
||||
// `dev-infra` and `docs-infra` are not affecting the public NPM packages. Similarly,
|
||||
// the `bazel` package is not considered part of the public API so that features
|
||||
// can land in patch branches.
|
||||
targetLabelExemptScopes: ['dev-infra', 'docs-infra', 'bazel'],
|
||||
// enables specific validations during the pull request merge process
|
||||
validators: {
|
||||
assertEnforceTested: true,
|
||||
assertIsolatedSeparateFiles: true,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
import {PullRequestConfig} from '@angular/dev-infra-private/ng-dev';
|
||||
|
||||
/**
|
||||
* Configuration for the merge tool in `ng-dev`. This sets up the labels which
|
||||
* are respected by the merge script (e.g. the target labels).
|
||||
*/
|
||||
export const pullRequest: PullRequestConfig = {
|
||||
githubApiMerge: false,
|
||||
mergeReadyLabel: /^action: merge(-assistance)?/,
|
||||
caretakerNoteLabel: /^(action: merge-assistance)|(PullApprove: disable)/,
|
||||
commitMessageFixupLabel: 'commit message fixup',
|
||||
requiredBaseCommits: {
|
||||
// PRs that target either `master` or the patch branch, need to be rebased
|
||||
// on top of the latest commit message validation fix.
|
||||
// These SHAs are the commits that update the required license text in the header.
|
||||
'master': '5aeb9a4124922d8ac08eb73b8f322905a32b0b3a',
|
||||
'10.0.x': '27b95ba64a5d99757f4042073fd1860e20e3ed24',
|
||||
},
|
||||
// `dev-infra` and `docs-infra` are not affecting the public NPM packages. Similarly,
|
||||
// the `bazel` package is not considered part of the public API so that features
|
||||
// can land in patch branches.
|
||||
targetLabelExemptScopes: ['dev-infra', 'docs-infra', 'bazel'],
|
||||
};
|
||||
@@ -1,34 +0,0 @@
|
||||
import {ReleaseConfig} from '@angular/ng-dev';
|
||||
|
||||
/** Configuration for the `ng-dev release` command. */
|
||||
export const release: ReleaseConfig = {
|
||||
publishRegistry: 'https://wombat-dressing-room.appspot.com',
|
||||
representativeNpmPackage: '@angular/core',
|
||||
npmPackages: [
|
||||
{name: '@angular/animations'},
|
||||
{name: '@angular/common'},
|
||||
{name: '@angular/compiler'},
|
||||
{name: '@angular/compiler-cli'},
|
||||
{name: '@angular/core'},
|
||||
{name: '@angular/elements'},
|
||||
{name: '@angular/forms'},
|
||||
{name: '@angular/language-service'},
|
||||
{name: '@angular/localize'},
|
||||
{name: '@angular/platform-browser'},
|
||||
{name: '@angular/platform-browser-dynamic'},
|
||||
{name: '@angular/platform-server'},
|
||||
{name: '@angular/router'},
|
||||
{name: '@angular/service-worker'},
|
||||
{name: '@angular/upgrade'},
|
||||
],
|
||||
buildPackages: async () => {
|
||||
// The buildTargetPackages function is loaded at runtime as the loading the script
|
||||
// causes an invocation of Bazel.
|
||||
const {performNpmReleaseBuild} = await import('../scripts/build/package-builder.mjs');
|
||||
return performNpmReleaseBuild();
|
||||
},
|
||||
releaseNotes: {
|
||||
hiddenScopes: ['aio', 'bazel', 'dev-infra', 'docs-infra', 'zone.js', 'devtools'],
|
||||
},
|
||||
releasePrLabels: ['area: build & ci', 'action: merge', 'PullApprove: disable'],
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
import {ReleaseConfig} from '@angular/dev-infra-private/ng-dev';
|
||||
import {join} from 'path';
|
||||
|
||||
/** Configuration for the `ng-dev release` command. */
|
||||
export const release: ReleaseConfig = {
|
||||
publishRegistry: 'https://wombat-dressing-room.appspot.com',
|
||||
representativeNpmPackage: '@angular/core',
|
||||
npmPackages: [
|
||||
{name: '@angular/animations'},
|
||||
{name: '@angular/bazel'},
|
||||
{name: '@angular/common'},
|
||||
{name: '@angular/compiler'},
|
||||
{name: '@angular/compiler-cli'},
|
||||
{name: '@angular/core'},
|
||||
{name: '@angular/elements'},
|
||||
{name: '@angular/forms'},
|
||||
{name: '@angular/language-service'},
|
||||
{name: '@angular/localize'},
|
||||
{name: '@angular/platform-browser'},
|
||||
{name: '@angular/platform-browser-dynamic'},
|
||||
{name: '@angular/platform-server'},
|
||||
{name: '@angular/router'},
|
||||
{name: '@angular/service-worker'},
|
||||
{name: '@angular/upgrade'},
|
||||
],
|
||||
buildPackages: async () => {
|
||||
// The buildTargetPackages function is loaded at runtime as the loading the script causes an
|
||||
// invocation of bazel.
|
||||
const {buildTargetPackages} = require(join(__dirname, '../scripts/build/package-builder'));
|
||||
return buildTargetPackages('dist/release-output', false, 'Release', /* isRelease */ true);
|
||||
},
|
||||
releaseNotes: {
|
||||
hiddenScopes: ['aio', 'dev-infra', 'docs-infra', 'zone.js', 'devtools'],
|
||||
},
|
||||
releasePrLabels: ['comp: build & ci', 'action: merge', 'PullApprove: disable'],
|
||||
};
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"target": "es2020",
|
||||
"module": "Node16",
|
||||
"target": "es2015",
|
||||
"module": "commonjs",
|
||||
"noEmit": true,
|
||||
"skipLibCheck": true,
|
||||
"types": []
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2,
|
||||
"tabs": false,
|
||||
"embeddedLanguageFormatting": "off",
|
||||
"singleQuote": true,
|
||||
"semicolon": true,
|
||||
"quoteProps": "preserve",
|
||||
|
||||
+452
-487
File diff suppressed because it is too large
Load Diff
Vendored
+5
-1
@@ -4,8 +4,12 @@
|
||||
|
||||
// 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",
|
||||
// The following extensions are useful when working on angular.io (i.e. inside the `aio/` directory).
|
||||
//"angular.ng-template",
|
||||
//"dbaeumer.vscode-eslint",
|
||||
],
|
||||
}
|
||||
|
||||
Vendored
+21
-9
@@ -16,7 +16,7 @@
|
||||
"remoteRoot": "${workspaceRoot}",
|
||||
"stopOnEntry": false,
|
||||
"timeout": 600000,
|
||||
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
|
||||
"outFiles": ["${workspaceFolder}/bazel-out/**/angular/**/*.js"],
|
||||
},
|
||||
{
|
||||
"name": "Attach to bazel test ... --config=debug (no source maps)",
|
||||
@@ -30,46 +30,58 @@
|
||||
"remoteRoot": "${workspaceRoot}",
|
||||
"stopOnEntry": false,
|
||||
"timeout": 600000,
|
||||
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
|
||||
"outFiles": ["${workspaceFolder}/bazel-out/**/angular/**/*.js"],
|
||||
},
|
||||
{
|
||||
"name": "IVY:packages/core/test/acceptance",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/node_modules/.bin/bazelisk",
|
||||
"args": ["test", "packages/core/test/acceptance", "--config=debug"],
|
||||
"args": [
|
||||
"test",
|
||||
"packages/core/test/acceptance",
|
||||
"--config=debug"
|
||||
],
|
||||
"port": 9229,
|
||||
"address": "localhost",
|
||||
"restart": true,
|
||||
"sourceMaps": true,
|
||||
"timeout": 600000,
|
||||
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
|
||||
"outFiles": ["${workspaceFolder}/bazel-out/**/angular/**/*.js"],
|
||||
},
|
||||
{
|
||||
"name": "IVY:packages/core/test/render3",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/node_modules/.bin/bazelisk",
|
||||
"args": ["test", "packages/core/test/render3", "--config=debug"],
|
||||
"args": [
|
||||
"test",
|
||||
"packages/core/test/render3",
|
||||
"--config=debug"
|
||||
],
|
||||
"port": 9229,
|
||||
"address": "localhost",
|
||||
"restart": true,
|
||||
"sourceMaps": true,
|
||||
"timeout": 600000,
|
||||
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
|
||||
"outFiles": ["${workspaceFolder}/bazel-out/**/angular/**/*.js"],
|
||||
},
|
||||
{
|
||||
"name": "IVY:packages/core/test",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/node_modules/.bin/bazelisk",
|
||||
"args": ["test", "packages/core/test", "--config=debug"],
|
||||
"args": [
|
||||
"test",
|
||||
"packages/core/test",
|
||||
"--config=debug"
|
||||
],
|
||||
"port": 9229,
|
||||
"address": "localhost",
|
||||
"restart": true,
|
||||
"sourceMaps": true,
|
||||
"timeout": 600000,
|
||||
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
|
||||
}
|
||||
"outFiles": ["${workspaceFolder}/bazel-out/**/angular/**/*.js"],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
+147520
File diff suppressed because one or more lines are too long
Vendored
-147529
File diff suppressed because one or more lines are too long
@@ -2,4 +2,4 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
yarn-path ".yarn/releases/yarn-1.22.19.cjs"
|
||||
yarn-path ".yarn/releases/yarn-1.22.17.cjs"
|
||||
|
||||
+13
-37
@@ -1,38 +1,33 @@
|
||||
load("//tools:defaults.bzl", "nodejs_binary")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
|
||||
load("//:yarn.bzl", "YARN_PATH")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
exports_files([
|
||||
"LICENSE",
|
||||
"karma-js.conf.js",
|
||||
"browser-providers.conf.js",
|
||||
YARN_PATH,
|
||||
"scripts/ci/bazel-payload-size.sh",
|
||||
"scripts/ci/track-payload-size.sh",
|
||||
"scripts/ci/payload-size.sh",
|
||||
"scripts/ci/payload-size.js",
|
||||
"package.json",
|
||||
"angular.json",
|
||||
])
|
||||
|
||||
filegroup(
|
||||
# filegroup is needed so that this package.json file can be a dep
|
||||
# in a js_library target, which doesn't allow source file deps
|
||||
name = "package_json",
|
||||
srcs = ["package.json"],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "tsconfig.json",
|
||||
actual = "//packages:tsconfig-build.json",
|
||||
)
|
||||
|
||||
js_library(
|
||||
name = "browser-providers",
|
||||
filegroup(
|
||||
name = "web_test_bootstrap_scripts",
|
||||
# do not sort
|
||||
srcs = [
|
||||
"browser-providers.conf.d.ts",
|
||||
"browser-providers.conf.js",
|
||||
"@npm//:node_modules/core-js-bundle/index.js",
|
||||
"//packages/zone.js/bundles:zone.umd.js",
|
||||
"//packages/zone.js/bundles:zone-testing.umd.js",
|
||||
"//packages/zone.js/bundles:task-tracking.umd.js",
|
||||
"//:test-events.js",
|
||||
"//:third_party/shims_for_internal_tests.js",
|
||||
# Including systemjs because it defines `__eval`, which produces correct stack traces.
|
||||
"@npm//:node_modules/systemjs/dist/system.src.js",
|
||||
"@npm//:node_modules/reflect-metadata/Reflect.js",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -61,22 +56,3 @@ config_setting(
|
||||
name = "stamp",
|
||||
values = {"stamp": "true"},
|
||||
)
|
||||
|
||||
nodejs_binary(
|
||||
name = "yarn_vendored",
|
||||
data = [".yarn/releases/yarn-1.22.19.cjs"],
|
||||
entry_point = ".yarn/releases/yarn-1.22.19.cjs",
|
||||
visibility = [
|
||||
"//aio/tools/examples/shared:__pkg__",
|
||||
"//integration:__subpackages__",
|
||||
],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "sauce_connect",
|
||||
actual = select({
|
||||
"@npm//@angular/build-tooling/bazel/constraints:linux_x64": "@sauce_connect_linux_amd64//:bin/sc",
|
||||
"@npm//@angular/build-tooling/bazel/constraints:macos_x64": "@sauce_connect_mac//:bin/sc",
|
||||
"@npm//@angular/build-tooling/bazel/constraints:macos_arm64": "@sauce_connect_mac//:bin/sc",
|
||||
}),
|
||||
)
|
||||
|
||||
+8890
-3105
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+7
-74
@@ -1,79 +1,12 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
# Contributor Code of Conduct
|
||||
## Version 0.3b-angular
|
||||
|
||||
## Our Pledge
|
||||
As contributors and maintainers of the Angular project, we pledge to respect everyone who contributes by posting issues, updating documentation, submitting pull requests, providing feedback in comments, and any other activities.
|
||||
|
||||
In the interest of fostering a safe and welcoming environment, we as
|
||||
the Angular team pledge to make participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity, gender expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
Communication through any of Angular's channels (GitHub, Discord, Gitter, IRC, mailing lists, Twitter, etc.) must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
||||
|
||||
## Our Standards
|
||||
We promise to extend courtesy and respect to everyone involved in this project regardless of gender, gender identity, sexual orientation, disability, age, race, ethnicity, religion, or level of experience. We expect anyone contributing to the Angular project to do the same.
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
If any member of the community violates this code of conduct, the maintainers of the Angular project may take action, removing issues, comments, and PRs or blocking accounts as deemed appropriate.
|
||||
|
||||
* Use welcoming and inclusive language
|
||||
* Respect each other
|
||||
* Provide and gracefully accept constructive criticism
|
||||
* Show empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* The use of sexualized language or imagery
|
||||
* Unwelcome sexual attention or advances
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Angular team are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Angular team have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, and to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies to all Angular communication channels - online or in person,
|
||||
and it also applies when an individual is representing the project or its community in
|
||||
public spaces. Examples of representing a project or community include using an official
|
||||
project e-mail address, posting via an official social media account, or acting
|
||||
as an appointed representative at an online or offline event. Representation of
|
||||
a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the Angular team at conduct@angular.io. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The Angular team
|
||||
will maintain confidentiality with regard to the reporter of an incident.
|
||||
Enforcement may result in an indefinite ban from all official Angular communication
|
||||
channels, or other actions as deemed appropriate by the Angular team.
|
||||
|
||||
Angular maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
### Appeal
|
||||
|
||||
If you are banned you may contest the decision. To do so email conduct@angular.io with the subject line "Repeal Ban for {{your name here}}" and body with the responses to the following:
|
||||
|
||||
* Why do you believe you did not violate the Code of Conduct?
|
||||
* Were other factors involved in this situation the leadership team may have been unaware of?
|
||||
* Why do you wish to be a part of the Angular community?
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
If you are subject to or witness unacceptable behavior, or have any other concerns, please email us at [conduct@angular.io](mailto:conduct@angular.io).
|
||||
|
||||
+14
-13
@@ -68,7 +68,7 @@ A minimal reproduction allows us to quickly confirm a bug (or point out a coding
|
||||
|
||||
We require a minimal reproduction to save maintainers' time and ultimately be able to fix more bugs.
|
||||
Often, developers find coding problems themselves while preparing a minimal reproduction.
|
||||
We understand that sometimes it might be hard to extract essential bits of code from a larger codebase, but we really need to isolate the problem before we can fix it.
|
||||
We understand that sometimes it might be hard to extract essential bits of code from a larger codebase but we really need to isolate the problem before we can fix it.
|
||||
|
||||
Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you, we are going to close an issue that doesn't have enough info to be reproduced.
|
||||
|
||||
@@ -94,7 +94,7 @@ Before you submit your Pull Request (PR) consider the following guidelines:
|
||||
5. In your forked repository, make your changes in a new git branch:
|
||||
|
||||
```shell
|
||||
git checkout -b my-fix-branch main
|
||||
git checkout -b my-fix-branch master
|
||||
```
|
||||
|
||||
6. Create your patch, **including appropriate test cases**.
|
||||
@@ -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:
|
||||
|
||||
@@ -117,7 +117,7 @@ Before you submit your Pull Request (PR) consider the following guidelines:
|
||||
git push origin my-fix-branch
|
||||
```
|
||||
|
||||
11. In GitHub, send a pull request to `angular:main`.
|
||||
11. In GitHub, send a pull request to `angular:master`.
|
||||
|
||||
### Reviewing a Pull Request
|
||||
|
||||
@@ -181,10 +181,10 @@ After your pull request is merged, you can safely delete your branch and pull th
|
||||
git push origin --delete my-fix-branch
|
||||
```
|
||||
|
||||
* Check out the main branch:
|
||||
* Check out the master branch:
|
||||
|
||||
```shell
|
||||
git checkout main -f
|
||||
git checkout master -f
|
||||
```
|
||||
|
||||
* Delete the local branch:
|
||||
@@ -193,10 +193,10 @@ After your pull request is merged, you can safely delete your branch and pull th
|
||||
git branch -D my-fix-branch
|
||||
```
|
||||
|
||||
* Update your local `main` with the latest upstream version:
|
||||
* Update your master with the latest upstream version:
|
||||
|
||||
```shell
|
||||
git pull --ff upstream main
|
||||
git pull --ff upstream master
|
||||
```
|
||||
|
||||
|
||||
@@ -246,8 +246,7 @@ The `footer` is optional. The [Commit Message Footer](#commit-footer) format des
|
||||
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
||||
│ elements|forms|http|language-service|localize|platform-browser|
|
||||
│ platform-browser-dynamic|platform-server|router|service-worker|
|
||||
│ upgrade|zone.js|packaging|changelog|docs-infra|migrations|
|
||||
│ devtools
|
||||
│ upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve
|
||||
│
|
||||
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|test
|
||||
```
|
||||
@@ -306,7 +305,9 @@ There are currently a few exceptions to the "use package name" rule:
|
||||
|
||||
* `migrations`: used for changes to the `ng update` migrations.
|
||||
|
||||
* `devtools`: used for changes in the [browser extension](./devtools/README.md).
|
||||
* `ngcc`: used for changes to the [Angular Compatibility Compiler](./packages/compiler-cli/ngcc/README.md)
|
||||
|
||||
* `ve`: used for changes specific to ViewEngine (legacy compiler/renderer).
|
||||
|
||||
* none/empty string: useful for `test` and `refactor` changes that are done across all packages (e.g. `test: add missing unit tests`) and for docs changes that are not related to a specific package (e.g. `docs: fix typo in tutorial`).
|
||||
|
||||
@@ -390,10 +391,10 @@ The following documents can help you sort out issues with GitHub accounts and mu
|
||||
|
||||
|
||||
[angular-group]: https://groups.google.com/forum/#!forum/angular
|
||||
[coc]: https://github.com/angular/code-of-conduct/blob/main/CODE_OF_CONDUCT.md
|
||||
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
|
||||
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
|
||||
[corporate-cla]: https://cla.developers.google.com/about/google-corporate
|
||||
[dev-doc]: https://github.com/angular/angular/blob/main/docs/DEVELOPER.md
|
||||
[dev-doc]: https://github.com/angular/angular/blob/master/docs/DEVELOPER.md
|
||||
[github]: https://github.com/angular/angular
|
||||
[discord]: https://discord.gg/angular
|
||||
[individual-cla]: https://cla.developers.google.com/about/google-individual
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2024 Google LLC. https://angular.io/license
|
||||
Copyright (c) 2010-2022 Google LLC. https://angular.io/license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<h1 align="center">Angular - The modern web developer's platform</h1>
|
||||
<h1 align="center">Angular - The modern web developer's platform.</h1>
|
||||
|
||||
<p align="center">
|
||||
<img src="aio/src/assets/images/logos/angular/angular_renaissance.png" alt="angular-logo" width="120px" height="120px"/>
|
||||
<img src="aio/src/assets/images/logos/angular/angular.png" alt="angular-logo" width="120px" height="120px"/>
|
||||
<br>
|
||||
<em>Angular is a development platform for building mobile and desktop web applications
|
||||
<br> using TypeScript/JavaScript and other languages.</em>
|
||||
<i>Angular is a development platform for building mobile and desktop web applications
|
||||
<br> using Typescript/JavaScript and other languages.</i>
|
||||
<br>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://angular.dev/"><strong>angular.dev</strong></a>
|
||||
<a href="https://www.angular.io"><strong>www.angular.io</strong></a>
|
||||
<br>
|
||||
</p>
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://circleci.com/gh/angular/workflows/angular/tree/main">
|
||||
<img src="https://img.shields.io/circleci/build/github/angular/angular/main.svg?logo=circleci&logoColor=fff&label=CircleCI" alt="CI status" />
|
||||
<a href="https://circleci.com/gh/angular/workflows/angular/tree/master">
|
||||
<img src="https://img.shields.io/circleci/build/github/angular/angular/master.svg?logo=circleci&logoColor=fff&label=CircleCI" alt="CI status" />
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/@angular/core">
|
||||
<img src="https://img.shields.io/npm/v/@angular/core.svg?logo=npm&logoColor=fff&label=NPM+package&color=limegreen" alt="Angular on npm" />
|
||||
@@ -35,12 +35,6 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://app.circleci.com/insights/github/angular/angular/workflows/default_workflow?branch=main">
|
||||
<img src="https://dl.circleci.com/insights-snapshot/gh/angular/angular/main/default_workflow/badge.svg" alt="InsightsSnapshot" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
## Documentation
|
||||
@@ -59,26 +53,6 @@ Get started with Angular, learn the fundamentals and explore advanced topics on
|
||||
- [Server Side Rendering][ssr]
|
||||
- [Schematics][schematics]
|
||||
- [Lazy Loading][lazyloading]
|
||||
- [Animations][animations]
|
||||
|
||||
### Local Development
|
||||
|
||||
To contribute to Angular docs, you can setup a local environment with the following commands:
|
||||
|
||||
```bash
|
||||
# Clone Angular repo
|
||||
git clone https://github.com/angular/angular.git
|
||||
|
||||
# Navigate to project directory
|
||||
cd angular
|
||||
|
||||
# Install dependencies
|
||||
yarn
|
||||
|
||||
# Build and run local dev server
|
||||
# Note: Initial build will take some time
|
||||
yarn docs
|
||||
```
|
||||
|
||||
## Development Setup
|
||||
|
||||
@@ -134,11 +108,11 @@ Check out our [upgrade guide](https://update.angular.io/) to find out the best w
|
||||
|
||||
### Contributing Guidelines
|
||||
|
||||
Read through our [contributing guidelines][contributing] to learn about our submission process, coding rules, and more.
|
||||
Read through our [contributing guidelines][contributing] to learn about our submission process, coding rules and more.
|
||||
|
||||
### Want to Help?
|
||||
|
||||
Want to report a bug, contribute some code, or improve the documentation? Excellent! Read up on our guidelines for [contributing][contributing] and then check out one of our issues labeled as <kbd>[help wanted](https://github.com/angular/angular/labels/help%20wanted)</kbd> or <kbd>[good first issue](https://github.com/angular/angular/labels/good%20first%20issue)</kbd>.
|
||||
Want to report a bug, contribute some code, or improve documentation? Excellent! Read up on our guidelines for [contributing][contributing] and then check out one of our issues labeled as <kbd>[help wanted](https://github.com/angular/angular/labels/help%20wanted)</kbd> or <kbd>[good first issue](https://github.com/angular/angular/labels/good%20first%20issue)</kbd>.
|
||||
|
||||
### Code of Conduct
|
||||
|
||||
@@ -148,7 +122,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]
|
||||
@@ -160,27 +134,26 @@ Join the conversation and help the community.
|
||||
**Love Angular? Give our repo a star :star: :arrow_up:.**
|
||||
|
||||
[contributing]: CONTRIBUTING.md
|
||||
[quickstart]: https://angular.dev/tutorials/learn-angular
|
||||
[quickstart]: https://angular.io/start
|
||||
[changelog]: CHANGELOG.md
|
||||
[ng]: https://angular.dev
|
||||
[documentation]: https://angular.dev/overview
|
||||
[ng]: https://angular.io
|
||||
[documentation]: https://angular.io/docs
|
||||
[angularmaterial]: https://material.angular.io/
|
||||
[cli]: https://angular.dev/tools/cli
|
||||
[architecture]: https://angular.dev/essentials
|
||||
[componentstemplates]: https://angular.dev/tutorials/learn-angular/components-in-angular
|
||||
[forms]: https://angular.dev/tutorials/learn-angular/forms
|
||||
[api]: https://angular.dev/api
|
||||
[angularelements]: https://angular.dev/guide/elements
|
||||
[ssr]: https://angular.dev/guide/ssr
|
||||
[schematics]: https://angular.dev/tools/cli/schematics
|
||||
[lazyloading]: https://angular.dev/guide/ngmodules/lazy-loading
|
||||
[cli]: https://cli.angular.io/
|
||||
[architecture]: https://angular.io/guide/architecture
|
||||
[componentstemplates]: https://angular.io/guide/displaying-data
|
||||
[forms]: https://angular.io/guide/forms-overview
|
||||
[api]: https://angular.io/api
|
||||
[angularelements]: https://angular.io/guide/elements
|
||||
[ssr]: https://angular.io/guide/universal
|
||||
[schematics]: https://angular.io/guide/schematics
|
||||
[lazyloading]: https://angular.io/guide/lazy-loading-ngmodules
|
||||
[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
|
||||
[youtube]: https://youtube.com/angular
|
||||
[meetup]: https://www.meetup.com/find/?keywords=angular
|
||||
[animations]: https://angular.dev/guide/animations
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
Angular is part of Google [Open Source Software Vulnerability Reward Program](https://bughunters.google.com/about/rules/6521337925468160/google-open-source-software-vulnerability-reward-program-rules). For vulnerabilities in Angular, please submit your report [here](https://bughunters.google.com/report).
|
||||
|
||||
For more information, check out [Angular's security policy](https://angular.io/guide/security).
|
||||
@@ -1,45 +1,19 @@
|
||||
workspace(
|
||||
name = "angular",
|
||||
managed_directories = {
|
||||
"@npm": ["node_modules"],
|
||||
"@aio_npm": ["aio/node_modules"],
|
||||
},
|
||||
managed_directories = {"@npm": ["node_modules"]},
|
||||
)
|
||||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
load("//:yarn.bzl", "YARN_LABEL")
|
||||
|
||||
# Add a patch fix for rules_webtesting v0.3.5 required for enabling runfiles on Windows.
|
||||
# TODO: Remove the http_archive for this transitive dependency when a release is cut
|
||||
# for https://github.com/bazelbuild/rules_webtesting/commit/581b1557e382f93419da6a03b91a45c2ac9a9ec8
|
||||
# and the version is updated in rules_nodejs.
|
||||
http_archive(
|
||||
name = "io_bazel_rules_webtesting",
|
||||
patch_args = ["-p1"],
|
||||
patches = [
|
||||
"//:tools/bazel-repo-patches/rules_webtesting__windows_runfiles_fix.patch",
|
||||
],
|
||||
sha256 = "e9abb7658b6a129740c0b3ef6f5a2370864e102a5ba5ffca2cea565829ed825a",
|
||||
urls = ["https://github.com/bazelbuild/rules_webtesting/releases/download/0.3.5/rules_webtesting.tar.gz"],
|
||||
)
|
||||
|
||||
# Fetch rules_nodejs so we can install our npm dependencies
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
patches = [
|
||||
"//tools/esm-interop:patches/bazel/nodejs_binary_esm_support.patch",
|
||||
],
|
||||
sha256 = "5dd1e5dea1322174c57d3ca7b899da381d516220793d0adef3ba03b9d23baa8e",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.8.3/rules_nodejs-5.8.3.tar.gz"],
|
||||
sha256 = "ddb78717b802f8dd5d4c01c340ecdc007c8ced5c1df7db421d0df3d642ea0580",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/4.6.0/rules_nodejs-4.6.0.tar.gz"],
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_nodejs//:repositories.bzl", "build_bazel_rules_nodejs_dependencies")
|
||||
|
||||
build_bazel_rules_nodejs_dependencies()
|
||||
|
||||
# The PKG rules are needed to build tar packages for integration tests. The builtin
|
||||
# rule in `@bazel_tools` is not Windows compatible and outdated.
|
||||
# NOTE: We cannot move past version 0.6.0 as pkg_tar no longer works on directories, which rules_nodejs
|
||||
# relies on for node_modules setup.
|
||||
http_archive(
|
||||
name = "rules_pkg",
|
||||
sha256 = "62eeb544ff1ef41d786e329e1536c1d541bb9bcad27ae984d57f18f314018e66",
|
||||
@@ -49,118 +23,31 @@ http_archive(
|
||||
],
|
||||
)
|
||||
|
||||
# Fetch Aspect lib for utilities like write_source_files
|
||||
# NOTE: We cannot move past version 1.23.2 of aspect_bazel_lib because it requires us to move to bazel 6.0.0 which
|
||||
# breaks our usage of managed_directories
|
||||
http_archive(
|
||||
name = "aspect_bazel_lib",
|
||||
sha256 = "4b2e774387bae6242879820086b7b738d49bf3d0659522ea5d9363be01a27582",
|
||||
strip_prefix = "bazel-lib-1.23.2",
|
||||
url = "https://github.com/aspect-build/bazel-lib/archive/refs/tags/v1.23.2.tar.gz",
|
||||
# Check the rules_nodejs version and download npm dependencies
|
||||
# Note: bazel (version 2 and after) will check the .bazelversion file so we don't need to
|
||||
# assert on that.
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "check_rules_nodejs_version", "node_repositories", "yarn_install")
|
||||
|
||||
check_rules_nodejs_version(minimum_version_string = "2.2.0")
|
||||
|
||||
# Setup the Node.js toolchain
|
||||
node_repositories(
|
||||
node_version = "16.10.0",
|
||||
package_json = ["//:package.json"],
|
||||
)
|
||||
|
||||
# Setup the Node.js toolchain.
|
||||
load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")
|
||||
|
||||
nodejs_register_toolchains(
|
||||
name = "nodejs",
|
||||
node_repositories = {
|
||||
"18.18.2-darwin_arm64": ("node-v18.18.2-darwin-arm64.tar.gz", "node-v18.18.2-darwin-arm64", "9f982cc91b28778dd8638e4f94563b0c2a1da7aba62beb72bd427721035ab553"),
|
||||
"18.18.2-darwin_amd64": ("node-v18.18.2-darwin-x64.tar.gz", "node-v18.18.2-darwin-x64", "5bb8da908ed590e256a69bf2862238c8a67bc4600119f2f7721ca18a7c810c0f"),
|
||||
"18.18.2-linux_arm64": ("node-v18.18.2-linux-arm64.tar.xz", "node-v18.18.2-linux-arm64", "2e630e18548627f61eaf573233da7949dc0a1df5eef3f486fa9820c5f6c121aa"),
|
||||
"18.18.2-linux_ppc64le": ("node-v18.18.2-linux-ppc64le.tar.xz", "node-v18.18.2-linux-ppc64le", "b0adff5cf5938266b711d6c724fb134d802e0dee40b3a3f73d162de1b3d11880"),
|
||||
"18.18.2-linux_s390x": ("node-v18.18.2-linux-s390x.tar.xz", "node-v18.18.2-linux-s390x", "c70ec2074b5e2b42c55bb4b8105418b67bf8a61c500d9376a07430dfcc341fdb"),
|
||||
"18.18.2-linux_amd64": ("node-v18.18.2-linux-x64.tar.xz", "node-v18.18.2-linux-x64", "75aba25ae76999309fc6c598efe56ce53fbfc221381a44a840864276264ab8ac"),
|
||||
"18.18.2-windows_amd64": ("node-v18.18.2-win-x64.zip", "node-v18.18.2-win-x64", "3bb0e51e579a41a22b3bf6cb2f3e79c03801aa17acbe0ca00fc555d1282e7acd"),
|
||||
},
|
||||
# We need at least Node 18.17 due to some transitive dependencies.
|
||||
node_version = "18.18.2",
|
||||
)
|
||||
|
||||
# Download npm dependencies.
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "yarn_install")
|
||||
load("//integration:npm_package_archives.bzl", "npm_package_archives")
|
||||
|
||||
yarn_install(
|
||||
name = "npm",
|
||||
# Note that we add the postinstall scripts here so that the dependencies are re-installed
|
||||
# Note that we add the postinstall script here so that the dependencies are re-installed
|
||||
# when the postinstall patches are modified.
|
||||
data = [
|
||||
YARN_LABEL,
|
||||
"//:.yarnrc",
|
||||
"//:tools/npm-patches/@bazel+jasmine+5.8.1.patch",
|
||||
"//tools:postinstall-patches.js",
|
||||
"//tools/esm-interop:patches/npm/@angular+build-tooling+0.0.0-e0ec7b60641d7f6369be45d8d02663fd50f320be.patch",
|
||||
"//tools/esm-interop:patches/npm/@bazel+concatjs+5.8.1.patch",
|
||||
"//tools/esm-interop:patches/npm/@bazel+esbuild+5.7.1.patch",
|
||||
"//tools/esm-interop:patches/npm/@bazel+protractor+5.7.1.patch",
|
||||
"//tools/esm-interop:patches/npm/rxjs+6.6.7.patch",
|
||||
],
|
||||
# Currently disabled due to:
|
||||
# 1. Missing Windows support currently.
|
||||
# 2. Incompatibilites with the `ts_library` rule.
|
||||
exports_directories_only = False,
|
||||
data = ["//tools:postinstall-patches.js"],
|
||||
manual_build_file_contents = npm_package_archives(),
|
||||
package_json = "//:package.json",
|
||||
# We prefer to symlink the `node_modules` to only maintain a single install.
|
||||
# See https://github.com/angular/dev-infra/pull/446#issuecomment-1059820287 for details.
|
||||
symlink_node_modules = True,
|
||||
yarn = YARN_LABEL,
|
||||
yarn_lock = "//:yarn.lock",
|
||||
)
|
||||
|
||||
yarn_install(
|
||||
name = "aio_npm",
|
||||
# Note that we add the postinstall scripts here so that the dependencies are re-installed
|
||||
# when the postinstall patches are modified.
|
||||
data = [
|
||||
YARN_LABEL,
|
||||
"//:.yarnrc",
|
||||
"//:tools/npm-patches/@bazel+jasmine+5.8.1.patch",
|
||||
"//aio:tools/cli-patches/bazel-architect-output.patch",
|
||||
"//aio:tools/cli-patches/patch.js",
|
||||
],
|
||||
# Currently disabled due to:
|
||||
# 1. Missing Windows support currently.
|
||||
# 2. Incompatibilites with the `ts_library` rule.
|
||||
exports_directories_only = False,
|
||||
manual_build_file_contents = npm_package_archives(),
|
||||
package_json = "//aio:package.json",
|
||||
# We prefer to symlink the `node_modules` to only maintain a single install.
|
||||
# See https://github.com/angular/dev-infra/pull/446#issuecomment-1059820287 for details.
|
||||
symlink_node_modules = True,
|
||||
yarn = YARN_LABEL,
|
||||
yarn_lock = "//aio:yarn.lock",
|
||||
)
|
||||
|
||||
yarn_install(
|
||||
name = "aio_example_deps",
|
||||
# Rename the default js_library target from "node_modules" as this obscures the
|
||||
# the source directory stamped as a filegroup in the manual BUILD contents below.
|
||||
all_node_modules_target_name = "node_modules_all",
|
||||
data = [
|
||||
YARN_LABEL,
|
||||
"//:.yarnrc",
|
||||
],
|
||||
# Disabled because, when False, yarn_install preserves the node_modules folder
|
||||
# with bin symlinks in the external repository. This is needed to link the shared
|
||||
# set of deps for example e2es.
|
||||
exports_directories_only = False,
|
||||
manual_build_file_contents = """\
|
||||
filegroup(
|
||||
name = "node_modules_files",
|
||||
srcs = ["node_modules"],
|
||||
)
|
||||
""",
|
||||
package_json = "//aio/tools/examples/shared:package.json",
|
||||
yarn = YARN_LABEL,
|
||||
yarn_lock = "//aio/tools/examples/shared:yarn.lock",
|
||||
)
|
||||
|
||||
load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies")
|
||||
|
||||
aspect_bazel_lib_dependencies()
|
||||
|
||||
# Load protractor dependencies
|
||||
load("@npm//@bazel/protractor:package.bzl", "npm_bazel_protractor_dependencies")
|
||||
|
||||
@@ -171,76 +58,23 @@ load("@io_bazel_rules_webtesting//web:repositories.bzl", "web_test_repositories"
|
||||
|
||||
web_test_repositories()
|
||||
|
||||
load("@npm//@angular/build-tooling/bazel/browsers:browser_repositories.bzl", "browser_repositories")
|
||||
load("@npm//@angular/dev-infra-private/bazel/browsers:browser_repositories.bzl", "browser_repositories")
|
||||
|
||||
browser_repositories()
|
||||
|
||||
load("@build_bazel_rules_nodejs//toolchains/esbuild:esbuild_repositories.bzl", "esbuild_repositories")
|
||||
|
||||
esbuild_repositories(
|
||||
npm_repository = "npm",
|
||||
)
|
||||
esbuild_repositories()
|
||||
|
||||
load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies")
|
||||
|
||||
rules_pkg_dependencies()
|
||||
|
||||
load("//packages/common/locales/generate-locales-tool:cldr-data.bzl", "cldr_json_data_repository", "cldr_xml_data_repository")
|
||||
load("//packages/common/locales/generate-locales-tool:cldr-data.bzl", "cldr_data_repository")
|
||||
|
||||
cldr_major_version = "41"
|
||||
|
||||
cldr_json_data_repository(
|
||||
name = "cldr_json_data",
|
||||
cldr_data_repository(
|
||||
name = "cldr_data",
|
||||
urls = {
|
||||
"https://github.com/unicode-org/cldr-json/releases/download/%s.0.0/cldr-%s.0.0-json-full.zip" % (cldr_major_version, cldr_major_version): "649b76647269e32b1b0a5f7b6eed52e9e63a1581f1afdcf4f6771e49c9713614",
|
||||
"https://github.com/unicode-org/cldr-json/releases/download/39.0.0/cldr-39.0.0-json-full.zip": "a631764b6bb7967fab8cc351aff3ffa3f430a23646899976dd9d65801446def6",
|
||||
},
|
||||
)
|
||||
|
||||
cldr_xml_data_repository(
|
||||
name = "cldr_xml_data",
|
||||
urls = {
|
||||
"https://github.com/unicode-org/cldr/releases/download/release-%s/cldr-common-%s.0.zip" % (cldr_major_version, cldr_major_version): "823c6170c41e2de2c229574e8a436332d25f1c9723409867fe721e00bc92d853",
|
||||
},
|
||||
)
|
||||
|
||||
# sass rules
|
||||
http_archive(
|
||||
name = "io_bazel_rules_sass",
|
||||
sha256 = "5633816e996a79c77f44306f6228b9ef18fc2ecb412d63b4e314a132225facba",
|
||||
strip_prefix = "rules_sass-79bd239ce77c101ea1aed575678020bd2999f17d",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/rules_sass/archive/79bd239ce77c101ea1aed575678020bd2999f17d.zip",
|
||||
],
|
||||
)
|
||||
|
||||
# Setup the rules_sass toolchain
|
||||
load("@io_bazel_rules_sass//sass:sass_repositories.bzl", "sass_repositories")
|
||||
|
||||
sass_repositories(
|
||||
yarn_script = YARN_LABEL,
|
||||
)
|
||||
|
||||
# Register git toolchains
|
||||
register_toolchains(
|
||||
"@npm//@angular/build-tooling/bazel/git-toolchain:git_linux_toolchain",
|
||||
"@npm//@angular/build-tooling/bazel/git-toolchain:git_macos_x86_toolchain",
|
||||
"@npm//@angular/build-tooling/bazel/git-toolchain:git_macos_arm64_toolchain",
|
||||
"@npm//@angular/build-tooling/bazel/git-toolchain:git_windows_toolchain",
|
||||
)
|
||||
|
||||
# Fetch sauce connect (tool to open Saucelabs tunnel for Saucelabs browser tests)
|
||||
http_archive(
|
||||
name = "sauce_connect_linux_amd64",
|
||||
build_file_content = """exports_files(["bin/sc"], visibility = ["//visibility:public"])""",
|
||||
sha256 = "26b9c3630f441b47854b6032f7eca6f1d88d3f62e50ee44c27015d71a5155c36",
|
||||
strip_prefix = "sc-4.8.2-linux",
|
||||
url = "https://saucelabs.com/downloads/sc-4.8.2-linux.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "sauce_connect_mac",
|
||||
build_file_content = """exports_files(["bin/sc"], visibility = ["//visibility:public"])""",
|
||||
sha256 = "28277ce81ef9ab84f5b87b526258920a8ead44789a5034346e872629bbf38089",
|
||||
strip_prefix = "sc-4.8.2-osx",
|
||||
url = "https://saucelabs.com/downloads/sc-4.8.2-osx.zip",
|
||||
)
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
load("//:packages.bzl", "link_packages")
|
||||
load("@npm//@angular/build-tooling/bazel/remote-execution:index.bzl", "ENABLE_NETWORK")
|
||||
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin")
|
||||
load("@npm//@angular-devkit/architect-cli:index.bzl", "architect", "architect_test")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
# All source and configuration files required to build the docs app
|
||||
APPLICATION_FILES = [
|
||||
"angular.json",
|
||||
"tsconfig.app.json",
|
||||
"tsconfig.json",
|
||||
"tsconfig.worker.json",
|
||||
] + glob(
|
||||
["src/**/*"],
|
||||
exclude = [
|
||||
"src/**/*.spec.ts",
|
||||
# Temporarily exclude generated sources produced by the non-bazel
|
||||
# build until the whole project is built by bazel and this directory
|
||||
# isn't needed.
|
||||
"src/generated/**/*",
|
||||
],
|
||||
)
|
||||
|
||||
TEST_FILES = APPLICATION_FILES + [
|
||||
"karma.conf.js",
|
||||
"tsconfig.spec.json",
|
||||
] + glob(
|
||||
["**/*.spec.ts"],
|
||||
)
|
||||
|
||||
APPLICATION_DEPS = link_packages([
|
||||
"@npm//@angular-devkit/build-angular",
|
||||
"@npm//@angular/animations",
|
||||
"@npm//@angular/cdk",
|
||||
"@npm//@angular/common",
|
||||
"@npm//@angular/compiler",
|
||||
"@npm//@angular/compiler-cli",
|
||||
"@npm//@angular/core",
|
||||
"@npm//@angular/docs",
|
||||
"@npm//@angular/forms",
|
||||
"@npm//@angular/material",
|
||||
"@npm//@angular/platform-browser",
|
||||
"@npm//@angular/platform-server",
|
||||
"@npm//@angular/router",
|
||||
"@npm//gsap",
|
||||
"@npm//marked",
|
||||
"@npm//ngx-progressbar",
|
||||
"@npm//ogl",
|
||||
"@npm//rxjs",
|
||||
"@npm//typescript",
|
||||
"//adev/src/assets/images",
|
||||
"//adev/src/assets/textures",
|
||||
"//adev/src/assets/previews",
|
||||
"//adev/src/assets:tutorials",
|
||||
"//adev/src/assets/icons",
|
||||
"//adev/src/assets:api",
|
||||
"//adev/src/assets:content",
|
||||
"@npm//@typescript/vfs",
|
||||
"@npm//@codemirror/state",
|
||||
"@npm//@codemirror/view",
|
||||
"@npm//@codemirror/language",
|
||||
"@npm//@codemirror/commands",
|
||||
"@npm//@codemirror/search",
|
||||
"@npm//@codemirror/autocomplete",
|
||||
"@npm//@codemirror/lint",
|
||||
"@npm//@codemirror/lang-html",
|
||||
"@npm//@codemirror/lang-angular",
|
||||
"@npm//@codemirror/lang-css",
|
||||
"@npm//@codemirror/lang-sass",
|
||||
"@npm//@codemirror/lang-javascript",
|
||||
"@npm//@lezer/highlight",
|
||||
"@npm//@lezer/javascript",
|
||||
"@npm//@lezer/common",
|
||||
"@npm//@xterm/xterm",
|
||||
"@npm//xterm-addon-fit",
|
||||
"@npm//angular-split",
|
||||
])
|
||||
|
||||
TEST_DEPS = APPLICATION_DEPS + link_packages([
|
||||
"@npm//@angular/platform-browser-dynamic",
|
||||
"@npm//@angular/build-tooling/bazel/browsers/chromium",
|
||||
"@npm//@types/jasmine",
|
||||
"@npm//@types/node",
|
||||
"@npm//assert",
|
||||
"@npm//jasmine",
|
||||
"@npm//jasmine-core",
|
||||
"@npm//karma-chrome-launcher",
|
||||
"@npm//karma-coverage",
|
||||
"@npm//karma-jasmine",
|
||||
"@npm//karma-jasmine-html-reporter",
|
||||
"//aio/tools:windows-chromium-path",
|
||||
])
|
||||
|
||||
copy_to_bin(
|
||||
name = "application_files_bin",
|
||||
srcs = APPLICATION_FILES,
|
||||
)
|
||||
|
||||
bool_flag(
|
||||
name = "fast_build_mode",
|
||||
build_setting_default = False,
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "fast",
|
||||
flag_values = {
|
||||
":fast_build_mode": "true",
|
||||
},
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "full",
|
||||
flag_values = {
|
||||
":fast_build_mode": "false",
|
||||
},
|
||||
)
|
||||
|
||||
config_based_architect_flags = select({
|
||||
":fast": ["--no-prerender"],
|
||||
":full": ["--prerender"],
|
||||
})
|
||||
|
||||
architect(
|
||||
name = "build",
|
||||
args = [
|
||||
"angular-dev:build",
|
||||
"--output-path=build",
|
||||
] + config_based_architect_flags,
|
||||
chdir = "$(RULEDIR)",
|
||||
data = APPLICATION_DEPS + [
|
||||
":application_files_bin",
|
||||
],
|
||||
# Network is required to inline fonts.
|
||||
exec_properties = ENABLE_NETWORK,
|
||||
output_dir = True,
|
||||
tags = [
|
||||
"no-remote-exec",
|
||||
],
|
||||
)
|
||||
|
||||
architect(
|
||||
name = "serve",
|
||||
args = [
|
||||
"angular-dev:serve",
|
||||
"--poll=1000",
|
||||
"--live-reload",
|
||||
"--watch",
|
||||
],
|
||||
chdir = package_name(),
|
||||
data = APPLICATION_DEPS + [
|
||||
":application_files_bin",
|
||||
],
|
||||
tags = [
|
||||
"no-remote-exec",
|
||||
],
|
||||
)
|
||||
|
||||
architect_test(
|
||||
name = "test",
|
||||
args = [
|
||||
"angular-dev:test",
|
||||
"--no-watch",
|
||||
],
|
||||
chdir = package_name(),
|
||||
data = TEST_DEPS + TEST_FILES,
|
||||
env = {
|
||||
"CHROME_BIN": "../$(CHROMIUM)",
|
||||
},
|
||||
toolchains = [
|
||||
"@npm//@angular/build-tooling/bazel/browsers/chromium:toolchain_alias",
|
||||
],
|
||||
)
|
||||
@@ -1,104 +0,0 @@
|
||||
{
|
||||
"$schema": "../node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": ".",
|
||||
"projects": {
|
||||
"angular-dev": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"style": "scss",
|
||||
"standalone": true,
|
||||
"changeDetection": "OnPush"
|
||||
}
|
||||
},
|
||||
"root": ".",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "adev",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:application",
|
||||
"options": {
|
||||
"externalDependencies": [
|
||||
"path"
|
||||
],
|
||||
"outputPath": "dist/angular-dev",
|
||||
"index": "src/index.html",
|
||||
"browser": "src/main.ts",
|
||||
"server": "src/main.server.ts",
|
||||
"polyfills": ["src/polyfills.ts", "zone.js"],
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/robots.txt",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": ["@angular/docs/styles/global-styles.scss"],
|
||||
"scripts": [],
|
||||
"webWorkerTsConfig": "tsconfig.worker.json",
|
||||
"optimization": {
|
||||
"fonts": {
|
||||
// TODO(josephperrott): enabled inline scripts
|
||||
"inline": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"optimization": false,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "angular-dev:build:production"
|
||||
},
|
||||
"development": {
|
||||
"buildTarget": "angular-dev:build:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development",
|
||||
"options": {
|
||||
"buildTarget": "web-ui:build",
|
||||
"headers": {
|
||||
"Cross-Origin-Opener-Policy": "same-origin",
|
||||
"Cross-Origin-Embedder-Policy": "require-corp"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "angular-dev:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"polyfills": ["zone.js", "zone.js/testing"],
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"include": ["src/app"],
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": ["src/favicon.ico", "src/assets"],
|
||||
"styles": ["@angular/docs/styles/global-styles.scss"],
|
||||
"scripts": [],
|
||||
"webWorkerTsConfig": "tsconfig.worker.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"analytics": "dca119a9-da31-47f7-a6cb-b60541037021"
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
{
|
||||
"hosting": {
|
||||
"target": "angular-docs",
|
||||
"public": "./build/browser",
|
||||
"ignore": ["**/.*"],
|
||||
"headers": [
|
||||
{
|
||||
"source": "assets/tutorials/common/*.jpg",
|
||||
"headers": [
|
||||
{
|
||||
"key": "Cross-Origin-Resource-Policy",
|
||||
"value": "cross-origin"
|
||||
},
|
||||
{
|
||||
"key": "Access-Control-Allow-Origin",
|
||||
"value": "*"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "*.[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].+(css|js)",
|
||||
"headers": [
|
||||
{
|
||||
"key": "Cache-Control",
|
||||
"value": "public,max-age=31536000,immutable"
|
||||
},
|
||||
{
|
||||
"key": "Access-Control-Allow-Origin",
|
||||
"value": "*"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "/[0-9a-f][0-9a-f][0-9a-f].[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].js",
|
||||
"headers": [
|
||||
{
|
||||
"key": "Cross-Origin-Embedder-Policy",
|
||||
"value": "require-corp"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "/@(ngsw-worker.js|ngsw.json)",
|
||||
"headers": [
|
||||
{
|
||||
"key": "Cache-Control",
|
||||
"value": "no-cache"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "/**",
|
||||
"headers": [
|
||||
{
|
||||
"key": "Cross-Origin-Opener-Policy",
|
||||
"value": "same-origin"
|
||||
},
|
||||
|
||||
{
|
||||
"key": "Cross-Origin-Embedder-Policy",
|
||||
"value": "require-corp"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"rewrites": [
|
||||
{
|
||||
"source": "**",
|
||||
"destination": "/index.html"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
const {getAdjustedChromeBinPathForWindows} = require('../aio/tools/windows-chromium-path');
|
||||
|
||||
process.env.CHROME_BIN = getAdjustedChromeBinPathForWindows();
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
{'reporter:jasmine-seed': ['type', JasmineSeedReporter]},
|
||||
],
|
||||
proxies: {
|
||||
'/dummy/image': 'src/assets/images/logos/angular/angular.png',
|
||||
},
|
||||
client: {
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
random: true,
|
||||
seed: '',
|
||||
},
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true, // removes the duplicated traces
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: require('path').join(__dirname, './coverage/site'),
|
||||
subdir: '.',
|
||||
reporters: [{type: 'html'}, {type: 'text-summary'}],
|
||||
},
|
||||
reporters: ['progress', 'kjhtml', 'jasmine-seed'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
customLaunchers: {
|
||||
ChromeHeadlessNoSandbox: {
|
||||
base: 'ChromeHeadless',
|
||||
// See /integration/README.md#browser-tests for more info on these args
|
||||
flags: [
|
||||
'--no-sandbox',
|
||||
'--headless',
|
||||
'--disable-gpu',
|
||||
'--disable-dev-shm-usage',
|
||||
'--hide-scrollbars',
|
||||
'--mute-audio',
|
||||
],
|
||||
},
|
||||
},
|
||||
browsers: ['ChromeHeadlessNoSandbox'],
|
||||
browserNoActivityTimeout: 60000,
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
|
||||
// Helpers
|
||||
function JasmineSeedReporter(baseReporterDecorator) {
|
||||
baseReporterDecorator(this);
|
||||
|
||||
this.onBrowserComplete = (browser, result) => {
|
||||
const seed = result.order && result.order.random && result.order.seed;
|
||||
if (seed) this.write(`${browser}: Randomized with seed ${seed}.\n`);
|
||||
};
|
||||
|
||||
this.onRunComplete = () => undefined;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
@defer (when isBrowser) {
|
||||
<adev-progress-bar />
|
||||
}
|
||||
<button (click)="focusFirstHeading()" class="adev-skip">Skip to main content</button>
|
||||
|
||||
<div class="adev-nav"></div>
|
||||
@if (displaySecondaryNav()) {
|
||||
<adev-secondary-navigation />
|
||||
}
|
||||
<div class="docs-app-main-content">
|
||||
<!--
|
||||
Avoid rendering cookies popup on the server,
|
||||
since there is no benefit of doing this and
|
||||
it requires additional state management.
|
||||
-->
|
||||
@defer (when isBrowser) {
|
||||
<docs-cookie-popup />
|
||||
|
||||
@defer (when displaySearchDialog(); prefetch on idle) {
|
||||
@if (displaySearchDialog()) {
|
||||
<docs-search-dialog (onClose)="displaySearchDialog.set(false)" />
|
||||
}
|
||||
}
|
||||
}
|
||||
<router-outlet />
|
||||
|
||||
@if (displayFooter()) {
|
||||
<footer adev-footer></footer>
|
||||
}
|
||||
</div>
|
||||
@@ -1,86 +0,0 @@
|
||||
@use '@angular/docs/styles/media-queries' as mq;
|
||||
|
||||
:host {
|
||||
max-width: 2560px;
|
||||
margin-inline: auto;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
min-height: 100vh;
|
||||
|
||||
@include mq.for-tablet-landscape-down {
|
||||
flex-direction: column;
|
||||
}
|
||||
// If navs are open, render a blurry background over content
|
||||
&:has(.docs-nav-secondary--open),
|
||||
&:has(.adev-nav-primary--open) {
|
||||
.docs-app-main-content {
|
||||
&::after {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:has(.adev-home) {
|
||||
.adev-nav {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
@include mq.for-tablet-landscape-up {
|
||||
footer {
|
||||
margin-left: var(--primary-nav-width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.adev-skip {
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
left: 0.5rem;
|
||||
z-index: 1000;
|
||||
background: var(--primary-contrast);
|
||||
color: var(--page-background);
|
||||
border: 1px solid var(--vivid-pink);
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.5rem;
|
||||
font-size: 0.875rem;
|
||||
transform: translateY(-150%);
|
||||
transition: transform 0.3s ease-out;
|
||||
&:focus {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.docs-app-main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
|
||||
// If navs are open, render a blurry background over content
|
||||
::after {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
backdrop-filter: blur(2px);
|
||||
background-color: color-mix(in srgb, var(--gray-1000) 5%, transparent);
|
||||
z-index: 50;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
@include mq.for-tablet {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: auto;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {AppComponent} from './app.component';
|
||||
import {provideRouter} from '@angular/router';
|
||||
import {routes} from './routes';
|
||||
import {Search, WINDOW} from '@angular/docs';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
const fakeSearch = {};
|
||||
const fakeWindow = {};
|
||||
|
||||
it('should create the app', () => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
provideRouter(routes),
|
||||
{
|
||||
provide: WINDOW,
|
||||
useValue: fakeWindow,
|
||||
},
|
||||
{
|
||||
provide: Search,
|
||||
useValue: fakeSearch,
|
||||
},
|
||||
],
|
||||
});
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,133 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {DOCUMENT, isPlatformBrowser} from '@angular/common';
|
||||
import {
|
||||
Component,
|
||||
inject,
|
||||
NgZone,
|
||||
OnInit,
|
||||
PLATFORM_ID,
|
||||
signal,
|
||||
WritableSignal,
|
||||
} from '@angular/core';
|
||||
import {NavigationEnd, NavigationSkipped, Router, RouterLink, RouterOutlet} from '@angular/router';
|
||||
import {filter, map, skip} from 'rxjs/operators';
|
||||
import {
|
||||
CookiePopup,
|
||||
getActivatedRouteSnapshotFromRouter,
|
||||
IS_SEARCH_DIALOG_OPEN,
|
||||
SearchDialog,
|
||||
WINDOW,
|
||||
} from '@angular/docs';
|
||||
import {Footer} from './core/layout/footer/footer.component';
|
||||
import {Navigation} from './core/layout/navigation/navigation.component';
|
||||
import {SecondaryNavigation} from './core/layout/secondary-navigation/secondary-navigation.component';
|
||||
import {ProgressBarComponent} from './core/layout/progress-bar/progress-bar.component';
|
||||
import {ESCAPE, SEARCH_TRIGGER_KEY} from './core/constants/keys';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'adev-root',
|
||||
imports: [
|
||||
CookiePopup,
|
||||
Navigation,
|
||||
Footer,
|
||||
SecondaryNavigation,
|
||||
RouterOutlet,
|
||||
RouterLink,
|
||||
SearchDialog,
|
||||
ProgressBarComponent,
|
||||
],
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss'],
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
private readonly document = inject(DOCUMENT);
|
||||
private readonly ngZone = inject(NgZone);
|
||||
private readonly router = inject(Router);
|
||||
private readonly window = inject(WINDOW);
|
||||
|
||||
currentUrl = signal('');
|
||||
displayFooter = signal(false);
|
||||
displaySecondaryNav = signal(false);
|
||||
displaySearchDialog: WritableSignal<boolean> = inject(IS_SEARCH_DIALOG_OPEN);
|
||||
|
||||
isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
||||
|
||||
ngOnInit(): void {
|
||||
this.setSearchDialogVisibilityOnKeyPress();
|
||||
this.closeSearchDialogOnNavigationSkipped();
|
||||
this.router.events
|
||||
.pipe(
|
||||
filter((e): e is NavigationEnd => e instanceof NavigationEnd),
|
||||
map((event) => event.urlAfterRedirects),
|
||||
)
|
||||
.subscribe((url) => {
|
||||
this.currentUrl.set(url);
|
||||
this.setComponentsVisibility();
|
||||
this.displaySearchDialog.set(false);
|
||||
});
|
||||
|
||||
this.focusFirstHeadingOnRouteChange();
|
||||
}
|
||||
|
||||
focusFirstHeading(): void {
|
||||
if (!this.isBrowser) {
|
||||
return;
|
||||
}
|
||||
|
||||
const h1 = this.document.querySelector<HTMLHeadingElement>('h1');
|
||||
h1?.focus();
|
||||
}
|
||||
|
||||
private setComponentsVisibility(): void {
|
||||
const activatedRoute = getActivatedRouteSnapshotFromRouter(this.router as any);
|
||||
|
||||
this.displaySecondaryNav.set(activatedRoute.data['displaySecondaryNav']);
|
||||
this.displayFooter.set(!activatedRoute.data['hideFooter']);
|
||||
}
|
||||
|
||||
private focusFirstHeadingOnRouteChange(): void {
|
||||
this.router.events
|
||||
.pipe(
|
||||
filter((e): e is NavigationEnd => e instanceof NavigationEnd),
|
||||
// Skip first emission, cause on the initial load we would like to `Skip to main content` popup when it's focused
|
||||
skip(1),
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.focusFirstHeading();
|
||||
});
|
||||
}
|
||||
|
||||
private setSearchDialogVisibilityOnKeyPress(): void {
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
this.window.addEventListener('keydown', (event: KeyboardEvent) => {
|
||||
if (event.key === SEARCH_TRIGGER_KEY && (event.metaKey || event.ctrlKey)) {
|
||||
this.ngZone.run(() => {
|
||||
event.preventDefault();
|
||||
this.displaySearchDialog.update((display) => !display);
|
||||
});
|
||||
}
|
||||
|
||||
if (event.key === ESCAPE && this.displaySearchDialog()) {
|
||||
this.ngZone.run(() => {
|
||||
event.preventDefault();
|
||||
this.displaySearchDialog.set(false);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private closeSearchDialogOnNavigationSkipped(): void {
|
||||
this.router.events.pipe(filter((event) => event instanceof NavigationSkipped)).subscribe(() => {
|
||||
this.displaySearchDialog.set(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {mergeApplicationConfig, ApplicationConfig} from '@angular/core';
|
||||
import {provideServerRendering} from '@angular/platform-server';
|
||||
import {appConfig} from './app.config';
|
||||
import {
|
||||
ReferenceScrollHandler,
|
||||
ReferenceScrollHandlerNoop,
|
||||
} from './features/references/services/reference-scroll-handler.service';
|
||||
|
||||
const serverConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideServerRendering(),
|
||||
{provide: ReferenceScrollHandler, useClass: ReferenceScrollHandlerNoop},
|
||||
],
|
||||
};
|
||||
|
||||
export const config = mergeApplicationConfig(appConfig, serverConfig);
|
||||
@@ -1,97 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
import {provideHttpClient, withFetch} from '@angular/common/http';
|
||||
import {
|
||||
ApplicationConfig,
|
||||
ENVIRONMENT_INITIALIZER,
|
||||
ErrorHandler,
|
||||
inject,
|
||||
provideZoneChangeDetection,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
DOCS_CONTENT_LOADER,
|
||||
ENVIRONMENT,
|
||||
EXAMPLE_VIEWER_CONTENT_LOADER,
|
||||
PREVIEWS_COMPONENTS,
|
||||
WINDOW,
|
||||
windowProvider,
|
||||
} from '@angular/docs';
|
||||
import {provideClientHydration} from '@angular/platform-browser';
|
||||
import {provideAnimationsAsync} from '@angular/platform-browser/animations/async';
|
||||
import {
|
||||
RouteReuseStrategy,
|
||||
Router,
|
||||
TitleStrategy,
|
||||
createUrlTreeFromSnapshot,
|
||||
provideRouter,
|
||||
withInMemoryScrolling,
|
||||
withViewTransitions,
|
||||
} from '@angular/router';
|
||||
import environment from './environment';
|
||||
import {PREVIEWS_COMPONENTS_MAP} from './../assets/previews/previews';
|
||||
import {ADevTitleStrategy} from './core/services/a-dev-title-strategy';
|
||||
import {AnalyticsService} from './core/services/analytics/analytics.service';
|
||||
import {ContentLoader} from './core/services/content-loader.service';
|
||||
import {CustomErrorHandler} from './core/services/errors-handling/error-handler';
|
||||
import {ExampleContentLoader} from './core/services/example-content-loader.service';
|
||||
import {ReuseTutorialsRouteStrategy} from './features/tutorial/tutorials-route-reuse-strategy';
|
||||
import {routes} from './routes';
|
||||
import {ReferenceScrollHandler} from './features/references/services/reference-scroll-handler.service';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideRouter(
|
||||
routes,
|
||||
withInMemoryScrolling({anchorScrolling: 'enabled', scrollPositionRestoration: 'enabled'}),
|
||||
withViewTransitions({
|
||||
onViewTransitionCreated: ({transition, to}) => {
|
||||
const router = inject(Router);
|
||||
const toTree = createUrlTreeFromSnapshot(to, []);
|
||||
// Skip the transition if the only thing changing is the fragment and queryParams
|
||||
if (
|
||||
router.isActive(toTree, {
|
||||
paths: 'exact',
|
||||
matrixParams: 'exact',
|
||||
fragment: 'ignored',
|
||||
queryParams: 'ignored',
|
||||
})
|
||||
) {
|
||||
transition.skipTransition();
|
||||
}
|
||||
},
|
||||
}),
|
||||
),
|
||||
provideClientHydration(),
|
||||
provideHttpClient(withFetch()),
|
||||
provideAnimationsAsync(),
|
||||
{provide: ENVIRONMENT, useValue: environment},
|
||||
{
|
||||
provide: ENVIRONMENT_INITIALIZER,
|
||||
multi: true,
|
||||
useValue: () => inject(AnalyticsService),
|
||||
},
|
||||
{provide: ErrorHandler, useClass: CustomErrorHandler},
|
||||
{provide: PREVIEWS_COMPONENTS, useValue: PREVIEWS_COMPONENTS_MAP},
|
||||
{provide: DOCS_CONTENT_LOADER, useClass: ContentLoader},
|
||||
{provide: EXAMPLE_VIEWER_CONTENT_LOADER, useClass: ExampleContentLoader},
|
||||
{
|
||||
provide: RouteReuseStrategy,
|
||||
useClass: ReuseTutorialsRouteStrategy,
|
||||
},
|
||||
{
|
||||
provide: WINDOW,
|
||||
useFactory: (document: Document) => windowProvider(document),
|
||||
deps: [DOCUMENT],
|
||||
},
|
||||
{provide: TitleStrategy, useClass: ADevTitleStrategy},
|
||||
provideZoneChangeDetection({eventCoalescing: true}),
|
||||
ReferenceScrollHandler,
|
||||
],
|
||||
};
|
||||
@@ -1,10 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
export const PRIMARY_NAV_ID = 'primaryNav';
|
||||
export const SECONDARY_NAV_ID = 'secondaryNav';
|
||||
@@ -1,12 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
export const COMMAND = 'Command';
|
||||
export const CONTROL = 'Control';
|
||||
export const ESCAPE = 'Escape';
|
||||
export const SEARCH_TRIGGER_KEY = 'k';
|
||||
@@ -1,12 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
export const GITHUB = 'https://github.com/angular/angular';
|
||||
export const X = 'https://x.com/angular';
|
||||
export const MEDIUM = 'https://blog.angular.io';
|
||||
export const YOUTUBE = 'https://www.youtube.com/channel/UCbn1OgGei-DV7aSRo_HaAiw';
|
||||
@@ -1,28 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
// File contains the enums used across whole application.
|
||||
|
||||
// The enum with the prefixes of the main routes
|
||||
export enum PagePrefix {
|
||||
API = 'api',
|
||||
CLI = 'cli',
|
||||
DOCS = 'docs',
|
||||
HOME = '',
|
||||
PLAYGROUND = 'playground',
|
||||
REFERENCE = 'reference',
|
||||
TUTORIALS = 'tutorials',
|
||||
}
|
||||
|
||||
// The enum with the default pages for each main tab
|
||||
export enum DefaultPage {
|
||||
DOCS = 'overview',
|
||||
REFERENCE = 'api',
|
||||
TUTORIALS = 'tutorials',
|
||||
PLAYGROUND = 'playground',
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
<div class="adev-footer-container">
|
||||
<div class="adev-footer-columns">
|
||||
<div>
|
||||
<h2>Social Media</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a [href]="MEDIUM" title="Angular blog">Blog</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [href]="X" title="X (formerly Twitter)">X (formerly Twitter)</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [href]="YOUTUBE" title="YouTube">YouTube</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://discord.gg/angular"
|
||||
title="Join the discussions at Angular Community Discord server."
|
||||
>
|
||||
Discord
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [href]="GITHUB" title="GitHub">GitHub</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://stackoverflow.com/questions/tagged/angular"
|
||||
title="Stack Overflow: where the community answers your technical Angular questions."
|
||||
>
|
||||
Stack Overflow
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Community</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/angular/angular/blob/main/CONTRIBUTING.md"
|
||||
title="Contribute to Angular"
|
||||
>
|
||||
Contribute
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/angular/code-of-conduct/blob/main/CODE_OF_CONDUCT.md"
|
||||
title="Treating each other with respect."
|
||||
>
|
||||
Code of Conduct
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/angular/angular/issues"
|
||||
title="Post issues and suggestions on github."
|
||||
>
|
||||
Report Issues
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://devlibrary.withgoogle.com/products/angular?sort=updated"
|
||||
title="Google's DevLibrary"
|
||||
>
|
||||
Google's DevLibrary
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://developers.google.com/community/experts/directory?specialization=angular"
|
||||
title="Angular Google Developer Experts"
|
||||
>
|
||||
Angular Google Developer Experts
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Resources</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a routerLink="/press-kit" title="Press contacts, logos, and branding.">Press Kit</a>
|
||||
</li>
|
||||
<li>
|
||||
<a routerLink="/roadmap" title="Roadmap">Roadmap</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Languages</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://angular.cn/" title="简体中文版">简体中文版</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://angular.tw/" title="正體中文版">正體中文版</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://angular.jp/" title="日本語版">日本語版</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://angular.kr/" title="한국어">한국어</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://angular-gr.web.app"
|
||||
title="Ελληνικά"
|
||||
>
|
||||
Ελληνικά
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="docs-license">
|
||||
Super-powered by Google ©2010-2024. Code licensed under an
|
||||
<a routerLink="/license" title="License text">MIT-style License</a>
|
||||
. Documentation licensed under
|
||||
<a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
@@ -1,59 +0,0 @@
|
||||
.adev-footer-columns {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 2rem;
|
||||
|
||||
@container footer (max-width: 600px) {
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.adev-footer-container {
|
||||
container: footer / inline-size;
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
padding: var(--layout-padding);
|
||||
padding-inline-end: 1rem;
|
||||
background-color: var(--page-background);
|
||||
transition: background-color 0.3s ease;
|
||||
|
||||
// this accounts for absolutely positioned TOC on the right
|
||||
@media only screen and (min-width: 1430px) {
|
||||
width: calc(100% - 195px - var(--layout-padding) * 3);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
margin-block-end: 1.75rem;
|
||||
letter-spacing: -0.00875rem;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.95rem;
|
||||
li {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--quaternary-contrast);
|
||||
font-weight: 300;
|
||||
transition: color 0.3s ease;
|
||||
&:hover {
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
}
|
||||
p.docs-license {
|
||||
transition: color 0.3s ease;
|
||||
color: var(--quaternary-contrast);
|
||||
font-weight: 300;
|
||||
grid-column: span 4;
|
||||
font-size: 0.75rem;
|
||||
margin-block-start: 2rem;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {WINDOW} from '@angular/docs';
|
||||
import {RouterTestingModule} from '@angular/router/testing';
|
||||
import {Footer} from './footer.component';
|
||||
|
||||
describe('Footer', () => {
|
||||
let component: Footer;
|
||||
let fixture: ComponentFixture<Footer>;
|
||||
const fakeWindow = {
|
||||
location: {
|
||||
origin: 'example-origin',
|
||||
},
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [Footer, RouterTestingModule],
|
||||
providers: [
|
||||
{
|
||||
provide: WINDOW,
|
||||
useValue: fakeWindow,
|
||||
},
|
||||
],
|
||||
});
|
||||
fixture = TestBed.createComponent(Footer);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,28 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {ChangeDetectionStrategy, Component} from '@angular/core';
|
||||
import {ExternalLink} from '@angular/docs';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {GITHUB, X, MEDIUM, YOUTUBE} from './../../constants/links';
|
||||
|
||||
@Component({
|
||||
selector: 'footer[adev-footer]',
|
||||
standalone: true,
|
||||
imports: [CommonModule, ExternalLink, RouterLink],
|
||||
templateUrl: './footer.component.html',
|
||||
styleUrls: ['./footer.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class Footer {
|
||||
readonly GITHUB = GITHUB;
|
||||
readonly X = X;
|
||||
readonly YOUTUBE = YOUTUBE;
|
||||
readonly MEDIUM = MEDIUM;
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
@use '@angular/docs/styles/media-queries' as mq;
|
||||
|
||||
// Dark/Light mode switcher & social media icon buttons
|
||||
// ul
|
||||
.adev-mini-menu {
|
||||
padding: 0;
|
||||
color: var(--primary-contrast);
|
||||
background-color: var(--page-background);
|
||||
border: 1px solid var(--senary-contrast);
|
||||
border-radius: 0.25rem;
|
||||
z-index: var(--z-index-mini-menu);
|
||||
box-shadow: 10px 4px 40px 0 rgba(0, 0, 0, 0.075);
|
||||
|
||||
@include mq.for-tablet {
|
||||
top: 75px;
|
||||
left: 5px;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
|
||||
// themes and versions
|
||||
button {
|
||||
padding: 1rem;
|
||||
min-width: 75px;
|
||||
min-height: 75px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
docs-icon {
|
||||
font-size: 1.5rem;
|
||||
color: var(--quaternary-contrast);
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--senary-contrast);
|
||||
span,
|
||||
docs-icon {
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// social links
|
||||
a {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
min-width: 50px;
|
||||
svg {
|
||||
fill: var(--quaternary-contrast);
|
||||
transition: fill 0.3s ease;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--senary-contrast);
|
||||
svg {
|
||||
fill: var(--primary-contrast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
color: var(--quaternary-contrast);
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
}
|
||||
|
||||
&-open {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.adev-version-picker {
|
||||
top: 30px;
|
||||
left: 10px;
|
||||
position: absolute;
|
||||
bottom: auto;
|
||||
|
||||
li {
|
||||
padding-inline: 0;
|
||||
}
|
||||
|
||||
li button {
|
||||
min-height: fit-content;
|
||||
}
|
||||
|
||||
@include mq.for-tablet {
|
||||
top: 30px;
|
||||
left: auto;
|
||||
bottom: auto;
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
@use '@angular/docs/styles/media-queries' as mq;
|
||||
|
||||
.adev-nav-item {
|
||||
color: var(--quaternary-contrast);
|
||||
position: relative;
|
||||
width: 6.875rem;
|
||||
|
||||
@include mq.for-phone-only {
|
||||
width: 5.05rem;
|
||||
}
|
||||
|
||||
@include mq.for-tablet {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 2px;
|
||||
@include mq.for-tablet {
|
||||
width: auto;
|
||||
top: auto;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
// TODO: Make this gradient if the page is currently active, and black if child page active
|
||||
background-color: var(--primary-contrast);
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
transform-origin: center;
|
||||
transition: opacity 0.3s ease, transform 0.3s ease;
|
||||
}
|
||||
|
||||
&:not(.adev-nav-item--logo) {
|
||||
@include mq.for-tablet {
|
||||
a,
|
||||
.adev-nav-button {
|
||||
gap: 0.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.adev-nav-button {
|
||||
width: 100%;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
a,
|
||||
.adev-nav-button {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@include mq.for-tablet {
|
||||
flex-direction: row;
|
||||
}
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding-block: 1.25rem;
|
||||
text-decoration: none;
|
||||
fill: var(--quaternary-contrast);
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
transition: fill 0.3s ease;
|
||||
}
|
||||
|
||||
&__label {
|
||||
margin: 0;
|
||||
font-size: 0.813; // 13px
|
||||
color: inherit;
|
||||
|
||||
abbr {
|
||||
font-size: 0.688; // 11px
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
color: var(--quaternary-contrast);
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
span,
|
||||
abbr {
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
a,
|
||||
.adev-nav-button {
|
||||
fill: var(--primary-contrast);
|
||||
}
|
||||
span,
|
||||
abbr {
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
i {
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
}
|
||||
|
||||
&--active {
|
||||
&::before {
|
||||
opacity: 1;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
|
||||
&:not(.adev-nav-item--logo) {
|
||||
path {
|
||||
fill: var(--primary-contrast);
|
||||
}
|
||||
}
|
||||
span,
|
||||
abbr,
|
||||
i {
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,450 +0,0 @@
|
||||
<!-- Primary Nav -->
|
||||
<div
|
||||
[attr.id]="PRIMARY_NAV_ID"
|
||||
(docsClickOutside)="closeMobileNav()"
|
||||
[docsClickOutsideIgnore]="[SECONDARY_NAV_ID]"
|
||||
>
|
||||
<!-- Mobile nav bar -->
|
||||
<div class="adev-mobile-nav-bar">
|
||||
<!-- Logo icon -->
|
||||
<button
|
||||
type="button"
|
||||
class="adev-mobile-nav-button"
|
||||
aria-label="Toggle mobile navigation"
|
||||
(click)="openMobileNav($event)"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 223 236" width="32">
|
||||
<g clip-path="url(#2a)">
|
||||
<path
|
||||
fill="url(#2b)"
|
||||
d="m222.077 39.192-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||
/>
|
||||
<path
|
||||
fill="url(#2c)"
|
||||
d="m222.077 39.192-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="2b"
|
||||
x1="49.009"
|
||||
x2="225.829"
|
||||
y1="213.75"
|
||||
y2="129.722"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#E40035" />
|
||||
<stop offset=".24" stop-color="#F60A48" />
|
||||
<stop offset=".352" stop-color="#F20755" />
|
||||
<stop offset=".494" stop-color="#DC087D" />
|
||||
<stop offset=".745" stop-color="#9717E7" />
|
||||
<stop offset="1" stop-color="#6C00F5" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="2c"
|
||||
x1="41.025"
|
||||
x2="156.741"
|
||||
y1="28.344"
|
||||
y2="160.344"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#FF31D9" />
|
||||
<stop offset="1" stop-color="#FF5BE1" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<clipPath id="2a"><path fill="#fff" d="M0 0h223v236H0z" /></clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<docs-icon role="presentation">menu</docs-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<nav
|
||||
class="adev-nav-primary docs-scroll-hide"
|
||||
[class.adev-nav-primary--open]="isMobileNavigationOpened()"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="adev-close-nav"
|
||||
(click)="closeMobileNav()"
|
||||
aria-label="Close navigation"
|
||||
>
|
||||
<docs-icon role="presentation">close</docs-icon>
|
||||
</button>
|
||||
<!-- Top section of primary nav -->
|
||||
<ul class="adev-nav__top">
|
||||
<!-- Home / Angular logo -->
|
||||
<li
|
||||
class="adev-nav-item adev-nav-item--logo"
|
||||
[class.adev-nav-item--active]="activeRouteItem() === HOME_ROUTE"
|
||||
>
|
||||
<a aria-label="Angular homepage" routerLink="/">
|
||||
<!-- Logo Symbol -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 223 236" width="32">
|
||||
<g clip-path="url(#a)">
|
||||
<path
|
||||
fill="url(#b)"
|
||||
d="m222.077 39.192-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||
/>
|
||||
<path
|
||||
fill="url(#c)"
|
||||
d="m222.077 39.192-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="b"
|
||||
x1="49.009"
|
||||
x2="225.829"
|
||||
y1="213.75"
|
||||
y2="129.722"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#E40035" />
|
||||
<stop offset=".24" stop-color="#F60A48" />
|
||||
<stop offset=".352" stop-color="#F20755" />
|
||||
<stop offset=".494" stop-color="#DC087D" />
|
||||
<stop offset=".745" stop-color="#9717E7" />
|
||||
<stop offset="1" stop-color="#6C00F5" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="c"
|
||||
x1="41.025"
|
||||
x2="156.741"
|
||||
y1="28.344"
|
||||
y2="160.344"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#FF31D9" />
|
||||
<stop offset="1" stop-color="#FF5BE1" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<clipPath id="a">
|
||||
<path fill="#fff" d="M0 0h223v236H0z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<div class="adev-beta-version">Beta Docs</div>
|
||||
</a>
|
||||
|
||||
<!-- Version picker for v18+ -->
|
||||
<div class="adev-nav-item">
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Select Angular version"
|
||||
role="menu"
|
||||
class="adev-version-button"
|
||||
[class.adev-mini-menu-open]="openedMenu === 'version-picker'"
|
||||
[cdkMenuTriggerFor]="docsVersionMiniMenu"
|
||||
[cdkMenuPosition]="miniMenuPositions"
|
||||
(cdkMenuClosed)="closeMenu()"
|
||||
(click)="openVersionMenu($event)"
|
||||
>
|
||||
{{ currentDocsVersion()?.displayName }}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="15"
|
||||
viewBox="0 -960 960 960"
|
||||
width="15"
|
||||
fill="inherit"
|
||||
>
|
||||
<path d="M480-345 240-585l56-56 184 184 184-184 56 56-240 240Z" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<ng-template #docsVersionMiniMenu>
|
||||
<ul class="adev-mini-menu adev-version-picker" cdkMenu>
|
||||
@for (item of versions(); track item) {
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
cdkMenuItem
|
||||
(click)="redirectToDocsVersion(item.url)"
|
||||
[attr.aria-label]="item.displayName"
|
||||
>
|
||||
<span>{{ item.displayName }}</span>
|
||||
</button>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</ng-template>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Search -->
|
||||
<li class="adev-nav-item">
|
||||
<button
|
||||
class="adev-nav-button"
|
||||
type="button"
|
||||
(click)="toggleSearchDialog($event)"
|
||||
title="Search docs"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="inherit"
|
||||
>
|
||||
<path
|
||||
d="M14.583 15.48 9.104 10a4.591 4.591 0 0 1-1.458.844 5.156 5.156 0 0 1-1.771.302c-1.5 0-2.77-.52-3.813-1.563C1.022 8.542.5 7.285.5 5.813c0-1.473.52-2.73 1.563-3.771C3.103 1 4.367.479 5.854.479 7.326.48 8.58 1 9.614 2.042c1.035 1.041 1.553 2.298 1.553 3.77 0 .598-.098 1.174-.292 1.73A5.287 5.287 0 0 1 10 9.104l5.5 5.459-.917.916ZM5.854 9.895c1.125 0 2.083-.4 2.875-1.198a3.95 3.95 0 0 0 1.188-2.885 3.95 3.95 0 0 0-1.188-2.886C7.938 2.13 6.98 1.73 5.854 1.73c-1.139 0-2.107.4-2.906 1.198-.799.799-1.198 1.76-1.198 2.886 0 1.125.4 2.086 1.198 2.885.799.799 1.767 1.198 2.906 1.198Z"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
class="adev-nav-item__label adev-search-desktop"
|
||||
[attr.aria-label]="'Open search dialog with ' + searchTitle"
|
||||
>
|
||||
<kbd>{{ searchLabel }}</kbd>
|
||||
<kbd>K</kbd>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<!-- Docs -->
|
||||
<li class="adev-nav-item" [class.adev-nav-item--active]="activeRouteItem() === DOCS_ROUTE">
|
||||
<a [routerLink]="DOCS_ROUTE">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="14"
|
||||
height="18"
|
||||
fill="inherit"
|
||||
>
|
||||
<path
|
||||
d="M3.645 13.792h6.708v-1.25H3.645v1.25Zm0-3.542h6.708V9H3.645v1.25Zm-2.063 7.083a1.2 1.2 0 0 1-.875-.375 1.2 1.2 0 0 1-.375-.875V1.917a1.2 1.2 0 0 1 .375-.875 1.2 1.2 0 0 1 .875-.375h7.52l4.563 4.562v10.854a1.2 1.2 0 0 1-.375.875 1.2 1.2 0 0 1-.875.375H1.582ZM8.478 5.792V1.917H1.582v14.166h10.833V5.792H8.478Z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="adev-nav-item__label">Docs</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- Tutorials -->
|
||||
<li
|
||||
class="adev-nav-item"
|
||||
[class.adev-nav-item--active]="activeRouteItem() === TUTORIALS_ROUTE"
|
||||
>
|
||||
<a [routerLink]="TUTORIALS_ROUTE">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="10"
|
||||
fill="inherit"
|
||||
>
|
||||
<path
|
||||
d="m5.668 10-5-5 5-5 1.187 1.188L3.022 5.02l3.813 3.812L5.668 10Zm6.667 0-1.188-1.188L14.98 4.98l-3.812-3.812L12.335 0l5 5-5 5Z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="adev-nav-item__label">Tutorials</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- Playground -->
|
||||
<li
|
||||
class="adev-nav-item"
|
||||
[class.adev-nav-item--active]="activeRouteItem() === PLAYGROUND_ROUTE"
|
||||
>
|
||||
<a [routerLink]="PLAYGROUND_ROUTE">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24">
|
||||
<path
|
||||
d="M450.001-611.691v-32.386q-39.385-9.923-64.692-41.897-25.308-31.975-25.308-74.025 0-49.922 35.038-84.96 35.039-35.038 84.961-35.038t84.961 35.038q35.038 35.038 35.038 84.96 0 42.05-25.308 74.025-25.307 31.974-64.692 41.897v32.386l273.846 157.538q17.173 9.912 26.663 26.582 9.491 16.671 9.491 36.495v62.152q0 19.824-9.491 36.495-9.49 16.67-26.663 26.582L516.154-111.771q-17.203 9.846-36.217 9.846t-36.091-9.846L176.155-265.847q-17.173-9.912-26.663-26.582-9.491-16.671-9.491-36.495v-62.152q0-19.824 9.491-36.495 9.49-16.67 26.663-26.582l273.846-157.538Zm-6.155 364.537L200-387.461v58.537q0 3.078 1.539 5.962 1.538 2.885 4.615 4.808l267.692 154.692q3.077 1.923 6.154 1.923t6.154-1.923l267.692-154.692q3.077-1.923 4.615-4.808 1.539-2.884 1.539-5.962v-58.537L516.154-247.154q-17.203 9.847-36.217 9.847t-36.091-9.847Zm6.155-162.847V-542.77L250.46-427.691l223.386 128.846q3.077 1.924 6.154 1.924t6.154-1.924l223.001-128.846L509.999-542.77v132.769h-59.998ZM480-699.999q25 0 42.5-17.5t17.5-42.5q0-25-17.5-42.5t-42.5-17.5q-25 0-42.5 17.5t-17.5 42.5q0 25 17.5 42.5t42.5 17.5Zm-2.308 538.46Z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="adev-nav-item__label">Playground</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- API Ref -->
|
||||
<li
|
||||
class="adev-nav-item"
|
||||
[class.adev-nav-item--active]="activeRouteItem() === REFERENCE_ROUTE"
|
||||
>
|
||||
<a [routerLink]="REFERENCE_ROUTE">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="14"
|
||||
height="18"
|
||||
fill="inherit"
|
||||
>
|
||||
<path
|
||||
d="M3.645 13.792h6.708v-1.25H3.645v1.25Zm0-3.542h6.708V9H3.645v1.25Zm-2.063 7.083a1.2 1.2 0 0 1-.875-.375 1.2 1.2 0 0 1-.375-.875V1.917a1.2 1.2 0 0 1 .375-.875 1.2 1.2 0 0 1 .875-.375h7.52l4.563 4.562v10.854a1.2 1.2 0 0 1-.375.875 1.2 1.2 0 0 1-.875.375H1.582ZM8.478 5.792V1.917H1.582v14.166h10.833V5.792H8.478Z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="adev-nav-item__label">Reference</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Bottom section of primary nav -->
|
||||
<div class="adev-nav__bottom">
|
||||
<!-- Social Icons Dots -->
|
||||
<div class="adev-nav-item" [class.adev-nav-item--active]="openedMenu === 'social'">
|
||||
<button
|
||||
type="button"
|
||||
[cdkMenuTriggerFor]="socialMiniMenu"
|
||||
[cdkMenuPosition]="miniMenuPositions"
|
||||
aria-label="Open social media links"
|
||||
(cdkMenuClosed)="closeMenu()"
|
||||
(cdkMenuOpened)="openMenu('social')"
|
||||
>
|
||||
<docs-icon role="presentation">more_horiz</docs-icon>
|
||||
</button>
|
||||
|
||||
<ng-template #socialMiniMenu>
|
||||
<ul class="adev-mini-menu" cdkMenu>
|
||||
<li>
|
||||
<a
|
||||
[href]="YOUTUBE"
|
||||
cdkMenuItem
|
||||
title="Angular YouTube channel"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<!-- Youtube Icon -->
|
||||
<svg
|
||||
width="20"
|
||||
height="15"
|
||||
viewBox="0 0 20 15"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M18.7556 2.94783C18.5803 1.98018 17.745 1.27549 16.7756 1.05549C15.325 0.747832 12.6403 0.527832 9.73563 0.527832C6.83266 0.527832 4.105 0.747832 2.65266 1.05549C1.685 1.27549 0.847969 1.93549 0.672656 2.94783C0.495625 4.04783 0.320312 5.58783 0.320312 7.56783C0.320312 9.54783 0.495625 11.0878 0.715625 12.1878C0.892656 13.1555 1.72797 13.8602 2.69563 14.0802C4.23563 14.3878 6.87563 14.6078 9.78031 14.6078C12.685 14.6078 15.325 14.3878 16.865 14.0802C17.8327 13.8602 18.668 13.2002 18.845 12.1878C19.0203 11.0878 19.2403 9.50314 19.285 7.56783C19.1956 5.58783 18.9756 4.04783 18.7556 2.94783ZM7.36031 10.6478V4.48783L12.728 7.56783L7.36031 10.6478Z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
[href]="X"
|
||||
cdkMenuItem
|
||||
title="Angular X (formerly Twitter) profile"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<!-- X Icon -->
|
||||
<svg
|
||||
width="17"
|
||||
height="16"
|
||||
viewBox="0 0 17 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M0.04145 0.04432l6.56351 8.77603L0 15.95564h1.48651l5.78263-6.24705 4.6722 6.24705h5.05865l-6.9328-9.26967L16.21504.04432h-1.48651l-5.32552 5.75341L5.1001.04432H.04145Zm2.18602 1.09497h2.32396l10.26221 13.72122h-2.32396L2.22747 1.13928Z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
[href]="MEDIUM"
|
||||
cdkMenuItem
|
||||
title="Angular Medium blog"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<!-- Medium Icon -->
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M7 6A7 7 0 107 20 7 7 0 107 6zM18 6.5A3 6.5 0 1018 19.5 3 6.5 0 1018 6.5zM23 8A1 5 0 1023 18 1 5 0 1023 8z"
|
||||
></path>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [href]="GITHUB" cdkMenuItem title="Angular Github" target="_blank" rel="noopener">
|
||||
<!-- Github Icon -->
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M7.59948 19.0428C7.59948 18.8069 7.59118 18.182 7.58656 17.3526C4.89071 17.9526 4.32164 16.0201 4.32164 16.0201C3.88087 14.8718 3.24533 14.5663 3.24533 14.5663C2.36518 13.9492 3.31179 13.9621 3.31179 13.9621C4.28471 14.0323 4.79656 14.9868 4.79656 14.9868C5.66102 16.5052 7.06456 16.0672 7.61748 15.8125C7.70564 15.17 7.95579 14.732 8.23271 14.4837C6.08056 14.2331 3.81764 13.3801 3.81764 9.57199C3.81764 8.48737 4.19564 7.6003 4.81548 6.90522C4.71625 6.65414 4.38302 5.64384 4.91056 4.27537C4.91056 4.27537 5.72471 4.00814 7.57594 5.29399C8.34856 5.07384 9.17795 4.96307 10.0027 4.95937C10.8256 4.96307 11.6546 5.07384 12.429 5.29399C14.2793 4.00814 15.0921 4.27537 15.0921 4.27537C15.621 5.64337 15.2883 6.65368 15.1881 6.90522C15.8093 7.6003 16.1841 8.48737 16.1841 9.57199C16.1841 13.3898 13.9179 14.2298 11.7589 14.4758C12.1073 14.7828 12.4166 15.3892 12.4166 16.3165C12.4166 17.6452 12.4041 18.7174 12.4041 19.0428C12.4041 19.3091 12.579 19.6178 13.071 19.5205C16.9193 18.2041 19.6936 14.4814 19.6936 10.0926C19.6936 4.60353 15.3538 0.154297 10.0009 0.154297C4.64887 0.154297 0.309021 4.60353 0.309021 10.0926C0.309483 14.4828 3.08656 18.2078 6.9381 19.5218C7.42225 19.6128 7.59948 19.3058 7.59948 19.0428Z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</ng-template>
|
||||
</div>
|
||||
<!-- TODO: Refactor this and make it better. Accessible, animated, etc. -->
|
||||
<div class="adev-nav-item" [class.adev-nav-item--active]="openedMenu === 'theme-picker'">
|
||||
<button
|
||||
type="button"
|
||||
[cdkMenuTriggerFor]="themeMiniMenu"
|
||||
[cdkMenuPosition]="miniMenuPositions"
|
||||
aria-label="Open theme picker"
|
||||
(cdkMenuClosed)="closeMenu()"
|
||||
(cdkMenuOpened)="openMenu('theme-picker')"
|
||||
>
|
||||
<docs-icon role="presentation">
|
||||
@switch (theme()) { @case ('light') {
|
||||
{{ 'light_mode' }}
|
||||
} @case ('dark') {
|
||||
{{ 'dark_mode' }}
|
||||
} @case ('auto') {
|
||||
{{ 'routine' }}
|
||||
} }
|
||||
</docs-icon>
|
||||
</button>
|
||||
|
||||
<ng-template #themeMiniMenu>
|
||||
<ul class="adev-mini-menu" cdkMenu>
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
cdkMenuItem
|
||||
(click)="setTheme('auto')"
|
||||
aria-label="Set default system theme"
|
||||
>
|
||||
<docs-icon class="docs-icon_high-contrast">routine</docs-icon>
|
||||
<span>System</span>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
cdkMenuItem
|
||||
(click)="setTheme('dark')"
|
||||
aria-label="Set dark theme"
|
||||
>
|
||||
<docs-icon class="docs-icon_high-contrast">dark_mode</docs-icon>
|
||||
<span>Dark</span>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
cdkMenuItem
|
||||
(click)="setTheme('light')"
|
||||
aria-label="Set light theme"
|
||||
>
|
||||
<docs-icon class="docs-icon_high-contrast">light_mode</docs-icon>
|
||||
<span>Light</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Tablet: Second horizontal nav layer which opens the secondary nav -->
|
||||
@if (activeRouteItem() === DOCS_ROUTE || activeRouteItem() === REFERENCE_ROUTE) {
|
||||
<div class="adev-secondary-tablet-bar">
|
||||
<button type="button" (click)="openMobileNav($event)">
|
||||
<docs-icon class="docs-icon_high-contrast">menu</docs-icon>
|
||||
@if (activeRouteItem() === DOCS_ROUTE) {
|
||||
<span>Docs</span>
|
||||
} @if (activeRouteItem() === REFERENCE_ROUTE) {
|
||||
<span>API</span>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -1,283 +0,0 @@
|
||||
@use '@angular/docs/styles/media-queries' as mq;
|
||||
|
||||
// primary nav
|
||||
:host {
|
||||
display: flex;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: var(--z-index-nav);
|
||||
|
||||
.adev-mobile-nav-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
// render tablet primary nav under blur when secondary is open
|
||||
@include mq.for-tablet {
|
||||
&:has(.adev-nav-primary--open) {
|
||||
z-index: 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.adev-mobile-nav-bar {
|
||||
display: none;
|
||||
@include mq.for-phone-only {
|
||||
display: flex;
|
||||
}
|
||||
gap: 0.75rem;
|
||||
backdrop-filter: blur(16px);
|
||||
background-color: color-mix(in srgb, var(--page-background) 70%, transparent);
|
||||
position: relative;
|
||||
width: 100vw;
|
||||
padding-block: 0.75rem;
|
||||
padding-inline: var(--layout-padding);
|
||||
border-block-end: 1px solid var(--septenary-contrast);
|
||||
box-sizing: border-box;
|
||||
|
||||
transform: translateY(0);
|
||||
// mobile bar: enter with delay
|
||||
transition: transform 0.3s ease-out 0.6s;
|
||||
|
||||
&:has(+ .adev-nav-primary--open) {
|
||||
transform: translateY(-100%);
|
||||
// mobile bar: exit without delay
|
||||
transition: transform 0.3s ease-in;
|
||||
}
|
||||
|
||||
docs-icon {
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
}
|
||||
|
||||
// First level navigation
|
||||
.adev-nav-primary {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
max-height: 100vh;
|
||||
overflow: auto;
|
||||
backdrop-filter: blur(16px);
|
||||
background-color: color-mix(in srgb, var(--page-background) 70%, transparent);
|
||||
// render primary nav / mini menu above tablet secondary bar
|
||||
z-index: 250;
|
||||
position: relative;
|
||||
transition: background-color 0.3s ease, border-color 0.3s ease;
|
||||
height: 100dvh;
|
||||
padding-block-start: 1rem;
|
||||
padding-block-end: 2rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
// div containing mobile close button and adev-nav_top
|
||||
> div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@include mq.for-phone-only {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
background-color: var(--page-background);
|
||||
box-shadow: 10px 4px 3px 0 rgba(0, 0, 0, 0.001);
|
||||
|
||||
transform: translateX(-100%);
|
||||
// primary nav: exit delayed
|
||||
// TODO: should only be delayed if there is a secondary nav
|
||||
transition: transform 0.3s ease-in 0.38s;
|
||||
|
||||
&.adev-nav-primary--open {
|
||||
transform: translateX(0%);
|
||||
// primary nav: enter after mobile nav bar exits
|
||||
transition: transform 0.3s ease-out 0.1s;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce-motion) {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
@include mq.for-tablet {
|
||||
flex-direction: row;
|
||||
width: 100vw;
|
||||
padding-inline: calc(var(--layout-padding) - 1.25rem);
|
||||
height: auto;
|
||||
padding-block: 0;
|
||||
}
|
||||
|
||||
// Add a subtle border for the home page
|
||||
border-block-end: 1px solid var(--septenary-contrast);
|
||||
@include mq.for-tablet-up {
|
||||
border-inline-end: 1px solid var(--septenary-contrast);
|
||||
}
|
||||
@include mq.for-phone-only {
|
||||
border-inline-end: 1px solid var(--septenary-contrast);
|
||||
}
|
||||
}
|
||||
|
||||
.adev-nav {
|
||||
&__top {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@include mq.for-tablet {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.adev-beta-version {
|
||||
font-family: 'Material Symbols Outlined';
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
// version dropdown button
|
||||
.adev-version-button {
|
||||
border: 1px solid var(--senary-contrast);
|
||||
border-radius: 0.25rem;
|
||||
width: fit-content;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 0.25rem;
|
||||
color: var(--quaternary-contrast);
|
||||
fill: var(--quaternary-contrast);
|
||||
transition: color 0.3s ease;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
|
||||
docs-icon {
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
@include mq.for-phone-only {
|
||||
&.adev-mini-menu-open {
|
||||
&::after {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@include mq.for-tablet-landscape-up {
|
||||
&.adev-mini-menu-open {
|
||||
&::after {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mq.for-tablet {
|
||||
> li:first-of-type {
|
||||
padding-inline-start: 1.25rem;
|
||||
}
|
||||
|
||||
li {
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__bottom {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
|
||||
@include mq.for-tablet {
|
||||
flex-direction: row;
|
||||
margin-inline-end: 1.25rem;
|
||||
}
|
||||
|
||||
.adev-nav-item--active {
|
||||
button {
|
||||
docs-icon {
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
padding-inline: 1rem;
|
||||
|
||||
@include mq.for-tablet {
|
||||
padding-inline: 0.5rem;
|
||||
}
|
||||
|
||||
docs-icon {
|
||||
color: var(--quaternary-contrast);
|
||||
font-size: 1.5rem;
|
||||
@include mq.for-tablet-landscape-down {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
docs-icon {
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.adev-close-nav {
|
||||
display: none;
|
||||
@include mq.for-phone-only {
|
||||
display: block;
|
||||
}
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
|
||||
.adev-search-desktop {
|
||||
height: 1.375rem;
|
||||
text-transform: capitalize;
|
||||
@include mq.for-tablet-landscape-down {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.adev-sub-navigation-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.adev-secondary-tablet-bar {
|
||||
font-size: 0.875rem;
|
||||
backdrop-filter: blur(16px);
|
||||
background-color: color-mix(in srgb, var(--page-background) 70%, transparent);
|
||||
border-block-end: 1px solid var(--septenary-contrast);
|
||||
padding-block: 1rem;
|
||||
padding-inline: var(--layout-padding);
|
||||
transition: background-color 0.3s ease, border-color 0.3s ease;
|
||||
button {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
color: var(--primary-contrast);
|
||||
padding: 0;
|
||||
font-weight: 500;
|
||||
}
|
||||
@include mq.for-tablet-landscape-up {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@include mq.for-phone-only {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {Navigation} from './navigation.component';
|
||||
import {RouterTestingModule} from '@angular/router/testing';
|
||||
import {By} from '@angular/platform-browser';
|
||||
import {PagePrefix} from '../../enums/pages';
|
||||
import {Theme, ThemeManager} from '../../services/theme-manager.service';
|
||||
import {Version, signal} from '@angular/core';
|
||||
import {of} from 'rxjs';
|
||||
import {VersionManager} from '../../services/version-manager.service';
|
||||
import {Search, WINDOW} from '@angular/docs';
|
||||
|
||||
describe('Navigation', () => {
|
||||
let component: Navigation;
|
||||
let fixture: ComponentFixture<Navigation>;
|
||||
|
||||
const fakeThemeManager = {
|
||||
theme: signal<Theme>('dark'),
|
||||
setTheme: (theme: Theme) => {},
|
||||
themeChanged$: of(),
|
||||
};
|
||||
|
||||
const fakeVersionManager = {
|
||||
currentDocsVersion: signal('v17'),
|
||||
versions: signal<Version[]>([]),
|
||||
};
|
||||
|
||||
const fakeWindow = {};
|
||||
const fakeSearch = {};
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [Navigation, RouterTestingModule],
|
||||
providers: [
|
||||
{
|
||||
provide: WINDOW,
|
||||
useValue: fakeWindow,
|
||||
},
|
||||
{
|
||||
provide: Search,
|
||||
useValue: fakeSearch,
|
||||
},
|
||||
],
|
||||
}).compileComponents();
|
||||
|
||||
TestBed.overrideProvider(ThemeManager, {useValue: fakeThemeManager});
|
||||
TestBed.overrideProvider(VersionManager, {useValue: fakeVersionManager});
|
||||
|
||||
fixture = TestBed.createComponent(Navigation);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should append active class to DOCS_ROUTE when DOCS_ROUTE is active', () => {
|
||||
component.activeRouteItem.set(PagePrefix.DOCS);
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
const docsLink = fixture.debugElement.query(By.css('a[href="/docs"]')).parent?.nativeElement;
|
||||
|
||||
expect(docsLink).toHaveClass('adev-nav-item--active');
|
||||
});
|
||||
|
||||
it('should not have active class when activeRouteItem is null', () => {
|
||||
component.activeRouteItem.set(null);
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
const docsLink = fixture.debugElement.query(By.css('a[href="/docs"]')).nativeElement;
|
||||
const referenceLink = fixture.debugElement.query(By.css('a[href="/reference"]')).nativeElement;
|
||||
|
||||
expect(docsLink).not.toHaveClass('adev-nav-item--active');
|
||||
expect(referenceLink).not.toHaveClass('adev-nav-item--active');
|
||||
});
|
||||
|
||||
it('should call themeManager.setTheme(dark) when user tries to set dark theme', () => {
|
||||
const openThemePickerButton = fixture.debugElement.query(
|
||||
By.css('button[aria-label^="Open theme picker"]'),
|
||||
).nativeElement;
|
||||
const setThemeSpy = spyOn(fakeThemeManager, 'setTheme');
|
||||
|
||||
openThemePickerButton.click();
|
||||
fixture.detectChanges();
|
||||
|
||||
const setDarkModeButton = fixture.debugElement.query(
|
||||
By.css('button[aria-label="Set dark theme"]'),
|
||||
).nativeElement;
|
||||
|
||||
setDarkModeButton.click();
|
||||
|
||||
expect(setThemeSpy).toHaveBeenCalledOnceWith('dark');
|
||||
});
|
||||
});
|
||||
@@ -1,228 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {CdkMenu, CdkMenuItem, CdkMenuTrigger} from '@angular/cdk/menu';
|
||||
import {CommonModule, DOCUMENT, Location, isPlatformBrowser} from '@angular/common';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
DestroyRef,
|
||||
OnInit,
|
||||
PLATFORM_ID,
|
||||
inject,
|
||||
} from '@angular/core';
|
||||
import {takeUntilDestroyed, toObservable} from '@angular/core/rxjs-interop';
|
||||
import {
|
||||
ClickOutside,
|
||||
NavigationList,
|
||||
NavigationState,
|
||||
WINDOW,
|
||||
IconComponent,
|
||||
getBaseUrlAfterRedirects,
|
||||
isApple,
|
||||
IS_SEARCH_DIALOG_OPEN,
|
||||
} from '@angular/docs';
|
||||
import {NavigationEnd, Router, RouterLink} from '@angular/router';
|
||||
import {filter, map, startWith} from 'rxjs/operators';
|
||||
import {DOCS_ROUTES, REFERENCE_ROUTES, TUTORIALS_ROUTES} from '../../../routes';
|
||||
import {GITHUB, MEDIUM, X, YOUTUBE} from '../../constants/links';
|
||||
import {PagePrefix} from '../../enums/pages';
|
||||
import {Theme, ThemeManager} from '../../services/theme-manager.service';
|
||||
import {VersionManager} from '../../services/version-manager.service';
|
||||
import {PRIMARY_NAV_ID, SECONDARY_NAV_ID} from '../../constants/element-ids';
|
||||
import {ConnectionPositionPair} from '@angular/cdk/overlay';
|
||||
import {COMMAND, CONTROL, SEARCH_TRIGGER_KEY} from '../../constants/keys';
|
||||
|
||||
type MenuType = 'social' | 'theme-picker' | 'version-picker';
|
||||
|
||||
@Component({
|
||||
selector: 'div.adev-nav',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterLink,
|
||||
NavigationList,
|
||||
ClickOutside,
|
||||
CdkMenu,
|
||||
CdkMenuItem,
|
||||
CdkMenuTrigger,
|
||||
IconComponent,
|
||||
],
|
||||
templateUrl: './navigation.component.html',
|
||||
styleUrls: ['./navigation.component.scss', './mini-menu.scss', './nav-item.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class Navigation implements OnInit {
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly document = inject(DOCUMENT);
|
||||
private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
||||
private readonly navigationState = inject(NavigationState);
|
||||
private readonly router = inject(Router);
|
||||
private readonly location = inject(Location);
|
||||
private readonly themeManager = inject(ThemeManager);
|
||||
private readonly isSearchDialogOpen = inject(IS_SEARCH_DIALOG_OPEN);
|
||||
private readonly window = inject(WINDOW);
|
||||
private readonly versionManager = inject(VersionManager);
|
||||
|
||||
readonly DOCS_ROUTE = PagePrefix.DOCS;
|
||||
readonly HOME_ROUTE = PagePrefix.HOME;
|
||||
readonly PLAYGROUND_ROUTE = PagePrefix.PLAYGROUND;
|
||||
readonly REFERENCE_ROUTE = PagePrefix.REFERENCE;
|
||||
readonly TUTORIALS_ROUTE = PagePrefix.TUTORIALS;
|
||||
|
||||
readonly GITHUB = GITHUB;
|
||||
readonly X = X;
|
||||
readonly MEDIUM = MEDIUM;
|
||||
readonly YOUTUBE = YOUTUBE;
|
||||
|
||||
readonly PRIMARY_NAV_ID = PRIMARY_NAV_ID;
|
||||
readonly SECONDARY_NAV_ID = SECONDARY_NAV_ID;
|
||||
|
||||
miniMenuPositions = [
|
||||
new ConnectionPositionPair(
|
||||
{originX: 'end', originY: 'center'},
|
||||
{overlayX: 'start', overlayY: 'center'},
|
||||
),
|
||||
new ConnectionPositionPair(
|
||||
{originX: 'end', originY: 'top'},
|
||||
{overlayX: 'start', overlayY: 'top'},
|
||||
),
|
||||
];
|
||||
|
||||
readonly APPLE_SEARCH_LABEL = `⌘`;
|
||||
readonly DEFAULT_SEARCH_LABEL = `ctrl`;
|
||||
|
||||
activeRouteItem = this.navigationState.primaryActiveRouteItem;
|
||||
theme = this.themeManager.theme;
|
||||
openedMenu: MenuType | null = null;
|
||||
|
||||
currentDocsVersion = this.versionManager.currentDocsVersion;
|
||||
// Set the values of the search label and title only on the client, because the label is user-agent specific.
|
||||
searchLabel = this.isBrowser
|
||||
? isApple
|
||||
? this.APPLE_SEARCH_LABEL
|
||||
: this.DEFAULT_SEARCH_LABEL
|
||||
: '';
|
||||
searchTitle = this.isBrowser
|
||||
? isApple
|
||||
? `${COMMAND} ${SEARCH_TRIGGER_KEY.toUpperCase()}`
|
||||
: `${CONTROL} ${SEARCH_TRIGGER_KEY.toUpperCase()}`
|
||||
: '';
|
||||
versions = this.versionManager.versions;
|
||||
|
||||
isMobileNavigationOpened = this.navigationState.isMobileNavVisible;
|
||||
isMobileNavigationOpened$ = toObservable(this.isMobileNavigationOpened);
|
||||
primaryRouteChanged$ = toObservable(this.activeRouteItem);
|
||||
|
||||
ngOnInit(): void {
|
||||
this.listenToRouteChange();
|
||||
this.preventToScrollContentWhenSecondaryNavIsOpened();
|
||||
this.closeMobileNavOnPrimaryRouteChange();
|
||||
}
|
||||
|
||||
redirectToDocsVersion(versionUrl: string): void {
|
||||
this.window.location.href = versionUrl;
|
||||
}
|
||||
|
||||
setTheme(theme: Theme): void {
|
||||
this.themeManager.setTheme(theme);
|
||||
}
|
||||
|
||||
openVersionMenu($event: MouseEvent): void {
|
||||
// It's required to avoid redirection to `home`
|
||||
$event.stopImmediatePropagation();
|
||||
$event.preventDefault();
|
||||
this.openMenu('version-picker');
|
||||
}
|
||||
|
||||
openMenu(menuType: MenuType): void {
|
||||
this.openedMenu = menuType;
|
||||
}
|
||||
|
||||
closeMenu(): void {
|
||||
this.openedMenu = null;
|
||||
}
|
||||
|
||||
openMobileNav($event: MouseEvent): void {
|
||||
$event.stopPropagation();
|
||||
this.navigationState.setMobileNavigationListVisibility(true);
|
||||
}
|
||||
|
||||
closeMobileNav(): void {
|
||||
this.navigationState.setMobileNavigationListVisibility(false);
|
||||
}
|
||||
|
||||
toggleSearchDialog(event: MouseEvent): void {
|
||||
event.stopPropagation();
|
||||
this.isSearchDialogOpen.update((isOpen) => !isOpen);
|
||||
}
|
||||
|
||||
private closeMobileNavOnPrimaryRouteChange(): void {
|
||||
this.primaryRouteChanged$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
||||
this.closeMobileNav();
|
||||
});
|
||||
}
|
||||
|
||||
private listenToRouteChange(): void {
|
||||
this.router.events
|
||||
.pipe(
|
||||
filter((event) => event instanceof NavigationEnd),
|
||||
map((event) => (event as NavigationEnd).urlAfterRedirects),
|
||||
)
|
||||
.pipe(
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
//using location because router.url will only return "/" here
|
||||
startWith(this.location.path()),
|
||||
)
|
||||
.subscribe((url) => {
|
||||
this.setActivePrimaryRoute(getBaseUrlAfterRedirects(url, this.router));
|
||||
});
|
||||
}
|
||||
|
||||
// Set active route item, based on urlAfterRedirects.
|
||||
// First check if url starts with the main prefixes (docs, reference, tutorials).
|
||||
// (*) Docs navigation tree contains items which will navigate to /tutorials.
|
||||
// In that case after click on such link we should mark as active item, and display tutorials navigation tree.
|
||||
// If it's not starting with prefix then check if specific path exist in the array of defined routes
|
||||
// (*) Reference navigation tree contains items which are not start with prefix like /migrations or /errors.
|
||||
private setActivePrimaryRoute(urlAfterRedirects: string): void {
|
||||
if (urlAfterRedirects === '') {
|
||||
this.activeRouteItem.set(PagePrefix.HOME);
|
||||
} else if (urlAfterRedirects.startsWith(PagePrefix.DOCS)) {
|
||||
this.activeRouteItem.set(PagePrefix.DOCS);
|
||||
} else if (
|
||||
urlAfterRedirects.startsWith(PagePrefix.REFERENCE) ||
|
||||
urlAfterRedirects.startsWith(PagePrefix.API)
|
||||
) {
|
||||
this.activeRouteItem.set(PagePrefix.REFERENCE);
|
||||
} else if (urlAfterRedirects === PagePrefix.PLAYGROUND) {
|
||||
this.activeRouteItem.set(PagePrefix.PLAYGROUND);
|
||||
} else if (urlAfterRedirects.startsWith(PagePrefix.TUTORIALS)) {
|
||||
this.activeRouteItem.set(PagePrefix.TUTORIALS);
|
||||
} else if (DOCS_ROUTES.some((route) => route.path === urlAfterRedirects)) {
|
||||
this.activeRouteItem.set(PagePrefix.DOCS);
|
||||
} else if (REFERENCE_ROUTES.some((route) => route.path === urlAfterRedirects)) {
|
||||
this.activeRouteItem.set(PagePrefix.REFERENCE);
|
||||
} else if (TUTORIALS_ROUTES.some((route) => route.path === urlAfterRedirects)) {
|
||||
this.activeRouteItem.set(PagePrefix.TUTORIALS);
|
||||
} else {
|
||||
// Reset if no active route item could be found
|
||||
this.activeRouteItem.set(null);
|
||||
}
|
||||
}
|
||||
|
||||
private preventToScrollContentWhenSecondaryNavIsOpened(): void {
|
||||
this.isMobileNavigationOpened$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((opened) => {
|
||||
if (opened) {
|
||||
this.document.body.style.overflowY = 'hidden';
|
||||
} else {
|
||||
this.document.body.style.removeProperty('overflow-y');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user