Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0371cc8
add how to guide by Claude
rosieyohannan Jan 27, 2026
065793d
editing flow of tutorial
rosieyohannan Feb 3, 2026
c3bc0c3
present onlt tag push trigger at this stage to slim things down and a…
rosieyohannan Feb 3, 2026
ca18283
some restructuring after following along
rosieyohannan Feb 12, 2026
d766dec
add some clarifying language
rosieyohannan Feb 12, 2026
c73a3b8
Merge branch 'main' into DOCSS-2000-cross-repo-triggers
rosieyohannan Feb 12, 2026
b64c12f
style fixes
rosieyohannan Feb 12, 2026
94cc284
fix title and scenario
rosieyohannan Feb 13, 2026
e2ee76e
Merge branch 'main' into DOCSS-2000-cross-repo-triggers
rosieyohannan Feb 27, 2026
670a3e7
use correct pipeline values
rosieyohannan Mar 2, 2026
2ba5259
use the same consumer pipeline config for both config location options
rosieyohannan Mar 2, 2026
a2a1325
Merge branch 'main' into DOCSS-2000-cross-repo-triggers
rosieyohannan Mar 2, 2026
86799ad
add screenshots
rosieyohannan Mar 2, 2026
b7aab46
fix style errors
rosieyohannan Mar 2, 2026
e63c9dd
Merge branch 'main' into DOCSS-2000-cross-repo-triggers
BeFunes Mar 3, 2026
b2a3aa9
Update docs/guides/modules/orchestrate/pages/set-up-cross-repo-trigge…
rosieyohannan Mar 4, 2026
668aa67
Update docs/guides/modules/orchestrate/pages/set-up-cross-repo-trigge…
rosieyohannan Mar 4, 2026
edfe61b
link to pipeline values docs
rosieyohannan Mar 4, 2026
3da7b70
Update docs/guides/modules/orchestrate/pages/set-up-cross-repo-trigge…
rosieyohannan Mar 4, 2026
813d939
Update docs/guides/modules/orchestrate/pages/set-up-cross-repo-trigge…
rosieyohannan Mar 4, 2026
f1f744c
link to pipeline values
rosieyohannan Mar 4, 2026
3e205d7
add diagrams and remove references to non-tag triggers
rosieyohannan Mar 6, 2026
dc98e93
Merge branch 'main' into DOCSS-2000-cross-repo-triggers
rosieyohannan Mar 6, 2026
a2c578f
move images to trigger setup section
rosieyohannan Mar 6, 2026
f3172e1
Merge branch 'main' into DOCSS-2000-cross-repo-triggers
rosieyohannan Mar 11, 2026
4ecbbce
Apply suggestion from @BeFunes
BeFunes Mar 11, 2026
95f96fa
Apply suggestion from @rosieyohannan
rosieyohannan Mar 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/guides/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
*** xref:orchestrate:schedule-triggers.adoc[Schedule triggers]
** How-to guides
*** xref:orchestrate:orchestration-cookbook.adoc[Orchestration cookbook]
*** xref:orchestrate:set-up-cross-repo-triggers-for-library-consumers.adoc[Set up cross-repo triggers for library consumers]
*** xref:orchestrate:how-to-override-config.adoc[How to override config]
*** xref:orchestrate:set-up-multiple-configuration-files-for-a-project.adoc[Set up multiple configuration files for a project]
*** xref:orchestrate:notify-a-slack-channel-of-a-paused-workflow.adoc[Notify a Slack channel of a paused workflow]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,343 @@
= Set up cross-repo triggers for library consumers
:page-platform: Cloud
:page-description: Learn how to automatically trigger consumer repository pipelines when you tag a new library release.
:experimental:
:page-show-readtime: true

*Cross-repo triggers allow you to run a pipeline to build code from one repository when an event occurs in another repository*. In this guide you will learn how to set up a cross-repo trigger. A cross-repo trigger watches for events in a repository other than the one that contains the pipeline configuration.

*For this how-to guide we have chosen the following scenario:*

When you tag a new release of an internal library, configure CircleCI to automatically run tests in the repositories that consume that library. Running integration tests validates that your library changes work with your dependent applications before you publish the release.

*What you will set up:*

* A trigger that watches for new tags in your library repository.
* A consumer pipeline that runs automatically when those tags are created.
* Configuration to test the consumer application against the specific library version that was tagged.

TIP: **Why tag-based triggers?** Tags represent stable release points in your library's development. Testing consumers against tagged versions ensures that each library release is validated before being published to package registries or deployed to production. While this guide focuses on tag-based triggers, if you need to *trigger on other events like branch pushes or pull requests*, see the xref:guides:orchestrate:triggers-overview.adoc[Triggers Overview] page for alternative approaches.

== Prerequisites

Before following this guide, ensure you have the following:

