-
Notifications
You must be signed in to change notification settings - Fork 15
JS unified CI script #273
Description
I've ported a bunch of js repos to all use the same CI script.
Essentially the idea is you can declare some, any or all of the following npm scripts in your package.json. In all cases if they exist, they will be run, if not, they will be skipped:
build
lint
dep-check
test:node
test:chrome
test:chrome-webworker
test:firefox
test:firefox-webworker
test:electron-main
test:electron-renderer
release
lint & dep-check are run first, then it fans out to test:*, if they all pass and we are on the master branch it fans in to release. test:node can optionally output coverage info, this could be expanded to all test:* scripts.
~/.npm, node_modules, dist etc are cached between runs on a per-os basis. If the cache does not exist npm i and npm run build (if it's declared) will be run.
In addition to the default GITHUB_TOKEN, you can set the following secrets for npm and docker hub perms. If they are not set nothing will happen:
NPM_TOKEN
DOCKER_USERNAME
DOCKER_TOKEN
This is the whole script:
name: test & maybe release
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: lts/*
- uses: ipfs/aegir/actions/cache-node-modules@master
- run: npm run --if-present lint
- run: npm run --if-present dep-check
test-node:
needs: check
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
node: [16]
fail-fast: true
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node }}
- uses: ipfs/aegir/actions/cache-node-modules@master
- run: npm run --if-present test:node
- uses: codecov/codecov-action@v1
test-chrome:
needs: check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: lts/*
- uses: ipfs/aegir/actions/cache-node-modules@master
- run: npm run --if-present test:chromes
test-chrome-webworker:
needs: check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: lts/*
- uses: ipfs/aegir/actions/cache-node-modules@master
- run: npm run --if-present test:chrome-webworker
test-firefox:
needs: check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: lts/*
- uses: ipfs/aegir/actions/cache-node-modules@master
- run: npm run --if-present test:firefox
test-firefox-webworker:
needs: check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: lts/*
- uses: ipfs/aegir/actions/cache-node-modules@master
- run: npm run --if-present test:firefox-webworker
test-electron-main:
needs: check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: lts/*
- uses: ipfs/aegir/actions/cache-node-modules@master
- run: npx xvfb-maybe npm run --if-present test:electron-main
test-electron-renderer:
needs: check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: lts/*
- uses: ipfs/aegir/actions/cache-node-modules@master
- run: npx xvfb-maybe npm run --if-present test:electron-renderer
release:
needs: [test-node, test-chrome, test-chrome-webworker, test-firefox, test-firefox-webworker, test-electron-main, test-electron-renderer]
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
steps:
- uses: actions/[email protected]
with:
fetch-depth: 0
- uses: actions/setup-node@v2
with:
node-version: lts/*
- uses: ipfs/aegir/actions/cache-node-modules@master
- uses: ipfs/aegir/actions/docker-login@master
with:
docker-token: ${{ secrets.DOCKER_TOKEN }}
docker-username: ${{ secrets.DOCKER_USERNAME }}
- run: npm run --if-present release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}It uses a few actions from the aegir repo but that's mainly to reduce duplication. I would not categorise this as an aegir-centric workflow, quite the opposite in fact - it doesn't install any extra deps or use any tool-specific config, the idea is that if you have a test:foo script run on a module, that module should define what test:foo means - if it doesn't mean anything, don't declare it and it won't be run.
This is now happily running on typescript, pure-ESM, node-js only and monorepo projects.
@rvagg hopefully this will also fit projects like multiformats with minimal changes to those projects - what do you think? I think you may need to change a couple of npm script names and add some semantic-release deps (no bad thing, you get control of the versions of things you are using that way and then there's less magic in the CI config).