Get Started

Integrating with Coveralls

Coveralls Builds

The Web App

The API

Get Help

Configuring Parallel Builds

What’s a Parallel Build?

Simply stated, a parallel build is a CI build that runs multiple CI jobs in parallel.

From the standpoint of CI, it means you’ll run tests and send coverage reports to Coveralls for different segments of your project, in different individual jobs, or steps, or stages of your CI build script.

From the standpoint of Coveralls, it means the Coveralls API will receive multiple coverage reports for the same build (at its /jobs endpoint), until you tell it that all jobs were sent and it’s time to close the build, merge the reports together and calculate total coverage for the build.*

* The way you tell Coveralls to close a build is by sending a request to the Parallel Build Webhook.

How do I set up a Parallel Build?

To set up a parallel build, you’ll need to do a few things:

  1. Set up your CI build script to run multiple jobs
  2. Configure your Coveralls Integration for parallel builds
  3. Configure CI to notify Coveralls when all jobs have run (Close the build)

We’ll cover each step in detail below, but, in the meantime, here’s a complete example showing all three steps in a Github Actions Workflow:

on: ["push", "pull_request"]

name: Coveralls Parallel Build Example

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        test_number:
          - 1
          - 2
    steps:
      - uses: actions/checkout@3
      - name: Use Node.js 16.x
        uses: actions/setup-node@3
        with:
          node-version: 16.x

      - name: Install dependencies
        run: npm install

      - name: Run tests
        run: make test-coverage-$
      
      - name: Send coverage to Coveralls (parallel)
        uses: coverallsapp/github-action@v1
        with:
          parallel: true
          flag-name: run-$

  finish:
    needs: test
    if: $
    runs-on: ubuntu-latest
    steps:
      - name: Close parallel build
        uses: coverallsapp/github-action@v1
        with:
          parallel-finished: true
          carryforward: "run-1,run-2"

Note that this example uses Github Actions’ configuration syntax (in YAML). If you’re using a different CI, you’ll need to translate the syntax to your CI’s configuration language.

Note also that this example is using a matrix strategy to run two (2) jobs in parallel. If you’re not using a matrix strategy, you’ll need to define each of your jobs in a series of individual steps.

Finally, note that this example is using the Coveralls Github Action, which is a Coveralls Integration with built-in support for parallel builds that simplifies the steps of sending coverage reports, and closing a build, with dedicated config parameters. If you’re using a different Coveralls Integration, your CI build script could have different commands, and be more, or less, verbose than this example.

Step-by-Step Instructions

1. Set up CI to Run Multiple Jobs

This means setting up your CI build script to run multiple jobs that send coverage reports to Coveralls.

Example

Here’s an example using Travis CI syntax from a .travis.yml config file:

language: node_js
node_js:
  - "node"
env:
  global:
    - COVERALLS_PARALLEL=true
jobs:
  include:
    - script: COVERALLS_FLAG_NAME=test-1 make test-coveralls-1
    - script: COVERALLS_FLAG_NAME=test-2 make test-coveralls-2

Here we’re configuring a couple of parallel jobs to run by listing them in sequence, without using a matrix strategy.

Also, note the use of environment variables here, to: (A) configure the Coveralls Integration for parallel builds (COVERALLS_PARALLEL=true); and (B) assign a “flag name” to each parallel job to help identify it at Coveralls (COVERALLS_FLAG_NAME=test-1).


2. Configure your Coveralls Integration for Parallel Builds

This means telling Coveralls that each job coming its way is a parallel job—in other words, that it should expect multiple jobs for the same build, and keep the build open until further notice.

Examples

One option for doing this is to set the purpose-specific environment variable, COVERALLS_PARALLEL=true, somewhere in your CI build script or config file.

We already saw this example above, in Step 1. It’s this part:

env:
  global:
    - COVERALLS_PARALLEL=true

Here, a global env var in your config file declares: “All (Coveralls) jobs are parallel.”

With another Coveralls Integration the equivalent could be a pre-defined input option, like this:

