Skip to content

Commit 4256a4d

Browse files
lantrixsamchungy
andauthored
Scoped registry (#9)
* Add custom scope * Lint README * Fix up workflow and docker compose * Lint * Quiet docker output * proper quiet for pull * Fix BATS * Lint * Add tests * Update README.md * Change scope URL * Add always-auth for legacy managers * Protocol-Relative URL info * Bump version --------- Co-authored-by: Sam Chung <samchungy@gmail.com>
1 parent ef8c8c3 commit 4256a4d

File tree

6 files changed

+92
-33
lines changed

6 files changed

+92
-33
lines changed

.github/workflows/main.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ jobs:
44
test:
55
runs-on: ubuntu-latest
66
steps:
7-
- uses: actions/checkout@v2
7+
- uses: actions/checkout@v4
88
- name: Lint
9-
run: docker-compose run lint
9+
run: docker compose run --quiet-pull lint
1010
- name: Tests
11-
run: docker-compose run tests
11+
run: docker compose run --quiet-pull tests

README.md

+37-21
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fseek-oss%2Fprivate-npm-buildkite-plugin%2Fbadge&style=flat)](https://actions-badge.atrox.dev/seek-oss/private-npm-buildkite-plugin/goto)
44
[![GitHub Release](https://img.shields.io/github/release/seek-oss/private-npm-buildkite-plugin.svg)](https://github.com/seek-oss/private-npm-buildkite-plugin/releases)
55

6-
76
A [Buildkite plugin](https://buildkite.com/docs/agent/v3/plugins) to allow pipeline steps to easily install
87
private packages from an [npm](https://www.npmjs.com) repository.
98

@@ -17,7 +16,7 @@ To read the value from an environment variable named `MY_TOKEN` when the plugin
1716
steps:
1817
- command: yarn install
1918
plugins:
20-
- seek-oss/private-npm#v1.2.0:
19+
- seek-oss/private-npm#v1.3.0:
2120
env: "MY_TOKEN"
2221
```
2322
@@ -27,77 +26,94 @@ To read the value from a file named `my_token_file`, use the `file` field.
2726
steps:
2827
- command: yarn install
2928
plugins:
30-
- seek-oss/private-npm#v1.2.0:
29+
- seek-oss/private-npm#v1.3.0:
3130
file: "my_token_file"
3231
```
3332

34-
Alternatively you can read the token directly from any value exposed to your `pipeline.yml` file. However, this
35-
approach is discouraged in favour of using with the `env` or `file` fields. This functionality remains in the interest
36-
of backwards compatibility.
33+
Alternatively you can read the token directly from any value exposed to your `pipeline.yml` file. However, this
34+
approach is discouraged in favour of using with the `env` or `file` fields. This functionality remains in the interest
35+
of backwards compatibility.
3736

3837
```yml
3938
steps:
4039
- command: yarn install
4140
plugins:
42-
- seek-oss/private-npm#v1.2.0:
41+
- seek-oss/private-npm#v1.3.0:
4342
token: ${MY_TOKEN}
4443
```
4544

46-
4745
You can also specify a custom npm registry if you are using your own mirror.
4846

4947
```yml
5048
steps:
5149
- command: yarn install
5250
plugins:
53-
- seek-oss/private-npm#v1.2.0:
51+
- seek-oss/private-npm#v1.3.0:
5452
env: "MY_TOKEN"
5553
registry: //myprivatenpm.com/
5654
```
5755

56+
If you set a registry, you can configure a specific scope to fetch packages from your custom registry.
57+
In this case, use only Protocol-Relative URL for `registry` as `https://` will be prepended in the
58+
scope in the `.npmrc` for you.
59+
60+
```yml
61+
steps:
62+
- command: yarn install
63+
plugins:
64+
- seek-oss/private-npm#v1.3.0:
65+
env: "MY_TOKEN"
66+
registry: //myprivatenpm.com/
67+
scope: "@myprivatescope"
68+
```
69+
5870
## Configuration
5971

60-
> **NOTE** Even thought `env`, `file` and `token` are described as optional, _at least one must be set_ or the plugin
72+
> **NOTE** Even thought `env`, `file` and `token` are described as optional, _at least one must be set_ or the plugin
6173
> will fail.
6274

6375
### `env` (optional)
6476

65-
The value of the NPM token will be read from the agent environment when the plugin executes. This is useful in working
66-
around cases where eager binding of variables in `pipeline.yml` means some variables are not present in the
77+
The value of the NPM token will be read from the agent environment when the plugin executes. This is useful in working
78+
around cases where eager binding of variables in `pipeline.yml` means some variables are not present in the
6779
environment when the configuration file is parsed.
6880

6981
> **NOTE** : Beware of using `NPM_TOKEN` as the name for the environment variable. When using that name the variable
7082
> is unstable and has a tedency to return an empty string in the context of this plugin.
7183

7284
### `file` (optional)
7385

74-
The value of the NPM token will be read from a file on the agent when the plugin executes. This is useful when working
86+
The value of the NPM token will be read from a file on the agent when the plugin executes. This is useful when working
7587
with secret that are created as files on the filesystem when a build is initiated.
7688

7789
### `token` (optional)
7890

79-
The value of the NPM token will be read from a variable which is available to the Buildkite YAML parsing context.
80-
This value is interpolated when the YAML configuration is parsed by the Buildgent agent and provided to the plugin "as
91+
The value of the NPM token will be read from a variable which is available to the Buildkite YAML parsing context.
92+
This value is interpolated when the YAML configuration is parsed by the Buildgent agent and provided to the plugin "as
8193
is".
8294

8395
Example: `${MY_TOKEN}`
84-
> **NOTE:** Don't put your tokens into source control. Don't use web interfaces you don't control to inject them into
85-
> your environment either. Rather use a Secrets Manager. If you are an AWS user, perhaps consider the
96+
97+
> **NOTE:** Don't put your tokens into source control. Don't use web interfaces you don't control to inject them into
98+
> your environment either. Rather use a Secrets Manager. If you are an AWS user, perhaps consider the
8699
> [aws-sm-buildkite-plugin](https://github.com/seek-oss/aws-sm-buildkite-plugin) which works well with this plugin.
87100

88-
> **NOTE:** There is anecdotal evidence to suggest that using `NPM_TOKEN` as the variable name containing the
89-
> token can intermittently cause the token to become empty. It is advised to use a different name as has been done in
101+
> **NOTE:** There is anecdotal evidence to suggest that using `NPM_TOKEN` as the variable name containing the
102+
> token can intermittently cause the token to become empty. It is advised to use a different name as has been done in
90103
> these docs.
91104

92105
### `registry` (optional)
93-
The path to a private npm repository. Please ensure you supply the trailing `/`!
106+
107+
The path to a private npm repository. Please ensure you supply the trailing `/`!
94108

95109
Example: `//myprivatenpm.com/`
96110

97111
### `output-path` (optional)
98-
The path to the .npmrc that will be created. Please ensure you supply the trailing `/`!
112+
113+
The path to the .npmrc that will be created. Please ensure you supply the trailing `/`!
99114

100115
Example: `./project/path/`
101116

102117
## License
118+
103119
MIT (see [LICENSE](./LICENSE))

docker-compose.yml

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
version: '3.4'
21
services:
32
tests:
43
image: buildkite/plugin-tester
54
volumes:
65
- ".:/plugin"
76
lint:
87
image: buildkite/plugin-linter
9-
command: ['--name', 'seek-oss/private-npm']
8+
command: ["--name", "seek-oss/private-npm"]
109
volumes:
11-
- ".:/plugin:ro"
10+
- ".:/plugin:ro"

hooks/pre-command

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set -euo pipefail
33
IFS=$'\n\t'
44

55
SEEK_OSS_PRIVATE_NPM_REGISTRY=${BUILDKITE_PLUGIN_PRIVATE_NPM_REGISTRY:-'//registry.npmjs.org/'}
6+
SEEK_OSS_PRIVATE_NPM_SCOPE=${BUILDKITE_PLUGIN_PRIVATE_NPM_SCOPE:-''}
67
SEEK_OSS_PRIVATE_NPM_TOKEN=${BUILDKITE_PLUGIN_PRIVATE_NPM_TOKEN:-''}
78
SEEK_OSS_PRIVATE_NPM_FILE=${BUILDKITE_PLUGIN_PRIVATE_NPM_FILE:-''}
89
SEEK_OSS_PRIVATE_NPM_ENV=${BUILDKITE_PLUGIN_PRIVATE_NPM_ENV:-''}
@@ -18,13 +19,14 @@ fi
1819

1920
if [[ -n "${SEEK_OSS_PRIVATE_NPM_FILE}" ]]
2021
then
22+
2123
SEEK_OSS_PRIVATE_NPM_TOKEN=$(cat "${SEEK_OSS_PRIVATE_NPM_FILE}")
2224
elif [[ -n "${SEEK_OSS_PRIVATE_NPM_ENV}" ]]
2325
then
2426
SEEK_OSS_PRIVATE_NPM_TOKEN="${!SEEK_OSS_PRIVATE_NPM_ENV}"
2527
fi
2628

27-
if [[ -z $SEEK_OSS_PRIVATE_NPM_TOKEN ]]
29+
if [[ -z $SEEK_OSS_PRIVATE_NPM_TOKEN ]]
2830
then
2931
echo ':no_entry_sign: :npm: :package: Failed! A valid NPM_TOKEN could not be determined'
3032
exit 1
@@ -38,3 +40,10 @@ mkdir -p "${OUTPUT_FILE%/*}" && cat > $OUTPUT_FILE << EOF
3840
${SEEK_OSS_PRIVATE_NPM_REGISTRY}:_authToken=${SEEK_OSS_PRIVATE_NPM_TOKEN}
3941
save-exact=true
4042
EOF
43+
if [[ -n "${SEEK_OSS_PRIVATE_NPM_SCOPE}" ]]
44+
then
45+
cat >> $OUTPUT_FILE << EOF
46+
always-auth=true
47+
${SEEK_OSS_PRIVATE_NPM_SCOPE}:registry=https:${SEEK_OSS_PRIVATE_NPM_REGISTRY}
48+
EOF
49+
fi

plugin.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ configuration:
88
properties:
99
registry:
1010
type: string
11+
scope:
12+
type: string
1113
token:
1214
type: string
1315
env:
@@ -16,4 +18,3 @@ configuration:
1618
type: string
1719
output-path:
1820
type: string
19-

tests/pre-command.bats

+38-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
#!/usr/bin/env bats
22

3-
load "$BATS_PATH/load.bash"
3+
setup() {
4+
load "$BATS_PLUGIN_PATH/load.bash"
5+
6+
# Uncomment to enable stub debugging
7+
# export GIT_STUB_DEBUG=/dev/tty
8+
}
9+
410
teardown() {
511
rm -f .npmrc
612
rm -f ./tests/path/to/project/.npmrc
@@ -24,6 +30,7 @@ teardown() {
2430
assert_equal "$(head -n1 .npmrc)" '//registry.npmjs.org/:_authToken=abc123'
2531
}
2632

33+
2734
@test "reads the token from a file if the file parameter is used" {
2835
export BUILDKITE_PLUGIN_PRIVATE_NPM_FILE='my_token_file'
2936
echo 'abc123' > my_token_file
@@ -32,7 +39,7 @@ teardown() {
3239

3340
assert_success
3441
assert [ -e '.npmrc' ]
35-
assert_equal "$(head -n1 .npmrc)" '//registry.npmjs.org/:_authToken=abc123'
42+
assert_equal "$(head -n1 .npmrc)" '//registry.npmjs.org/:_authToken=abc123'
3643
}
3744

3845
@test "fails if the file parameter is used but no file exists" {
@@ -117,6 +124,33 @@ teardown() {
117124
assert_equal "$(head -n1 .npmrc)" '//myprivateregistry.org/:_authToken=abc123'
118125
}
119126

127+
@test "creates a npmrc file with supplied scoped registry path and env" {
128+
export BUILDKITE_PLUGIN_PRIVATE_NPM_ENV='MY_ENV_VAR'
129+
export MY_ENV_VAR='abc123'
130+
export BUILDKITE_PLUGIN_PRIVATE_NPM_REGISTRY='//myprivateregistry.org/'
131+
export BUILDKITE_PLUGIN_PRIVATE_NPM_SCOPE='@myprivatescope'
132+
133+
run $PWD/hooks/pre-command
134+
135+
assert_success
136+
assert [ -e '.npmrc' ]
137+
assert_equal "$(head -n1 .npmrc)" '//myprivateregistry.org/:_authToken=abc123'
138+
assert_equal "$(tail -n1 .npmrc)" '@myprivatescope:registry=https://myprivateregistry.org/'
139+
}
140+
141+
@test "creates a npmrc file with supplied scoped and default registry path and env" {
142+
export BUILDKITE_PLUGIN_PRIVATE_NPM_ENV='MY_ENV_VAR'
143+
export MY_ENV_VAR='abc123'
144+
export BUILDKITE_PLUGIN_PRIVATE_NPM_SCOPE='@myprivatescope'
145+
146+
run $PWD/hooks/pre-command
147+
148+
assert_success
149+
assert [ -e '.npmrc' ]
150+
assert_equal "$(head -n1 .npmrc)" '//registry.npmjs.org/:_authToken=abc123'
151+
assert_equal "$(tail -n1 .npmrc)" '@myprivatescope:registry=https://registry.npmjs.org/'
152+
}
153+
120154
@test "creates a npmrc file with supplied output path and token" {
121155
export BUILDKITE_PLUGIN_PRIVATE_NPM_TOKEN='abc123'
122156
export BUILDKITE_PLUGIN_PRIVATE_NPM_OUTPUT_PATH='./tests/path/to/project/'
@@ -135,7 +169,7 @@ teardown() {
135169
refute [ -e '.npmrc' ]
136170
}
137171

138-
# There is an exclusive relationship between file, env, and token. These tests ensure only value is set and fail with
172+
# There is an exclusive relationship between file, env, and token. These tests ensure only value is set and fail with
139173
# a meaninful message otherwise
140174
@test "fails if env and file are both set" {
141175
export BUILDKITE_PLUGIN_PRIVATE_NPM_FILE='my_token_file'
@@ -180,4 +214,4 @@ teardown() {
180214
assert_failure
181215
assert_output ':no_entry_sign: :npm: :package: Failed! Only one of file, env or token parameters may be set'
182216
refute [ -e '.npmrc' ]
183-
}
217+
}

0 commit comments

Comments
 (0)