• Stars
    star
    125
  • Rank 286,335 (Top 6 %)
  • Language
    TypeScript
  • Created over 7 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

GitHub Actions toolkit to monitor a repository and run testcases

Sherlock

GitHub Actions toolkit to monitor a repository and run testcases

What is it?

Sherlock will:

  • Add reproducible / unreproducible / broken-repro labels on your issues
  • Tell you why the assertions are failing
  • Allow you to replay the reproduction cases locally with a single command

In the future, Sherlock will (non exhaustive list):

  • Bisect to find out which commit introduced a bug
  • Close the obsolete issues after each release

Installation

yarn add -D @arcanis/sherlock

Then create a new GitHub Workflow with the following content:

on: [issues]

name: Sherlock
jobs:
  issue:
    name: Running Sherlock
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@master

      - name: Use Node.js 10.x
        uses: actions/setup-node@master
        with:
          version: 10.x

      - name: Use Yarn 1.17.2
        run: |
          npm install -g [email protected]
          yarn

      - name: Sherlock Payload
        id: sherlock-payload
        run: |
          yarn sherlock payload

      - name: Sherlock Execution
        if: ${{ steps.sherlock-payload.outputs.outcome == 'success' }}
        uses: docker://node:lts-jessie
        with:
          entrypoint: bash
          args: scripts/actions/sherlock-docker.sh

      - name: Sherlock Reporting
        if: ${{ steps.sherlock-payload.outputs.outcome == 'success' }}
        run: |
          yarn sherlock report
        env:
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

Documentation

What's a test from Sherlock's perspective?

Sherlock will pick up any code block that includes a particular fence:

This is my reproduction case:

```js repro
const foo = ...;
```

Note that the repro keyword is important here: it's what allows Sherlock to know that the code sample is a test and should be run against master.

How to write tests?

Sherlock uses expect, the validator provided by the Jest project. The expect function is automatically exposed as a global variable, so you just need to write your assertions as if you were in an actual test:

expect([`foo`, `bar`]).toEqual([`bar`, `foo`]);

Note that any exception thrown that is not an assertion will cause Sherlock to report the test as broken - if the exception is expected, then you should mark it as such:

expect(() => {
  somethingThatWillThrow();
}).toThrow();

How to use promises?

Sherlock automatically supports top-level await in the testcase, so just use await fn() as you usually would and you're good to go! And since expect has builtin support for promises, you can use them in your assertions too:

await expect(doSomethingAsync()).resolves.toEqual(42);

How to setup the environment under which the tests will run?

There are three options:

  • Create a sherlock.setup.js at the root of your repository
  • Define a sherlock.requireList array in your package.json
  • Use the --require flag when calling yarn sherlock exec

The specified scripts will then be loaded into the environment before the testcase runs. It's a good way to expose global helper functions that will abstract the boilerplate required by the reproduction cases:

const {promises: fs} = require(`fs`);

global.preparePackageJson = async function (data) {
  await fs.writeFile(`package.json`, JSON.stringify(data, null, 2));
};

How to run a testcase on my own machine?

Running issues from local markdown file

You can describe your issue in a local markdown file:

my_test_post.md

This is my reproduction case:

```js repro
const foo = ...;
```

And run the following command:

yarn sherlock my_test_post.md

Running issues from GitHub repo on local machine

Just go into your repository, ensure that your package.json contains the right fields:

{
  "repository": {
    "type": "git",
    "url": "https://github.com/octocat/example.git"
  }
}

Then run the following command:

yarn sherlock 1

This will download and run (on your machine, so be careful!) the testcase for the issue 1. It also works with full length GitHub issues, so you can just copy-paste it:

yarn sherlock https://github.com/octocat/example/issues/1

How does it work?

Each time a new issue is created (or edited, or unlabeled), we run a three-part pipeline:

  • First we extract the issue metadata and store it in a known location
  • Then we spawn a container that executes the embed script and stores its result somewhere
  • Then we report back the result to GitHub

The reason why we do all this in three steps (rather than a single one) is that we need to execute the script within its own container in order to prevent it from accessing the GitHub token that we use to report back the result.

How to make it better?