- name: Coveralls Parallel Build Example
  uses: coverallsapp/github-action@v1
  with:
    parallel: true  # <-- this is the parallel option for the Coveralls Github Action integration

Finally, another equivalent could be passing the same env var on the command-line, like this:

COVERALLS_PARALLEL=true bundle exec rake coveralls:push


3. Configure CI to Notify Coveralls When All Jobs Have Run

This means telling Coveralls that all jobs have been sent, so it can close the build.

This step is special because it involves sending a request to an API endpoint called the Parallel Build Webhook—or the (Close) Parallel Build Webhook—since that’s what it for, closing a parallel build.

Examples

Here’s an example we saw in our complete example above, using a Github Actions Workflow with the Coveralls Github Action:

  finish:
    needs: test
    if: $
    runs-on: ubuntu-latest
    steps:
      - name: Close parallel build
        uses: coverallsapp/github-action@v1
        with:
          parallel-finished: true
          carryforward: "run-1,run-2"

Here, using the configuration syntax of Github Actions, we’re calling the Coveralls Github Action with a special input option, parallel-finished: true, which tells Coveralls to close the build associated with the given Workflow.

Under the hood, the Coveralls Github Action is calling the Parallel Build Webhook on our behalf, making a POST request to the /webhook endpoint, with a payload that looks like this:

{
  "payload": {
       "build_num": $BUILD_NUMBER,
       "status": "done"
     }
}

Where build_num is the build number that our CI service (Github Actions) assigned to the build, and status is the status of the build, which is always "done" when closing a build.


Another example could be for a very pared-down CI setup—a shell script, for instance—in which you’d need to make that POST request to the Parallel Build Webhook yourself, like this:

curl -k $COVERALLS_ENDPOINT/webhook?repo_token=$COVERALLS_REPO_TOKEN -d "payload[build_num]=$BUILD_NUMBER&payload[status]=done"

Where COVERALLS_ENDPOINT is the base URL for your Coveralls instance (if it’s not the default for Coveralls Cloud, https://coveralls.io), and COVERALLS_REPO_TOKEN is your Coveralls Repo Token.

Even in a modern CI environment with a robust integration like the Coveralls Github Action, there might be a reason to make this call directly. For instance, in order to pass a different build number than the one you know your integration will be sourcing from your environment.

Carryforward Flags

Since we’re discussing Parallel Builds here, it’s worth mentioning Carryforward Flags, which is a special feature often used in combination with Parallel Builds, typically for monorepos.

With Carryforward Flags, you can tell Coveralls that, if some coverage reports, for some portions of your project, are missing from a given build, it should carry forward the last known report it has on file for those subprojects. This is useful because it saves you from having to build your entire project on every pull request.

It’s also apt that we just discussed the Parallel Build Webhook, because that’s how the Carryforward Flags feature is enabled, by passing the carryforward parameter to the (Close) Parallel Build Webhook:

Examples

We snuck an example of this into our complete example above, using a Github Actions Workflow with the Coveralls Github Action:

  finish:
    needs: test
    if: $
    runs-on: ubuntu-latest
    steps:
      - name: Close parallel build
        uses: coverallsapp/github-action@v1
        with:
          parallel-finished: true
          carryforward: "run-1,run-2"

Note that, in this example, we’re simply using the predefined input option, carryforward, provided by the Coveralls Github Action, and passing it some comma-separated values, which tells Coveralls to carry forward the last known coverage reports for the run-1 and run-2 flags—if they’re missing from the current build.


Another way to do this would be to make the POST request to the Parallel Build Webhook yourself, passing the ?carryforward= URL parameter, like this:

curl --location 'https://coveralls.io/webhook?repo_token=$COVERALLS_REPO_TOKEN&carryforward=subproject-1,subproject-2,subproject-3' \
--header 'Content-Type: application/json' \
--data '{
    "payload": {
        "build_num": $BUILD_NUMBER,
        "status": "done"
    }
}'

Here we’re telling Coveralls to carry forward the last known coverage reports for subproject-1, subproject-2, and subproject-3—again, if they’re missing from the current build.

 


Any problems, questions or comments about this doc? Let us know.