> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackshift.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Pipelines

> Chain builds, approvals, store submissions, and channel promotions into one automated release flow, defined as YAML in your repository.

<Tip>
  **Live.** This area is documented as current, user-reliable behavior.
</Tip>

## Goal

Define a pipeline file, trigger it from a push, tag, schedule, or button, and follow a run through its steps.

## Prerequisites

* A build profile connected to a GitHub repository
* mobile\_pipelines is enabled on the plan

## Workflow

<Steps>
  <Step>
    Add a YAML file under .stackshift/pipelines/ in your repository, for example release.yml.
  </Step>

  <Step>
    Press Sync on the Pipelines tab (or push to the configured branch) so StackShift picks up the file.
  </Step>

  <Step>
    Trigger a run manually, from a matching push or tag, on a cron schedule, or from CI with a pipeline:dispatch token.
  </Step>

  <Step>
    Watch the run: each step links to its build, submission, or update, and approval steps pause the run until someone approves.
  </Step>
</Steps>

## Pipeline file format

A pipeline has a name, triggers, optional concurrency settings, and a set of jobs. Jobs run in the order their needs allow. Supported job types: build (cloud build for android or ios), submit (store submission), promote (pin a release to a channel), approval (pause for a human decision), notify (send a webhook event), run (your own commands in the build container), and ota\_publish (export the JavaScript bundle and publish it as an over-the-air update).

```yaml theme={null}
name: Release to Play Store
on:
  tag: ["v*"]
jobs:
  build_android:
    type: build
    platform: android
  approve:
    type: approval
    needs: [build_android]
  submit_play:
    type: submit
    needs: [approve, build_android]
    platform: android
    release: ${{ jobs.build_android.release_id }}
    destination: play
  announce:
    type: notify
    needs: [submit_play]
    if: always()
```

## Triggers

* push: a list of branch names or patterns, matched on every push.
* tag: a list of tag patterns like v\*, matched when a tag is pushed.
* schedule: a standard cron expression, evaluated in UTC.
* Every pipeline can also be run manually from the dashboard or dispatched from CI.

## Conditions and values

A job can set if: to always(), success(), failure(), or simple comparisons like trigger.branch == 'main'. Step parameters can reference earlier results with $&#123;&#123; jobs.&lt;name>.release_id &#125;&#125; and trigger details with $\{\{ trigger.tag }}. Only these known values are available; pipeline files cannot run arbitrary code.

## Concurrency

* Set concurrency.group to make runs in the same group queue behind each other.
* Add cancel\_in\_progress: true to stop the previous run when a new one starts.

## Scripts and over-the-air publishing

run steps execute your commands (tests, code generation, checks) in the same isolated container as builds, with the repository checked out at the run's ref — but never with access to signing secrets. ota\_publish steps export your Expo or React Native JavaScript bundle on the build infrastructure and publish it as an over-the-air update in one step.

```yaml theme={null}
jobs:
  test:
    type: run
    commands: |
      npm ci
      npm test
  ship_update:
    type: ota_publish
    needs: [test]
    platform: android
    channel: production
    runtime_version: "1.4.0"
```

## Expected result

<Check>
  Pushing a tag like v1.4.0 builds the app, waits for an approval, submits to the store, and notifies your webhook — with no manual steps in between.
</Check>

## Common failures

<Warning>
  * The file has a syntax error: it appears on the Pipelines tab with the error message and never runs.
  * A step references a job it does not depend on: add the referenced job to needs.
  * The build step targets a platform with no configured build profile.
  * The account plan does not include builds or store submissions, so those steps fail with a plan message.
</Warning>
