GitLab’s CI/CD can trigger other pipelines, but it’s not about just calling a function; it’s about a complex dance of security tokens and event propagation.
Imagine you have a project, "App A," that builds and deploys your main application. You also have another project, "App B," which is responsible for integration testing against a deployed instance of "App A." You want "App B"'s pipeline to run only after "App A" has successfully deployed.
Here’s how you’d set that up. In App A’s .gitlab-ci.yml:
deploy_app_a:
stage: deploy
script:
- echo "Deploying App A to production..."
# Your actual deployment commands here
environment:
name: production
url: https://app-a.example.com
only:
- main # Or your production branch
trigger_app_b_pipeline:
stage: post_deploy
script:
- echo "Triggering App B pipeline..."
- 'curl --request POST --header "PRIVATE-TOKEN: $GITLAB_TRIGGER_TOKEN" "https://gitlab.example.com/api/v4/projects/$PROJECT_B_ID/trigger/pipeline?ref=main&token=$GITLAB_TRIGGER_TOKEN"'
needs:
- deploy_app_a # Ensure this runs after deployment
only:
- main
And in App B’s .gitlab-ci.yml:
integration_test:
stage: test
script:
- echo "Running integration tests against App A..."
# Your integration test commands here
- 'curl https://app-a.example.com/health' # Example check
For this to work, you need two things:
- A
PROJECT_B_IDvariable: This is the numerical ID of your "App B" project. You can find it in "App B"'s project settings under "General" -> "General information." - A
GITLAB_TRIGGER_TOKENvariable: This is a special token that grants permission to trigger pipelines in "App B."
Here’s how to create and use the trigger token:
In "App B," navigate to Settings > CI/CD > Pipelines. Expand the "CI/CD Triggers" section and click "Create trigger." Give it a description (e.g., "Trigger from App A"). GitLab will generate a token. Copy this token immediately as it will only be shown once.
Now, go to "App A"'s project settings > CI/CD > Variables. Add two new Protected and Masked variables:
- Key:
GITLAB_TRIGGER_TOKEN - Value: The trigger token you just copied from "App B."
- Key:
PROJECT_B_ID - Value: The numerical ID of "App B."
The curl command in App A’s .gitlab-ci.yml uses the GitLab API to initiate a new pipeline in "App B." The PRIVATE-TOKEN header authenticates the request using the trigger token. $PROJECT_B_ID specifies which project to trigger, and ref=main tells it to trigger a pipeline for the main branch of "App B."
The needs: [deploy_app_a] clause in "App A" ensures that the trigger_app_b_pipeline job only runs after the deploy_app_a job has successfully completed. This establishes the desired sequence: deploy "App A," then trigger tests for "App B."
The environment block in deploy_app_a is not strictly necessary for triggering, but it’s good practice for tracking deployments and can be used in conjunction with environment-specific triggers or approvals.
You can also trigger pipelines in the same project, but that’s usually less common and might indicate a workflow that could be simplified within a single .gitlab-ci.yml.
The token parameter in the curl command is redundant if you’re already passing PRIVATE-TOKEN in the header. The API endpoint projects/:id/trigger/pipeline expects either a token query parameter or an Authorization: Bearer <token> header. Using PRIVATE-TOKEN is generally preferred for clarity and consistency with other GitLab API calls.
The ref parameter is crucial. If you omit it, the pipeline will be triggered on the default branch, which might not be what you intend if you have different branches for development and production.
If you want to pass variables to the downstream pipeline, you can add them to the curl command:
trigger_app_b_pipeline:
stage: post_deploy
script:
- echo "Triggering App B pipeline with variables..."
- 'curl --request POST --header "PRIVATE-TOKEN: $GITLAB_TRIGGER_TOKEN" "https://gitlab.example.com/api/v4/projects/$PROJECT_B_ID/trigger/pipeline?ref=main&token=$GITLAB_TRIGGER_TOKEN&variables[APP_A_VERSION]=1.2.3&variables[DEPLOY_ENV]=staging"'
needs:
- deploy_app_a
only:
- main
These variables (APP_A_VERSION, DEPLOY_ENV) will then be available in "App B"'s pipeline environment.
The most surprising thing about this mechanism is how the trigger token acts as a credential for initiating a pipeline, rather than an execution context. It’s a lightweight, project-specific credential for an API endpoint, not a full-fledged service account.
When you trigger a pipeline this way, it runs as a distinct pipeline in the target project, with its own set of jobs and execution context. It doesn’t inherit the environment variables or the Git history of the triggering pipeline, except for those explicitly passed as variables.
The next thing you’ll likely want to tackle is how to wait for the triggered pipeline to complete and then act on its success or failure, which often involves polling the GitLab API or using webhooks.