* A CircleCI account connected to GitHub using the GitHub App integration.
* A "library" repository and a "consumer" repository. These repositories must be in the same GitHub organization. If you want to follow the centralized config options, you will need a third repository for your centralized config store.
* Admin access to both the library repository and the consumer repository in GitHub.

=== Decide on your configuration approach

You have two options for structuring your cross-repo trigger setup. Each approach has different benefits depending on your situation.

[.table-scroll]
--
[cols="1,1,1",options="header"]
|===
| |Option 1: Config in consumer repository |Option 2: Centralized config repository

|**Description**
|The pipeline configuration file lives in the same repository as the consumer code.
|The pipeline configuration file lives in a separate repository dedicated to CI/CD configurations.

|**Config source**
|Consumer repository
|Central config repository

|**Checkout source**
|Consumer repository
|Consumer repository

|**Trigger source**
|Library repository
|Library repository

|**When to use**
|Use this option when each consumer has unique test requirements or when you want teams to maintain their own CI/CD configurations.
|Use this option when you want a platform team to maintain consistent test configurations across multiple consumers, or when you want to reuse the same configuration file for multiple consumer repositories.

|**Repository structure**
a|
[source,shell]
----
my-library/
my-consumer-app/
├── .circleci/
│ └── config.yml
└── src/
----
a|
[source,shell]
----
my-library/
my-consumer-app/
└── src/
circleci-configs/
├── .circleci/
│ ├── consumer-config.yml
│ └── other-config.yml
----

|**Benefits**
|Teams maintain their own configurations
a|
* **Consistency**: Ensure all consumers test library changes using the same validation approach.
* **Maintenance**: Update test procedures across all consumers by modifying a single configuration file.
* **Governance**: Platform teams can enforce testing standards and best practices.
* **Reusability**: Share configuration logic across multiple consumer repositories.

|===
--

NOTE: This guide demonstrates both approaches. The steps below use tabs to show the differences between Option 1 and Option 2.

== 1. Create configuration file for your consumer pipeline

To follow this how-to guide you will need a CircleCI configuration file for your consumer pipeline. This file will define the steps you want to run when the library changes.

This section covers some elements you might want to include in your configuration file. If you just want to follow along you can use the example config file provided at the end of this section.

When a change to your library triggers your consumer pipeline, you need to know which _version_ of the library initiated the trigger so you can test against that specific version. CircleCI provides built-in pipeline values that capture details about the trigger event, including the tag name, branch name, commit SHA, and repository name.

CircleCI automatically populates the following pipeline values when a cross-repo trigger fires:

* `pipeline.event.github.ref`: The full Git ref that was pushed, this will be a tag name for tag triggers.
* `pipeline.event.github.after`: The SHA of the most recent commit on the branch after the push.
* `pipeline.event.github.repository.name`: The name of the library repository that triggered the pipeline.

You can use these values directly in your configuration without declaring them as parameters.

Here is an example consumer configuration file that uses the built-in pipeline values. This configuration works regardless of whether you store your configuration in the consumer repository or a centralized config repository. CircleCI automatically populates the pipeline values with trigger information regardless of where the config file is stored.

.Example consumer configuration file using built-in pipeline values
[source,yaml]
----
version: 2.1

# Minimal config file for library integration tests
# This config will be triggered when the library repository has events (tags, pushes, etc.)

jobs:
test-with-library:
docker:
- image: cimg/node:18.0
steps:
- checkout # checks out the consumer repository code

- run:
name: Display trigger information
command: |
echo "=== Cross-repo trigger information ==="
echo "Library version/tag: << pipeline.event.github.ref >>"
echo "Library commit: << pipeline.event.github.after >>"
echo "Library repo: << pipeline.event.github.repository.name >>"

- run:
name: Install consumer dependencies
command: |
# Create a minimal package.json for the consumer app
echo '{"name": "my-consumer-app", "version": "1.0.0", "dependencies": {}}' > package.json
npm install

- run:
name: Install library version from trigger
command: |
# In a real scenario, this would install from npm registry:
# npm install @myorg/my-library@<< pipeline.event.github.ref >>

echo "Installing library from trigger..."
LIBRARY_VERSION="<< pipeline.event.github.ref >>"
if [ -z "$LIBRARY_VERSION" ]; then
LIBRARY_VERSION="<< pipeline.event.github.after >>"
fi
echo "Would install: @myorg/my-library@${LIBRARY_VERSION}"
echo "Installation simulated successfully"

- run:
name: Run integration tests
command: |
echo "Running integration tests with library..."
echo "Testing consumer app functionality with library..."
echo "All integration tests passed!"

workflows:
validate-library-integration:
jobs:
- test-with-library:
filters:
tags:
only: /.*/
----

