From 676ce573844bd018489b9a849f4e015a09e5a8e8 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Thu, 16 Jan 2025 14:40:16 +0000 Subject: [PATCH] build: ensure package substitutions work with pnpm `workspace:*` links We'll be using `workspace:*` protocol links to link first-party packages together in the pnpm workspace. For this reason, we need to make sure they are properly replaced in `package.json` files, before packaging. --- tools/bazel/npm_package.bzl | 10 +++++----- tools/defaults.bzl | 10 +++++----- tools/package_json_release_filter.jq | 5 +++++ tools/substitutions.bzl | 20 ++++++++++++++++---- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/tools/bazel/npm_package.bzl b/tools/bazel/npm_package.bzl index 137f629e5981..927609e17d63 100644 --- a/tools/bazel/npm_package.bzl +++ b/tools/bazel/npm_package.bzl @@ -6,7 +6,7 @@ load("@aspect_rules_js//npm:defs.bzl", _npm_package = "npm_package") load("@rules_pkg//:pkg.bzl", "pkg_tar") load("//tools:link_package_json_to_tarballs.bzl", "link_package_json_to_tarballs") load("//tools:snapshot_repo_filter.bzl", "SNAPSHOT_REPO_JQ_FILTER") -load("//tools:substitutions.bzl", "NO_STAMP_PACKAGE_SUBSTITUTIONS", "get_npm_package_substitutions_for_rjs") +load("//tools:substitutions.bzl", "substitutions") def npm_package( name, @@ -71,8 +71,8 @@ def npm_package( "//conditions:default": "substituted/package.json", }), out = "substituted_final/package.json", - substitutions = NO_STAMP_PACKAGE_SUBSTITUTIONS, - stamp_substitutions = get_npm_package_substitutions_for_rjs(), + substitutions = substitutions["rjs"]["nostamp"], + stamp_substitutions = substitutions["rjs"]["stamp"], ) stamp_targets = [] @@ -81,8 +81,8 @@ def npm_package( name = "stamp_file_%s" % f, template = f, out = "substituted/%s" % f, - substitutions = NO_STAMP_PACKAGE_SUBSTITUTIONS, - stamp_substitutions = get_npm_package_substitutions_for_rjs(), + substitutions = substitutions["rjs"]["nostamp"], + stamp_substitutions = substitutions["rjs"]["stamp"], ) stamp_targets.append("stamp_file_%s" % f) diff --git a/tools/defaults.bzl b/tools/defaults.bzl index e7e64c2a3e4d..a642782bd39a 100644 --- a/tools/defaults.bzl +++ b/tools/defaults.bzl @@ -10,7 +10,7 @@ load("@npm//@angular/build-tooling/bazel:extract_js_module_output.bzl", "extract load("@rules_pkg//:pkg.bzl", "pkg_tar") load("//tools:link_package_json_to_tarballs.bzl", "link_package_json_to_tarballs") load("//tools:snapshot_repo_filter.bzl", "SNAPSHOT_REPO_JQ_FILTER") -load("//tools:substitutions.bzl", "NO_STAMP_PACKAGE_SUBSTITUTIONS", "NPM_PACKAGE_SUBSTITUTIONS") +load("//tools:substitutions.bzl", "substitutions") _DEFAULT_TSCONFIG_NG = "//:tsconfig-build-ng" _DEFAULT_TSCONFIG_TEST = "//:tsconfig-test.json" @@ -159,8 +159,8 @@ def pkg_npm(name, pkg_deps = [], use_prodmode_output = False, **kwargs): package_name = None, validate = False, substitutions = select({ - "//:stamp": NPM_PACKAGE_SUBSTITUTIONS, - "//conditions:default": NO_STAMP_PACKAGE_SUBSTITUTIONS, + "//:stamp": substitutions["legacy"]["stamp"], + "//conditions:default": substitutions["legacy"]["nostamp"], }), visibility = visibility, nested_packages = nested_packages, @@ -221,8 +221,8 @@ def ng_package(deps = [], **kwargs): deps = deps, license = "//:LICENSE", substitutions = select({ - "//:stamp": NPM_PACKAGE_SUBSTITUTIONS, - "//conditions:default": NO_STAMP_PACKAGE_SUBSTITUTIONS, + "//:stamp": substitutions["legacy"]["stamp"], + "//conditions:default": substitutions["legacy"]["nostamp"], }), **kwargs ) diff --git a/tools/package_json_release_filter.jq b/tools/package_json_release_filter.jq index 279a16102e01..4b5a0eb20c62 100644 --- a/tools/package_json_release_filter.jq +++ b/tools/package_json_release_filter.jq @@ -30,3 +30,8 @@ # Add engines; versions substituted via pkg_npm + {"engines": {"node": "0.0.0-ENGINES-NODE", "npm": "0.0.0-ENGINES-NPM", "yarn": "0.0.0-ENGINES-YARN"}} + +# Remove all `workspace:` pnpm prefixes. Afterwards we can conveniently rely on +# substitutions from the stamp values. Note that we are doing it this way because +# substitutions can apply to multiple files, and `workspace:` can't be reliably replaced. +| walk(if type == "string" and startswith("workspace:") then sub("workspace:"; "") else . end) diff --git a/tools/substitutions.bzl b/tools/substitutions.bzl index 4b8b9c79c0af..9ecf21fdb245 100644 --- a/tools/substitutions.bzl +++ b/tools/substitutions.bzl @@ -1,9 +1,10 @@ load("//:constants.bzl", "RELEASE_ENGINES_NODE", "RELEASE_ENGINES_NPM", "RELEASE_ENGINES_YARN") -NPM_PACKAGE_SUBSTITUTIONS = { +_stamp_substitutions = { # Version of the local package being built, generated via the `--workspace_status_command` flag. "0.0.0-PLACEHOLDER": "{STABLE_PROJECT_VERSION}", "0.0.0-EXPERIMENTAL-PLACEHOLDER": "{STABLE_PROJECT_EXPERIMENTAL_VERSION}", + # --- "BUILD_SCM_HASH-PLACEHOLDER": "{BUILD_SCM_ABBREV_HASH}", "0.0.0-ENGINES-NODE": RELEASE_ENGINES_NODE, "0.0.0-ENGINES-NPM": RELEASE_ENGINES_NPM, @@ -12,15 +13,26 @@ NPM_PACKAGE_SUBSTITUTIONS = { "\\./(.+)/packages/angular/ssr/third_party/beasties": "../third_party/beasties/index.js", } -NO_STAMP_PACKAGE_SUBSTITUTIONS = dict(NPM_PACKAGE_SUBSTITUTIONS, **{ +_no_stamp_substitutions = dict(_stamp_substitutions, **{ "0.0.0-PLACEHOLDER": "0.0.0", "0.0.0-EXPERIMENTAL-PLACEHOLDER": "0.0.0", }) -def get_npm_package_substitutions_for_rjs(): +def _adjust_substitutions_for_rules_js(subs): result = {} - for key, value in NPM_PACKAGE_SUBSTITUTIONS.items(): + for key, value in subs.items(): # in `rules_js`, or `expand_template` from `bazel-lib`, stamp variables # can only be retrieved via `{{X}}` syntax. result[key] = value.replace("{", "{{").replace("}", "}}") return result + +substitutions = { + "legacy": { + "stamp": _stamp_substitutions, + "nostamp": _no_stamp_substitutions, + }, + "rjs": { + "stamp": _adjust_substitutions_for_rules_js(_stamp_substitutions), + "nostamp": _adjust_substitutions_for_rules_js(_no_stamp_substitutions), + }, +}