In codemagic.yaml, how do you make a Codemagic workflow build automatically on pull requests into main and on release tags, and skip stale builds?
answer
- webhook first, then events
- branch_patterns with include and source
- tag_patterns ignore watched branches
- cancel_previous_builds for same branch
- when: changeset and condition
basics
~20 sCodemagic starts a workflow from its triggering section: events such as push, pull_request or tag, filtered by branch_patterns and tag_patterns and delivered by a repository webhook. cancel_previous_builds and a when block drop stale or irrelevant builds.
solid answer
~40 sAutomatic builds need a webhook in the repository; with no `events` listed a workflow only runs manually. Under `triggering`, `events` picks `push`, `pull_request`, `pull_request_labeled` (GitHub only) or `tag`. `branch_patterns` entries carry `pattern`, `include` and, for pull requests, `source` (true matches the PR's source branch, false its target), so `pattern: main, source: false` builds PRs into main. `tag_patterns` filters tag builds, and watched branch settings do not affect them. `cancel_previous_builds: true` cancels ongoing and queued webhook builds when a newer one arrives for the same branch. A workflow-level `when` skips work: `changeset` with `includes`/`excludes` stops a build whose watched files did not change since the last successful build, and `condition` evaluates `env.` or `event.` values. `[skip ci]` in the commit message skips the build entirely.
code
yaml · 32 linesworkflows:
pr-checks:
name: Scooter PR checks
triggering:
events:
- pull_request
branch_patterns:
- pattern: 'main'
include: true
source: false
cancel_previous_builds: true
when:
changeset:
includes:
- '.'
excludes:
- '**/*.md'
scripts:
- flutter pub get
- flutter test
store-release:
name: Scooter store release
triggering:
events:
- tag
tag_patterns:
- pattern: 'v+([0-9]).+([0-9]).+([0-9])'
include: true
scripts:
- flutter pub get
- flutter build appbundle --releasego deeper
Recall that builds start from events listed under triggering, and that a repository webhook must exist for them to fire.
Explain source versus target in branch_patterns, why tag builds ignore branches, and how changeset compares against the last successful build.
Show a trigger layout that keeps PR feedback fast, cancels superseded runs safely, and never cancels or skips a release tag build.
Weigh machine minutes against feedback speed across many workflows, deciding what runs per PR, per merge and per tag.
## Webhooks come first Codemagic reacts to repository events through a **webhook**. For `codemagic.yaml` workflows you create it from the app settings (**Create webhook**) or add it manually in the Git provider. Without a webhook, and without any `events` in the workflow, builds start only by hand or through the REST API. When a webhook fires, Codemagic reads `codemagic.yaml` from the **source branch** of the event, so a pull request whose source branch lacks a valid file is skipped. ## Events The `triggering.events` list takes four values: | Event | Starts a build when | |---|---| | `push` | A commit lands on a watched branch | | `pull_request` | A pull request is opened or updated, building the merge result | | `pull_request_labeled` | A label is added to a GitHub pull request | | `tag` | A tag is created; the tagged commit is built | ## Branch and tag patterns `branch_patterns` narrows which branches count. Each entry has: - `pattern`: a branch name or wildcard such as `'*'`, `'release/*'` or `'{test,qa}/*'`; - `include`: `true` to watch matches, `false` to exclude them; - `source`: for pull requests only, `true` if the pattern describes the PR's **source** branch and `false` if it describes the **target** branch. Patterns are applied top to bottom, each one limiting the set further, and on conflict the later one wins. **Tag builds ignore watched branch settings**; `tag_patterns` filters them instead, with the same `pattern`/`include` shape. A semantic-version pattern looks like `'v+([0-9]).+([0-9]).+([0-9])'`. ## Dropping stale builds A busy branch can queue several builds for commits nobody will ship. `cancel_previous_builds: true` tells Codemagic to cancel ongoing and queued **webhook** builds triggered by push or pull request commits when a more recent build has started for the **same branch**. The documented template sets it to `false`. Release tags are usually left alone: each tag is a distinct version. ## Skipping irrelevant builds with when A workflow-level `when` block adds conditions: 1. **`changeset`** with `includes` and `excludes` globs. The build runs if `codemagic.yaml` changed or a watched path changed **since the last successful build**. `includes` defaults to `'.'`; adding any `includes` entry drops that default. A skipped build is still created: it stops after fetching the sources. 2. **`condition`** with `==`, `not`, `and`, `or`. Environment variables are read as `env.NAME` (shell `$NAME` is not supported there) and the webhook payload as `event`, which does not exist for manual or scheduled builds. For a clean skip that never starts a build, put `[skip ci]` or `[ci skip]` in the commit message. ## Other ways a build starts Webhook events are one of several entry points, and knowing the others explains builds that seem to appear from nowhere: - **Manual**: Start new build in the UI, choosing a branch and a workflow. - **Scheduled**: the Scheduled builds tab runs a chosen workflow on a branch on selected days at a UTC time; the start may be delayed up to 15 minutes at peak hours, and such builds show Schedule as their trigger. - **REST API**: a call can start a workflow and pass values such as `instance_type`, which then override the file. - **GitHub merge queue**: push builds on branches matching `'gh-readonly-queue/main/*'` test what the queue is about to merge. The `event` variable used in `when.condition` is only filled for webhook builds, so a condition that reads it behaves differently for manual and scheduled runs. Write conditions that also make sense when `event` is absent, or keep such workflows webhook-only. ## Putting it together For a scooter-sharing app, a sensible split is: - `pr-checks`: `pull_request` into `main` (`source: false`), `cancel_previous_builds: true`, and a changeset that excludes Markdown; - `store-release`: `tag` with a version `tag_patterns` entry, never cancelled. The general theory of which work belongs on which trigger is pipeline design; the Codemagic part is knowing which keys express it and their defaults.
- Why can a Codemagic pull request build be skipped with a 'no workflows configured' message?Webhook builds read `codemagic.yaml` from the pull request's source branch. If that branch has no valid file, or its file has no workflow whose triggers match the PR, Codemagic skips the build and records the reason under the webhook's recent deliveries.
- How would you run a Codemagic workflow only when a pull request gets a specific label?Add `pull_request_labeled` to `events` (GitHub only), then a workflow-level `when.condition` that inspects the webhook payload through `event`, for example the label's name. The condition is evaluated during the build and skips it when false.
saying these in an interview costs you the question
- Committing codemagic.yaml alone makes pushes start builds without a webhook
- branch_patterns also decide which tags start a build
- source: true means the pattern matches the pull request's target branch
- A changeset-skipped build is never created at all
- Inside a when condition an environment variable is written as $NAME