Skip to main content

For JavaScript Engineers

A typical build for a JavaScript / TypeScript project produces a number of useful reports:

  • Test reports (Jest, Mocha, etc.)
  • Test coverage reports
  • Integration test artifacts (Cypress screenshots/videos, etc.)
  • Component previews (Storybook, Ladle, etc.)
  • Documentation

Though useful for debugging and development, these outputs are usually disabled in continuous integration (CI) pipelines because the outputs are not accessible. It is almost impossible to look at those outputs from a CI pipeline running remotely. It's even difficult for developers to access these outputs for local builds. Who knows that the human-readable version of the Jest coverage report is under coverage/lcov-report by default? Stoat is the easiest way to make all of this information trivial to access for both local and remote builds.

For remote builds, Stoat hosts these outputs and makes them accessible with a single click in a GitHub comment:

javascript comment screenshot

The comment can also track build times and other metrics. Additionally, the comment is fully customizable, so you can choose what to display and how it should appear in the comment. Visit our templating documentation for more information about customization.

Example Repo

See a real build that generates and links to JavaScript build outputs in this pull request.

Relevant Tutorials

To get started with Stoat as a JavaScript / TypeScript engineer, we have an end-to-end tutorial below.

We also have tutorials for specific use-cases:

JavaScript User Tutorial

In this doc, we are going to show you how to create previews for typical JavaScript build outputs. We are going to use this repo as an example: penx/storybook-code-coverage, authored by Alasdair McLeay. The author wrote a detailed article about the set-up of this repo: Combining Storybook, Cypress and Jest Code Coverage. This repo uses Jest for unit tests, Cypress for integration tests, and Storybook for visual previews. Each module generates their own test coverage reports, which can be merged together into one report. The original repo doesn't have a GitHub workflow to build the entire project, but we will add one as part of this portfolio.

We have two goals here:

  1. Write a GitHub workflow to run the CI pipeline.
  2. Use Stoat to provide previews for the latest test coverage reports, static Storybook pages, and Cypress videos on every pull request.

1. Add GitHub workflow

Create a YAML file at .github/workflows/ci.yaml with the following content:

.github/workflows/ci.yaml
name: Continuous Integration

on:
# Trigger the ci pipeline for every comment on the default branch or a pull request.
# The default branch for the sample repo is `master`.
push:
branches:
- master
pull_request:
branches:
- master

jobs:
ci:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up node and cache
uses: actions/setup-node@v3
with:
node-version: '16.8.0'
cache: 'yarn'

- name: Install dependencies
run: yarn install --frozen-lockfile --prefer-offline

# This project has a `coverage` script that runs all the
# tests and merge all their coverage reports.
- name: Run tests and generate report
run: yarn coverage

- name: Generate storybook
run: yarn build-storybook

When you set it up for your own projects, most of the YAML file can be exactly the same. The only differences are:

  • Replace master with the name of your default branch.
  • Replace 16.8.0 with the version of Node.js you are using.
  • Run the test script that is set in package.json. Typically, it is jest --coverage for unit test.

Note that the Stoat action is appended at the end of the ci job. This one step can carry out various tasks according to the Stoat config.

2. Install Stoat

Set up Stoat with our getting started guide. During the CLI setup process, an action should have been appended to your GitHub workflow:

.github/workflows/ci.yaml
...
- name: Generate storybook
run: yarn build-storybook

- name: Run stoat action
uses: stoat-dev/stoat-action@v0
if: always()

3. Configure Stoat

Update .stoat/config.yaml and paste in the following content:

.stoat/config.yaml
---
version: 1
enabled: true
plugins:
job_runtime:
enabled: true
static_hosting:
merged-test-coverage:
path: coverage/merged/lcov-report
storybook:
path: storybook-static
cypress-video:
path: cypress/videos/spec.js.mp4

The Stoat config is a YAML file that contains a list of tasks. Each task contains one Stoat plugin. In the example above, we have four tasks:

  • Setting the job_runtime plugin to enabled reports the time it takes to run every GitHub job. The build data is tracked by the Stoat action attached to the ci job.
  • Task merged-test-coverage looks for the test coverage report under coverage/merged/lcov-report, and uses the Stoat static_hosting plugin to upload it to the Stoat server. The entire directory will be uploaded, so the preview will include all the HTML, JavaScript, and CSS files.
  • Task storybook is very similar. It looks for the static Storybook build under storybook-static, and uploads them to the Stoat server.
  • Same for the cypress-video task. The only difference is that this task uploads a single file instead of a directory.

4. That's It!

Now, commit the two files to the codebase, and create a pull request. After the build completes (about two minutes), you will be able to see the previews in a comment from the Stoat bot:

javascript comment screenshot (with ids)

Now you can click on the links to see the previews or watch the Cypress video. This comment will be auto updated whenever the CI workflow is triggered and completed.

The Stoat comment is also highly customizable. For example, currently, in each row of the preview table, the Name column is just the task ID in the Stoat config. You can change it to something more friendly by adding a metadata name field to each of the task:

.stoat/config.yaml
version: 1
enabled: true
plugins:
job_runtime:
enabled: true
static_hosting:
merged-test-coverage:
# The metadata and name fields are newly added here.
metadata:
name: Test coverage report
path: coverage/merged/lcov-report
storybook:
metadata:
name: Storybook
path: storybook-static
cypress-video:
metadata:
name: Cypress video
path: cypress/videos/spec.js.mp4

Commit and push the change.

After another two minutes, the comment is updated with the new names and runtime chart:

javascript comment screenshot (with names)

You can find the exact pull request used for this tutorial here.

Now you're ready to start using Stoat for your JavaScript and TypeScript projects!