Bitbucket is getting a new navigation

We’re rolling out these changes, so the documentation may not match your experience in the Bitbucket Cloud app. Read about the new Bitbucket navigation

Share Pipelines Configurations

Premium only

Pipelines configuration sharing is a Bitbucket Cloud Premium feature. Learn more about Bitbucket Premium

Being able to share your YAML configuration in Bitbucket Pipelines allows you to define and share pipeline definitions within the same repository or workspace, which enables you to streamline your pipeline definitions by not having to repeatedly create each pipeline configuration.

Setup YAML sharing for your repository

  1. Create a seperate YAML file within your repository, with the suffix *pipelines.yml. For the sake of the example below, we are placing this file at .bitbucket/shared-pipelines.yml. Put your Pipeline definition under the definitions: pipelines section of the file.

All pipelines defined under the definitions: pipelines section will be exported and can be imported by the main pipelines file in that repository. Check out the example below.

definitions: pipelines: share-pipeline-1: - step: name: "hello world" script: - echo hello

You can edit this local config sharing file via the Bitbucket user interface (UI), but note that the file cannot be validated in-editor against the pipelines YAML syntax.

2. In your main bitbucket-pipelines.yml file, declare a name and slug for your Import Source under definitions: imports. When importing from within the same repository, the slug is simply the path to the file you want to import:

definitions: imports: shared-pipelines: .bitbucket/shared-pipelines.yml

3. Further on in the same bitbucket-pipelines.yml file, specify the import property in your pipeline, referencing the pipeline name and the name of the import source from which you want to import the shared pipeline configuration. You can use any of the pipelines start-conditions when importing a pipeline.

Example of importing in a custom triggered pipeline:

pipelines: custom: import-pipeline: import: share-pipeline-1@shared-pipelines

Example of importing in a branch triggered pipeline for a branch named main

pipelines: branches: main: import: share-pipeline-1@shared-pipelines

Setup YAML sharing for your workspace

  1. Create a repository in the workspace where you’ll be adding the shared pipeline definition. For more information on creating a repository, refer to our Create a Git repository help document.

  2. Create a separate YAML file (as with Step 1 above of sharing config within a repository) but note that pipelines shared between repositories must additionally have their export files declare export: true as a top-level property, to allow them to be shared across repositories. In the example below, we’re saving our shared configuration in a repository called shared-pipelines and have again saved this export file at .bitbucket/shared-pipelines.yml.

Example

export: true definitions: pipelines: share-pipeline-2: - step: name: "hello world" script: - echo hello

You can also use the main bitbucket-pipelines.yml configuration file of a repository to share pipelines under the definition section while also having pipelines configured as usual for that repository. It must also declare export: true in this case.

export: true definitions: pipelines: share-pipeline-3: - step: name: "hello world" script: - echo hello pipelines: default: - step: name: "Default Pipelines" script: - echo "I'm the default pipeline of this repository."

A good way to separate ‘exported’ pipelines from other pipelines is by including them under the definitions section, which allows you to separate the Pipeline definitions you want to export from the Pipelines you want to run on the actual repository itself.

  • For example - you may run some basic .yaml validation logic in a Pipeline against the repository containing the exported .yaml, but not want to actually export that .yaml validation logic to other repositories for them to consume.

3. In the repository where you want to reuse the pipeline definition, you need to declare a name and slug for your import source. When importing from a seperate repository, the slug must specify the repo name and the git branch or tag reference of your target configuration. If you are using a custom filepath, you’ll need to specify this path, but if you are exporting from the bitbucket-pipelines.yml file of another repository, you do not need to specify the file path:

definitions: imports: shared-pipelines-custom: shared-pipelines:master:.bitbucket/shared-pipelines.yml shared-pipelines-standard: shared-pipelines:master # <- from `bitbucket-pipelines.yml`

4. Further on in the same bitbucket-pipelines.yml, specify the import property in your pipeline, referencing the pipeline name and the name of the import source from which you want to import the shared pipeline configuration. You can use any of the pipelines start-conditions when importing a pipeline.

