Integrating Captain with your CI Platform

Here, we'll walk through everything needed to integrating with your CI platform.

  1. Setting the RWX_ACCESS_TOKEN
  2. Installing the Captain CLI
  3. Integrating Captain with your test framework

Setting RWX_ACCESS_TOKEN

You need to make an RWX_ACCESS_TOKEN environment variable available to your CI script. You'll do this by:

  1. First generating an access token,
  2. setting it in your CI

Generating an Access Token

  • Navigate to your Access Tokens settings page
    • Log in to RWX
    • From the hamburger navigation menu, select "Manage {organization}"
    • Click on "Access Tokens" on the menu on the left
  • Click "Create new"
  • Enter a description, such as "GitHub Actions"
  • Click "Create token"
  • Copy the Access Token (you'll use it in the next section)

Setting the Access Token in your CI

It's best to set the rwx access token as a secret in your CI platform, and then expose it to your CI script as an environment variable named RWX_ACCESS_TOKEN.

Installing Captain

Install captain via some variation of this script, substituting the appropriate OS and architecture for your system.

tmp="$(mktemp -d)/captain" && \
  curl -o "$tmp" -fsSL "https://releases.captain.build/v1/linux/x86_64/captain" && \
  sudo install "$tmp" /usr/local/bin && \
  rm "$tmp" && \
  captain --version

Here are supported OS, architectures, and their download URLs:

OSArchitectureURL
darwinx86_64https://releases.captain.build/v1/darwin/x86_64/captain
darwinaarch64https://releases.captain.build/v1/darwin/aarch64/captain
linuxx86_64https://releases.captain.build/v1/linux/x86_64/captain
linuxaarch64https://releases.captain.build/v1/linux/aarch64/captain

Integrating Captain with your test framework

Captain integrates with many test frameworks. Find instructions for your specific test framework here.

This example integrates with Ruby's RSpec but can be used as a baseline for integrating with a different framework. Here is the captain configuration file for this example (also available in the example repo):

# .captain/config.yaml

test-suites:
  captain-examples-rspec:
    command: bundle exec rspec --format json --out tmp/rspec.json --format progress
    results:
      path: tmp/rspec.json
    output:
      reporters:
        junit-xml: tmp/junit.xml

captain run takes the following parameters:

FlagEnvironment VariableDescriptionRequired
--suite-idCAPTAIN_SUITE_IDA unique identifier for your test suite. Also accepted as the first command line argument❗️
--whoCAPTAIN_WHOWho triggered the build❗️
--shaCAPTAIN_SHAThe build's SHA hash❗️
--branchCAPTAIN_BRANCHThe build's branch❗️
--test-results-Path to the test results file generated by the test suite❗️
--titleCAPTAIN_TITLEHow to display the build in captain cloud-
--commit-messageCAPTAIN_COMMIT_MESSAGEThe build's commit message-
--build-urlCAPTAIN_BUILD_URLThe build's URL (for linking back to the build from captain cloud)-

If git is available, it can set be used to set all params other than --suite-id and --build-url:

# note: all of these params are equivalent to captain CLI flags, (e.g. CAPTAIN_WHO is equivalent to --who)
CAPTAIN_WHO=$(git show -s --format='%an <%ae>')
CAPTAIN_SHA=$(git rev-parse HEAD)
# try to find the current branch, and fall back to a branch or tag that the current commit is in
CAPTAIN_BRANCH=$({
  git branch --show-current
  git branch --contains HEAD | grep -v 'HEAD detached' | sed 's/^\* //' | head -n 1
  git tag --contains HEAD | head -n 1
} | head -n 1)
CAPTAIN_COMMIT_MESSAGE=$(git show -s --format='%B')
CAPTAIN_TITLE=$(echo "$CAPTAIN_COMMIT_MESSAGE" | head -n 1)

export CAPTAIN_WHO CAPTAIN_SHA CAPTAIN_BRANCH CAPTAIN_COMMIT_MESSAGE CAPTAIN_TITLE

We've extracted these git commands into a helper shell script. source it in your CI script to set all params except for required --suite-id and optional --build-url.

Here is an example of using the helper script to set all the params required for captain:

source set-captain-env-from-git.sh

# suite id is captain-examples-rspec
captain run captain-examples-rspec

Partitioning

If your CI platform can run a build across multiple nodes, captain run can be used to parallelize (and thus speed up) your test suite.

Start by updating your Captain configuration to enable partitioning as follows:

test-suites:
  captain-examples-rspec:
    # existing config...
    partition:
      command: bundle exec rspec --format json --out tmp/rspec.json --format progress {{ testFiles }}
      globs:
        - spec/**/*_spec.rb

captain run with partitioning needs all of the following parameters:

FlagEnvironment VariableDescriptionRequired
--shaCAPTAIN_SHAThe build's SHA hash❗️
--partition-indexCAPTAIN_PARTITION_INDEXThe 0-indexed node of the currently running partition❗️
--partition-totalCAPTAIN_PARTITION_TOTALThe total number of partitions❗️
--suite-idCAPTAIN_BUILD_URLThe build's URL (for linking back to the build from captain cloud)❗️
--partition-delimiterCAPTAIN_PARTITION_DELIMITERThe delimiter used to separate partitioned files in the output. Default is " "-

Finding documentation on parallelizing CI may be tricky! Try searching for the following keywords in your CI Platform's documentation: "parallelism", "slicing" or "matrix".

# include env vars from the previous example.
export CAPTAIN_SUITE_ID=captain-examples-rspec

# in this example, we assume that the CI platform exposes CI_NODE_INDEX and CI_NODE_TOTAL
# you'll have to tweak this to match your CI platform's settings.
captain run captain-examples-rspec \
--partition-index "$CI_NODE_INDEX" \
--partition-total "$CI_NODE_TOTAL"

For an example of these techniques being used directly in code, see this example repo and its scripts directory.