Skip to content

Other CI providers

Shorebird has no plugin for these CI systems, and doesn’t need one. Each recipe on this page is the generic CI setup in that provider’s syntax:

  1. Install Shorebird with its install script and add ~/.shorebird/bin to the PATH. When the machine sets XDG_CONFIG_HOME, as Microsoft’s hosted Ubuntu images do, Shorebird installs to $XDG_CONFIG_HOME/shorebird instead, so use that path.
  2. Store a Shorebird key as a secret named SHOREBIRD_TOKEN and pass it to the job as an environment variable. Use a service account key; see Authentication.
  3. Run shorebird release or shorebird patch where you ran flutter build.

Each recipe shows an Android release job and an iOS release job. For a patch, run shorebird patch in the same job instead, with the release’s version:

shorebird patch android --release-version=1.0.0+1 --track=stable

The Android jobs need a JDK and the Android SDK, and the iOS jobs a macOS machine with Xcode and CocoaPods; Shorebird installs its own Flutter. Sign the app on the builder as you would for flutter build: Android reads your Gradle signing config (see Android code signing), and iOS needs your distribution certificate and profile (see iOS code signing). A patch built with a different Xcode or CocoaPods than its release can stop in CI, so the recipes for hosted machines (Azure, Bitrise, CircleCI) pin the macOS image and Xcode. On a Mac you run yourself (Jenkins, Bitbucket), keep its Xcode and CocoaPods the same while you patch a release. Hosted images can still update CocoaPods, so check it too; see Build patches with the same toolchain as the release.

Add SHOREBIRD_TOKEN as a secret variable: edit the pipeline, open Variables, add the variable and select Keep this value secret. Azure Pipelines doesn’t pass secret variables to scripts on its own, so each step that runs shorebird maps it with env: (Set secret variables). The task.prependpath logging command adds Shorebird to the PATH of the steps after it.

trigger: none

variables:
  FLUTTER_VERSION: '3.47.9'

jobs:
  - job: release_android
    pool:
      vmImage: ubuntu-24.04
    steps:
      - bash: |
          curl -fsSL https://shorebird.dev/install.sh | bash
          # Shorebird installs under XDG_CONFIG_HOME when it is set, as on Ubuntu.
          SHOREBIRD_DIR="${XDG_CONFIG_HOME:+$XDG_CONFIG_HOME/shorebird}"
          echo "##vso[task.prependpath]${SHOREBIRD_DIR:-$HOME/.shorebird}/bin"
        displayName: Install Shorebird
      - bash: shorebird release android --flutter-version="$FLUTTER_VERSION"
        displayName: Shorebird release
        env:
          SHOREBIRD_TOKEN: $(SHOREBIRD_TOKEN)

  - job: release_ios
    pool:
      vmImage: macOS-26
    steps:
      - bash:
          sudo xcode-select -s /Applications/Xcode_26.6.app/Contents/Developer
        displayName: Select Xcode
      - bash: |
          curl -fsSL https://shorebird.dev/install.sh | bash
          # Shorebird installs under XDG_CONFIG_HOME when it is set, as on Ubuntu.
          SHOREBIRD_DIR="${XDG_CONFIG_HOME:+$XDG_CONFIG_HOME/shorebird}"
          echo "##vso[task.prependpath]${SHOREBIRD_DIR:-$HOME/.shorebird}/bin"
        displayName: Install Shorebird
      - bash: shorebird release ios --flutter-version="$FLUTTER_VERSION"
        displayName: Shorebird release
        env:
          SHOREBIRD_TOKEN: $(SHOREBIRD_TOKEN)

The Ubuntu image includes Java 17 and the Android SDK. macOS-latest moves to a new image when Microsoft updates it, so the iOS job names macOS-26 and selects an Xcode from the image’s software list. For iOS signing, Azure Pipelines has Install Apple certificate and provisioning profile tasks.

Add the key as a Secret text credential, here with the ID shorebird-token, and bind it with credentials() in the environment directive (Using a Jenkinsfile). Jenkins agents usually keep their home directory between builds, and the install script stops with Error: Shorebird is already installed when ~/.shorebird exists, so the stage installs Shorebird only when it’s missing.

pipeline {
  agent none
  environment {
    SHOREBIRD_TOKEN = credentials('shorebird-token')
    FLUTTER_VERSION = '3.47.9'
  }
  stages {
    stage('Release Android') {
      agent { label 'android' }
      steps {
        sh '''
          [ -d "$HOME/.shorebird" ] || curl -fsSL https://shorebird.dev/install.sh | bash
          export PATH="$HOME/.shorebird/bin:$PATH"
          shorebird release android --flutter-version="$FLUTTER_VERSION"
        '''
      }
    }
    stage('Release iOS') {
      agent { label 'macos' }
      steps {
        sh '''
          [ -d "$HOME/.shorebird" ] || curl -fsSL https://shorebird.dev/install.sh | bash
          export PATH="$HOME/.shorebird/bin:$PATH"
          shorebird release ios --flutter-version="$FLUTTER_VERSION"
        '''
      }
    }
  }
}

