Compare commits

..

46 Commits

Author SHA1 Message Date
Jason Aden 7edc5e96f3 docs: add changelog for 4.1.3 2017-05-17 15:44:25 -07:00
Jason Aden 7b802faa96 release: cut the 4.1.3 release 2017-05-17 15:42:14 -07:00
Victor Berchet 6f039d7a3c build: do not create the bundles when updating the public API
- 1.7x faster on my machine (2.7 vs 4.6 min)
- should solve the memory issue
2017-05-17 15:12:12 -07:00
vikerman 0a82f7d69f fix(platform-server): wait for async app initializers to complete before removing server side styles (#16712)
This fixes a flicker when transitioning from server rendered page to client rendered page in lazy loaded routes by waiting for the lazy loaded route to finish loading, assuming initialNavigation on the route is set to 'enabled'.

Fixes #15716
2017-05-17 15:12:08 -07:00
Adol1111 b7f85813d5 fix(compiler-cli): import routing module with forRoot (#16438) 2017-05-17 15:10:59 -07:00
Miško Hevery a5bdbed306 fix: add typescript 2.3.2 typings test (#16738)
Closes #16663
2017-05-17 15:10:59 -07:00
Victor Berchet 883ca285de fix(router): Wrap Promise-like instances in native Promises (#16759)
Hybrid apps (mix of Angular and AngularJS) might return AngularJS implementation
of Promises that do not play well with the change detection. Wrapping them in
native Promises fix this issue.

This could be the case when a Resolver returns a `$q` promise.
2017-05-17 15:10:58 -07:00
lozanol afb7540067 fix(upgrade): Prevent renaming of $inject property (#16706)
Use bracket notation to access $inject in downgradeInjectable to
support property renaming. Since the return type is any,
Closure compiler renames $inject.
2017-05-17 15:10:58 -07:00
Jack Sun 47df3d681f fix(upgrade): use quote to prevent ClossureCompiler obfuscating $event. (#16724)
This is critical for AngularJS to get the $event object in template.
2017-05-17 15:10:57 -07:00
Jason Aden cd7fe31fbc docs: add saved replies (#16726) 2017-05-17 15:10:56 -07:00
Peter Bacon Darwin 4203b1bb1f docs(common): remove h1s from API docs
Only one h1 is allowed per document, and this is provided by the template.
So we cannot have any h1 tags (or `#` markdown shorthand) in any API docs.

Closes #16193
2017-05-17 15:10:56 -07:00
Aaron Hoffman 055db5ad6a docs(router): Change CanDeactivate to CanLoad (#16237)
fix mistake in docs. CanDeactivate should be CanLoad
2017-05-17 15:10:55 -07:00
Jason Aden 62a8618536 docs: add changelog for 4.1.2 2017-05-10 15:44:28 -07:00
Jason Aden 419fe0ca0d release: cut the 4.1.2 release 2017-05-10 15:42:11 -07:00
Jason Aden e46a65f8fd build: update key for pushing to PACKAGE-builds repos (#16667) 2017-05-09 17:34:35 -07:00
Pete Bacon Darwin f0e1043a1d docs(*) fix dangling links in API docs (#16632)
* docs(animations): fix links to `Component` animations

* docs(core): fix links to `ReflectiveInjector` methods

The `resolve` and other methods were moved from the
`Injector` to the `ReflectiveInjector`.

* docs(core): fix links to `Renderer`

The local links were assuming that that methods were on the
current document (e.g. `RootRenderer`), but they are actually
on the `Renderer` class.

* docs(router): fix links to methods

* docs(forms): fix links to methods

* docs(core): fix links to methods

* docs(router): fix API page links and an internal link
2017-05-09 17:34:35 -07:00
Pete Bacon Darwin c1938f5af1 docs(core): remove link to non-existent class in InjectableDecorator (#16653)
Closes #16640
2017-05-09 17:34:34 -07:00
Victor Berchet 915eae50b4 fix(router): fix redirect to a URL with a param having multiple values (#16376)
fixes #16310

PR Close #16376
2017-05-09 17:34:33 -07:00
Victor Berchet 68675e625a test(router): simplify redirect tests (#16376) 2017-05-09 17:34:32 -07:00
Martin Probst d0e1688514 fix(compiler): avoid a ...null spread in extraction (#16547)
This code only runs in ES5 mode in the test suite, so this is difficult to test.
However `updateFromTemplate` is being called with a spread operator, as
`...updateFromTemplate(...)`. The spread operator should fail on `null` values.
This change avoids the problem by always returning a (possibly empty) array.

PR Close #16547
2017-05-09 17:34:31 -07:00
Tobias Bosch ee6705af49 fix(core): detach projected views when a parent view is destroyed (#16592)
This also clarifies via a test 
that we only update projected views when the view is created or destroyed,
but not when it is attached/detached/moved.

Fixes #15578

PR Close #16592
2017-05-09 17:34:31 -07:00
Tobias Bosch 9218812011 fix(core): projected views should be dirty checked when the declaring component is dirty checked. (#16592)
Previously a projected view was only dirty checked when the
component in which it was inserted was dirty checked.

This fix changes the behavior so that a view is also dirty checked if
the declaring component is dirty checked.

Note: This does not change the order of change detection,
only the fact whether a projected view is dirty checked or not.

Fixes #14321
2017-05-09 17:34:30 -07:00
David Herges ec77bf9fb0 docs(core): EventEmitter docs for isAsync defaults (#15780)
- solves #15758
2017-05-09 17:34:29 -07:00
Jason Hodges fee5b2ad56 docs(animations): remove duplicate word (#16508) 2017-05-09 17:34:24 -07:00
Alex Rickabaugh 9c70a3cfb1 fix(http): flatten metadata for @angular/http/testing
@angular/http/testing used to publish a metadata structure which paralleled
the .d.ts structure. This causes ngc to write incorrect imports for this
bundle when compiling providers using MockBackend and other http testing
classes.

This change restructures the @angular/http/testing build a bit, modeling it
after @angular/platform-browser-animations, and produces a FESM structure
that has flat metadata.

Fixes #15521.
2017-05-09 17:33:59 -07:00
Alex Rickabaugh ec3b6e9603 fix(http): introduce encodingHint for text() for better ArrayBuffer support
Currently, if a Response has an ArrayBuffer body and text() is called, Angular
attempts to convert the ArrayBuffer to a string. Doing this requires knowing
the encoding of the bytes in the buffer, which is context that we don't have.

Instead, we assume that the buffer is encoded in UTF-16, and attempt to process
it that way. Unfortunately the approach chosen (interpret buffer as Uint16Array and
create a Javascript string from each entry using String.fromCharCode) is incorrect
as it does not handle UTF-16 surrogate pairs. What Angular actually implements, then,
is UCS-2 decoding, which is equivalent to UTF-16 with characters restricted to the
base plane.

No standard way of decoding UTF-8 or UTF-16 exists in the browser today. APIs like
TextDecoder are only supported in a few browsers, and although hacks like using the
FileReader API with a Blob to force browsers to do content encoding detection and
decoding exist, they're slow and not compatible with the synchronous text() API.

Thus, this bug is fixed by introducing an encodingHint parameter to text(). The
default value of this parameter is 'legacy', indicating that the existing broken
behavior should be used - this prevents breaking existing apps. The only other
possible value of the hint is 'iso-8859' which interprets each byte of the buffer
with String.fromCharCode. UTF-8 and UTF-16 are not supported - it is up to the
consumer to get the ArrayBuffer and decode it themselves.

The parameter is a hint, as it's not always used (for example, if the conversion
to text doesn't involve an ArrayBuffer source). Additionally, this leaves the door
open for future implementations to perform more sophisticated encoding detection
and ignore the user-provided value if it can be proven to be incorrect.

Fixes #15932.

PR Close #16420
2017-05-09 17:33:59 -07:00
Alex Rickabaugh 63066f7697 fix(http): honor RequestArgs.search and RequestArgs.params map type
Currently `new Request({search: ...})` is not honored, and
`new Request({params: {'x': 'y'}) doesn't work either, as this object would have
toString() called. This change allows both of these cases to work, as proved by
the 2 new tests.

Fixes #15761

PR Close #16392
2017-05-09 17:33:58 -07:00
Matias Niemelä 5f6d0f2340 revert: fix: public API golden files (#16414)
This reverts commit dcaa11a88b.
2017-05-04 15:00:09 -07:00
Matias Niemelä 4a0e93b03b revert: test(compiler-cli): add test for missingTranslation parameter
This reverts commit 109229246c.
2017-05-04 14:51:30 -07:00
Matias Niemelä 1f5dce2128 docs: add changelog for 4.1.1 2017-05-04 14:22:43 -07:00
Matias Niemelä 14e7e43ad8 release: cut the 4.1.1 release 2017-05-04 14:18:24 -07:00
Olivier Combe 54d4b893fd test(compiler-cli): add test for missingTranslation parameter 2017-05-04 14:05:17 -07:00
Alex Eagle 4670cf51cc test: cleanup rxjs custom build
The latest rxjs release works with closure compiler out of the box.
We no longer need to compile our own.

Also put closure options into a file rather than using a shell script.
2017-05-04 14:05:16 -07:00
Georgios Kalpakas dd4e501999 fix(upgrade): initialize all inputs in time for ngOnChanges()
Previously, non-bracketed inputs (e.g. `xyz="foo"`) on downgraded components
were initialized using `attrs.$observe()` (which uses `$evalAsync()` under the
hood), while bracketed inputs (e.g. `[xyz]="'foo'"`) were initialized using
`$watch()`. If the downgraded component was created during a `$digest` (e.g. by
an `ng-if` watcher), the non-bracketed inputs were not initialized in time for
the initial call to `ngOnChanges()` and `ngOnInit()`.

This commit fixes it by using `$watch()` to initialize all inputs. `$observe()`
is still used for subsequent updates on non-bracketed inputs, because it is more
performant.

Fixes #16212
2017-05-04 14:05:16 -07:00
Georgios Kalpakas 9124994849 build: update concurrently to latest version
The regression in `concurrently` v3.2.0 (which made us roll back to v3.1.0
in #14378) has been fixed in v3.3.0 (see kimmobrunfeldt/concurrently#89).
2017-05-04 14:05:16 -07:00
Igor Minar 4fbc61469f docs: fix links in api docs 2017-05-04 14:05:16 -07:00
Tobias Bosch 8a883f24f6 refactor(compiler): simplify AOT tests 2017-05-04 14:05:15 -07:00
Tobias Bosch 07cef367ac fix(core): don’t stop change detection because of errors
- prevents unsubscribing from the zone on error
- prevents unsubscribing from directive `EventEmitter`s on error
- prevents detaching views in dev mode if there on error
- ensures that `ngOnInit` is only called 1x (also in prod mode)

Fixes #9531
Fixes #2413
Fixes #15925
2017-05-04 14:05:15 -07:00
Chuck Jazdzewski c060110695 fix(language-service): remove asserts for non-null expressions (#16422)
Reworked some of the code so asserts are no longer necessary.
Added additional and potentially redundant checks
Added checks where the null checker found real problems.

PR Close #16422
2017-05-04 14:05:15 -07:00
Victor Berchet 93ff3166ab docs(common): fix API docs for NgComponentOutlet (#16411)
fixes #16373

PR Close #16411
2017-05-04 14:05:14 -07:00
Tobias Bosch 85a1b54c6e fix(core): don’t set ng-version for dynamically created components (#16394)
Angular uses the `ng-version` attribute to indicate which elements
were used to bootstrap an application. However, after 4.0 we also
added this attribute for all dynamically created components.

Fixes #15880

PR Close #16394
2017-05-04 14:05:14 -07:00
Tobias Bosch acf83b90bc fix(core): allow to detach OnPush components (#16394)
Fixes #9720
2017-05-04 14:05:14 -07:00
Tobias Bosch f66e59ebe4 fix(core): allow directives to inject the component’s ChangeDetectorRef. (#16394)
When a directive lives on the same element as a component
(e.g. `<my-comp myDir>`), the directive was not able to get hold
of the `ChangeDetectorRef` of the component on that element. However,
as directives are supposed to decorate components, this is incorrect.

This commit enables this use case.

Closes #12816
2017-05-04 14:05:14 -07:00
Chuck Jazdzewski d932e724ab ci(language-service): update ci tests to official 2.3 build (#16415)
PR Close #16415
2017-05-04 14:05:13 -07:00
Victor Berchet dcaa11a88b fix: public API golden files (#16414) 2017-05-04 14:05:13 -07:00
Miško Hevery 427d63a422 fix: strictNullCheck support. (#16389) (#16389)
Fix #16357

Workaround for https://github.com/Microsoft/TypeScript/issues/10078

Closes #16389

PR Close #16389
2017-05-04 14:05:13 -07:00
14920 changed files with 293047 additions and 1495370 deletions
-41
View File
@@ -1,41 +0,0 @@
# Bazel does not yet support wildcards or other .gitignore semantics for
# .bazelignore. Two issues for this feature request are outstanding:
# https://github.com/bazelbuild/bazel/issues/7093
# https://github.com/bazelbuild/bazel/issues/8106
.git
node_modules
dist
aio/node_modules
aio/tools/examples/shared/node_modules
aio/tools/examples/shared/example-scaffold
# All integration test node_modules folders
integration/animations/node_modules
integration/cli-elements-universal/node_modules
integration/cli-hello-world/node_modules
integration/cli-hello-world-ivy-i18n/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/injectable-def/node_modules
integration/ivy-i18n/node_modules
integration/ng-add-localize/node_modules
integration/ng_elements/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/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
-188
View File
@@ -1,188 +0,0 @@
# 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
# Do not attempt to de-flake locally.
# On CI we might set this to `3` to run with deflaking.
test --flaky_test_attempts=1
###############################
# Filesystem interactions #
###############################
# Create symlinks in the project:
# - dist/bin for outputs
# - dist/testlogs, dist/genfiles
# - bazel-out
# NB: bazel-out should be excluded from the editor configuration.
# The checked-in /.vscode/settings.json does this for VSCode.
# Other editors may require manual config to ignore this directory.
# In the past, we say a problem where VSCode traversed a massive tree, opening file handles and
# eventually a surprising failure with auto-discovery of the C++ toolchain in
# MacOS High Sierra.
# See https://github.com/bazelbuild/bazel/issues/4603
build --symlink_prefix=dist/
# Turn off legacy external runfiles
build --nolegacy_external_runfiles
run --nolegacy_external_runfiles
test --nolegacy_external_runfiles
# Turn on --incompatible_strict_action_env which was on by default
# in Bazel 0.21.0 but turned off again in 0.22.0. Follow
# https://github.com/bazelbuild/bazel/issues/7026 for more details.
# This flag is needed to so that the bazel cache is not invalidated
# when running bazel via `yarn bazel`.
# See https://github.com/angular/angular/issues/27514.
build --incompatible_strict_action_env
run --incompatible_strict_action_env
test --incompatible_strict_action_env
# Do not build runfile trees by default. If an execution strategy relies on runfile
# symlink teee, the tree is created on-demand. See: https://github.com/bazelbuild/bazel/issues/6627
# and https://github.com/bazelbuild/bazel/commit/03246077f948f2790a83520e7dccc2625650e6df
build --nobuild_runfile_links
build --enable_runfiles
###############################
# Release support #
# Turn on these settings with #
# --config=release #
###############################
# Releases should always be stamped with version control info
# This command assumes node on the path and is a workaround for
# https://github.com/bazelbuild/bazel/issues/4802
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
###############################
# Output #
###############################
# A more useful default output mode for bazel query
# Prints eg. "ng_module rule //foo:bar" rather than just "//foo:bar"
query --output=label_kind
# By default, failing tests don't print any output, it goes to the log file
test --test_output=errors
################################
# Settings for CircleCI #
################################
# Bazel flags for CircleCI are in /.circleci/bazel.linux.rc and /.circleci/bazel.windows.rc
##################################
# Remote Build Execution support #
# Turn on these settings with #
# --config=remote #
##################################
# The following --define=EXECUTOR=remote will be able to be removed
# once https://github.com/bazelbuild/bazel/issues/7254 is fixed
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
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
# Remote instance and caching
build:remote --remote_instance_name=projects/internal-200822/instances/primary_instance
build:remote --bes_instance_name=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 #
# --config=saucelabs #
##################################
# For saucelabs tests we don't want to enable flaky test attempts. Karma has its own integrated
# retry mechanism and we do not want to retry unnecessarily if Karma already tried multiple times.
test:saucelabs --flaky_test_attempts=1
################
# Flag Aliases #
################
# --ng_perf will ask the Ivy compiler to produce performance results for each build.
build --flag_alias=ng_perf=//packages/compiler-cli:ng_perf
####################################################
# User bazel configuration
# NOTE: This needs to be the *last* entry in the config.
####################################################
# 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
-1
View File
@@ -1 +0,0 @@
5.0.0
+3
View File
@@ -0,0 +1,3 @@
{
"directory" : "bower_components"
}
-19
View File
@@ -1,19 +0,0 @@
# Encryption
Based on https://github.com/circleci/encrypted-files
In the CircleCI web UI, we have a secret variable called `KEY`
https://circleci.com/gh/angular/angular/edit#env-vars
which is only exposed to non-fork builds
(see "Pass secrets to builds from forked pull requests" under
https://circleci.com/gh/angular/angular/edit#advanced-settings)
We use this as a symmetric AES encryption key to encrypt tokens like
a GitHub token that enables publishing snapshots.
To create the github_token file, we take this approach:
- Find the angular-builds:token in the internal pw database
- Go inside the CircleCI default docker image so you use the same version of openssl as we will at runtime: `docker run --rm -it circleci/node:10.12`
- echo "https://[token]:@github.com" > credentials
- openssl aes-256-cbc -e -in credentials -out .circleci/github_token -k $KEY
- If needed, base64-encode the result so you can copy-paste it out of docker: `base64 github_token`
-16
View File
@@ -1,16 +0,0 @@
# Settings in this file should be OS agnostic. Use the bazel.<OS>.rc files for OS specific settings.
# 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
# More details on failures
build --verbose_failures=true
# CI supports colors but Bazel does not detect it.
common --color=yes
-23
View File
@@ -1,23 +0,0 @@
# These options are enabled when running on CI
# We do this by copying this file to /etc/bazel.bazelrc at the start of the build.
# See documentation in /docs/BAZEL.md
# Import config items common to both Linux and Windows setups.
# https://docs.bazel.build/versions/master/guide.html#bazelrc-syntax-and-semantics
try-import %workspace%/.circleci/bazel.common.rc
# Save downloaded repositories in a location that can be cached by CircleCI. This helps us
# speeding up the analysis time significantly with Bazel managed node dependencies on the CI.
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
# https://circleci.com/docs/2.0/configuration-reference/#resource_class
build --local_cpu_resources=20
build --local_ram_resources=40960
# All build executed remotely should be done using our RBE configuration.
build:remote --google_default_credentials
build --config=remote
-17
View File
@@ -1,17 +0,0 @@
# These options are enabled when running on CI
# We do this by copying this file to $env:ProgramData\bazel.bazelrc at the start of the build.
# See documentation in /docs/BAZEL.md
# Import config items common to both Linux and Windows setups.
# https://docs.bazel.build/versions/master/guide.html#bazelrc-syntax-and-semantics
try-import %workspace%/.circleci/bazel.common.rc
# Manually set the local resources used in windows CI runs
build --local_ram_resources=120000
build --local_cpu_resources=32
# All windows jobs run on master and should use http caching
build --remote_http_cache=https://storage.googleapis.com/angular-team-cache
build --remote_accept_cached=true
build --remote_upload_local_results=true
build --google_default_credentials
-16
View File
@@ -1,16 +0,0 @@
# This config is remaining in place to prevent pull requests failing because of CircleCI config missing.
version: 2.1
jobs:
pass:
docker:
- image: cimg/base:2022.05
steps:
- run: echo "This too shall pass (always)"
workflows:
version: 2
default_workflow:
jobs:
- pass
-76
View File
@@ -1,76 +0,0 @@
####################################################################################################
# Helpers for defining environment variables for CircleCI.
#
# In CircleCI, each step runs in a new shell. The way to share ENV variables across steps is to
# export them from `$BASH_ENV`, which is automatically sourced at the beginning of every step (for
# the default `bash` shell).
#
# See also https://circleci.com/docs/2.0/env-vars/#using-bash_env-to-set-environment-variables.
####################################################################################################
# Set and print an environment variable.
#
# Use this function for setting environment variables that are public, i.e. it is OK for them to be
# visible to anyone through the CI logs.
#
# Usage: `setPublicVar <name> <value>`
function setPublicVar() {
setSecretVar $1 "$2";
echo "$1=$2";
}
# Set (without printing) an environment variable.
#
# Use this function for setting environment variables that are secret, i.e. should not be visible to
# everyone through the CI logs.
#
# Usage: `setSecretVar <name> <value>`
function setSecretVar() {
# WARNING: Secrets (e.g. passwords, access tokens) should NOT be printed.
# (Keep original shell options to restore at the end.)
local -r originalShellOptions=$(set +o);
set +x -eu -o pipefail;
local assignmentStatement="export $1=\"${2:-}\";"
echo "${assignmentStatement}" >> $BASH_ENV;
eval "${assignmentStatement}"
# Restore original shell options.
eval "$originalShellOptions";
}
# Create a function to set an environment variable, when called.
#
# Use this function for creating setter for public environment variables that require expensive or
# time-consuming computaions and may not be needed. When needed, you can call this function to set
# the environment variable (which will be available through `$BASH_ENV` from that point onwards).
#
# Arguments:
# - `<name>`: The name of the environment variable. The generated setter function will be
# `setPublicVar_<name>`.
# - `<code>`: The code to run to compute the value for the variable. Since this code should be
# executed lazily, it must be properly escaped. For example:
# ```sh
# # DO NOT do this:
# createPublicVarSetter MY_VAR "$(whoami)"; # `whoami` will be evaluated eagerly
#
# # DO this isntead:
# createPublicVarSetter MY_VAR "\$(whoami)"; # `whoami` will NOT be evaluated eagerly
# ```
#
# Usage: `createPublicVarSetter <name> <code>`
#
# Example:
# ```sh
# createPublicVarSetter MY_VAR 'echo "FOO"';
# echo $MY_VAR; # Not defined
#
# setPublicVar_MY_VAR;
# source $BASH_ENV;
# echo $MY_VAR; # FOO
# ```
function createPublicVarSetter() {
echo "setPublicVar_$1() { setPublicVar $1 \"$2\"; }" >> $BASH_ENV;
}
-4
View File
@@ -1,4 +0,0 @@
####################################################################################################
# Set bazel configuration for CircleCI runs.
####################################################################################################
cp "${PROJECT_ROOT}/.circleci/bazel.linux.rc" ".bazelrc.user";
-89
View File
@@ -1,89 +0,0 @@
#!/usr/bin/env bash
# Variables
readonly projectDir=$(realpath "$(dirname ${BASH_SOURCE[0]})/..")
readonly envHelpersPath="$projectDir/.circleci/env-helpers.inc.sh";
# Load helpers and make them available everywhere (through `$BASH_ENV`).
source $envHelpersPath;
echo "source $envHelpersPath;" >> $BASH_ENV;
####################################################################################################
# Define PUBLIC environment variables for CircleCI.
####################################################################################################
# See https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables for more info.
####################################################################################################
setPublicVar CI "$CI"
setPublicVar PROJECT_ROOT "$projectDir";
setPublicVar CI_AIO_MIN_PWA_SCORE "95";
# This is the branch being built; e.g. `pull/12345` for PR builds.
setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
setPublicVar CI_BUILD_URL "$CIRCLE_BUILD_URL";
setPublicVar CI_COMMIT "$CIRCLE_SHA1";
# `CI_COMMIT_RANGE` is only used on push builds (a.k.a. non-PR, non-scheduled builds and rerun
# workflows of such builds).
setPublicVar CI_GIT_BASE_REVISION "${CIRCLE_GIT_BASE_REVISION}";
setPublicVar CI_GIT_REVISION "${CIRCLE_GIT_REVISION}";
setPublicVar CI_COMMIT_RANGE "$CIRCLE_GIT_BASE_REVISION..$CIRCLE_GIT_REVISION";
setPublicVar CI_PULL_REQUEST "${CIRCLE_PR_NUMBER:-false}";
setPublicVar CI_REPO_NAME "$CIRCLE_PROJECT_REPONAME";
setPublicVar CI_REPO_OWNER "$CIRCLE_PROJECT_USERNAME";
setPublicVar CI_PR_REPONAME "$CIRCLE_PR_REPONAME";
setPublicVar CI_PR_USERNAME "$CIRCLE_PR_USERNAME";
####################################################################################################
# Define "lazy" PUBLIC environment variables for CircleCI.
# (I.e. functions to set an environment variable when called.)
####################################################################################################
createPublicVarSetter CI_STABLE_BRANCH "\$(npm info @angular/core dist-tags.latest | sed -r 's/^\\s*([0-9]+\\.[0-9]+)\\.[0-9]+.*$/\\1.x/')";
####################################################################################################
# Define SECRET environment variables for CircleCI.
####################################################################################################
setSecretVar CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN "$AIO_DEPLOY_TOKEN";
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";
# 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
setPublicVar SAUCE_PID_FILE /tmp/angular/sauce-connect-pid-file.lock
setPublicVar SAUCE_TUNNEL_IDENTIFIER "angular-framework-${CIRCLE_BUILD_NUM}-${CIRCLE_NODE_INDEX}"
# Amount of seconds we wait for sauceconnect to establish a tunnel instance. In order to not
# acquire CircleCI instances for too long if sauceconnect failed, we need a connect timeout.
setPublicVar SAUCE_READY_FILE_TIMEOUT 120
####################################################################################################
# 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.
####################################################################################################
readonly bazelVarEnv="/tmp/bazel-ci-env.sh"
echo "# Setup by /.circle/env.sh" > $bazelVarEnv
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_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
-13
View File
@@ -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"]')"
-11
View File
@@ -1,11 +0,0 @@
#!/bin/sh
# Install bazel remote cache proxy
# This is temporary until the feature is no longer experimental on CircleCI.
# See remote cache documentation in /docs/BAZEL.md
set -u -e
readonly DOWNLOAD_URL="https://5-116431813-gh.circle-artifacts.com/0/pkg/bazel-remote-proxy-$(uname -s)_$(uname -m)"
curl --fail -o ~/bazel-remote-proxy "$DOWNLOAD_URL"
chmod +x ~/bazel-remote-proxy
-31
View File
@@ -1,31 +0,0 @@
# VSCode Remote Development - Developing inside a Container
This folder contains configuration files that can be used to opt into working on this repository in a [Docker container](https://www.docker.com/resources/what-container) via [VSCode](https://code.visualstudio.com/)'s Remote Development feature (see below).
Info on remote development and developing inside a container with VSCode:
- [VSCode: Remote Development](https://code.visualstudio.com/docs/remote/remote-overview)
- [VSCode: Developing inside a Container](https://code.visualstudio.com/docs/remote/containers)
- [VSCode: Remote Development FAQ](https://code.visualstudio.com/docs/remote/faq)
## Usage
_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.
In a nutshell, you need to:
- Install the [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension.
- Copy [recommended-Dockerfile](./recommended-Dockerfile) to `Dockerfile` (and optionally tweak to suit your needs).
- Copy [recommended-devcontainer.json](./recommended-devcontainer.json) to `devcontainer.json` (and optionally tweak to suit your needs).
- Open VSCode and bring up the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette).
- Type `Remote-Containers: Open Folder in Container` and choose your local clone of [angular/angular](https://github.com/angular/angular).
The `.devcontainer/devcontainer.json` and `.devcontainer/Dockerfile` files are ignored by git, so you can have your own local versions. We may occasionally update the template files ([recommended-devcontainer.json](./recommended-devcontainer.json), [recommended-Dockerfile](./recommended-Dockerfile)), in which case you will need to manually update your local copies (if desired).
## Updating `recommended-devcontainer.json` and `recommended-Dockerfile`
You can update and commit the recommended config files (which people use as basis for their local configs), if you find that something is broken, out-of-date or can be improved.
Please, keep in mind that any changes you make will potentially be used by many people on different environments. Try to keep these config files cross-platform compatible and free of personal preferences.
-24
View File
@@ -1,24 +0,0 @@
# 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
LABEL name="Angular dev environment" \
description="This image can be used to create a dev environment for building Angular." \
vendor="angular" \
version="1.0"
EXPOSE 4000 4200 4433 5000 8080 9876
# Switch to `root` (CircleCI images use `circleci` as the user).
USER root
# Configure `Node.js`/`npm`.
RUN npm config --global set user root
# Go! (And keep going.)
CMD ["tail", "--follow", "/dev/null"]
@@ -1,16 +0,0 @@
// Reference: https://code.visualstudio.com/docs/remote/containers#_devcontainerjson-reference
{
"name": "Angular dev container",
"dockerFile": "Dockerfile",
"appPort": [4000, 4200, 4433, 5000, 8080, 9876],
"postCreateCommand": "yarn install",
"extensions": [
"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",
],
}
+1 -1
View File
@@ -1,4 +1,4 @@
# https://editorconfig.org
# http://editorconfig.org
root = true
+3
View File
@@ -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
+37 -4
View File
@@ -1,6 +1,39 @@
Please help us process issues more efficiently by filing an
issue using one of the following templates:
<!--
IF YOU DON'T FILL OUT THE FOLLOWING INFORMATION WE MIGHT CLOSE YOUR ISSUE WITHOUT INVESTIGATING
-->
https://github.com/angular/angular/issues/new/choose
**I'm submitting a ...** (check one with "x")
```
[ ] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
```
Thank you!
**Current behavior**
<!-- Describe how the bug manifests. -->
**Expected behavior**
<!-- Describe what the behavior would be without the bug. -->
**Minimal reproduction of the problem with instructions**
<!--
If the current behavior is a bug or you can illustrate your feature request better with an example,
please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via
https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5).
-->
**What is the motivation / use case for changing the behavior?**
<!-- Describe the motivation or the concrete use case -->
**Please tell us about your environment:**
<!-- Operating system, IDE, package manager, HTTP server, ... -->
* **Angular version:** 2.0.X
<!-- Check whether this is still an issue in the most recent Angular version -->
* **Browser:** [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
<!-- All browsers where this could be reproduced -->
* **Language:** [all | TypeScript X.X | ES6/7 | ES5]
* **Node (for AoT issues):** `node --version` =
-86
View File
@@ -1,86 +0,0 @@
name: Bug Report
description: Report a bug in the Angular Framework
body:
- type: dropdown
id: affected-packages
attributes:
label: Which @angular/* package(s) are the source of the bug?
options:
- animations
- bazel
- common
- compiler-cli
- compiler
- core
- elements
- forms
- language-service
- localize
- platform-browser-dynamic
- platform-browser
- platform-server
- router
- service-worker
- upgrade
- zone.js
- Don't known / other
multiple: true
validations:
required: true
- type: dropdown
id: is-regression
attributes:
label: Is this a regression?
options:
- 'Yes'
- 'No'
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
validations:
required: true
- type: input
id: reproduction
attributes:
label: Please provide a link to a minimal reproduction of the bug
- type: textarea
id: exception-or-error
attributes:
label: Please provide the exception or error you saw
render: true
- type: textarea
id: environment
attributes:
label: Please provide the environment you discovered this bug in (run `ng version`)
render: true
placeholder: |
Angular CLI: 12.0.5
Node: 14.17.0
Package Manager: yarn 1.22.10
OS: linux x64
Angular: 12.0.5
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1200.5
@angular-devkit/build-angular 12.0.5
@angular-devkit/core 12.0.5
rxjs 6.6.7
typescript 4.2.4
- type: textarea
id: other
attributes:
label: Anything else?
@@ -1,47 +0,0 @@
name: 'Feature Request'
description: Suggest a feature for Angular Framework
body:
- type: dropdown
id: affected-packages
attributes:
label: Which @angular/* package(s) are relevant/related to the feature request?
options:
- animations
- bazel
- common
- compiler-cli
- compiler
- core
- elements
- forms
- language-service
- localize
- platform-browser-dynamic
- platform-browser
- platform-server
- router
- service-worker
- upgrade
multiple: true
- type: textarea
id: description
attributes:
label: Description
validations:
required: true
- type: textarea
id: proposed-solution
attributes:
label: Proposed solution
validations:
required: true
- type: textarea
id: alternatives-considered
attributes:
label: Alternatives considered
validations:
required: true
-58
View File
@@ -1,58 +0,0 @@
name: 'Docs or angular.io Bug Report'
description: Report an issue in Angular's documentation or angular.io application
body:
- type: textarea
id: description
attributes:
label: Describe the problem that you experienced
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
- type: textarea
id: reproduction-steps
attributes:
label: Describe the actions that led you to experience the problem
- type: textarea
id: expected-vs-actual-behavior
attributes:
label: Describe what you want to experience that would fix the problem
- type: textarea
id: screenshot
attributes:
label: Add a screenshot if that helps illustrate the problem
- type: textarea
id: exception-or-error
attributes:
label: If this problem caused an exception or error, please paste it here
render: true
placeholder: |
```
Paste the exception or error here inside a markdown code block,
which is annotated by three grave \(&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
render: true
-54
View File
@@ -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]
-14
View File
@@ -1,14 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Security issue disclosure
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
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
about: Questions and requests for support
+23 -30
View File
@@ -1,43 +1,36 @@
## 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
**Please check if the PR fulfills these requirements**
- [ ] 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)
## PR Type
What kind of change does this PR introduce?
**What kind of change does this PR introduce?** (check one with "x")
```
[ ] Bugfix
[ ] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Other... Please describe:
```
<!-- Please check the one that applies to this PR using "x". -->
- [ ] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, local variables)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Documentation content changes
- [ ] angular.io application / infrastructure changes
- [ ] Other... Please describe:
**What is the current behavior?** (You can also link to an open issue here)
## What is the current behavior?
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
Issue Number: N/A
**What is the new behavior?**
## What is the new behavior?
**Does this PR introduce a breaking change?** (check one with "x")
```
[ ] Yes
[ ] No
```
If this PR contains a breaking change, please describe the impact and migration path for existing applications: ...
## Does this PR introduce a breaking change?
**Other information**:
- [ ] Yes
- [ ] No
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->
## Other information
-17
View File
@@ -1,17 +0,0 @@
name: 'Installing Yarn dependencies'
description: 'Installs the dependencies using Yarn'
runs:
using: 'composite'
steps:
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3
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
-131
View File
@@ -1,131 +0,0 @@
# Configuration for angular-robot
# options for the size plugin
size:
disabled: true
maxSizeIncrease: 2000
circleCiStatusName: 'ci/circleci: test'
# options for the merge plugin
merge:
# the status will be added to your pull requests
status:
# set to true to disable
disabled: false
# the name of the status
context: 'ci/angular: merge status'
# text to show when all checks pass
successText: 'All checks passed!'
# text to show when some checks are failing
failureText: 'The following checks are failing:'
# 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
# the name of the status
context: 'google3'
# text to show when the status is pending, {{PRNumber}} will be replaced by the PR number
pendingDesc: 'Googler: run g3sync presubmit {{PRNumber}}'
# text to show when the status is success
successDesc: 'Does not affect google3'
# link to use for the details
url: 'http://go/angular/g3sync'
# list of patterns to check for the files changed by the PR
include:
exclude:
# 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!"
# label to monitor
mergeLabel: 'action: merge'
# adding any of these labels will also add the merge label
mergeLinkedLabels:
- 'action: merge-assistance'
# list of checks that will determine if the merge label can be added
checks:
# require that the PR has reviews from all requested reviewers
#
# This enables us to request reviews from both eng and tech writers, or multiple eng folks, and prevents accidental merges.
# Rather than merging PRs with pending reviews, if all approvals are obtained and additional reviews are not needed, any pending reviewers should be removed via GitHub UI (this also leaves an audit trail behind these decisions).
requireReviews: true,
# 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.
requiredLabels:
- 'target: *'
# list of labels that a PR shouldn't have, checked after the required labels with a regexp
forbiddenLabels:
- 'target: TBD'
- 'action: cleanup'
- 'action: review'
- 'state: blocked'
# list of PR statuses that need to be successful
requiredStatuses:
- 'google-internal-tests'
- '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."
# options for the triage plugin
triage:
# number of the milestone to apply when the issue has not been triaged yet
needsTriageMilestone: 83,
# number of the milestone to apply when the issue is triaged
defaultMilestone: 82,
# arrays of labels that determine if an issue has been triaged by the caretaker
l1TriageLabels:
- - 'area: *'
# arrays of labels that determine if an issue has been fully triaged
l2TriageLabels:
- - 'P0'
- 'area: *'
- - 'P1'
- 'area: *'
- - 'P2'
- 'area: *'
- - 'P3'
- 'area: *'
- - 'P4'
- 'area: *'
- - 'P5'
- 'area: *'
- - 'feature'
- 'area: *'
- - 'discussion'
- 'area: *'
- - 'needs clarification'
- 'area: *'
- - 'needs reproduction'
- 'area: *'
# options for the triage PR plugin
triagePR:
# set to true to disable
disabled: false
# number of the milestone to apply when the PR has not been triaged yet
needsTriageMilestone: 83,
# number of the milestone to apply when the PR is triaged
defaultMilestone: 82,
# arrays of labels that determine if a PR has been triaged by the caretaker
l1TriageLabels:
- - 'area: *'
# arrays of labels that determine if a PR has been fully triaged
l2TriageLabels:
- - 'area: *'
# options for rerunning CI
rerunCircleCI:
# set to true to disable
disabled: false
# the label which when added triggers a rerun of the default CircleCI workflow
triggerRerunLabel: 'action: rerun CI at HEAD'
-38
View File
@@ -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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- 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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
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'
-50
View File
@@ -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@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3
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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
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}}'
-42
View File
@@ -1,42 +0,0 @@
# This workflow builds the AIO 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 AIO app for preview deployment
on:
pull_request:
types: [synchronize, labeled]
permissions: read-all
jobs:
aio-build:
runs-on: ubuntu-latest
# We only want to build and deploy the AIO app if the `aio: preview` label has been
# added, or if the label is already applied and new changes have been made in the PR.
if: |
(github.event.action == 'labeled' && github.event.label.name == 'aio: preview') ||
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'aio: preview'))
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: ./.github/actions/yarn-install
- uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
bazelrc: ./.bazelrc.user
# Build the web package. Note: We run Bazel from a low-resource Github action container,
# so we manually need to instruct Bazel to run more actions concurrently as by default
# the number of concurrent actions is determined based on the host resources.
- run: bazel build //aio:build --jobs=32 --announce_rc --verbose_failures
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
workflow-artifact-name: 'aio'
pull-number: '${{github.event.pull_request.number}}'
artifact-build-revision: '${{github.event.pull_request.head.sha}}'
deploy-directory: './dist/bin/aio/build'
-44
View File
@@ -1,44 +0,0 @@
# This workflow runs whenever the AIO 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 AIO preview to Firebase
on:
workflow_run:
workflows: ['Build AIO app for preview deployment']
types: [completed]
permissions:
# Needed in order to be able to comment on the pull request.
pull-requests: write
env:
PREVIEW_PROJECT: ng-dev-previews
PREVIEW_SITE: ng-dev-previews-fw
jobs:
aio-deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
- name: Configure Firebase deploy target
working-directory: aio/
run: |
# We can use `npx` as the Firebase deploy actions uses it too.
npx -y firebase-tools@latest target:clear --project ${{env.PREVIEW_PROJECT}} hosting aio
npx -y firebase-tools@latest target:apply --project ${{env.PREVIEW_PROJECT}} hosting aio ${{env.PREVIEW_SITE}}
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
github-token: '${{secrets.GITHUB_TOKEN}}'
workflow-artifact-name: 'aio'
firebase-config-dir: './aio/'
firebase-public-dir: './aio/dist'
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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
-68
View File
@@ -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@23ff15729ef2fc348714a3bb66d2f655ca9066f2 # v3
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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
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@23ff15729ef2fc348714a3bb66d2f655ca9066f2 # v3
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}}
-64
View File
@@ -1,64 +0,0 @@
name: CI
on:
pull_request_target:
types: [opened, synchronize, reopened]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true
permissions: {}
defaults:
run:
shell: bash
jobs:
saucelabs:
runs-on: ubuntu-latest-4core
env:
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
SAUCE_USERNAME: ${{ vars.SAUCE_USERNAME }}
SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- 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
-285
View File
@@ -1,285 +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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
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 code lint in aio
run: yarn -s --cwd aio lint
- 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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- 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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Install node modules
run: yarn install --frozen-lockfile --network-timeout 100000
- name: Run CI tests for framework
run: yarn test:ci
aio:
runs-on: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Install node modules for aio
run: yarn install --cwd aio --frozen-lockfile
- name: Run AIO tests with upstream packages
run: yarn --cwd aio test:ci
- name: Check generated bundle sizes
run: yarn --cwd aio payload-size
adev:
runs-on:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- 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
aio-local:
runs-on:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Install node modules
run: yarn install --cwd aio --frozen-lockfile
- name: Run AIO tests with local packages
run: yarn --cwd aio test-local:ci
- name: Check generated bundle sizes
run: yarn --cwd aio payload-size aio-local
aio-deploy:
needs: [aio]
if: needs.aio.result == 'success' && github.event_name == 'push'
runs-on:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Install node modules for aio
run: yarn install --cwd aio --frozen-lockfile
- name: Set the stable branch environment variable
id: latest_version
run: |
echo "CI_STABLE_BRANCH=$(npm info @angular/core dist-tags.latest | sed -r 's/^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$/\1.x/')" >> $GITHUB_OUTPUT
echo "CI_BRANCH=$(echo ${{ github.event.ref }} | cut -d '/' -f 3)" >> $GITHUB_OUTPUT
- name: Deploy aio to production
env:
CI_AIO_MIN_PWA_SCORE: '95'
CI_COMMIT: ${{ github.event.after }}
CI_REPO_NAME: 'angular'
CI_PULL_REQUEST: 'false'
CI_REPO_OWNER: 'angular'
CI_BUILD_URL: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
CI_STABLE_BRANCH: ${{ steps.latest_version.outputs.CI_STABLE_BRANCH }}
CI_BRANCH: ${{ steps.latest_version.outputs.CI_BRANCH }}
CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN: ${{ secrets.AIO_DEPLOY_TOKEN }}
CI_SECRET_PAYLOAD_FIREBASE_TOKEN: ${{ secrets.AIO_PAYLOAD_TOKEN }}
run: yarn --cwd aio deploy-production
- name: Notify about failed deployment
if: ${{ failure() }}
uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v=v1.24.0
with:
channel-id: 'C07DT5M6V,CKV1F72BG'
slack-message: 'Deploy to aio job failed for ${{ github.base_ref }} branch failed on build ${{ github.event.after }}: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
env:
SLACK_BOT_TOKEN: ${{ secrets.ANGULAR_ROBOT_SLACK_TOKEN }}
publish-snapshots:
if: github.event_name == 'push'
runs-on:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- 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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- 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: |
mkdir -p packages/zone.js/build/
mkdir -p packages/zone.js/build/test/
mkdir -p packages/zone.js/test/
cp dist/bin/packages/zone.js/bundles/zone.umd.js packages/zone.js/build/zone.umd.js
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/
cp dist/bin/packages/zone.js/test/closure/zone.closure.mjs ./packages/zone.js/build/test/zone.closure.mjs
# 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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Set up Sauce Tunnel Daemon
run: yarn bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
env:
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
SAUCE_USERNAME: ${{ vars.SAUCE_USERNAME }}
SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }}
- name: Run all saucelabs bazel tests
run: |
TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "fixme-saucelabs", ...)')
yarn bazel test --config=saucelabs --jobs=$JOBS ${TESTS}
-25
View File
@@ -1,25 +0,0 @@
name: DevInfra
on:
pull_request_target:
types: [opened, synchronize, reopened]
# Declare default permissions as read only.
permissions:
contents: read
jobs:
labels:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: angular/dev-infra/github-actions/commit-message-based-labels@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
-19
View File
@@ -1,19 +0,0 @@
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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
run-tests-guide-url: http://go/angular-g3sync-start
github-token: ${{ secrets.GITHUB_TOKEN }}
sync-config: ./.ng-dev/google-sync-config.json
-14
View File
@@ -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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
-55
View File
@@ -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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- 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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
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
-52
View File
@@ -1,52 +0,0 @@
name: OpenSSF Scorecard
on:
branch_protection_rule:
schedule:
- cron: '0 0 * * 0'
push:
branches: [main]
workflow_dispatch:
# Declare default permissions as read only.
permissions:
contents: read
jobs:
analysis:
name: Scorecards analysis
runs-on: ubuntu-latest
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
with:
persist-credentials: false
- name: 'Run analysis'
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
with:
results_file: results.sarif
results_format: sarif
repo_token: ${{ secrets.GITHUB_TOKEN }}
publish_results: true
# Upload the results as artifacts.
- name: 'Upload artifact'
uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- name: 'Upload to code-scanning'
uses: github/codeql-action/upload-sarif@b374143c1149a9115d881581d29b8390bbcbb59c # v3.22.11
with:
sarif_file: results.sarif
-44
View File
@@ -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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
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 }}
-48
View File
@@ -1,48 +0,0 @@
# Update the `events.json` file that powers the [AIO events page](https://angular.io/events) (if
# necessary) and create a pull request.
#
# For more details on the overall process, see
# [aio/scripts/generate-events/README.md](../../aio/scripts/generate-events/README.md).
name: Update AIO events
on:
workflow_dispatch:
inputs: {}
schedule:
# Run every day at 15:00.
- cron: '0 15 * * *'
# Declare default permissions as read only.
permissions:
contents: read
jobs:
update_events:
name: Update `events.json` (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 `events.json`
run: node aio/scripts/generate-events/index.mjs --ignore-invalid-dates
- name: Create a PR (if necessary)
uses: angular/dev-infra/github-actions/create-pr-for-changes@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
with:
branch-prefix: docs-update-events
pr-title: 'docs: update events'
pr-description: |
Generated `events.json` with the latest events retrieved from the Firebase DB.
pr-labels: |
action: review
area: docs
target: patch
angular-robot-token: ${{ secrets.ANGULAR_ROBOT_ACCESS_TOKEN }}
+3 -38
View File
@@ -1,33 +1,18 @@
.DS_STORE
/dist/
/bazel-out
/integration/bazel/bazel-*
*.log
/node_modules/
# CircleCI temporary file for cache key computation.
# See `save_month_to_file` in `.circleci/config.yml`.
month.txt
node_modules
bower_components
# Include when developing application packages.
pubspec.lock
.c9
.idea/
.devcontainer/*
!.devcontainer/README.md
!.devcontainer/recommended-devcontainer.json
!.devcontainer/recommended-Dockerfile
.settings/
.vscode/launch.json
.vscode/settings.json
.vscode/tasks.json
*.swo
*.swp
modules/.settings
.vscode
modules/.vscode
.vimrc
.nvimrc
# Don't check in secret files
*secret.js
@@ -41,23 +26,3 @@ yarn-error.log
# rollup-test output
/modules/rollup-test/dist/
# User specific bazel settings
.bazelrc.user
# User specific ng-dev settings
.ng-dev.user*
.notes.md
baseline.json
# Ignore .history for the xyz.local-history VSCode extension
.history
# Husky
.husky/_
aio/content/examples/.DS_Store
# Ignore cache created with the Angular CLI.
.angular/
-145
View File
@@ -1,145 +0,0 @@
<type>(<scope>): <summary>
<Describe the motivation behind this change - explain WHY you are making this change. Wrap all lines
at 100 characters.>
Fixes #<issue number>
# ────────────────────────────────────────── 100 chars ────────────────────────────────────────────┤
# Example Commit Messages
# =======================
# ─── Example: Simple refactor ────────────────────────────────────────────────────────────────────┤
# refactor(core): rename refreshDynamicEmbeddedViews to refreshEmbeddedViews
#
# Improve code readability. The original name no longer matches how the function is used.
# ─────────────────────────────────────────────────────────────────────────────────────────────────┤
# ─── Example: Simple docs change ─────────────────────────────────────────────────────────────────┤
# docs: clarify the service limitation in providers.md guide
#
# Fixes #36332
# ─────────────────────────────────────────────────────────────────────────────────────────────────┤
# ─── Example: A bug fix ──────────────────────────────────────────────────────────────────────────┤
# fix(ngcc): ensure lockfile is removed when `analyzeFn` fails
#
# Previously an error thrown in the `analyzeFn` would cause the ngcc process to exit immediately
# without removing the lockfile, and potentially before the unlocker process had been successfully
# spawned resulting in the lockfile being orphaned and left behind.
#
# Now we catch these errors and remove the lockfile as needed.
# ─────────────────────────────────────────────────────────────────────────────────────────────────┤
# ─── Example: Breaking change ────────────────────────────────────────────────────────────────────┤
# feat(bazel): simplify ng_package by dropping esm5 and fesm5
#
# esm5 and fesm5 distributions are no longer needed and have been deprecated in the past.
#
# https://v9.angular.io/guide/deprecations#esm5-and-fesm5-code-formats-in-angular-npm-packages
#
# This commit modifies ng_package to no longer distribute these two formats in npm packages built by
# ng_package (e.g. @angular/core).
#
# This commit intentionally doesn't fully clean up the ng_package rule to remove all traces of esm5
# and fems5 build artifacts as that is a bigger cleanup and currently we are narrowing down the
# scope of this change to the MVP needed for v10, which in this case is 'do not put esm5 and fesm5'
# into the npm packages.
#
# More cleanup to follow: https://angular-team.atlassian.net/browse/FW-2143
#
# BREAKING CHANGE: esm5 and fesm5 format is no longer distributed in Angular's npm packages e.g.
# @angular/core
#
# Angular CLI will automatically downlevel the code to es5 if differential loading is enabled in the
# Angular project, so no action is required from Angular CLI users.
#
# If you are not using Angular CLI to build your application or library, and you need to be able to
# build es5 artifacts, then you will need to downlevel the distributed Angular code to es5 on your
# own.
#
#
# Fixes #1234
# ─────────────────────────────────────────────────────────────────────────────────────────────────┤
# Angular Commit Message Format
# =============================
#
# The full specification of the Angular Commit Message Format can be found at
# https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit
#
# The following is an excerpt of the specification with the most commonly needed info.
#
# Each commit message consists of a *header*, a *body*, and a *footer*.
#
# <header>
# <BLANK LINE>
# <body>
# <BLANK LINE>
# <footer>
#
# The header is mandatory.
#
# The body is mandatory for all commits except for those of scope "docs". When the body is required
# it must be at least 20 characters long.
#
# The footer is optional.
#
# Any line of the commit message cannot be longer than 100 characters.
#
#
# Commit Message Header
# ---------------------
#
# <type>(<scope>): <short summary>
# │ │ │
# │ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
# │ │
# │ └─⫸ 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
# │
# └─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test
# https://github.com/angular/angular/blob/main/CONTRIBUTING.md#type
#
#
# Commit Message Body
# ---------------------
#
# Just as in the summary, use the imperative, present tense: "fix" not "fixed" nor "fixes".
#
# Explain the motivation for the change in the commit message body. This commit message should
# explain WHY you are making the change. You can include a comparison of the previous behavior with
# the new behavior in order to illustrate the impact of the change.
#
#
# Commit Message Footer
# ---------------------
#
# The footer can contain information about breaking changes and is also the place to reference
# GitHub issues, Jira tickets, and other PRs that this commit closes or is related to.
#
# ```
# BREAKING CHANGE: <breaking change summary>
# <BLANK LINE>
# <breaking change description + migration instructions>
# <BLANK LINE>
# <BLANK LINE>
# Fixes #<issue number>
# ```
#
# Breaking Change section should start with the phrase "BREAKING CHANGE: " followed by a summary of
# the breaking change, a blank line, and a detailed description of the breaking change that also
# includes migration instructions.
#
-11
View File
@@ -1,11 +0,0 @@
#!/bin/sh
. "$(dirname $0)/_/husky.sh"
set +e
yarn -s ng-dev commit-message pre-commit-validate --file $1 2>/dev/null
if [ $? -ne 0 ]; then
echo "WARNING: failed to run commit message validation (ng-dev commit-mesage pre-commit-validate)"
fi
exit 0;
-11
View File
@@ -1,11 +0,0 @@
#!/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;
-11
View File
@@ -1,11 +0,0 @@
#!/bin/sh
. "$(dirname $0)/_/husky.sh"
set +e
yarn -s ng-dev commit-message restore-commit-message-draft $1 $2 2>/dev/null
if [ $? -ne 0 ]; then
echo "WARNING: failed to attempt to restore commit message draft (ng-dev commit-message restore-commit-message-draft)"
fi
exit 0;
-1
View File
@@ -1 +0,0 @@
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
-21
View File
@@ -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',
};
-38
View File
@@ -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',
],
};
-15
View File
@@ -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,
};
-59
View File
@@ -1,59 +0,0 @@
import {FormatConfig} from '@angular/ng-dev';
/**
* Configuration for the `ng-dev format` command.
*/
export const format: FormatConfig = {
'prettier': {
'matchers': [
'**/*.{yaml,yml}',
'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/elements/**/*.{js,ts}',
'packages/misc/**/*.{js,ts}',
],
},
'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/elements/**/*.{js,ts}',
'!packages/misc/**/*.{js,ts}',
],
},
'buildifier': true,
};
-15
View File
@@ -1,15 +0,0 @@
# The file is inert unless it's explicitly included into the local git config via:
#
# ```
# git config --add include.path '../.ng-dev/gitconfig'
# ```
#
# Calling that command will append the following into `.git/config` of the current git workspace
# (i.e. $GIT_DIR, typically `angular/.git/config`):
#
# ```
# [include]
# path = ../.ng-dev/gitconfig
# ```
[commit]
template = .gitmessage
-12
View File
@@ -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,
};
-49
View File
@@ -1,49 +0,0 @@
{
"syncedFilePatterns": ["LICENSE", "modules/benchmarks/**", "packages/**"],
"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/language-service/**",
"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/**"
]
}
-20
View File
@@ -1,20 +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'],
};
-34
View File
@@ -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'],
};
-10
View File
@@ -1,10 +0,0 @@
{
"compilerOptions": {
"strict": true,
"target": "es2020",
"module": "Node16",
"noEmit": true,
"skipLibCheck": true,
"types": []
}
}
-1
View File
@@ -1 +0,0 @@
engine-strict = true
+1 -1
View File
@@ -1 +1 @@
18.13.0
6.9.5
-9
View File
@@ -1,9 +0,0 @@
{
"printWidth": 100,
"tabWidth": 2,
"tabs": false,
"singleQuote": true,
"semicolon": true,
"quoteProps": "preserve",
"bracketSpacing": false
}
+234 -1386
View File
File diff suppressed because it is too large Load Diff
+75
View File
@@ -0,0 +1,75 @@
language: node_js
sudo: false
node_js:
- '6.9.5'
addons:
# firefox: "38.0"
apt:
sources:
# needed to install g++ that is used by npms's native modules
- ubuntu-toolchain-r-test
packages:
# needed to install g++ that is used by npms's native modules
- g++-4.8
# https://docs.travis-ci.com/user/jwt
jwt:
# SAUCE_ACCESS_KEY<=secret for NGBUILDS_IO_KEY to work around travis-ci/travis-ci#7223, unencrypted value in valentine as NGBUILDS_IO_KEY>
# we alias NGBUILDS_IO_KEY to $SAUCE_ACCESS_KEY in env.sh and set the SAUCE_ACCESS_KEY there
- secure: "L7nrZwkAtFtYrP2DykPXgZvEKjkv0J/TwQ/r2QGxFTaBq4VZn+2Dw0YS7uCxoMqYzDwH0aAOqxoutibVpk8Z/16nE3tNmU5RzltMd6Xmt3qU2f/JDQLMo6PSlBodnjOUsDHJgmtrcbjhqrx/znA237BkNUu6UZRT7mxhXIZpn0U="
branches:
except:
- g3
cache:
yarn: true
directories:
- ./node_modules
- ./.chrome/chromium
- ./aio/node_modules
env:
global:
# GITHUB_TOKEN_ANGULAR=<github token, a personal access token of the angular-builds account, account access in valentine>
# This is needed for the e2e Travis matrix task to publish packages to github for continuous packages delivery.
- secure: "aCdHveZuY8AT4Jr1JoJB4LxZsnGWRe/KseZh1YXYe5UtufFCtTVHvUcLn0j2aLBF0KpdyS+hWf0i4np9jthKu2xPKriefoPgCMpisYeC0MFkwbmv+XlgkUbgkgVZMGiVyX7DCYXVahxIoOUjVMEDCbNiHTIrfEuyq24U3ok2tHc="
# FIREBASE_TOKEN
# This is needed for publishing builds to the "aio-staging" firebase site.
# TODO(i): the token was generated using the iminar@google account, we should switch to a shared/role-base account.
- secure: "MPx3UM77o5IlhT75PKHL0FXoB5tSXDc3vnCXCd1sRy4XUTZ9vjcV6nNuyqEf+SOw659bGbC1FI4mACGx1Q+z7MQDR85b1mcA9uSgHDkh+IR82CnCVdaX9d1RXafdJIArahxfmorbiiPPLyPIKggo7ituRm+2c+iraoCkE/pXxYg="
matrix:
# Order: a slower build first, so that we don't occupy an idle travis worker waiting for others to complete.
- CI_MODE=e2e
- CI_MODE=e2e_2
- CI_MODE=js
- CI_MODE=saucelabs_required
- CI_MODE=browserstack_required
- CI_MODE=saucelabs_optional
- CI_MODE=browserstack_optional
- CI_MODE=docs_test
- CI_MODE=aio
- CI_MODE=aio_e2e
matrix:
fast_finish: true
allow_failures:
- env: "CI_MODE=saucelabs_optional"
- env: "CI_MODE=browserstack_optional"
- env: "CI_MODE=aio_e2e"
before_install:
# source the env.sh script so that the exported variables are available to other scripts later on
- source ./scripts/ci/env.sh print
install:
- ./scripts/ci/install.sh
script:
- ./scripts/ci/build.sh
- ./scripts/ci/test.sh
# deploy is part of 'script' and not 'after_success' so that we fail the build if the deployment fails
- ./scripts/ci/deploy.sh
- ./scripts/ci/angular.sh
# all the scripts under this line will not quickly abort in case ${TRAVIS_TEST_RESULT} is 1 (job failure)
- ./scripts/ci/cleanup.sh
- ./scripts/ci/print-logs.sh
-25
View File
@@ -1,25 +0,0 @@
# VSCode Configuration
This folder contains opt-in [Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings), [Tasks](https://code.visualstudio.com/docs/editor/tasks), [Launch Configurations](https://code.visualstudio.com/Docs/editor/debugging#_launch-configurations) and [Extension Recommendations](https://code.visualstudio.com/docs/editor/extension-gallery#_workspace-recommended-extensions) that the Angular team recommends using when working on this repository.
## Usage
To use the recommended configurations follow the steps below:
- install the recommended extensions in `.vscode/extensions.json`
- copy (or link) `.vscode/recommended-settings.json` to `.vscode/settings.json`
- copy (or link) `.vscode/recommended-launch.json` to `.vscode/launch.json`
- copy (or link) `.vscode/recommended-tasks.json` to `.vscode/tasks.json`
- restart the editor
If you already have your custom workspace settings, you should instead manually merge the file contents.
This isn't an automatic process, so you will need to repeat it when settings are updated.
To see the recommended extensions select "Extensions: Show Recommended Extensions" in the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette).
## Editing `.vscode/recommended-*.json` files
If you wish to add extra configuration items please keep in mind any modifications you make here will be used by many users.
Try to keep these settings/configurations to things that help facilitate the development process and avoid altering the user workflow whenever possible.
-16
View File
@@ -1,16 +0,0 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"BazelBuild.vscode-bazel",
"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",
//"errata-ai.vale-server",
],
}
-75
View File
@@ -1,75 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Attach to bazel test ... --config=debug",
"type": "node",
"request": "attach",
"port": 9229,
"address": "localhost",
"restart": false,
"sourceMaps": true,
"localRoot": "${workspaceRoot}",
"remoteRoot": "${workspaceRoot}",
"stopOnEntry": false,
"timeout": 600000,
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
},
{
"name": "Attach to bazel test ... --config=debug (no source maps)",
"type": "node",
"request": "attach",
"port": 9229,
"address": "localhost",
"restart": false,
"sourceMaps": false,
"localRoot": "${workspaceRoot}",
"remoteRoot": "${workspaceRoot}",
"stopOnEntry": false,
"timeout": 600000,
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.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"],
"port": 9229,
"address": "localhost",
"restart": true,
"sourceMaps": true,
"timeout": 600000,
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.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"],
"port": 9229,
"address": "localhost",
"restart": true,
"sourceMaps": true,
"timeout": 600000,
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
},
{
"name": "IVY:packages/core/test",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": ["test", "packages/core/test", "--config=debug"],
"port": 9229,
"address": "localhost",
"restart": true,
"sourceMaps": true,
"timeout": 600000,
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
}
]
}
-32
View File
@@ -1,32 +0,0 @@
{
// Format js and ts files on save with `clang-format.executable`
// If `clang-format.executable` is not being used, these two settings should be removed otherwise it will break existing formatting.
// You can instead run `yarn gulp format` to manually format your code.
"[javascript]": {
"editor.formatOnSave": true,
},
"[typescript]": {
"editor.formatOnSave": true,
},
// Please install https://marketplace.visualstudio.com/items?itemName=xaver.clang-format to take advantage of `clang-format` in VSCode.
// (See https://clang.llvm.org/docs/ClangFormat.html for more info `clang-format`.)
"clang-format.executable": "${workspaceRoot}/node_modules/.bin/clang-format",
// Exclude third party modules and build artifacts from the editor watchers/searches.
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/node_modules/**": true,
"**/bazel-out/**": true,
"**/dist/**": true,
"**/aio/src/generated/**": true,
},
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
"**/bazel-out": true,
"**/dist": true,
"**/aio/src/generated": true,
".history": true,
},
"git.ignoreLimitWarning": true,
}
-109
View File
@@ -1,109 +0,0 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "IVY:packages/core/test/...",
"type": "shell",
"command": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"packages/core/test",
"packages/core/test/acceptance",
"packages/core/test/render3",
],
"group": "test",
"presentation": {
"reveal": "always",
"panel": "dedicated",
},
},
{
"label": "VE:packages/core/test/...",
"type": "shell",
"command": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"packages/core/test",
"packages/core/test/acceptance",
"packages/core/test/render3",
],
"group": "test",
"presentation": {
"reveal": "always",
"panel": "dedicated",
},
},
{
"label": "IVY:packages/core/test/acceptance",
"type": "shell",
"command": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"packages/core/test/acceptance",
],
"group": "test",
"presentation": {
"reveal": "always",
"panel": "dedicated",
},
},
{
"label": "VE:packages/core/test/acceptance",
"type": "shell",
"command": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"packages/core/test/acceptance",
],
"group": "test",
"presentation": {
"reveal": "always",
"panel": "dedicated",
},
},
{
"label": "IVY:packages/core/test",
"type": "shell",
"command": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"packages/core/test",
],
"group": "test",
"presentation": {
"reveal": "always",
"panel": "dedicated",
},
},
{
"label": "VE:packages/core/test",
"type": "shell",
"command": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"packages/core/test",
],
"group": "test",
"presentation": {
"reveal": "always",
"panel": "dedicated",
},
},
{
"label": "IVY:packages/core/test/render3",
"type": "shell",
"command": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"packages/core/test/render3",
],
"group": "test",
"presentation": {
"reveal": "always",
"panel": "dedicated",
},
},
],
}
-13
View File
@@ -1,13 +0,0 @@
# Yarn Vendoring
We utilize Yarn's `yarn-path` configuration in a shared `.yarnrc` file to enforce
everyone using the same version of Yarn. Yarn checks the `.yarnrc` file to
determine if yarn should delegate the command to a vendored version at the
provided path.
## How to update
To update to the latest version of Yarn as our vendored version:
- Run this command
```sh
yarn policies set-version latest
```
- Remove the previous version
-147529
View File
File diff suppressed because one or more lines are too long
-5
View File
@@ -1,5 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
yarn-path ".yarn/releases/yarn-1.22.19.cjs"
-82
View File
@@ -1,82 +0,0 @@
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/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",
srcs = [
"browser-providers.conf.d.ts",
"browser-providers.conf.js",
],
)
filegroup(
name = "angularjs_scripts",
srcs = [
# We also declare the unminified AngularJS files since these can be used for
# local debugging (e.g. see: packages/upgrade/test/common/test_helpers.ts)
"@npm//:node_modules/angular-1.5/angular.js",
"@npm//:node_modules/angular-1.5/angular.min.js",
"@npm//:node_modules/angular-1.6/angular.js",
"@npm//:node_modules/angular-1.6/angular.min.js",
"@npm//:node_modules/angular-1.7/angular.js",
"@npm//:node_modules/angular-1.7/angular.min.js",
"@npm//:node_modules/angular-mocks-1.5/angular-mocks.js",
"@npm//:node_modules/angular-mocks-1.6/angular-mocks.js",
"@npm//:node_modules/angular-mocks-1.7/angular-mocks.js",
"@npm//:node_modules/angular-mocks-1.8/angular-mocks.js",
"@npm//:node_modules/angular-1.8/angular.js",
"@npm//:node_modules/angular-1.8/angular.min.js",
],
)
# Detect if the build is running under --stamp
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",
}),
)
+5718 -2814
View File
File diff suppressed because it is too large Load Diff
-9175
View File
File diff suppressed because it is too large Load Diff
-79
View File
@@ -1,79 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
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.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* 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
+132 -262
View File
@@ -1,7 +1,7 @@
# Contributing to Angular
We would love for you to contribute to Angular and help make it even better than it is today!
As a contributor, here are the guidelines we would like you to follow:
We would love for you to contribute to Angular and help make it even better than it is
today! As a contributor, here are the guidelines we would like you to follow:
- [Code of Conduct](#coc)
- [Question or Problem?](#question)
@@ -12,168 +12,109 @@ As a contributor, here are the guidelines we would like you to follow:
- [Commit Message Guidelines](#commit)
- [Signing the CLA](#cla)
## <a name="coc"></a> Code of Conduct
Help us keep Angular open and inclusive.
Please read and follow our [Code of Conduct][coc].
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct][coc].
## <a name="question"></a> Got a Question or Problem?
Do not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests.
Instead, we recommend using [Stack Overflow](https://stackoverflow.com/questions/tagged/angular) to ask support-related questions. When creating a new question on Stack Overflow, make sure to add the `angular` tag.
Please, do not open issues for the general support questions as we want to keep GitHub issues for bug reports and feature requests. You've got much better chances of getting your question answered on [StackOverflow](https://stackoverflow.com/questions/tagged/angular) where the questions should be tagged with tag `angular`.
Stack Overflow is a much better place to ask questions since:
StackOverflow is a much better place to ask questions since:
- there are thousands of people willing to help on Stack Overflow
- questions and answers stay available for public viewing so your question/answer might help someone else
- Stack Overflow's voting system assures that the best answers are prominently visible.
- there are thousands of people willing to help on StackOverflow
- questions and answers stay available for public viewing so your question / answer might help someone else
- StackOverflow's voting system assures that the best answers are prominently visible.
To save your and our time, we will systematically close all issues that are requests for general support and redirect people to Stack Overflow.
If you would like to chat about the question in real-time, you can reach out via [our Discord server][discord].
To save your and our time we will be systematically closing all the issues that are requests for general support and redirecting people to StackOverflow.
If you would like to chat about the question in real-time, you can reach out via [our gitter channel][gitter].
## <a name="issue"></a> Found a Bug?
If you find a bug in the source code, you can help us by [submitting an issue](#submit-issue) to our [GitHub Repository][github].
Even better, you can [submit a Pull Request](#submit-pr) with a fix.
If you find a bug in the source code, you can help us by
[submitting an issue](#submit-issue) to our [GitHub Repository][github]. Even better, you can
[submit a Pull Request](#submit-pr) with a fix.
## <a name="feature"></a> Missing a Feature?
You can *request* a new feature by [submitting an issue](#submit-issue) to our GitHub Repository.
If you would like to *implement* a new feature, please consider the size of the change in order to determine the right steps to proceed:
* For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed.
This process allows us to better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted into the project.
**Note**: Adding a new topic to the documentation, or significantly re-writing a topic, counts as a major feature.
You can *request* a new feature by [submitting an issue](#submit-issue) to our GitHub
Repository. If you would like to *implement* a new feature, please submit an issue with
a proposal for your work first, to be sure that we can use it.
Please consider what kind of change it is:
* For a **Major Feature**, first open an issue and outline your proposal so that it can be
discussed. This will also allow us to better coordinate our efforts, prevent duplication of work,
and help you to craft the change so that it is successfully accepted into the project.
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
## <a name="submit"></a> Submission Guidelines
### <a name="submit-issue"></a> Submitting an Issue
Before you submit an issue, please search the issue tracker. An issue for your problem might already exist and the discussion might inform you of workarounds readily available.
Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.
We want to fix all the issues as soon as possible, but before fixing a bug, we need to reproduce and confirm it.
In order to reproduce bugs, we require that you provide a minimal reproduction.
Having a minimal reproducible scenario gives us a wealth of important information without going back and forth to you with additional questions.
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. In order to reproduce bugs we will systematically ask you to provide a minimal reproduction scenario using http://plnkr.co. Having a live, reproducible scenario gives us wealth of important information without going back & forth to you with additional questions like:
A minimal reproduction allows us to quickly confirm a bug (or point out a coding problem) as well as confirm that we are fixing the right problem.
- version of Angular used
- 3rd-party libraries and their versions
- and most importantly - a use-case that fails
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.
A minimal reproduce scenario using http://plnkr.co/ allows us to quickly confirm a bug (or point out coding problem) as well as confirm that we are fixing the right problem. If plunker is not a suitable way to demonstrate the problem (for example for issues related to our npm packaging), please create a standalone git repository demonstrating the problem.
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.
We will be insisting on a minimal reproduce scenario in order to save maintainers time and ultimately be able to fix more bugs. Interestingly, from our experience users often find coding problems themselves while preparing a minimal plunk. We understand that sometimes it might be hard to extract essentials bits of code from a larger code-base but we really need to isolate the problem before we can fix it.
You can file new issues by selecting from our [new issue templates](https://github.com/angular/angular/issues/new/choose) and filling out the issue template.
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 don't have enough info to be reproduced.
You can file new issues by filling out our [new issue form](https://github.com/angular/angular/issues/new).
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
Before you submit your Pull Request (PR) consider the following guidelines:
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR that relates to your submission.
You don't want to duplicate existing efforts.
2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add.
Discussing the design upfront helps to ensure that we're ready to accept your work.
3. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
We cannot accept code without a signed CLA.
Make sure you author all contributed Git commits with email address associated with your CLA signature.
4. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the angular/angular repo.
5. In your forked repository, make your changes in a new git branch:
* Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR
that relates to your submission. You don't want to duplicate effort.
* Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
We cannot accept code without this.
* 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**.
7. Follow our [Coding Rules](#rules).
8. Run the full Angular test suite, as described in the [developer documentation][dev-doc], and ensure that all tests pass.
9. Commit your changes using a descriptive commit message that follows our [commit message conventions](#commit).
Adherence to these conventions is necessary because release notes are automatically generated from these messages.
* Create your patch, **including appropriate test cases**.
* Follow our [Coding Rules](#rules).
* Run the full Angular test suite, as described in the [developer documentation][dev-doc],
and ensure that all tests pass.
* Commit your changes using a descriptive commit message that follows our
[commit message conventions](#commit). Adherence to these conventions
is necessary because release notes are automatically generated from these messages.
```shell
git commit --all
git commit -a
```
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:
* Push your branch to GitHub:
```shell
git push origin my-fix-branch
```
11. In GitHub, send a pull request to `angular:main`.
### Reviewing a Pull Request
The Angular team reserves the right not to accept pull requests from community members who haven't been good citizens of the community. Such behavior includes not following the [Angular code of conduct](https://github.com/angular/code-of-conduct) and applies within or outside of Angular managed channels.
#### Addressing review feedback
If we ask for changes via code reviews then:
1. Make the required updates to the code.
2. Re-run the Angular test suites to ensure tests are still passing.
3. Create a fixup commit and push to your GitHub repository (this will update your Pull Request):
* In GitHub, send a pull request to `angular:master`.
* If we suggest changes then:
* Make the required updates.
* Re-run the Angular test suites to ensure tests are still passing.
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
```shell
git commit --all --fixup HEAD
git push
git rebase master -i
git push -f
```
For more info on working with fixup commits see [here](docs/FIXUP_COMMITS.md).
That's it! Thank you for your contribution!
##### Updating the commit message
A reviewer might often suggest changes to a commit message (for example, to add more context for a change or adhere to our [commit message guidelines](#commit)).
In order to update the commit message of the last commit on your branch:
1. Check out your branch:
```shell
git checkout my-fix-branch
```
2. Amend the last commit and modify the commit message:
```shell
git commit --amend
```
3. Push to your GitHub repository:
```shell
git push --force-with-lease
```
> NOTE:<br />
> If you need to update the commit message of an earlier commit, you can use `git rebase` in interactive mode.
> See the [git docs](https://git-scm.com/docs/git-rebase#_interactive_mode) for more details.
#### After your pull request is merged
After your pull request is merged, you can safely delete your branch and pull the changes from the main (upstream) repository:
After your pull request is merged, you can safely delete your branch and pull the changes
from the main (upstream) repository:
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
@@ -181,10 +122,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,212 +134,141 @@ 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
```
## <a name="rules"></a> Coding Rules
To ensure consistency throughout the source code, keep these rules in mind as you are working:
* All features or bug fixes **must be tested** by one or more specs (unit-tests).
* All public API methods **must be documented**.
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at **100 characters**.
* All public API methods **must be documented**. (Details TBC).
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at
**100 characters**. An automated formatter is available, see
[DEVELOPER.md](docs/DEVELOPER.md#clang-format).
An automated formatter is available, see [DEVELOPER.md](docs/DEVELOPER.md#clang-format).
## <a name="commit"></a> Commit Message Guidelines
We have very precise rules over how our git commit messages can be formatted. This leads to **more
readable messages** that are easy to follow when looking through the **project history**. But also,
we use the git commit messages to **generate the Angular change log**.
## <a name="commit"></a> Commit Message Format
*This specification is inspired by and supersedes the [AngularJS commit message format][commit-message-format].*
We have very precise rules over how our Git commit messages must be formatted.
This format leads to **easier to read commit history**.
Each commit message consists of a **header**, a **body**, and a **footer**.
### Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
format that includes a **type**, a **scope** and a **subject**:
```
<header>
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```
The `header` is mandatory and must conform to the [Commit Message Header](#commit-header) format.
The **header** is mandatory and the **scope** of the header is optional.
The `body` is mandatory for all commits except for those of type "docs".
When the body is present it must be at least 20 characters long and must conform to the [Commit Message Body](#commit-body) format.
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.
The `footer` is optional. The [Commit Message Footer](#commit-footer) format describes what the footer is used for and the structure it must have.
Footer should contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-via-commit-messages/) if any.
#### <a name="commit-header"></a>Commit Message Header
Samples: (even more [samples](https://github.com/angular/angular/commits/master))
```
<type>(<scope>): <short summary>
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ 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
│
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|test
docs(changelog): update change log to beta.5
```
```
fix(release): need to depend on latest rxjs and zone.js
The version in our package.json gets copied to the one we publish, and users need the latest of these.
```
The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is optional.
##### Type
### Revert
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
### Type
Must be one of the following:
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
* **ci**: Changes to our CI configuration files and scripts (examples: CircleCi, SauceLabs)
* **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
* **docs**: Documentation only changes
* **feat**: A new feature
* **fix**: A bug fix
* **perf**: A code change that improves performance
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
semi-colons, etc)
* **test**: Adding missing tests or correcting existing tests
##### Scope
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages).
### Scope
The scope should be the name of the npm package affected (as perceived by person reading changelog generated from commit messages.
The following is the list of supported scopes:
* `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`
* **common**
* **compiler**
* **compiler-cli**
* **core**
* **forms**
* **http**
* **language-service**
* **platform-browser**
* **platform-browser-dynamic**
* **platform-server**
* **platform-webworker**
* **platform-webworker-dynamic**
* **router**
* **upgrade**
* **tsc-wrapped**
There are currently a few exceptions to the "use package name" rule:
There is currently few exception to the "use package name" rule:
* `packaging`: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc.
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc.
* **changelog**: used for updating the release notes in CHANGELOG.md
* **aio**: used for docs-app (angular.io) related changes within the /aio directory of the repo
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`)
* `changelog`: used for updating the release notes in CHANGELOG.md
* `dev-infra`: used for dev-infra related changes within the directories /scripts and /tools
* `docs-infra`: used for docs-app (angular.io) related changes within the /aio directory of the repo
* `migrations`: used for changes to the `ng update` migrations.
* `devtools`: used for changes in the [browser extension](./devtools/README.md).
* 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`).
##### Summary
Use the summary field to provide a succinct description of the change:
### Subject
The subject contains succinct description of the change:
* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize the first letter
* don't capitalize first letter
* no dot (.) at the end
### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.
#### <a name="commit-body"></a>Commit Message Body
### Footer
The footer should contain any information about **Breaking Changes** and is also the place to
reference GitHub issues that this commit **Closes**.
Just as in the summary, use the imperative, present tense: "fix" not "fixed" nor "fixes".
Explain the motivation for the change in the commit message body. This commit message should explain _why_ you are making the change.
You can include a comparison of the previous behavior with the new behavior in order to illustrate the impact of the change.
#### <a name="commit-footer"></a>Commit Message Footer
The footer can contain information about breaking changes and deprecations and is also the place to reference GitHub issues, Jira tickets, and other PRs that this commit closes or is related to.
For example:
```
BREAKING CHANGE: <breaking change summary>
<BLANK LINE>
<breaking change description + migration instructions>
<BLANK LINE>
<BLANK LINE>
Fixes #<issue number>
```
or
```
DEPRECATED: <what is deprecated>
<BLANK LINE>
<deprecation description + recommended update path>
<BLANK LINE>
<BLANK LINE>
Closes #<pr number>
```
Breaking Change section should start with the phrase "BREAKING CHANGE: " followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.
Similarly, a Deprecation section should start with "DEPRECATED: " followed by a short description of what is deprecated, a blank line, and a detailed description of the deprecation that also mentions the recommended update path.
### Revert commits
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
The content of the commit message body should contain:
- information about the SHA of the commit being reverted in the following format: `This reverts commit <SHA>`,
- a clear description of the reason for reverting the commit message.
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
A detailed explanation can be found in this [document][commit-message-format].
## <a name="cla"></a> Signing the CLA
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
* For individuals, we have a [simple click-through form][individual-cla].
* For corporations, we'll need you to
* For individuals we have a [simple click-through form][individual-cla].
* For corporations we'll need you to
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
If you have more than one GitHub accounts, or multiple email addresses associated with a single GitHub account, you must sign the CLA using the primary email address of the GitHub account used to author Git commits and send pull requests.
The following documents can help you sort out issues with GitHub accounts and multiple email addresses:
* https://help.github.com/articles/setting-your-commit-email-address-in-git/
* https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean
* https://help.github.com/articles/about-commit-email-addresses/
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
[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
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
[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
[gitter]: https://gitter.im/angular/angular
[individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html
[js-style-guide]: https://google.github.io/styleguide/jsguide.html
[jsfiddle]: https://jsfiddle.net/
[plunker]: https://plnkr.co/edit
[runnable]: https://runnable.com/
[stackoverflow]: https://stackoverflow.com/questions/tagged/angular
[jsfiddle]: http://jsfiddle.net
[plunker]: http://plnkr.co/edit
[runnable]: http://runnable.com
[stackoverflow]: http://stackoverflow.com/questions/tagged/angular
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2010-2023 Google LLC. https://angular.io/license
Copyright (c) 2014-2017 Google, Inc. http://angular.io
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+18 -174
View File
@@ -1,186 +1,30 @@
<h1 align="center">Angular - The modern web developer's platform</h1>
[![Build Status](https://travis-ci.org/angular/angular.svg?branch=master)](https://travis-ci.org/angular/angular)
[![CircleCI](https://circleci.com/gh/angular/angular/tree/master.svg?style=shield)](https://circleci.com/gh/angular/angular/tree/master)
[![Join the chat at https://gitter.im/angular/angular](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/angular/angular?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Issue Stats](http://issuestats.com/github/angular/angular/badge/pr?style=flat)](http://issuestats.com/github/angular/angular)
[![Issue Stats](http://issuestats.com/github/angular/angular/badge/issue?style=flat)](http://issuestats.com/github/angular/angular)
[![npm version](https://badge.fury.io/js/%40angular%2Fcore.svg)](https://badge.fury.io/js/%40angular%2Fcore)
<p align="center">
<img src="aio/src/assets/images/logos/angular/angular_renaissance.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>
<br>
</p>
[![Sauce Test Status](https://saucelabs.com/browser-matrix/angular2-ci.svg)](https://saucelabs.com/u/angular2-ci)
*Safari (7+), iOS (7+), Edge (14) and IE mobile (11) are tested on [BrowserStack][browserstack].*
<p align="center">
<a href="https://angular.dev/"><strong>angular.dev</strong></a>
<br>
</p>
Angular
=========
<p align="center">
<a href="CONTRIBUTING.md">Contributing Guidelines</a>
·
<a href="https://github.com/angular/angular/issues">Submit an Issue</a>
·
<a href="https://blog.angular.io/">Blog</a>
<br>
<br>
</p>
Angular is a development platform for building mobile and desktop web applications using Typescript/JavaScript (JS) and other languages.
<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>&nbsp;
<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" />
</a>&nbsp;
<a href="https://discord.gg/angular">
<img src="https://img.shields.io/discord/463752820026376202.svg?logo=discord&logoColor=fff&label=Discord&color=7389d8" alt="Discord conversation" />
</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
Get started with Angular, learn the fundamentals and explore advanced topics on our documentation website.
- [Getting Started][quickstart]
- [Architecture][architecture]
- [Components and Templates][componentstemplates]
- [Forms][forms]
- [API][api]
### Advanced
- [Angular Elements][angularelements]
- [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
### Prerequisites
- Install [Node.js] which includes [Node Package Manager][npm]
### Setting Up a Project
Install the Angular CLI globally:
```
npm install -g @angular/cli
```
Create workspace:
```
ng new [PROJECT NAME]
```
Run the application:
```
cd [PROJECT NAME]
ng serve
```
Angular is cross-platform, fast, scalable, has incredible tooling, and is loved by millions.
## Quickstart
[Get started in 5 minutes][quickstart].
## Ecosystem
<p>
<img src="/docs/images/angular-ecosystem-logos.png" alt="angular ecosystem logos" width="500px" height="auto">
</p>
## Want to help?
- [Angular Command Line (CLI)][cli]
- [Angular Material][angularmaterial]
Want to file 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 in the [hotlist: community-help](https://github.com/angular/angular/labels/hotlist%3A%20community-help).
## Changelog
[Learn about the latest improvements][changelog].
## Upgrading
Check out our [upgrade guide](https://update.angular.io/) to find out the best way to upgrade your project.
## Contributing
### Contributing Guidelines
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>.
### Code of Conduct
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct][codeofconduct].
## Community
Join the conversation and help the community.
- [X (formerly Twitter)][X (formerly Twitter)]
- [Discord][discord]
- [Gitter][gitter]
- [YouTube][youtube]
- [StackOverflow][stackoverflow]
- Find a Local [Meetup][meetup]
[![Love Angular badge](https://img.shields.io/badge/angular-love-blue?logo=angular&angular=love)](https://www.github.com/angular/angular)
**Love Angular? Give our repo a star :star: :arrow_up:.**
[contributing]: CONTRIBUTING.md
[quickstart]: https://angular.dev/tutorials/learn-angular
[changelog]: CHANGELOG.md
[ng]: https://angular.dev
[documentation]: https://angular.dev/overview
[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
[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
[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
[browserstack]: https://www.browserstack.com/
[contributing]: http://github.com/angular/angular/blob/master/CONTRIBUTING.md
[quickstart]: https://angular.io/docs/ts/latest/quickstart.html
[ng]: http://angular.io
-3
View File
@@ -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).
-236
View File
@@ -1,236 +0,0 @@
workspace(
name = "angular",
managed_directories = {
"@npm": ["node_modules"],
"@aio_npm": ["aio/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"],
)
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"],
)
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",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.6.0/rules_pkg-0.6.0.tar.gz",
"https://github.com/bazelbuild/rules_pkg/releases/download/0.6.0/rules_pkg-0.6.0.tar.gz",
],
)
# 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",
)
# Setup the Node.js toolchain.
load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")
nodejs_register_toolchains(
name = "nodejs",
node_version = "18.13.0",
)
# 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
# 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,
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")
npm_bazel_protractor_dependencies()
# Setup the rules_webtesting toolchain
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")
browser_repositories()
load("@build_bazel_rules_nodejs//toolchains/esbuild:esbuild_repositories.bzl", "esbuild_repositories")
esbuild_repositories(
npm_repository = "npm",
)
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")
cldr_major_version = "41"
cldr_json_data_repository(
name = "cldr_json_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",
},
)
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 = "7a90567717c3417a23ff4b21963a698a6e9aa669ac9e682121ea33f218a2816a",
strip_prefix = "rules_sass-425ecafa8268bc013d684216363fe75bc802323e",
urls = [
"https://github.com/bazelbuild/rules_sass/archive/425ecafa8268bc013d684216363fe75bc802323e.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",
)
-140
View File
@@ -1,140 +0,0 @@
load("//:packages.bzl", "link_packages")
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",
"@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,
)
architect(
name = "build",
args = [
"angular-dev:build",
"--output-path=build",
],
chdir = "$(RULEDIR)",
data = APPLICATION_DEPS + [
":application_files_bin",
],
output_dir = True,
)
architect(
name = "serve",
args = [
"angular-dev:serve",
"--poll=1000",
"--live-reload",
"--watch",
],
chdir = package_name(),
data = APPLICATION_DEPS + [
":application_files_bin",
],
)
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",
],
)
-105
View File
@@ -1,105 +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",
"prerender": true,
"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"
}
}
-73
View File
@@ -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"
}
]
}
}
-74
View File
@@ -1,74 +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;
}
-135
View File
@@ -1,135 +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 {input, confirm} from '@inquirer/prompts';
import {existsSync} from 'fs';
import {copyFile, mkdir, writeFile} from 'fs/promises';
import {dirname, join} from 'path';
import {fileURLToPath} from 'url';
import {copyFolder} from './utils/fs.mjs';
const EXAMPLES_BASE = join(
dirname(fileURLToPath(import.meta.url)),
'../../src/content/examples',
);
const STACKBLITZ_TEMPLATE = join(
dirname(fileURLToPath(import.meta.url)),
'../../src/content/stackblitz-template',
);
const MAIN_TS_FILENAME = 'main.ts';
const STACKBLITZ_CONFIG_FILENAME = 'stackblitz.json';
createExample();
async function createExample(): Promise<void> {
console.info('Create example');
const name = await input({message: 'What is the example name?'});
const description = await input({message: 'Could you provide the description of the example?'});
const tags: string[] = [];
let addMoreTags = true;
while (addMoreTags) {
const tag = await input({message: 'Could you provide the tag of the example?'});
if (!!tag) {
tags.push(tag);
}
console.info();
addMoreTags = await confirm({message: 'Would you like to add another tag?', default: true});
}
const shouldCopySrcAppFolderFromTemplate = await confirm({
message: 'Would you like to copy /src/app/**.* from template?',
default: true,
});
const shouldCopyMainTsFromTemplate = await confirm({
message: 'Would you like to copy /src/main.ts from template?',
default: false,
});
const examplePath = join(EXAMPLES_BASE, name);
await createEmptyExample(examplePath, name, description, tags);
await copyFilesFromTemplate(
examplePath,
shouldCopySrcAppFolderFromTemplate,
shouldCopyMainTsFromTemplate,
);
}
/**
* Create the directory and marker files for the new example.
*/
async function createEmptyExample(
examplePath: string,
exampleName: string,
description: string,
tags: string[],
): Promise<void> {
validateExampleName(exampleName);
await ensureExamplePath(examplePath);
await writeStackBlitzFile(examplePath, description, tags);
}
function validateExampleName(exampleName: string): void {
if (/\s/.test(exampleName)) {
throw new Error(`Unable to create example. The example name contains spaces: '${exampleName}'`);
}
}
/**
* Ensure that the new example directory exists.
*/
async function ensureExamplePath(examplePath: string): Promise<void> {
if (existsSync(examplePath)) {
throw new Error(
`Unable to create example. The path to the new example already exists: ${examplePath}`,
);
}
await mkdir(examplePath);
}
/**
* Write the `stackblitz.json` file into the new example.
*/
async function writeStackBlitzFile(
examplePath: string,
description: string,
tags: string[],
): Promise<void> {
const config = {
description,
ignore: ['**/*.d.ts', '**/*.js', '**/*.[1,2].*'],
tags,
};
await writeFile(
join(examplePath, STACKBLITZ_CONFIG_FILENAME),
JSON.stringify(config, null, 2) + '\n',
);
}
async function copyFilesFromTemplate(
examplePath: string,
shouldCopySrcAppFolderFromTemplate: boolean,
shouldCopyMainTsFromTemplate: boolean,
): Promise<void> {
if (shouldCopySrcAppFolderFromTemplate) {
const appTemplateFolderPath = join(STACKBLITZ_TEMPLATE, 'src/app');
const exampleAppFolderPath = join(examplePath, 'src/app');
await copyFolder(appTemplateFolderPath, exampleAppFolderPath);
}
if (shouldCopyMainTsFromTemplate) {
const mainTsTemplatePath = join(STACKBLITZ_TEMPLATE, 'src', MAIN_TS_FILENAME);
const exampleMainTsPath = join(examplePath, 'src', MAIN_TS_FILENAME);
await copyFile(mainTsTemplatePath, exampleMainTsPath);
}
}
@@ -1,158 +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 ts from 'typescript';
import * as fs from 'fs';
import {dirname, join, relative} from 'path';
import {fileURLToPath} from 'url';
import {readFile, writeFile} from 'fs/promises';
const TYPESCRIPT_EXTENSION = '.ts';
const SKIP_FILES_WITH_EXTENSIONS = ['.e2e-spec.ts', '.spec.ts', '.po.ts'];
const EXAMPLES_PATH = `../../content/examples`;
interface File {
path: string;
content: string;
}
interface AnalyzedFiles {
path: string;
componentNames: string[];
}
/** Absolute disk path to the project directory. */
const examplesDir = join(
dirname(fileURLToPath(import.meta.url)),
'../../src/content/examples',
);
const projectDir = join(dirname(fileURLToPath(import.meta.url)), '../../src');
const previewsComponentMapFileName = 'previews.ts';
main();
async function main() {
const files = await retrieveAllTypescriptFiles(
examplesDir,
(path) => !SKIP_FILES_WITH_EXTENSIONS.some((extensionToSkip) => path.endsWith(extensionToSkip)),
);
const filesWithComponent = files
.map((file) => ({
componentNames: analyzeFile(file),
path: file.path,
}))
.filter((result) => result.componentNames.length > 0);
const previewsComponentMap = generatePreviewsComponentMap(filesWithComponent);
fs.mkdirSync(join(projectDir, 'assets/previews'), {recursive: true});
await writeFile(
join(projectDir, 'assets/previews', previewsComponentMapFileName),
previewsComponentMap,
);
}
/** Recursively search the provided directory for all typescript files and asynchronously load them. */
function retrieveAllTypescriptFiles(
baseDir: string,
predicateFn: (path: string) => boolean,
): Promise<File[]> {
const typescriptFiles: Promise<File>[] = [];
const checkFilesInDirectory = (dir: string) => {
const files = fs.readdirSync(dir, {withFileTypes: true});
for (const file of files) {
const fullPathToFile = join(dir, file.name);
const relativeFilePath = relative(baseDir, fullPathToFile);
if (
file.isFile() &&
file.name.endsWith(TYPESCRIPT_EXTENSION) &&
predicateFn(relativeFilePath)
) {
typescriptFiles.push(
readFile(fullPathToFile, {encoding: 'utf-8'}).then((fileContent) => {
return {
path: relativeFilePath,
content: fileContent,
};
}),
);
} else if (file.isDirectory()) {
checkFilesInDirectory(fullPathToFile);
}
}
};
checkFilesInDirectory(baseDir);
return Promise.all(typescriptFiles);
}
/** Returns list of the `Standalone` @Component class names for given file */
function analyzeFile(file: File): string[] {
const componentClassNames: string[] = [];
const sourceFile = ts.createSourceFile(file.path, file.content, ts.ScriptTarget.Latest, false);
const visitNode = (node: ts.Node): void => {
if (ts.isClassDeclaration(node)) {
const decorators = ts.getDecorators(node);
const componentName = node.name ? node.name.text : null;
if (decorators && decorators.length) {
for (const decorator of decorators) {
const call = decorator.expression;
if (
ts.isCallExpression(call) &&
ts.isIdentifier(call.expression) &&
call.expression.text === 'Component' &&
call.arguments.length > 0 &&
ts.isObjectLiteralExpression(call.arguments[0])
) {
const hasStandaloneProperty = call.arguments[0].properties.some(
(property) =>
property.name &&
ts.isIdentifier(property.name) &&
property.name.text === 'standalone',
);
if (hasStandaloneProperty && componentName) {
componentClassNames.push(componentName);
}
}
}
}
}
ts.forEachChild(node, visitNode);
};
visitNode(sourceFile);
return componentClassNames;
}
function generatePreviewsComponentMap(data: AnalyzedFiles[]): string {
let result = '';
for (const fileData of data) {
for (const componentName of fileData.componentNames) {
const key = `${fileData.path}${
fileData.componentNames.length > 1 ? '_' + componentName : ''
}`.replace(/\\/g, '/');
result += `['${key}']: () => import('${EXAMPLES_PATH}/${fileData.path
.replace(/\\/g, '/')
.replace('.ts', '')}').then(c => c.${componentName}),\n`;
}
}
return fs
.readFileSync('scripts/examples/previews-components.template', 'utf8')
.replace(/\${previewsComponents}/g, result);
}
@@ -1,23 +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
*/
/**
******************************************************************************
* DO NOT MANUALLY EDIT THIS FILE. THIS FILE IS AUTOMATICALLY GENERATED.
******************************************************************************
*/
import {Type} from '@angular/core';
/**
* Map of the previews components, values are functions which returns the promise of the component type, which will be displayed as preview in the ExampleViewer component.
* Keys has to be equal to paths written down in the docs markdown files.
*/
export const PREVIEWS_COMPONENTS_MAP: Record<string, () => Promise<Type<unknown>>> = {
${previewsComponents}
};
@@ -1,221 +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 {dirname, join} from 'path';
import {readFile, writeFile} from 'fs/promises';
import {
ASSETS_EXAMPLE_PATH,
CSS_TS_COPYRIGHT,
EXAMPLES_PATH,
HTML_COPYRIGHT,
STACKBLITZ_TEMPLATE_PATH,
STACKBLITZ_CONFIG_FILENAME,
TEMPORARY_EXAMPLES_PATH,
EXCLUDE_FILES_FOR_STACKBLITZ,
} from './utils/examples-constants.mjs';
import {copyFolder, createFolder, removeFolder} from './utils/fs.mjs';
import jsdom from 'jsdom';
import {glob} from 'glob';
import {regionParser} from './../../prerender/markdown-pipeline/regions/region-parser.mjs';
interface StackblitzConfig {
ignore: string[];
file: string;
tags: string[];
description: string;
}
export async function generateStackblitzExample(
exampleFolderName: string,
primaryFilePath: string,
title: string,
) {
const exampleDir = join(EXAMPLES_PATH, exampleFolderName);
const temporaryExampleDir = join(TEMPORARY_EXAMPLES_PATH, exampleFolderName);
const config = await readFile(join(exampleDir, STACKBLITZ_CONFIG_FILENAME), 'utf-8');
const stackblitzConfig: StackblitzConfig = JSON.parse(config);
primaryFilePath = join(...primaryFilePath.split('/'));
await createFolder(temporaryExampleDir);
await combineTemplateWithExample(exampleDir, temporaryExampleDir);
await generateStackblitzHtml(
temporaryExampleDir,
stackblitzConfig,
exampleFolderName,
primaryFilePath,
title,
);
await removeFolder(temporaryExampleDir);
}
async function combineTemplateWithExample(
exampleDir: string,
temporaryExampleDir: string,
): Promise<void> {
// Copy template files to TEMP folder
await copyFolder(STACKBLITZ_TEMPLATE_PATH, temporaryExampleDir);
// Copy example files to TEMP folder
await copyFolder(exampleDir, temporaryExampleDir);
}
async function generateStackblitzHtml(
temporaryExampleDir: string,
stackBlitzConfig: StackblitzConfig,
exampleFolderName: string,
primaryFilePath: string,
title: string,
): Promise<void> {
const defaultIncludes = [
'**/*.ts',
'**/*.js',
'**/*.css',
'**/*.html',
'**/*.md',
'**/*.json',
'**/*.svg',
];
const exampleFilePaths = await glob(defaultIncludes, {
cwd: temporaryExampleDir,
nodir: true,
dot: true,
ignore: stackBlitzConfig.ignore,
});
const postData = await createPostData(
temporaryExampleDir,
stackBlitzConfig,
exampleFilePaths,
title,
);
const primaryFile = getPrimaryFile(primaryFilePath ?? stackBlitzConfig.file, exampleFilePaths);
const html = createStackblitzHtml(postData, primaryFile);
const stackblitzHtmlPath = join(
join(ASSETS_EXAMPLE_PATH, exampleFolderName),
`${primaryFile}.html`,
);
await createFolder(dirname(stackblitzHtmlPath));
await writeFile(stackblitzHtmlPath, html, 'utf-8');
}
function getPrimaryFile(primaryFilePath: string, exampleFilePaths: string[]): string {
if (primaryFilePath) {
if (!exampleFilePaths.some((filePath) => filePath === primaryFilePath)) {
throw new Error(`The specified primary file (${primaryFilePath}) does not exist!`);
}
return primaryFilePath;
} else {
const defaultPrimaryFilePaths = [
'src/app/app.component.html',
'src/app/app.component.ts',
'src/app/main.ts',
];
const primaryFile = defaultPrimaryFilePaths.find((path) =>
exampleFilePaths.some((filePath) => filePath === path),
);
if (!primaryFile) {
throw new Error(
`None of the default primary files (${defaultPrimaryFilePaths.join(', ')}) exists.`,
);
}
return primaryFile;
}
}
async function createPostData(
exampleDir: string,
config: StackblitzConfig,
exampleFilePaths: string[],
title: string,
): Promise<Record<string, string>> {
const postData: Record<string, string> = {};
for (const filePath of exampleFilePaths) {
if (EXCLUDE_FILES_FOR_STACKBLITZ.some((excludedFile) => filePath.endsWith(excludedFile))) {
continue;
}
let content = await readFile(join(exampleDir, filePath), 'utf-8');
content = appendCopyright(filePath, content);
content = extractRegions(filePath, content);
postData[`project[files][${filePath}]`] = content;
}
const tags = ['angular', 'example', ...(config.tags || [])];
tags.forEach((tag, index) => (postData[`project[tags][${index}]`] = tag));
postData['project[description]'] = `Angular Example - ${config.description}`;
postData['project[template]'] = 'node';
postData['project[title]'] = title ?? 'Angular Example';
return postData;
}
function createStackblitzHtml(postData: Record<string, string>, primaryFile: string): string {
const baseHtml = createBaseStackblitzHtml(primaryFile);
const doc = new jsdom.JSDOM(baseHtml).window.document;
const form = doc.querySelector('form');
for (const [key, value] of Object.entries(postData)) {
const element = htmlToElement(doc, `<input type="hidden" name="${key}">`);
if (element && form) {
element.setAttribute('value', value as string);
form.appendChild(element);
}
}
return doc.documentElement.outerHTML;
}
function createBaseStackblitzHtml(primaryFile: string) {
const file = `?file=${primaryFile}`;
const action = `https://stackblitz.com/run${file}`;
return `
<!DOCTYPE html><html lang="en"><body>
<form id="mainForm" method="post" action="${action}" target="_self"></form>
<script>
var embedded = 'ctl=1';
var isEmbedded = window.location.search.indexOf(embedded) > -1;
if (isEmbedded) {
var form = document.getElementById('mainForm');
var action = form.action;
var actionHasParams = action.indexOf('?') > -1;
var symbol = actionHasParams ? '&' : '?'
form.action = form.action + symbol + embedded;
}
document.getElementById("mainForm").submit();
</script>
</body></html>
`.trim();
}
function appendCopyright(filename: string, content: string): string {
if (filename.endsWith('.html')) {
return `${HTML_COPYRIGHT}${content}`;
} else if (filename.endsWith('.ts') || filename.endsWith('.css')) {
return `${CSS_TS_COPYRIGHT}${content}`;
}
return content;
}
function htmlToElement(document: Document, html: string) {
const div = document.createElement('div');
div.innerHTML = html;
return div.firstElementChild;
}
function extractRegions(path: string, contents: string): string {
const regionParserResult = regionParser(contents, path);
return regionParserResult.contents;
}
-8
View File
@@ -1,8 +0,0 @@
{
"extends": "../../tsconfig.json",
"ts-node": {
"compilerOptions": {
"module": "es2020"
}
}
}
@@ -1,55 +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 {dirname, join} from 'path';
import {fileURLToPath} from 'url';
const BASE = dirname(fileURLToPath(import.meta.url));
// Directory paths
export const ASSETS_EXAMPLE_PATH = join(
BASE,
'../../../src/assets/content/examples',
);
export const EXAMPLES_PATH = join(BASE, '../../../src/content/examples');
export const STACKBLITZ_TEMPLATE_PATH = join(
BASE,
'../../../src/content/stackblitz-template',
);
export const TEMPORARY_EXAMPLES_PATH = join(fileURLToPath(import.meta.url), '../../../../TEMP');
// Extensions
export const TEST_FILES_EXTENSION_SUFFIX = '.spec.ts';
export const TEST_FILES_E2E_EXTENSION_SUFFIX = '.e2e-spec.ts';
// Filename
// TODO: BUILD.bazel and example-config will be deprecated when migration to standalone examples will be done.
export const BUILD_BAZEL_FILENAME = 'BUILD.bazel';
export const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
export const STACKBLITZ_CONFIG_FILENAME = 'stackblitz.json';
// Copyright
const PAD = '\n\n';
const COPYRIGHT =
'@license\n' +
'Copyright Google LLC All Rights Reserved.\n' +
'\n' +
'Use of this source code is governed by an MIT-style license that can be\n' +
'found in the LICENSE file at https://angular.dev/license\n';
export const CSS_TS_COPYRIGHT = `/*\n${COPYRIGHT}\n*/${PAD}`;
export const HTML_COPYRIGHT = `<!-- \n${COPYRIGHT}\n-->${PAD}`;
// Exclude
export const EXCLUDE_FILES_FOR_STACKBLITZ = [
STACKBLITZ_CONFIG_FILENAME,
BUILD_BAZEL_FILENAME,
EXAMPLE_CONFIG_FILENAME,
TEST_FILES_EXTENSION_SUFFIX,
TEST_FILES_E2E_EXTENSION_SUFFIX,
];
-77
View File
@@ -1,77 +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 {Dirent, existsSync, readdirSync} from 'fs';
import {copyFile, mkdir, readFile, readdir, rm, stat} from 'fs/promises';
import {join, relative} from 'path';
export async function copyFolder(source: string, destination: string) {
if (!existsSync(destination)) {
await mkdir(destination, {recursive: true});
}
const files = await readdir(source);
for (const file of files) {
const sourcePath = join(source, file);
const destPath = join(destination, file);
const stats = await stat(sourcePath);
const isDirectory = await stats.isDirectory();
if (isDirectory) {
await copyFolder(sourcePath, destPath);
} else {
await copyFile(sourcePath, destPath);
}
}
}
/** Recursively search the provided directory for all files which satisfy predicate and asynchronously load them. */
export function retrieveFiles(
baseDir: string,
predicate?: (file: Dirent) => boolean,
): Promise<{path: string; content: string}[]> {
const filesWithContent: Promise<{path: string; content: string}>[] = [];
const checkFilesInDirectory = (dir: string) => {
const files = readdirSync(dir, {withFileTypes: true});
for (const file of files) {
const fullPathToFile = join(dir, file.name);
if (file.isFile() && (predicate ? predicate(file) : true)) {
filesWithContent.push(
readFile(fullPathToFile, {encoding: 'utf-8'}).then((fileContent) => {
return {
path: relative(baseDir, fullPathToFile),
content: fileContent,
};
}),
);
} else if (file.isDirectory()) {
checkFilesInDirectory(fullPathToFile);
}
}
};
checkFilesInDirectory(baseDir);
return Promise.all(filesWithContent);
}
export async function createFolder(path: string): Promise<void> {
if (!existsSync(path)) {
await mkdir(path, {recursive: true});
}
}
export async function removeFolder(path: string): Promise<void> {
if (existsSync(path)) {
await rm(path, {recursive: true});
}
}
-30
View File
@@ -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="adev-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>
-86
View File
@@ -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(.adev-nav-secondary--open),
&:has(.adev-nav-primary--open) {
.adev-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);
}
}
.adev-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;
}
-37
View File
@@ -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();
});
});
-125
View File
@@ -1,125 +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);
});
}
}
-24
View File
@@ -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);
-97
View File
@@ -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';

Some files were not shown because too many files have changed in this diff Show More