Michał Miler
Michał Miler
Senior Software Engineer

Sharing Artifacts Between GitLab CI Matrix Jobs: React Build Example

Apr 02, 20253 min read

When working with GitLab CI/CD pipelines that involve complex deployment scenarios, particularly with multi-tenant or multi-environment setups, passing artifacts between jobs can be challenging. In this article, we'll explore a versatile approach to dynamically generate and share build artifacts across jobs using GitLab's parallel:matrix feature, focusing on a practical React application build example.

Understanding parallel:matrix and Dynamic Artifacts Challenge

GitLab's parallel:matrix feature allows you to run multiple jobs in parallel while dynamically assigning different values to environment variables. This is especially useful in CI/CD workflows where:

  • You need to deploy to multiple environments or tenants concurrently
  • You are building applications with different configurations
  • Each parallel job requires unique parameters or branding

However, when working with these parallel jobs, handling artifacts becomes complex. When multiple parallel jobs generate different build artifacts, you need a way to ensure each artifact is uniquely identifiable and properly passed to corresponding downstream jobs. This creates a challenge: how do we generate unique builds for each parallel execution and ensure they're available to subsequent jobs? The solution we'll explore uses a naming convention for artifact directories to reliably pass environment-specific builds between matrix jobs. By using parallel:matrix, GitLab will automatically create a parallel job for each combination in your matrix, and our artifact approach ensures builds flow correctly between these jobs.

Practical Example: Multi-Tenant React Build Pipeline

Initial Setup

Here's a GitLab CI configuration that demonstrates our approach with a React application:

default: image: node:22.14.0-bookworm-slim stages: - install-dependencies - build - deploy .tenants: parallel: matrix: - VITE_TITLE: u11d VITE_COLOR: "#620bef" - VITE_TITLE: MedusaJS VITE_COLOR: "#ffffff" - VITE_TITLE: Terraform VITE_COLOR: "#7b42bc" - VITE_TITLE: AWS VITE_COLOR: "#ff9900" install-dependencies: stage: install-dependencies needs: [] script: - yarn artifacts: paths: - node_modules expire_in: 1 hour build: stage: build extends: - .tenants environment: $VITE_TITLE needs: - install-dependencies script: - yarn build - mv dist dist-$VITE_TITLE artifacts: paths: - dist-$VITE_TITLE expire_in: 1 hour deploy: stage: deploy extends: - .tenants environment: $VITE_TITLE needs: - build script: - echo "Deploying to $TENANT" - cd dist-$VITE_TITLE - ls # all build artifacts for $VITE_TITLE are available in `dist-$VITE_TITLE`

sharing-artifacts-between-gitlab-ci-matrix-jobs-image1.webp

How It Works

  1. Dependency Installation: The install-dependencies job installs required node modules and shares them as artifacts.
  2. Parallel Matrix: The .tenants template defines a matrix with four different tenants, each with unique branding parameters (VITE_TITLE and VITE_COLOR).
  3. Dynamic Builds: The build job runs in parallel for each tenant configuration, creating four separate builds with tenant-specific branding.
  4. Artifact Naming Strategy: Each build output is renamed from dist to dist-$VITE_TITLE (e.g., dist-u11d, dist-AWS, etc.) to avoid conflicts.
  5. Targeted Artifact Sharing: These uniquely named build directories are shared as artifacts between jobs.
  6. Artifact Consumption: The deploy job accesses the correct build artifact by using the same naming convention (dist-$VITE_TITLE).

This approach results in a pipeline that looks like this: Pipeline graph

Final Results

The approach produces four distinct builds with tenant-specific branding: sharing-artifacts-between-gitlab-ci-matrix-jobs-image3.png

sharing-artifacts-between-gitlab-ci-matrix-jobs-image4.png

sharing-artifacts-between-gitlab-ci-matrix-jobs-image5.png

sharing-artifacts-between-gitlab-ci-matrix-jobs-image6.png

Working Example

A complete working example of this implementation is available in our public GitLab repository: https://gitlab.com/u11d-michal-miler/gitlab-ci-artifacts-sharing

Feel free to clone the repository and experiment with the pipeline to see how the artifact sharing works in practice.

Conclusion

The technique explained above isn't limited to React applications. You can use similar approaches to:

  • Building artifacts for different platforms
  • Creating configuration files dynamically for multiple environments
  • Managing complex multi-tenant deployments
  • Customizing builds for different client brands

The key is GitLab's powerful artifact and variable sharing mechanisms combined with a strategic naming convention, which allows you to create truly dynamic and flexible CI/CD pipelines.

Sharing artifacts in GitLab CI, especially with parallel matrix jobs, doesn't have to be complicated. By leveraging a consistent naming pattern and GitLab's built-in artifact functionality, you can create robust, flexible build pipelines that work seamlessly across multiple scenarios and environments.

In the next article, we'll explore how to extend this approach to pass dynamic environment variables between GitLab CI matrix jobs using AWS OIDC as an example.

Need Help?

If you're struggling to implement this approach or have specific questions, don't hesitate to reach out to our DevOps team or seek community support.

A person sitting and typing on a laptop keyboard
RELATED POSTS
Michał Miler
Michał Miler
Senior Software Engineer

Passing Dynamic Environment Variables Between GitLab CI Matrix Jobs: AWS OIDC Example

Apr 09, 20254 min read
Article image
Michał Miler
Michał Miler
Senior Software Engineer

Passing Body Data in Strapi Webhooks: Triggering GitHub Workflows Example

Nov 27, 20246 min read
Article image
Tomasz Fidecki
Tomasz Fidecki
Managing Director | Technology

Templating Values in Kustomize: Unlocking the Potential of Dynamic Naming for Kubernetes Resources

Mar 13, 20247 min read
Article image