Skip to content

Commit 43716d3

Browse files
committed
fix(builtin): make .pack and .publish targets work again
fixes #1493
1 parent 0ef5d82 commit 43716d3

4 files changed

Lines changed: 131 additions & 119 deletions

File tree

.bazelci/presubmit.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ tasks:
66
platform: ubuntu1604
77
run_targets:
88
- "@nodejs//:yarn_node_repositories"
9+
# Regression test for #1493
10+
- "//packages/create:npm_package.pack"
911
- "//internal/node/test:no_deps"
1012
- "//internal/node/test:has_deps_legacy"
1113
- "//internal/node/test:has_deps"
@@ -198,6 +200,8 @@ tasks:
198200
platform: macos
199201
run_targets:
200202
- "@nodejs//:yarn_node_repositories"
203+
# Regression test for #1493
204+
- "//packages/create:npm_package.pack"
201205
- "//internal/node/test:no_deps"
202206
- "//internal/node/test:has_deps_legacy"
203207
- "//internal/node/test:has_deps"

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ readonly PKG_NPM_LABELS=`$BAZEL query --output=label 'kind("pkg_npm", //...)'`
179179
$BAZEL build --config=release $PKG_NPM_LABELS
180180
# publish one package at a time to make it easier to spot any errors or warnings
181181
for pkg in $PKG_NPM_LABELS ; do
182-
$BAZEL run -- ${pkg}.${NPM_COMMAND} --access public --tag latest
182+
$BAZEL run --config=release -- ${pkg}.${NPM_COMMAND} --access public --tag latest
183183
done
184184
```
185185

internal/pkg_npm/packager.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,8 @@ function main(args) {
177177
}
178178

179179
const npmTemplate = fs.readFileSync(require.resolve(runNpmTemplatePath), {encoding: 'utf-8'});
180-
// Resolve the outDir to an absolute path so it doesn't depend on Bazel's bazel-out symlink
181-
fs.writeFileSync(packPath, npmTemplate.replace('TMPL_args', `pack "${path.resolve(outDir)}"`));
182-
fs.writeFileSync(
183-
publishPath, npmTemplate.replace('TMPL_args', `publish "${path.resolve(outDir)}"`));
180+
fs.writeFileSync(packPath, npmTemplate.replace('TMPL_args', `pack "${outDir}"`));
181+
fs.writeFileSync(publishPath, npmTemplate.replace('TMPL_args', `publish "${outDir}"`));
184182
}
185183

186184
if (require.main === module) {

internal/pkg_npm/pkg_npm.bzl

Lines changed: 124 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,129 @@ to the `deps` of one of their targets.
99
load("//:providers.bzl", "DeclarationInfo", "JSNamedModuleInfo", "NodeContextInfo")
1010
load("//internal/common:path_utils.bzl", "strip_external")
1111

12+
_DOC = """The pkg_npm rule creates a directory containing a publishable npm artifact.
13+
14+
Example:
15+
16+
```python
17+
load("@build_bazel_rules_nodejs//:index.bzl", "pkg_npm")
18+
19+
pkg_npm(
20+
name = "my_package",
21+
srcs = ["package.json"],
22+
deps = [":my_typescript_lib"],
23+
substitutions = {"//internal/": "//"},
24+
)
25+
```
26+
27+
You can use a pair of `// BEGIN-INTERNAL ... // END-INTERNAL` comments to mark regions of files that should be elided during publishing.
28+
For example:
29+
30+
```javascript
31+
function doThing() {
32+
// BEGIN-INTERNAL
33+
// This is a secret internal-only comment
34+
doInternalOnlyThing();
35+
// END-INTERNAL
36+
}
37+
```
38+
39+
With the Bazel stamping feature, pkg_npm will replace any placeholder version in your package with the actual version control tag.
40+
See the [stamping documentation](https://github.com/bazelbuild/rules_nodejs/blob/master/docs/index.md#stamping)
41+
42+
Usage:
43+
44+
`pkg_npm` yields three labels. Build the package directory using the default label:
45+
46+
```sh
47+
$ bazel build :my_package
48+
Target //:my_package up-to-date:
49+
bazel-out/fastbuild/bin/my_package
50+
$ ls -R bazel-out/fastbuild/bin/my_package
51+
```
52+
53+
Dry-run of publishing to npm, calling `npm pack` (it builds the package first if needed):
54+
55+
```sh
56+
$ bazel run :my_package.pack
57+
INFO: Running command line: bazel-out/fastbuild/bin/my_package.pack
58+
my-package-name-1.2.3.tgz
59+
$ tar -tzf my-package-name-1.2.3.tgz
60+
```
61+
62+
Actually publish the package with `npm publish` (also builds first):
63+
64+
```sh
65+
# Check login credentials
66+
$ bazel run @nodejs//:npm_node_repositories who
67+
# Publishes the package
68+
$ bazel run :my_package.publish
69+
```
70+
71+
> Note that the `.pack` and `.publish` commands require that the `bazel-out` symlink exists in your project.
72+
> Also, you must run the command from the workspace root directory containing the `bazel-out` symlink.
73+
74+
You can pass arguments to npm by escaping them from Bazel using a double-hyphen, for example:
75+
76+
`bazel run my_package.publish -- --tag=next`
77+
"""
78+
79+
PKG_NPM_ATTRS = {
80+
"srcs": attr.label_list(
81+
doc = """Files inside this directory which are simply copied into the package.""",
82+
allow_files = True,
83+
),
84+
"hide_build_files": attr.bool(
85+
doc = """If set BUILD and BUILD.bazel files are prefixed with `_` in the npm package.
86+
The default is True since npm packages that contain BUILD files don't work with
87+
`yarn_install` and `npm_install` without a post-install step that deletes or renames them.
88+
89+
NB: Bazel has a change in https://github.com/bazelbuild/bazel/pull/10261
90+
(expected in version 2.1) that adds .bazelignore
91+
support for external repositories, which will make this attribute obsolete.""",
92+
default = True,
93+
),
94+
"nested_packages": attr.label_list(
95+
doc = """Other pkg_npm rules whose content is copied into this package.""",
96+
allow_files = True,
97+
),
98+
"node_context_data": attr.label(
99+
default = "@build_bazel_rules_nodejs//internal:node_context_data",
100+
providers = [NodeContextInfo],
101+
doc = "Internal use only",
102+
),
103+
"replace_with_version": attr.string(
104+
doc = """If set this value is replaced with the version stamp data.
105+
See the section on stamping in the README.""",
106+
default = "0.0.0-PLACEHOLDER",
107+
),
108+
"substitutions": attr.string_dict(
109+
doc = """Key-value pairs which are replaced in all the files while building the package.""",
110+
),
111+
"vendor_external": attr.string_list(
112+
doc = """External workspaces whose contents should be vendored into this workspace.
113+
Avoids 'external/foo' path segments in the resulting package.""",
114+
),
115+
"deps": attr.label_list(
116+
doc = """Other targets which produce files that should be included in the package, such as `rollup_bundle`""",
117+
allow_files = True,
118+
),
119+
"_packager": attr.label(
120+
default = Label("//internal/pkg_npm:packager"),
121+
cfg = "host",
122+
executable = True,
123+
),
124+
"_run_npm_template": attr.label(
125+
default = Label("@nodejs//:run_npm.sh.template"),
126+
allow_single_file = True,
127+
),
128+
}
129+
130+
PKG_NPM_OUTPUTS = {
131+
"pack": "%{name}.pack",
132+
"publish": "%{name}.publish",
133+
}
134+
12135
# Takes a depset of files and returns a corresponding list of file paths without any files
13136
# that aren't part of the specified package path. Also include files from external repositories
14137
# that explicitly specified in the vendor_external list.
@@ -118,122 +241,9 @@ def _pkg_npm(ctx):
118241
runfiles = ctx.runfiles([package_dir]),
119242
)]
120243

121-
PKG_NPM_ATTRS = {
122-
"srcs": attr.label_list(
123-
doc = """Files inside this directory which are simply copied into the package.""",
124-
allow_files = True,
125-
),
126-
"hide_build_files": attr.bool(
127-
doc = """If set BUILD and BUILD.bazel files are prefixed with `_` in the npm package.
128-
The default is True since npm packages that contain BUILD files don't work with
129-
`yarn_install` and `npm_install` without a post-install step that deletes or renames them.
130-
131-
NB: Bazel has a change in https://github.com/bazelbuild/bazel/pull/10261
132-
(expected in version 2.1) that adds .bazelignore
133-
support for external repositories, which will make this attribute obsolete.""",
134-
default = True,
135-
),
136-
"nested_packages": attr.label_list(
137-
doc = """Other pkg_npm rules whose content is copied into this package.""",
138-
allow_files = True,
139-
),
140-
"node_context_data": attr.label(
141-
default = "@build_bazel_rules_nodejs//internal:node_context_data",
142-
providers = [NodeContextInfo],
143-
doc = "Internal use only",
144-
),
145-
"replace_with_version": attr.string(
146-
doc = """If set this value is replaced with the version stamp data.
147-
See the section on stamping in the README.""",
148-
default = "0.0.0-PLACEHOLDER",
149-
),
150-
"substitutions": attr.string_dict(
151-
doc = """Key-value pairs which are replaced in all the files while building the package.""",
152-
),
153-
"vendor_external": attr.string_list(
154-
doc = """External workspaces whose contents should be vendored into this workspace.
155-
Avoids 'external/foo' path segments in the resulting package.""",
156-
),
157-
"deps": attr.label_list(
158-
doc = """Other targets which produce files that should be included in the package, such as `rollup_bundle`""",
159-
allow_files = True,
160-
),
161-
"_packager": attr.label(
162-
default = Label("//internal/pkg_npm:packager"),
163-
cfg = "host",
164-
executable = True,
165-
),
166-
"_run_npm_template": attr.label(
167-
default = Label("@nodejs//:run_npm.sh.template"),
168-
allow_single_file = True,
169-
),
170-
}
171-
172-
PKG_NPM_OUTPUTS = {
173-
"pack": "%{name}.pack",
174-
"publish": "%{name}.publish",
175-
}
176-
177244
pkg_npm = rule(
178245
implementation = _pkg_npm,
179246
attrs = PKG_NPM_ATTRS,
180-
doc = """The pkg_npm rule creates a directory containing a publishable npm artifact.
181-
182-
Example:
183-
184-
```python
185-
load("@build_bazel_rules_nodejs//:index.bzl", "pkg_npm")
186-
187-
pkg_npm(
188-
name = "my_package",
189-
srcs = ["package.json"],
190-
deps = [":my_typescript_lib"],
191-
substitutions = {"//internal/": "//"},
192-
)
193-
```
194-
195-
You can use a pair of `// BEGIN-INTERNAL ... // END-INTERNAL` comments to mark regions of files that should be elided during publishing.
196-
For example:
197-
198-
```javascript
199-
function doThing() {
200-
// BEGIN-INTERNAL
201-
// This is a secret internal-only comment
202-
doInternalOnlyThing();
203-
// END-INTERNAL
204-
}
205-
```
206-
207-
Usage:
208-
209-
`pkg_npm` yields three labels. Build the package directory using the default label:
210-
211-
```sh
212-
$ bazel build :my_package
213-
Target //:my_package up-to-date:
214-
bazel-out/fastbuild/bin/my_package
215-
$ ls -R bazel-out/fastbuild/bin/my_package
216-
```
217-
218-
Dry-run of publishing to npm, calling `npm pack` (it builds the package first if needed):
219-
220-
```sh
221-
$ bazel run :my_package.pack
222-
INFO: Running command line: bazel-out/fastbuild/bin/my_package.pack
223-
my-package-name-1.2.3.tgz
224-
$ tar -tzf my-package-name-1.2.3.tgz
225-
```
226-
227-
Actually publish the package with `npm publish` (also builds first):
228-
229-
```sh
230-
# Check login credentials
231-
$ bazel run @nodejs//:npm_node_repositories who
232-
# Publishes the package
233-
$ bazel run :my_package.publish
234-
```
235-
236-
You can pass arguments to npm by escaping them from Bazel using a double-hyphen `bazel run my_package.publish -- --tag=next`
237-
""",
247+
doc = _DOC,
238248
outputs = PKG_NPM_OUTPUTS,
239249
)

0 commit comments

Comments
 (0)