Skip to content

Commit 3ee021c

Browse files
authored
Add end-to-end test suite (#80)
1 parent d6a8488 commit 3ee021c

File tree

11 files changed

+280
-28
lines changed

11 files changed

+280
-28
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
dist
22
lib
3+
coverage

.github/actions/setup/action.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Set up Node.js
2+
description: Install Node.js and development dependencies
3+
4+
inputs:
5+
node-version:
6+
description: Node.js version to install
7+
default: "18"
8+
install-command:
9+
description: Install command to run
10+
default: npm ci
11+
12+
runs:
13+
using: "composite"
14+
steps:
15+
- name: "Install Node.js"
16+
uses: actions/setup-node@v3
17+
with:
18+
node-version: ${{ inputs.node-version }}
19+
cache: npm
20+
21+
- name: "Install development dependencies"
22+
shell: bash
23+
run: ${{ inputs.install-command }}

.github/workflows/ci-cd.yml

Lines changed: 133 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
# GitHub Actions workflow
2-
# https://help.github.com/en/actions/automating-your-workflow-with-github-actions
3-
# https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions
4-
# https://help.github.com/en/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions
5-
61
name: CI-CD
72

83
on:
@@ -12,12 +7,28 @@ on:
127
tags-ignore:
138
- "*"
149

10+
# run CI every Monday at 12:25 UTC
1511
schedule:
16-
- cron: "0 0 1 * *"
12+
- cron: "25 12 * * 1"
1713

1814
jobs:
15+
lint:
16+
name: Lint
17+
runs-on: ubuntu-latest
18+
timeout-minutes: 10
19+
20+
steps:
21+
- name: Checkout source
22+
uses: actions/checkout@v3
23+
24+
- name: Install Node.js and dependencies
25+
uses: ./.github/actions/setup
26+
27+
- name: Run linters
28+
run: npm run lint
29+
1930
test:
20-
name: Node ${{ matrix.node }} on ${{ matrix.os }}
31+
name: Run tests using Node ${{ matrix.node }} on ${{ matrix.os }}
2132
runs-on: ${{ matrix.os }}
2233
timeout-minutes: 10
2334
strategy:
@@ -36,25 +47,19 @@ jobs:
3647
- name: Checkout source
3748
uses: actions/checkout@v3
3849

39-
- name: Install Node ${{ matrix.node }}
40-
uses: actions/setup-node@v3
50+
- name: Install Node.js ${{ matrix.node }} and dependencies
51+
uses: ./.github/actions/setup
4152
with:
4253
node-version: ${{ matrix.node }}
4354

44-
- name: Install dependencies
45-
run: npm ci
46-
47-
- name: Run linters
48-
run: npm run lint
49-
5055
- name: Build the code
5156
run: npm run build
5257

5358
- name: Run tests
5459
run: npm run coverage
5560

5661
- name: Send code coverage results to Coveralls
57-
uses: coverallsapp/github-action@v1.1.0
62+
uses: coverallsapp/github-action@045a25193560dc194e405657f552faeb6b9433aa
5863
with:
5964
github-token: ${{ secrets.GITHUB_TOKEN }}
6065
parallel: true
@@ -66,31 +71,132 @@ jobs:
6671
needs: test
6772
steps:
6873
- name: Let Coveralls know that all tests have finished
69-
uses: coverallsapp/github-action@v1.1.0
74+
uses: coverallsapp/github-action@045a25193560dc194e405657f552faeb6b9433aa
7075
with:
7176
github-token: ${{ secrets.GITHUB_TOKEN }}
7277
parallel-finished: true
7378

74-
deploy:
75-
name: Publish to NPM
76-
if: github.ref == 'refs/heads/master'
79+
build:
80+
name: Build
7781
runs-on: ubuntu-latest
7882
timeout-minutes: 10
79-
needs: test
8083

8184
steps:
8285
- name: Checkout source
8386
uses: actions/checkout@v3
8487

85-
- name: Install Node
86-
uses: actions/setup-node@v3
87-
88-
- name: Install dependencies
89-
run: npm ci
88+
- name: Install Node.js and dependencies
89+
uses: ./.github/actions/setup
9090

91-
- name: Build the code
91+
- name: Build
9292
run: npm run build
9393

94+
- name: Upload publish artifact
95+
uses: actions/upload-artifact@v3
96+
with:
97+
name: publish-artifact
98+
path: lib
99+
100+
e2e:
101+
name: Run end-to-end tests
102+
runs-on: ubuntu-latest
103+
timeout-minutes: 10
104+
needs: build
105+
106+
services:
107+
verdaccio:
108+
image: verdaccio/verdaccio:5
109+
ports:
110+
- 4873:4873
111+
112+
steps:
113+
- name: Checkout source
114+
uses: actions/checkout@v3
115+
116+
- name: Install Node.js and dependencies
117+
uses: ./.github/actions/setup
118+
with:
119+
install-command: npm install --production
120+
121+
- name: Download publish artifact
122+
uses: actions/download-artifact@v3
123+
with:
124+
name: publish-artifact
125+
path: lib
126+
127+
- id: setup
128+
name: Login to local registry and set up fixture package
129+
shell: bash
130+
run: |
131+
echo "token=$(./e2e/00-login.sh)" >> "$GITHUB_OUTPUT"
132+
echo "package=$(./e2e/01-setup-package.sh ./e2e/fixture 0.0.1)" >> "$GITHUB_OUTPUT"
133+
134+
- name: Run CLI end-to-end test
135+
shell: bash
136+
env:
137+
TOKEN: ${{ steps.setup.outputs.token }}
138+
PACKAGE: ${{ steps.setup.outputs.package }}
139+
run: |
140+
./e2e/02-publish.sh ${PACKAGE} ${TOKEN}
141+
./e2e/03-verify.sh ${PACKAGE}
142+
./e2e/02-publish.sh ${PACKAGE} ${TOKEN}
143+
./e2e/01-setup-package.sh ${PACKAGE} 0.0.2
144+
./e2e/02-publish.sh ${PACKAGE} ${TOKEN}
145+
./e2e/03-verify.sh ${PACKAGE}
146+
147+
- id: action-no-publish
148+
name: Publish with already published version
149+
uses: ./
150+
with:
151+
registry: http://localhost:4873
152+
package: ${{ steps.setup.outputs.package }}/package.json
153+
token: ${{ steps.setup.outputs.token }}
154+
155+
- name: Check action output
156+
if: ${{ steps.action-no-publish.outputs.type != 'none' }}
157+
run: |
158+
echo "::error::Expected release type to be 'none', got '${{ steps.action-no-publish.outputs.type }}'"
159+
exit 1
160+
161+
- name: Create new version for Action end-to-end test
162+
shell: bash
163+
run: ./e2e/01-setup-package.sh ${{ steps.setup.outputs.package }} 0.0.3
164+
165+
- id: action-publish
166+
name: Publish a new version
167+
uses: ./
168+
with:
169+
registry: http://localhost:4873
170+
package: ${{ steps.setup.outputs.package }}/package.json
171+
token: ${{ steps.setup.outputs.token }}
172+
173+
- name: Check release output
174+
if: ${{ steps.action-publish.outputs.type != 'patch' }}
175+
run: |
176+
echo "::error::Expected release type to be 'patch', got '${{ steps.action-publish.outputs.type }}'"
177+
exit 1
178+
179+
deploy:
180+
if: ${{ github.ref == 'refs/heads/master' }}
181+
name: Publish to NPM
182+
runs-on: ubuntu-latest
183+
timeout-minutes: 10
184+
needs:
185+
- lint
186+
- test
187+
- build
188+
- e2e
189+
190+
steps:
191+
- name: Checkout source
192+
uses: actions/checkout@v3
193+
194+
- name: Download publish artifact
195+
uses: actions/download-artifact@v3
196+
with:
197+
name: publish-artifact
198+
path: lib
199+
94200
- name: Publish to NPM
95201
uses: ./
96202
with:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@ pids
4444
# Test output
4545
/.nyc_output
4646
/coverage
47+
/e2e/fixture

.prettierignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
dist
22
lib
3+
coverage
4+
.nyc_output
35
package-lock.json

e2e/00-login.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env bash
2+
# Login into the registry and extract the auth token
3+
# Usage: 00-login.sh
4+
5+
set -e
6+
7+
REGISTRY_HOSTNAME="localhost:4873"
8+
9+
registry_url=http://${REGISTRY_HOSTNAME}
10+
token_matcher='^\/\/'${REGISTRY_HOSTNAME}'\/:_authToken="(.+)"$'
11+
temporary_dir=${RUNNER_TEMP:-${TMPDIR}}
12+
npmrc=${temporary_dir}.npmrc-e2e
13+
14+
{
15+
echo -e "test"
16+
sleep 1
17+
echo -e "test"
18+
} | NPM_CONFIG_USERCONFIG=${npmrc} npm login --registry ${registry_url} > /dev/null 2>&1
19+
20+
echo "DEBUG: wrote config to temporary file: ${npmrc}" 1>&2
21+
22+
npmrc_contents=$(<${npmrc})
23+
rm -f ${npmrc}
24+
25+
if [[ "${npmrc_contents}" =~ ${token_matcher} ]]; then
26+
echo "${BASH_REMATCH[1]}"
27+
exit 0
28+
fi
29+
30+
echo "ERROR: No token found" 1>&2
31+
exit 1

e2e/01-setup-package.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env bash
2+
# Create a test fixture package
3+
# Usage: 01-setup-package.sh <package_directory> <version>
4+
5+
set -e
6+
7+
PACKAGE_SPEC=$1
8+
PACKAGE_VERSION=$2
9+
10+
package_manifest=${PACKAGE_SPEC}/package.json
11+
12+
mkdir -p ${PACKAGE_SPEC}
13+
14+
echo "{" > ${package_manifest}
15+
echo " \"name\": \"@jsdevtools/fixture\"," >> ${package_manifest}
16+
echo " \"version\": \"${PACKAGE_VERSION}\"" >> ${package_manifest}
17+
echo "}" >> ${package_manifest}
18+
19+
echo "DEBUG: wrote ${package_manifest}" 1>&2
20+
echo ${PACKAGE_SPEC}

e2e/02-publish.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env bash
2+
# Publish a package to the registry using the CLI
3+
# Usage: 02-publish.sh <package_directory> <token>
4+
5+
set -e
6+
7+
REGISTRY_URL="http://localhost:4873"
8+
PACKAGE_SPEC=$1
9+
TOKEN=$2
10+
11+
node ./bin/npm-publish --token=${TOKEN} --registry=${REGISTRY_URL} ${PACKAGE_SPEC}/package.json

e2e/03-verify.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env bash
2+
# Verify that a package was published
3+
# Usage: 03-verify.sh <package_directory>
4+
5+
set -e
6+
7+
REGISTRY_URL="http://localhost:4873"
8+
PACKAGE_SPEC=$1
9+
10+
package_name=$(cd $1 && npm pkg get name | sed 's/"//g')
11+
package_version=$(cd $1 && npm pkg get version | sed 's/"//g')
12+
13+
npm view $package_name@$package_version

e2e/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# End-to-end tests
2+
3+
This directory contains scripts to run end-to-end tests against a locally running [Verdaccio][] registry.
4+
5+
These test are run automatically in CI, but can be run locally, too.
6+
7+
[Verdaccio]: https://verdaccio.org/
8+
9+
## Usage
10+
11+
### Launch a Verdaccio registry
12+
13+
We use Docker to run a default instance of the Verdaccio server.
14+
15+
```shell
16+
docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio
17+
```
18+
19+
### Setup
20+
21+
Login to the local registry and create a fixture package.
22+
23+
```shell
24+
export TOKEN=$(./e2e/00-login.sh)
25+
export PACKAGE=$(./e2e/01-setup-package.sh ./e2e/fixture 0.0.1)
26+
```
27+
28+
### Test the CLI
29+
30+
1. Publish the package to the registry.
31+
2. Verify the package was published.
32+
3. Try to publish again, verify publish is skipped.
33+
4. Create a new version.
34+
5. Publish the new version.
35+
6. Verify the new version was published.
36+
37+
```shell
38+
./e2e/02-publish.sh ${PACKAGE} ${TOKEN}
39+
./e2e/03-verify.sh ${PACKAGE}
40+
./e2e/02-publish.sh ${PACKAGE} ${TOKEN}
41+
./e2e/01-setup-package.sh ${PACKAGE} 0.0.2
42+
./e2e/02-publish.sh ${PACKAGE} ${TOKEN}
43+
./e2e/03-verify.sh ${PACKAGE}
44+
```

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"lib"
3030
],
3131
"scripts": {
32-
"clean": "shx rm -rf .nyc_output coverage lib dist",
32+
"clean": "shx rm -rf .nyc_output coverage lib dist e2e/fixture",
3333
"lint": "npm run _eslint && npm run _prettier -- --check",
3434
"format": "npm run _eslint -- --fix && npm run _prettier -- --write",
3535
"build": "npm run build:typescript && npm run build:ncc && npm run build:node_modules",

0 commit comments

Comments
 (0)