Replace android and macos with the labels of your agents. An agent keeps the Shorebird version it installed, so run shorebird upgrade on it from time to time; Shorebird’s servers stop accepting old CLI versions over time. On a Mac agent, the Xcode that xcode-select -p prints is the one that builds, and the agent’s user needs your signing certificate in a keychain it can unlock. Keep both the same while you patch a release.

Add SHOREBIRD_TOKEN under Secrets in the Workflow Editor. Bitrise passes secrets to steps as environment variables. Each workflow picks its stack, which sets the machine image and the Xcode version.

format_version: '25'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
project_type: flutter

workflows:
  release-android:
    meta:
      bitrise.io:
        stack: ubuntu-noble-24.04-bitrise-2025-android
    steps:
      - git-clone@8: {}
      - script@1:
          title: Shorebird release
          inputs:
            - content: |-
                set -ex
                curl -fsSL https://shorebird.dev/install.sh | bash
                export PATH="$HOME/.shorebird/bin:$PATH"
                shorebird release android --flutter-version=3.47.9

  release-ios:
    meta:
      bitrise.io:
        stack: osx-xcode-26.6.x
    steps:
      - git-clone@8: {}
      - certificate-and-profile-installer@1: {}
      - script@1:
          title: Shorebird release
          inputs:
            - content: |-
                set -ex
                curl -fsSL https://shorebird.dev/install.sh | bash
                export PATH="$HOME/.shorebird/bin:$PATH"
                shorebird release ios --flutter-version=3.47.9

Each script step installs Shorebird and runs it, so PATH doesn’t need to carry over to later steps. The stack ID names an Xcode version; keep the same stack while you patch a release. Bitrise’s stack list has the current IDs. The certificate-and-profile-installer step installs the .p12 certificates and provisioning profiles you’ve uploaded to the app’s Code Signing tab in Bitrise; see iOS code signing.

Add SHOREBIRD_TOKEN as an environment variable in your project’s settings, or in a context shared by several projects. A job gets a context’s variables only when the workflow names it, so with a context add context: <name> to each job under workflows:. A run step that appends to $BASH_ENV sets the PATH for the steps after it (Environment variables).

version: 2.1

commands:
  install_shorebird:
    steps:
      - run:
          name: Install Shorebird
          command: |
            curl -fsSL https://shorebird.dev/install.sh | bash
            echo 'export PATH="$HOME/.shorebird/bin:$PATH"' >> "$BASH_ENV"

jobs:
  release-android:
    docker:
      - image: cimg/android:2026.10
    # 8 GB of memory; a Flutter release build can run out of the default 4 GB.
    resource_class: large
    steps:
      - checkout
      - install_shorebird
      - run: shorebird release android --flutter-version=3.47.9

  release-ios:
    macos:
      xcode: '26.6'
    resource_class: m4pro.medium
    steps:
      - checkout
      - install_shorebird
      - run: shorebird release ios --flutter-version=3.47.9

workflows:
  release:
    jobs:
      - release-android
      - release-ios

The cimg/android image includes a JDK and the Android SDK. On macOS, the xcode key picks the machine image and its Xcode; Using macOS lists the versions and when CircleCI retires each one. Keep the same value while you patch a release, and move to a new Xcode with a new release.

Add SHOREBIRD_TOKEN under Repository settings → Pipelines → Repository variables and check Secured. Bitbucket passes repository variables to every step as environment variables (Variables and secrets).

Bitbucket’s own steps run Linux containers. For iOS, a step runs on a macOS runner that you host on your own Mac, selected with runs-on.

pipelines:
  custom:
    release:
      - step:
          name: Release Android
          # Any image with Git, a JDK and the Android SDK works.
          image: ghcr.io/cirruslabs/flutter:stable
          # 8 GB of memory, billed at twice the rate; a Flutter release build
          # can run out of the default 4 GB.
          size: 2x
          script:
            - curl -fsSL https://shorebird.dev/install.sh | bash
            - export PATH="$HOME/.shorebird/bin:$PATH"
            - shorebird release android --flutter-version=3.47.9
      - step:
          name: Release iOS
          runs-on:
            - self.hosted
            - macos
          script:
            - '[ -d "$HOME/.shorebird" ] || curl -fsSL
              https://shorebird.dev/install.sh | bash'
            - export PATH="$HOME/.shorebird/bin:$PATH"
            - shorebird release ios --flutter-version=3.47.9

Run it from the pipeline’s Run pipeline dialog, which lists custom pipelines. A macOS runner isn’t a container, so ~/.shorebird stays between builds; the iOS step installs Shorebird only when it’s missing. The runner’s Xcode and signing certificate are whatever that Mac has, so keep them the same while you patch a release.