Bitbucket Pipelines share SOME steps between branches

Viewed 20179

Is it possible to share steps between branches and still run branch specific steps? For example, the develop and release branch has the same build process, but uploaded to separate S3 buckets.

pipelines:
  default:
    - step:
        script:
          - cd source
          - npm install
          - npm build
  develop:
    - step:
        script:
          - s3cmd put --config s3cmd.cfg ./build s3://develop

  staging:
    - step:
        script:
          - s3cmd put --config s3cmd.cfg ./build s3://staging

I saw this post (Bitbucket Pipelines - multiple branches with same steps) but it's for the same steps.

5 Answers

Use YAML anchors:

definitions:
  steps:
    - step: &Test-step
        name: Run tests
        script:
          - npm install
          - npm run test
    - step: &Deploy-step
        name: Deploy to staging
        deployment: staging
        script:
          - npm install
          - npm run build
          - fab deploy
pipelines:
  default:
    - step: *Test-step
    - step: *Deploy-step
  branches:
    master:
      - step: *Test-step
      - step:
        <<: *Deploy-step
        name: Deploy to production
        deployment: production
        trigger: manual

Docs: https://confluence.atlassian.com/bitbucket/yaml-anchors-960154027.html

Although it's not officially supported yet, you can pre-define steps now.
You can use yaml anchors. I got this tip from bitbucket staff when I had an issue running the same steps across a subset of branches.

definitions:
  step: &Build
    name: Build
    script:
      - npm install
      - npm build

pipelines:
  default:
    - step: *Build
  branches:
    master:
      - step: *Build
      - step:
          name: deploy
          # do some deploy from master only

I think Bitbucket can't do it. You can use one pipeline and check the branch name:

pipelines:
  default:
    - step:
        script:
          - cd source
          - npm install
          - npm build 
          - if [[ $BITBUCKET_BRANCH = develop ]]; then s3cmd put --config s3cmd.cfg ./build s3://develop; fi
          - if [[ $BITBUCKET_BRANCH = staging ]]; then s3cmd put --config s3cmd.cfg ./build s3://staging; fi

The two last lines will be executed only on the specified branches.

You can define and re-use steps with YAML Anchors.

  • anchor & to define a chunk of configuration
  • alias * to refer to that chunk elsewhere

And the source branch is saved in a default variable called BITBUCKET_BRANCH

You'd also need to pass the build results (in this case the build/ folder) from one step to the next, which is done with artifacts.

Combining all three will give you the following config:

definitions:
  steps:
    - step: &build
        name: Build
        script:
          - cd source
          - npm install
          - npm build
        artifacts: # defining the artifacts to be passed to each future step.
          - ./build

    - step: &s3-transfer
        name: Transfer to S3
        script:
          - s3cmd put --config s3cmd.cfg ./build s3://${BITBUCKET_BRANCH}

pipelines:
  default:
    - step: *build
  
  develop:
    - step: *build
    - step: *s3-transfer

  staging:
    - step: *build
    - step: *s3-transfer

You can now also use glob patterns as mentioned in the referenced post and steps for both develop and staging branches in one go:

  "{develop,staging}":
    - step: *build
    - step: *s3-transfer
Related