IMPORTANT: The `filters` section is required because CircleCI does not run workflows for tags unless you explicitly specify tag filters. The pattern `/.*/` matches all tags. Both lightweight and annotated tags are supported.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested, and this is actually not needed because the TAG is triggering the pipeline, but the checkout reference is a branch, not a tag.
It's super confusing, but basically no tag filter is needed


In this example:

* When a tag like `v1.2.3` is created in the library repository, `<< pipeline.event.github.ref >>` will contain `v1.2.3`.
* The workflow filter ensures the workflow runs for tag events.
* The configuration installs that specific version using `npm install @myorg/my-library@v1.2.3`.
* If triggered by a push (not a tag), it falls back to using the commit SHA.
* The consumer tests then run against the exact library version that triggered the pipeline.

Once you have created your config file, or decided to use our example, commit and push the config file to either your consumer repository or your centralized config repository. We recommend storing CircleCI configuration files in a `.circleci` directory in your repository but you can store them wherever you like as long as they have a `.yml` extension.

== 2. Set up your consumer project in CircleCI

Follow steps in the xref:guides:getting-started:create-project.adoc[Create a Project in CircleCI] guide, or just follow the in-app guidance to create/set up your consumer project in CircleCI.

== 3. Set up the consumer pipeline

The consumer pipeline defines what should run when the library changes. Follow these steps, selecting the project you set up for your consumer repository.

include::guides:ROOT:partial$app-navigation/steps-to-project-settings.adoc[]

. Select **Project Setup** in the sidebar.
. Select **Add Pipeline** at the top of the pipelines section.
. Give your pipeline a descriptive name, for example `Library integration tests`.
. Configure the pipeline sources and config file based on your chosen approach:
+
[tabs]
====
Option 1: Config in consumer repository::
+
--
.. For **Config source**, select your consumer repository from the dropdown menu.
.. In the **Config filepath** field, you can either leave the default if you want to run your existing `circleci/config.yml` file, or enter the path to the specific configuration file for this pipeline if you want to run a different build on changes to the library, for example `.circleci/library-integration-tests-config.yml`.
.. For **Checkout source**, select your consumer repository from the dropdown menu.

.. Select btn:[Save].

.Example of a pipeline configured for a consumer repository
image::guides:ROOT:cross-repo-pipeline-consumer.png[Pipeline configured for consumer repository]

You now have a pipeline configured for your consumer repository. The next step is to add a trigger that watches for events in your library repository.
--

Option 2: Centralized config repository::
+
--
.. For **Config source**, select your central config repository from the dropdown menu (not the consumer repository). Select the branch where your configuration files are stored (typically `main`).
.. In the **Config path** field, enter the path to the specific configuration file for this consumer, for example `.circleci/consumer-app-config.yml`.
+
TIP: If your central config repository contains configurations for multiple projects, use descriptive file names like `.circleci/consumer-app-integration-tests.yml` or organize them in subdirectories like `.circleci/consumers/my-app/config.yml`.

.. For **Checkout source**, select your consumer repository from the dropdown menu (this is the repository whose code will be tested).
.. Select **Save**.
+
NOTE: When using centralized configuration, the `checkout` step will check out code from the consumer repository (the checkout source), not from the central config repository. This allows you to maintain configurations separately from application code.

.Example of a pipeline configured for a centralized config repository
image::guides:ROOT:cross-repo-pipeline-central.png[Pipeline configured for centralized config repository]

Your pipeline is now configured to fetch its configuration from the central repository while checking out code from the consumer repository.
--
====

== 4. Add a trigger for library events

The trigger tells CircleCI to run the consumer pipeline when tags are created in your library repository. This guide focuses on tag-based triggers as they are the most common pattern for library releases.

=== 4.a. Create the trigger in CircleCI

. Select **GitHub trigger +** at the bottom of the pipeline box.
. From the **Event** dropdown menu, select **Tag pushes**.
+
NOTE: You can also configure triggers for other events like **PR merged** or **All pushes**. See the xref:guides:orchestrate:triggers-overview.adoc[Triggers Overview] for more information.

. From the **Event Source** dropdown menu, select your library repository instead of the consumer repository.
+
The trigger will now run the consumer pipeline when a new tag is created in the library repository, which is ideal for testing against official library releases.
+
Changing the *event source* is what enables the cross-repo trigger. The trigger now watches for events in the library repository rather than the consumer repository.

. Because the event source differs from the config source, you will see a field labeled **Config branch**. Enter the branch name where your consumer pipeline configuration is stored (typically `main`).
+
This tells CircleCI which branch to use when fetching the configuration file from the consumer repository.
+
If you are using a centralized config repository, you will also need to enter a branch name for the checkout source, typically `main`.

. Select btn:[Save].

=== 4.b. Configure tag filters in your workflow

The trigger is now configured in CircleCI, but you also need to update your configuration file for your integration tests to run workflows for tags.

