Skip to content
This repository was archived by the owner on Aug 29, 2023. It is now read-only.
This repository was archived by the owner on Aug 29, 2023. It is now read-only.

JS unified CI script #273

@achingbrain

Description

@achingbrain

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).

cc @galargh @marten-seemann

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions