Sharing Artifacts Between GitLab CI Matrix Jobs: React Build Example

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`
How It Works
- Dependency Installation: The
install-dependencies
job installs required node modules and shares them as artifacts. - Parallel Matrix: The
.tenants
template defines a matrix with four different tenants, each with unique branding parameters (VITE_TITLE
andVITE_COLOR
). - Dynamic Builds: The
build
job runs in parallel for each tenant configuration, creating four separate builds with tenant-specific branding. - Artifact Naming Strategy: Each build output is renamed from
dist
todist-$VITE_TITLE
(e.g.,dist-u11d
,dist-AWS
, etc.) to avoid conflicts. - Targeted Artifact Sharing: These uniquely named build directories are shared as artifacts between jobs.
- 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:
Final Results
The approach produces four distinct builds with tenant-specific branding:
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.