Some things that GitHub could do to make Sherlock better integrated:

  • support a copy button on code blocks (this way we can just copy the repro to try it out locally)
  • support CI-like status for issues (this way we could avoid polluting the comment thread)
  • support for fine-tuned triggers (this way we could avoid spawning the workflow for issue events we don't care)

License (MIT)

Copyright © 2019 Maël Nison

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Icon provided by game-icons.net.

More Repositories

1

clipanion

Type-safe CLI library / framework with no runtime dependencies
TypeScript
882
star
2

pnp-webpack-plugin

Transparently adds support for Plug'n'Play to Webpack
JavaScript
259
star
3

virtjs

JS collection of standardized devices, useful for emulating engines
JavaScript
213
star
4

typanion

Static and runtime type assertion library with no dependencies
TypeScript
208
star
5

secretsanta

Host secret santa without leaking your guests' informations 🎄
HTML
190
star
6

colibrijs

Color extractor
JavaScript
150
star
7

ts-pnp

Transparently adds support for Plug'n'Play to TypeScript
JavaScript
65
star
8

cpp-loader

A C++ loader for Webpack
C++
58
star
9

sparkle

WebGL particle engine
JavaScript
49
star
10

graphql-typescript-integration

TypeScript
35
star
11

eslint-plugin-arca

Various ESLint rules tailored to the author's preferred style
TypeScript
33
star
12

mono-layout

Fast implementation of a browser-like text layout engine, for Node and browsers
C++
27
star
13

pokelib

A library allowing to control & change the runtime values of a Pokemon game
JavaScript
26
star
14

pxeger

Reverse regular expression engine - generate all possible values for a regular expression
JavaScript
25
star
15

jest-pnp-resolver

Transparently adds support for Plug'n'Play to Jest
JavaScript
24
star
16

pnp-rust

JavaScript
23
star
17

ohui

Javascript curses library
JavaScript
22
star
18

rollup-plugin-pnp-resolve

Transparently adds support for Plug'n'Play to Rollup
JavaScript
19
star
19

node-sea

Pack entire packages and application into portable scripts
TypeScript
18
star
20

emmagic

Easily transport your data structures between your C++ and Javascript
C++
16
star
21

trivia.ff9

Extraction & conversion tools for Final Fantasy IX
C++
16
star
22

js.voxel

[DEPRECATED, cf readme for an alternative] Javascript voxel engine
JavaScript
15
star
23

peg.arcanis.fr

PEG.js web editor
JavaScript
14
star
24

gist-proxy-server

JavaScript
14
star
25

datefuzz

jQuery plugin for simple fuzzy date management
CSS
12
star
26

magicbin

Simple process manager; alternative to pm2
TypeScript
12
star
27

mpllvm

Metaprogramming type resolver for LLVM
C++
11
star
28

js.perlin

Javascript perlin's noise implementation - Demo on the arcanis/voxplode repository
JavaScript
9
star
29

pikasprite

A set of pokemon icons
CSS
8
star
30

voxplode

HTML5 game powered by the SWAT framework
JavaScript
8
star
31

babel-plugin-lazy-import

JavaScript
7
star
32

git-smart-project

Collection of smarter Git utilities
TypeScript
7
star
33

pokequery

Prolog library for issuing complex query on the Pokemon databases
JavaScript
6
star
34

RTWorldReader

Javascript library for importing .rtw files into webgl applications
JavaScript
6
star
35

astar-wasm

JavaScript
5
star
36

node-webpack

Isomorphic module loading via Webpack
JavaScript
5
star
37

boost.log

C++
5
star
38

embin

Shell
4
star
39

slice-ansi

JavaScript
4
star
40

arcanis

4
star
41

trivia.gol404

JavaScript
4
star
42

chenille

Keep master green at all times
JavaScript
3
star
43

epitech.pfa

JavaScript
3
star
44

build-pnm

Generate package-name-maps files by consuming the PnP API
JavaScript
3
star
45

tsc-with-workspaces

TypeScript
2
star
46

willikins

JavaScript
2
star
47

is-pnp

Detects whether PnP is enabled or not when running your scripts
JavaScript
2
star
48

tppserver

JavaScript
2
star
49

fe13-planificator

A planificator for Fire Emblem Awakening
JavaScript
2
star
50

arcanis.github.io

HTML
2
star
51

react-tailwind-select

TypeScript
2
star
52

epitech.generic-linked-list

A generic linked list. With bits of preprocessing metaprogrammation.
C
2
star
53

require-context-node

JavaScript
2
star
54

node-tput

tput for node.js
C++
1
star
55

multisweeper

Multiplayer minesweeper
CSS
1
star
56

term-capture

Capture your terminal as HTML
Python
1
star
57

presentation.jsmontreal-20130312

JavaScript
1
star
58

js.spark

Yet another javascript particle engine
JavaScript
1
star
59

tco

C++
1
star
60

ghost-theme

My own ghost theme
CSS
1
star
61

nitro

Advanced HTML5 mobile development framework, for Angular aficionados
JavaScript
1
star
62

arca-rs

Just a couple of Rust utilities I use
Rust
1
star
63

jest-coverage-ts

TypeScript
1
star
64

rollup-node-resolve-regression

JavaScript
1
star
65

tinylogic

JavaScript
1
star
66

webpack-project-generator

JavaScript
1
star
67

esfuse

TypeScript
1
star
68

ts-monorepo-example

JavaScript
1
star