Example importing in custom triggered pipelines:

pipelines: custom: import-pipeline-2: import: share-pipeline-2@shared-pipelines-custom import-pipeline-3: import: share-pipeline-3@shared-pipelines-standard

Example importing in a branch triggered pipeline for a branch named main

pipelines: branches: main: import: share-pipeline-3@shared-pipelines-standard

YAML sharing formatting and rules

Import Sources

  • An import source slug can use any of the three structures below:

    • {config-filepath} for imports within the same repository.

    • {repo-slug-of-exported-pipeline}:{branch/tag-to-import-from} for imports from the bitbucket-pipelines.yml file of a seperate repository.

    • {repo-slug-of-exported-pipeline}:{branch/tag-to-import-from}:{config-filepath} for imports from other files of a seperate repository.

  • For imports from external repositories:

    • The import statement will always reference the HEAD commit of the targeted branch.

    • The import statement will always exact match for pipeline name, glob pattern match is not supported.

    • If you want to reference your exported YAML at particular points in time for use in import statements, you can use a tag instead of the branch name to reference a specific commit rather than the HEAD if the branch.

  • You can specify up to a maximum of 50 import sources in any one pipelines file.

Import Statements

  • An import statement uses the following structure:

    • {pipeline-name}@{import-source-name}

Inline Import Statements (Legacy)

Previously, we have supported an inline syntax for import statements that does not use import source definitions. This structure only supports the use-case of sharing pipelines definitions from the bitbucket-pipelines.yml file of another repository. This format is still supported, but not recommended:

  • {repo-slug-of-exported-pipeline}:{branch/tag-to-import-from}:{pipeline-name}

Security & Access

You do not need to declare export: true for pipelines exported within the same repository. If they don’t need to be shared outside their home repository, export: true shouldn’t be set in order to appropriately scope access to usage.

Important note: Users can execute pipelines that import configurations from repositories they do not have direct access to, if that pipeline configuration has explicitly been declared as export: true.

  • Shared pipeline configs follow a different access control scheme than the one used for users.

  • This is done to avoid complex scenarios where a user doesn’t have access to a repo where a shared pipeline config is stored, leading to their builds failing due to permissions issues.

  • We treat the importing of an external pipeline as an action taken by the repository, not the user. The pipeline is considered to be “shared” with all repo's in that Workspace if it has been set to export: true.

  • Once you mark a pipeline .yaml file with export: true, assume that any repository in the same workspace can view the contents of that Pipeline configuration file, as the contents may be inferable via things like build logs etc.

  • Do not store sensitive information directly within the configuration of exported Pipelines. Always leverage variables and secrets for managing sensitive information as these values are inherited from the importing repository.

  • Note: If a user attempts to navigate via the UI to the source file where a shared pipeline config is stored and they do not have permission to view the repository, they will not be able to view that source file in the UI.

FAQ

Question: Can I share Pipeline Configurations across different Workspaces? Are my shared Pipeline Configurations secure from outside my Workspace?

Answer: Pipeline Config sharing is scoped to the Workspace in which Pipeline Configurations are exported from. Exported Pipeline Configurations cannot be accessed by repositories that are not in the same Workspace.


Question: How do I maintain the stability of the configuration when importing from another repository? What happens if the config in the exporting repo changes and breaks my build?

Answer: Pipelines Config import statements support pinning your import to either a Git Branch or a Git Tag.

When targeting a branch, the import will always pull from the HEAD if that branch, meaning you will get the latest version of the exported Pipeline Configuration. We recommend using this model if you want to maintain currency with any upstream changes.

When targeting a tag, the Pipeline Configuration will always be imported from the commit referenced by the tag pinned. This allows users to create static point-in-time references and version their Pipeline Configurations. In the future, we may add support for pinning to specific commits if this is something users see value in.


Question: What happens if a pipeline is rerun and the imported configuration has changed since the first time it was run?

