Skip to content

Commit

Permalink
Add end-to-end test suite (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
mcous authored Apr 14, 2023
1 parent d6a8488 commit 3ee021c
Show file tree
Hide file tree
Showing 11 changed files with 280 additions and 28 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
dist
lib
coverage
23 changes: 23 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Set up Node.js
description: Install Node.js and development dependencies

inputs:
node-version:
description: Node.js version to install
default: "18"
install-command:
description: Install command to run
default: npm ci

runs:
using: "composite"
steps:
- name: "Install Node.js"
uses: actions/setup-node@v3
with:
node-version: ${{ inputs.node-version }}
cache: npm

- name: "Install development dependencies"
shell: bash
run: ${{ inputs.install-command }}
160 changes: 133 additions & 27 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# GitHub Actions workflow
# https://help.github.com/en/actions/automating-your-workflow-with-github-actions
# https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions
# https://help.github.com/en/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions

name: CI-CD

on:
Expand All @@ -12,12 +7,28 @@ on:
tags-ignore:
- "*"

# run CI every Monday at 12:25 UTC
schedule:
- cron: "0 0 1 * *"
- cron: "25 12 * * 1"

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Checkout source
uses: actions/checkout@v3

- name: Install Node.js and dependencies
uses: ./.github/actions/setup

- name: Run linters
run: npm run lint

test:
name: Node ${{ matrix.node }} on ${{ matrix.os }}
name: Run tests using Node ${{ matrix.node }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 10
strategy:
Expand All @@ -36,25 +47,19 @@ jobs:
- name: Checkout source
uses: actions/checkout@v3

- name: Install Node ${{ matrix.node }}
uses: actions/setup-node@v3
- name: Install Node.js ${{ matrix.node }} and dependencies
uses: ./.github/actions/setup
with:
node-version: ${{ matrix.node }}

- name: Install dependencies
run: npm ci

- name: Run linters
run: npm run lint

- name: Build the code
run: npm run build

- name: Run tests
run: npm run coverage

- name: Send code coverage results to Coveralls
uses: coverallsapp/github-action@v1.1.0
uses: coverallsapp/github-action@045a25193560dc194e405657f552faeb6b9433aa
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel: true
Expand All @@ -66,31 +71,132 @@ jobs:
needs: test
steps:
- name: Let Coveralls know that all tests have finished
uses: coverallsapp/github-action@v1.1.0
uses: coverallsapp/github-action@045a25193560dc194e405657f552faeb6b9433aa
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel-finished: true

deploy:
name: Publish to NPM
if: github.ref == 'refs/heads/master'
build:
name: Build
runs-on: ubuntu-latest
timeout-minutes: 10
needs: test

steps:
- name: Checkout source
uses: actions/checkout@v3

- name: Install Node
uses: actions/setup-node@v3

- name: Install dependencies
run: npm ci
- name: Install Node.js and dependencies
uses: ./.github/actions/setup

- name: Build the code
- name: Build
run: npm run build

- name: Upload publish artifact
uses: actions/upload-artifact@v3
with:
name: publish-artifact
path: lib

e2e:
name: Run end-to-end tests
runs-on: ubuntu-latest
timeout-minutes: 10
needs: build

services:
verdaccio:
image: verdaccio/verdaccio:5
ports:
- 4873:4873

steps:
- name: Checkout source
uses: actions/checkout@v3

- name: Install Node.js and dependencies
uses: ./.github/actions/setup
with:
install-command: npm install --production

- name: Download publish artifact
uses: actions/download-artifact@v3
with:
name: publish-artifact
path: lib

- id: setup
name: Login to local registry and set up fixture package
shell: bash
run: |
echo "token=$(./e2e/00-login.sh)" >> "$GITHUB_OUTPUT"
echo "package=$(./e2e/01-setup-package.sh ./e2e/fixture 0.0.1)" >> "$GITHUB_OUTPUT"
- name: Run CLI end-to-end test
shell: bash
env:
TOKEN: ${{ steps.setup.outputs.token }}
PACKAGE: ${{ steps.setup.outputs.package }}
run: |
./e2e/02-publish.sh ${PACKAGE} ${TOKEN}
./e2e/03-verify.sh ${PACKAGE}
./e2e/02-publish.sh ${PACKAGE} ${TOKEN}
./e2e/01-setup-package.sh ${PACKAGE} 0.0.2
./e2e/02-publish.sh ${PACKAGE} ${TOKEN}
./e2e/03-verify.sh ${PACKAGE}
- id: action-no-publish
name: Publish with already published version
uses: ./
with:
registry: http://localhost:4873
package: ${{ steps.setup.outputs.package }}/package.json
token: ${{ steps.setup.outputs.token }}

- name: Check action output
if: ${{ steps.action-no-publish.outputs.type != 'none' }}
run: |
echo "::error::Expected release type to be 'none', got '${{ steps.action-no-publish.outputs.type }}'"
exit 1
- name: Create new version for Action end-to-end test
shell: bash
run: ./e2e/01-setup-package.sh ${{ steps.setup.outputs.package }} 0.0.3

- id: action-publish
name: Publish a new version
uses: ./
with:
registry: http://localhost:4873
package: ${{ steps.setup.outputs.package }}/package.json
token: ${{ steps.setup.outputs.token }}

- name: Check release output
if: ${{ steps.action-publish.outputs.type != 'patch' }}
run: |
echo "::error::Expected release type to be 'patch', got '${{ steps.action-publish.outputs.type }}'"
exit 1
deploy:
if: ${{ github.ref == 'refs/heads/master' }}
name: Publish to NPM
runs-on: ubuntu-latest
timeout-minutes: 10
needs:
- lint
- test
- build
- e2e

steps:
- name: Checkout source
uses: actions/checkout@v3

- name: Download publish artifact
uses: actions/download-artifact@v3
with:
name: publish-artifact
path: lib

- name: Publish to NPM
uses: ./
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ pids
# Test output
/.nyc_output
/coverage
/e2e/fixture
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
dist
lib
coverage
.nyc_output
package-lock.json
31 changes: 31 additions & 0 deletions e2e/00-login.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Login into the registry and extract the auth token
# Usage: 00-login.sh

set -e

REGISTRY_HOSTNAME="localhost:4873"

registry_url=http://${REGISTRY_HOSTNAME}
token_matcher='^\/\/'${REGISTRY_HOSTNAME}'\/:_authToken="(.+)"$'
temporary_dir=${RUNNER_TEMP:-${TMPDIR}}
npmrc=${temporary_dir}.npmrc-e2e

{
echo -e "test"
sleep 1
echo -e "test"
} | NPM_CONFIG_USERCONFIG=${npmrc} npm login --registry ${registry_url} > /dev/null 2>&1

echo "DEBUG: wrote config to temporary file: ${npmrc}" 1>&2

npmrc_contents=$(<${npmrc})
rm -f ${npmrc}

if [[ "${npmrc_contents}" =~ ${token_matcher} ]]; then
echo "${BASH_REMATCH[1]}"
exit 0
fi

echo "ERROR: No token found" 1>&2
exit 1
20 changes: 20 additions & 0 deletions e2e/01-setup-package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Create a test fixture package
# Usage: 01-setup-package.sh <package_directory> <version>

set -e

PACKAGE_SPEC=$1
PACKAGE_VERSION=$2

package_manifest=${PACKAGE_SPEC}/package.json

mkdir -p ${PACKAGE_SPEC}

echo "{" > ${package_manifest}
echo " \"name\": \"@jsdevtools/fixture\"," >> ${package_manifest}
echo " \"version\": \"${PACKAGE_VERSION}\"" >> ${package_manifest}
echo "}" >> ${package_manifest}

echo "DEBUG: wrote ${package_manifest}" 1>&2
echo ${PACKAGE_SPEC}
11 changes: 11 additions & 0 deletions e2e/02-publish.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
# Publish a package to the registry using the CLI
# Usage: 02-publish.sh <package_directory> <token>

set -e

REGISTRY_URL="http://localhost:4873"
PACKAGE_SPEC=$1
TOKEN=$2

node ./bin/npm-publish --token=${TOKEN} --registry=${REGISTRY_URL} ${PACKAGE_SPEC}/package.json
13 changes: 13 additions & 0 deletions e2e/03-verify.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# Verify that a package was published
# Usage: 03-verify.sh <package_directory>

set -e

REGISTRY_URL="http://localhost:4873"
PACKAGE_SPEC=$1

package_name=$(cd $1 && npm pkg get name | sed 's/"//g')
package_version=$(cd $1 && npm pkg get version | sed 's/"//g')

npm view $package_name@$package_version
44 changes: 44 additions & 0 deletions e2e/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# End-to-end tests

This directory contains scripts to run end-to-end tests against a locally running [Verdaccio][] registry.

These test are run automatically in CI, but can be run locally, too.

[Verdaccio]: https://verdaccio.org/

## Usage

### Launch a Verdaccio registry

We use Docker to run a default instance of the Verdaccio server.

```shell
docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio
```

### Setup

Login to the local registry and create a fixture package.

```shell
export TOKEN=$(./e2e/00-login.sh)
export PACKAGE=$(./e2e/01-setup-package.sh ./e2e/fixture 0.0.1)
```

### Test the CLI

1. Publish the package to the registry.
2. Verify the package was published.
3. Try to publish again, verify publish is skipped.
4. Create a new version.
5. Publish the new version.
6. Verify the new version was published.

```shell
./e2e/02-publish.sh ${PACKAGE} ${TOKEN}
./e2e/03-verify.sh ${PACKAGE}
./e2e/02-publish.sh ${PACKAGE} ${TOKEN}
./e2e/01-setup-package.sh ${PACKAGE} 0.0.2
./e2e/02-publish.sh ${PACKAGE} ${TOKEN}
./e2e/03-verify.sh ${PACKAGE}
```
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"lib"
],
"scripts": {
"clean": "shx rm -rf .nyc_output coverage lib dist",
"clean": "shx rm -rf .nyc_output coverage lib dist e2e/fixture",
"lint": "npm run _eslint && npm run _prettier -- --check",
"format": "npm run _eslint -- --fix && npm run _prettier -- --write",
"build": "npm run build:typescript && npm run build:ncc && npm run build:node_modules",
Expand Down

0 comments on commit 3ee021c

Please sign in to comment.