By default, *CircleCI does not run workflows for tags unless you explicitly specify tag filters*. For more information, see the xref:guides:orchestrate:workflows.adoc#executing-workflows-for-a-git-tag[Executing Workflows for a Git Tag] section.

In the configuration file for your consumer pipeline, add tag filters to your workflow if they are not already present. Here is an example:

.Example of a workflow with tag filters
[source,yaml]
----
workflows:
validate-library-integration:
jobs:
- your-job-name:
filters:
tags:
only: /.*/ # Matches all tags
----

The pattern `/.*/` matches all tags. Both lightweight and annotated tags are supported.

Your cross-repo trigger is now fully configured. When a tag is created in your library repository, CircleCI will trigger the consumer pipeline and run your workflows.
Comment on lines +333 to +355
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So all of this can be removed too. I'm almost tempted to say we should leave it to avoid confusing customers, but truly - it's not needed 😢

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about if I remove but then add a note that if you don't use the tag trigger but instead choose all pushes you need it? and just point people to where we explain in the workflows doc: https://circleci.com/docs/guides/orchestrate/workflows/#executing-workflows-for-a-git-tag but actually that section needs updating too to reference the ability to use a tag trigger?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the "Tag pushes" triggers is not the reason why this is not needed, it's more nuanced than that.
It's still true that when you use "Tag pushes", in a single repo situation you will need that filter.

The reason is that the filter: \n tags: filter behind the scenes looks at the pipeline value pipeline.git.tag, which is only populated if the checkout ref is a tag.
In this situation, pipeline.git.tag is empty, because we're checking out a branch (main). The fact that you're triggering through tag does not affect it.

I don't think this is how things should work, but at the moment it's the reality, unfortunately.


== 5. Test your cross-repo trigger

Verify that your trigger is configured correctly by creating a tag in your library repository.

. Navigate to your library repository in GitHub.
. Create a new tag using the command line or GitHub interface:
+
[source,console]
----
$ git tag v1.2.3
$ git push origin v1.2.3
----

. Open the link:https://app.circleci.com/[CircleCI web app, window="_blank"] in your browser and select your organization.
. You should see a new pipeline running with the name you configured in step 2.
. Select the running pipeline to view the workflow and jobs.
. Verify that the library information is passed to your jobs by checking the job output.
+
.Example of the job output for a cross-repo trigger
image::guides:ROOT:cross-repo-check-job.png[Cross-repo trigger output]

If your pipeline does not trigger:

* Verify that the trigger event source is set to your library repository.
* Check that the config branch name matches the branch where your `.circleci/config.yml` file exists.
* Ensure the event type matches the action you performed (for example, creating a tag for "Tag created" triggers).

== Conclusion

You have now set up a tag-based cross-repo trigger system that automatically validates library releases against consumer repositories.

**What happens now:**

When you create a tag in your library repository (for example, `v1.2.3`), the following workflow runs automatically:

[mermaid]
----
flowchart TD
A[Create tag v1.2.3 in library repository] --> B[Trigger detects new tag]
B --> C[Consumer pipeline starts]
C --> D[Check out consumer application code]
D --> E[Workflow runs with tag filters]
E --> F[Install library version v1.2.3]
F --> G[Run integration tests]
G --> H{Tests pass?}
H -->|Yes| I[Verify release works with consumer]
H -->|No| J[Fix issues before publishing]
I --> K[Publish library release with confidence]
----

This setup helps you catch integration issues early and ensures that library releases do not break dependent applications. You now have confidence that when you publish a library release, it will work correctly with your consumers.

TIP: *Multiple consumers for one library?* If you have multiple consumer repositories that depend on your library, repeat the steps in this guide for each consumer repository. Each consumer can have its own pipeline configuration and trigger settings based on its specific testing requirements.

== Next steps

* Learn about trigger types in the xref:guides:orchestrate:triggers-overview.adoc[Triggers Overview] page. Explore triggering on pushes or pull requests instead of tags.
* Learn about xref:guides:orchestrate:workflows.adoc#executing-workflows-for-a-git-tag[Workflow Filtering]. Configure more advanced workflow filters for different scenarios.
* Implement dynamic configuration for complex validation scenarios. See the xref:guides:orchestrate:dynamic-config.adoc[Dynamic Configuration] page for more information.
5 changes: 3 additions & 2 deletions styles/config/vocabularies/Docs/accept.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
\bgithub organization\b
\b[Gg]it[Hh]ub organization\b
\bcircleci organization\b
\bbitbucket organization\b
.circleci/config.yml
Expand Down Expand Up @@ -150,7 +150,8 @@ FAQs?
Fastfile
Fastlane
/bFastlane Match/b
filename
[Ff]ilename
[Ff]ilepath
framebuffer
frameit
\bFree Plan\b
Expand Down