Answer: If the entire pipeline is rerun, the Pipeline Configuration will be reimported at the point in time that the rerun executes. If the configuration has changed since the initial run, the executed configuration will reflect the new configuration.


Question: What happens if a step is rerun and the imported configuration has changed since the first time it was run?

Answer: If a single step is rerun, the configuration for that step will be exactly the same as the first time the step was run. To reiterate, this is different to the behavior when the entire pipeline is rerun.


Question: How are variables and secrets handled when importing Pipeline Configurations?

Answer: All the variables and secrets from the importing repository will be available to the build, including when that build is executing an imported Pipeline Configuration. If the imported configuration utilizes variables in its scripts, and those variable values are made available by the repository it was imported by, then those variable values will be executed in the build.

Variable values from the exporting repository are not shared or reused in importing repositories.

Note: There is a known limitation with using variables in custom pipelines that utilize a shared Pipeline Configuration. If a repository imports a shared Pipeline Configuration and uses it as part of a custom pipeline, variable values specified at runtime via the UI will not pass to the pipeline execution. Instead, the default values specified in the exported Pipeline configuration will be used.


Question: Can I import a pipeline from a different branch / reference of the same repository?

Answer: Yes. You can use the {repo-slug-of-pipeline}:{branch/tag-to-import-from}:{config-filepath} import source slug pattern to reference an export file on a different branch / tag than your main pipelines file, e.g. for a file on test of the repo same-repo:

definitions: imports: same-repo-different-branch: same-repo:test:.bitbucket/pipelines.yml

Note: When making this type of reference, you will need to declare export: true in the export config file, despite being in the same repository.


Question: Can I customize elements of the imported Pipeline config like step size, max time, image, etc.?

Answer: Yes. Refer to our Dynamic pipelines help documentation for more details.


Question: Can individual steps be shared?

Answer: Yes, individual steps can be shared. See the example provided in the following community post for more information: Share a step across pipelines.


Question: How can I test shared pipeline configurations in shared-pipeline if it is stored in the definitions section?

Answer: You can use a yaml anchor to do it, here is an example:

export: true definitions: pipelines: share-pipeline-1: &share-pipeline-1 - step: name: "hello world" script: - echo hello pipelines: custom: test-share-pipeline-1: *share-pipeline-1

Question: What is the precedence for definitions like caches or services if I have it defined in 2 different repositories with the same name?

Answer: For global options( image, clone, max-time, size, docker) and definitions like caches, services, we always take them from the exporting repository and not the importing repository.

For example, if you have a .bitbucket/shared-pipelines.yml file like this in a repository:

image: atlassian/default-image:3 definitions: services: docker: memory: 1024 redis: image: redis:6 memory: 512 caches: my-custom-cache-without-key: cache my-custom-cache: key: files: - cache-key.txt path: cache pipelines: export-pipeline: - step: services: - docker - redis script: - ls -la - ls -la cache/ || true - echo $BITBUCKET_BUILD_NUMBER > artifact.txt - echo $BITBUCKET_BUILD_NUMBER > cache/cache.txt artifacts: - artifact.txt caches: - my-custom-cache - my-custom-cache-without-key

And bitbucket-pipelines.yml importing this config can be configured as in the example provided below:

image: maven:3.9-eclipse-temurin-11 definitions: services: docker: memory: 2048 redis: image: redis:7 memory: 1024 caches: my-custom-cache: key: files: - local.txt path: local my-custom-cache-without-key: local-path imports: shared-pipelines: .bitbucket/shared-pipelines.yml pipelines: default: import: export-pipeline@shared-pipelines

The default pipeline triggered in this repository will use docker and redis service defined in shared-pipeline, with redis:6 image for redis service. And my-custom-cache, my-custom-cache-without-key from the exporting file and not the importing file.

Also, the step build image is atlassian/default-image:3 not maven:3.9-eclipse-temurin-1.

Still need help?

The Atlassian Community is here for you.