Sign inSign up

Automate Chromatic with GitLab Pipelines

Chromatic’s automation can be included as part of your GitLab pipeline workflow with relative ease.

Setup

To integrate Chromatic with your existing pipeline, you’ll need to add the following:

.gitlab-ci.yml
image: node:iron

stages:
  - UI_Tests

cache:
  key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
  paths:
    - .npm/

before_script:
  # ⚠️ See your package manager's documentation for the correct command to install dependencies in a CI environment.
  - npm ci

Chromatic:
  stage: UI_Tests
  script:
    - npx chromatic

We recommend saving the project token as a masked environment variable named CHROMATIC_PROJECT_TOKEN for security reasons. When the Chromatic CLI is executed, it will read the environment variable automatically without any additional flags. Refer to the official GitLab environment variables documentation to learn more about it.

Performance optimization

To improve the performance of your pipeline, you can use the interruptible option if a job should be canceled when a newer pipeline starts before the job completes. This is the recommended strategy as the external status checks won’t update by default, even if you create a new build for the same branch.

This keyword has no effect if automatic cancellation of redundant pipelines is disabled. When enabled, a running job with interruptible: true is canceled when starting a pipeline for a new change on the same branch.

.gitlab-ci.yml
image: node:iron

stages:
  - UI_Tests

cache:
  key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
  paths:
    - .npm/

before_script:
  # ⚠️ See your package manager's documentation for the correct command to install dependencies in a CI environment.
  - npm ci

Chromatic:
  stage: UI_Tests
  script:
    - npx chromatic

  # The external Chromatic status checks won't be canceled when a newer pipeline starts before the job completes saving you build minutes
  # You may get an increase in the number of builds, but they won't cancel each other.
  interruptible: true

Run Chromatic on specific branches

If you need to customize your workflow to run Chromatic on specific branches, adjust your pipeline like so:

.gitlab-ci.yml
# Additional pipeline configurations

# Sets the stages for the pipeline
stages:
  - UI_Tests

# 👇 Adds Chromatic as a job
Chromatic:
  stage: UI_Tests
  script:
    - npx chromatic

  #👇Filters the execution to run only on the main branch.
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: always

Read the official GitLab conditional pipeline documentation.

Now your pipeline will only run Chromatic in the main branch.

Run Chromatic on large projects

Chromatic is prepared to handle large file uploads (with a limit of 5000 files, including stories and assets). If your project exceeds this limit, we recommend adjusting your pipeline and run the chromatic command with the --zip flag to compress your build before uploading it. For example:

.gitlab-ci.yml
# Additional pipeline configurations

# Sets the stages for the pipeline
stages:
  - UI_Tests

# 👇 Adds Chromatic as a job
Chromatic:
  stage: UI_Tests
  # 👇 Runs Chromatic with the flag to compress the build output.
  script:
    - npx chromatic --zip

Run Chromatic on monorepos

Chromatic can be run on monorepos that have multiple subprojects. Each subproject will need it’s own project token.

Prerequisites

  1. Ensure that you’re in the correct working directory for the subproject.
  2. Have build-storybook npm script in the subproject’s package.json file OR explicitly name the script using the buildScriptName parameter and make sure the script is listed in the subproject’s package.json file.

If you’ve already built your Storybook in a separate CI step, you can alternatively point the action at the build output using the storybookBuildDir parameter.

.gitlab-ci.yml
# .gitlab-ci.yml

# Additional pipeline configurations

# Sets the stages for the pipeline
stages:
  - UI_Tests

# 👇 Runs Chromatic in parallel for each monorepo subproject.
Chromatic_publish_project_1:
  stage: UI_Tests
  before_script:
    # Other steps
    - cd packages/project_1
  script:
    - npx chromatic
  variables:
    CHROMATIC_PROJECT_TOKEN: $CHROMATIC_PROJECT_TOKEN_1

chromatic_publish_project_2:
  stage: UI_Tests
  before_script:
    # Other steps
    - cd packages/project_2
  script:
    - npx chromatic
  variables:
    CHROMATIC_PROJECT_TOKEN: $CHROMATIC_PROJECT_TOKEN_2

Additional paralellization can be achieved when configuring your workflow to run Chromatic on multiple subprojects. Read the official GitLab documentation.

Disable Shallow Cloning

GitLab performs a shallow clone by default, which can lead to required patch builds depending on how frequently you run builds between commits. In order to avoid this, adjust your workflow to include a GIT_DEPTH of 0. This ensures Chromatic can fetch your entire git history, without having to adjust your general Git strategy settings within GitLab:

.gitlab-ci.yml
# Additional pipeline configurations

# 👇 Sets the depth to fetch all git history
variables:
  GIT_DEPTH: 0

Enable TurboSnap

TurboSnap is an advanced Chromatic feature implemented to improve the build time for large projects, disabled by default once you add Chromatic to your CI environment. To enable it, you’ll need to adjust your existing workflow and run the chromatic command with the --only-changed flag as follows:

