Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add end-to-end test suite #80

Merged
merged 18 commits into from
Apr 14, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:
@@ -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:
@@ -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
@@ -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:
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -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
@@ -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",