.gitlab-ci.yml
# Additional pipeline configurations

# Sets the stages for the pipeline
stages:
  - UI_Tests

# 👇 Adds Chromatic as a job
Chromatic:
  stage: UI_Tests
  # 👇 Enables Chromatic's TurboSnap feature.
  script:
    - npx chromatic --only-changed

TurboSnap is highly customizable and can be configured to fit your requirements. For more information, read our documentation.

UI Test and UI Review

UI Tests and UI Review rely on branch and baseline detection to keep track of snapshots. We recommend the following configuration.

Command exit code for “required” checks

If you are using pull request statuses as required checks before merging, you may not want your pipeline to fail if test snapshots render without errors (but with changes). To achieve this, pass the flag --exit-zero-on-changes to the chromatic command, and your step will continue in such cases. For example:

.gitlab-ci.yml
# Additional pipeline configurations

# Sets the stages for the pipeline
stages:
  - UI_Tests

# 👇 Adds Chromatic as a job
Chromatic:
  stage: UI_Tests
  # 👇 Runs Chromatic with the flag to prevent pipeline failure
  script:
    - npx chromatic --exit-zero-on-changes

When using --exit-zero-on-changes your pipeline execution still stop and fail if your Storybook contains stories that error. If you’d prefer Chromatic never to block your pipeline, you can use npx chromatic || true.

Re-run failed builds after verifying UI test results

Builds that contain visual changes need to be verified. They will fail if you are not using --exit-zero-on-changes. Once you accept all the changes, re-run the pipeline and the Run Chromatic step will pass.

If you deny any change, you will need to make the necessary code changes to fix the test (and thus start a new build) to get Chromatic to pass again.

Maintain a clean “main” branch

A clean main branch is a development best practice and highly recommended for Chromatic. This means testing your main branch to ensure builds are passing. It’s important to note that baselines will not persist through branching and merging unless you test your main branch.

If the builds are a result of direct commits to main, you will need to accept changes to keep the main branch clean. If they’re merged from feature-branches, you will need to make sure those branches are passing before you merge into main.

GitLab squash/rebase merge and the “main” branch

GitLab’s squash/rebase merge functionality creates new commits that have no association to the branch being merged. If you are already using this option, then we will automatically detect this situation and bring baselines over (see Branching and Baselines for more details).

If you’re using this functionality but notice the incoming changes were not accepted as baselines in Chromatic, then you’ll need to adjust the pipeline and include the --auto-accept-changes flag. For example:

.gitlab-ci.yml
# Additional pipeline configurations

# Sets the stages for the pipeline
stages:
  - UI_Tests

# 👇 Checks if the branch is not main and runs Chromatic
Chromatic_Auto_Accept_Changes:
  stage: UI_Tests
  script:
    - npx chromatic --auto-accept-changes
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: always

  # 👇 Checks if the branch is not main and runs Chromatic
Chromatic:
  stage: UI_Tests
  script:
    - npx chromatic
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      when: always
      allow_failure: true

Including the --auto-accept-changes flag ensures all incoming changes will be accepted as baselines. Additionally, you’ll maintain a clean main branch.

If you want to test the changes introduced by the rebased branch, you can adjust your workflow and include a new step with the ignore-last-build-on-branch flag. For example:

.gitlab-ci.yml
# Additional pipeline configurations

# Sets the stages for the pipeline
stages:
  - UI_Tests

# 👇 Adds Chromatic as a job
Chromatic:
  stage: UI_Tests
  script:
    # 👇 Option to skip the last build on target branch
    - npx chromatic --ignore-last-build-on-branch=my-branch

Including the --ignore-last-build-on-branch flag ensures the latest build for the specific branch is not used as a baseline.

Run Chromatic on external forks of open source projects

You can enable PR checks for external forks by sharing your project token where you configured the Chromatic command (often in package.json or in the pipeline step).

Sharing project tokens allows contributors and others to run Chromatic builds on your project, consuming your snapshot quota. They cannot access your account, settings, or accept baselines. This can be an acceptable tradeoff for open source projects that value community contributions.

Skipping builds for certain branches

Sometimes you might want to skip running a build for a certain branch, but still have Chromatic mark the latest commit on that branch as “passed”. Otherwise pull requests could be blocked due to required checks that remain pending. To avoid this issue, you can run chromatic with the --skip flag. This flag accepts a branch name or glob pattern.

One use case for this feature is skipping builds for branches created by a bot. For instance, Renovate automatically updates a projects dependencies. Although some dependencies can result in UI changes, you might not find it worthwhile to run Chromatic for every single dependency update. Instead, you could rely on Chromatic running against the main or develop branch.

To skip builds for renovate branches, use the following:

npx chromatic --skip 'renovate/**'

To apply this to multiple branches, use an “extended glob”. See the globs guide for details.

npx chromatic --skip '@(renovate/**|your-custom-branch/**)'