Claude-skill-registry codemagic
Comprehensive guide for creating, configuring, and troubleshooting codemagic.yaml files for CI/CD workflows. Use when building mobile apps (Flutter, iOS, Android, React Native) with Codemagic, setting up build pipelines, configuring environment variables, implementing code signing, managing artifacts, or debugging workflow issues.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/codemagic" ~/.claude/skills/majiayu000-claude-skill-registry-codemagic && rm -rf "$T"
skills/data/codemagic/SKILL.mdCodemagic CI/CD Configuration
Configure Codemagic CI/CD workflows using codemagic.yaml for mobile app builds.
File Location
Place
codemagic.yaml in the root directory of your repository. Codemagic automatically detects and uses this file for build configuration.
Core Workflow Structure
Each workflow in codemagic.yaml defines a complete build pipeline:
workflows: workflow-id: name: Workflow Name instance_type: mac_mini_m2 # mac_mini_m2, linux, linux_x2, windows_x2 max_build_duration: 60 # minutes (1-120) environment: # Environment configuration triggering: # Build triggers scripts: # Build steps artifacts: # Output files publishing: # Publishing destinations
Environment Configuration
Version Management
Specify tool versions in the
environment section:
environment: flutter: stable # stable, beta, master, or version (e.g., 3.7.6) xcode: latest # latest, edge, or version (e.g., 14.3) cocoapods: default # default or version node: 18.0.0 # version java: 11 # version ruby: 2.7.2 # version
For Flutter Version Management (FVM), set:
environment: flutter: fvm
Environment Variables
Define variables at three levels with precedence (highest to lowest):
- Workflow-specific variables:
environment: vars: PUBLIC_VAR: "value" API_ENDPOINT: "https://api.example.com"
- Variable groups (from Codemagic UI):
environment: groups: - app_store_credentials - firebase_credentials - keystore_credentials
- Built-in variables - Codemagic exports these automatically:
- Unique build identifier$CM_BUILD_ID
- Project ID$CM_PROJECT_ID
- Git branch name$CM_BRANCH
- Git tag (if applicable)$CM_TAG
- Git commit hash$CM_COMMIT
- PR number (true/false)$CM_PULL_REQUEST
- Repository slug$CM_REPO_SLUG
- Build directory path$CM_BUILD_DIR
- JSON array of artifact URLs$CM_ARTIFACT_LINKS
See references/built-in-vars.md for complete list.
Sharing Variables Between Scripts
Variables defined in scripts are scoped to that script only. To share variables, write to
$CM_ENV:
macOS/Linux:
scripts: - name: Set variable script: | echo "MY_VAR=value" >> $CM_ENV - name: Use variable script: | echo "Using $MY_VAR"
Windows:
scripts: - name: Set variable script: | Add-Content -Path $env:CM_ENV -Value "MY_VAR=value"
Caching
Cache dependencies to speed up builds:
environment: cache: cache_paths: - ~/.gradle/caches - ~/.pub-cache - $HOME/Library/Caches/CocoaPods
Important: Each workflow has its own cache. Caching symlinks is not supported.
Build Triggers
Define when builds start automatically in the
triggering section:
triggering: events: - push # Commits to tracked branches - pull_request # Pull request opened/updated - tag # Tag created - pull_request_labeled # Label added to PR
Note: Automatic triggering requires webhook configuration in your repository.
Branch/Tag Patterns
Limit triggers to specific branches or tags:
triggering: events: - push branch_patterns: - pattern: 'main' include: true - pattern: 'develop' include: true - pattern: 'feature/*' include: true - pattern: 'hotfix/*' include: true tag_patterns: - pattern: 'v*.*.*' include: true
Conditional Triggering
Skip builds based on changed files or custom conditions:
Changeset filtering:
triggering: events: - push when: changeset: includes: - '.' # All files excludes: - '**/*.md' # Skip markdown-only changes - 'docs/**' # Skip docs changes
Custom conditions:
triggering: events: - pull_request when: condition: not event.pull_request.draft # Skip draft PRs
Using environment variables:
when: condition: env.CM_BRANCH == "main"
Complex conditions:
when: condition: | env.CM_BRANCH == "main" and not event.pull_request.draft
Cancel Previous Builds
Automatically cancel outdated builds:
triggering: cancel_previous_builds: true
Scripts
The
scripts section defines build steps:
Basic Script Formats
Single-line:
scripts: - echo "Hello world"
Named script:
scripts: - name: Run tests script: flutter test
Multi-line:
scripts: - name: Build iOS script: | flutter build ios --release cd ios xcodebuild -archive
Python/other languages:
scripts: - | #!/usr/bin/env python3 import os print("Running Python script")
Script Options
Ignore failures:
scripts: - name: Optional step script: flutter test ignore_failure: true # Workflow continues even if this fails
Conditional execution:
scripts: - name: Deploy to production script: ./deploy.sh when: condition: env.CM_BRANCH == "main"
Changeset-based execution:
scripts: - name: Build Android script: ./gradlew assembleRelease when: changeset: includes: - 'android/**'
Working Directory
Set working directory globally or per-script:
Workflow-level:
workflows: my-workflow: working_directory: packages/my_app
Script-level:
scripts: - name: Build in subdirectory working_directory: ios script: xcodebuild
Important: Using
cd between scripts doesn't work because each script runs in a subshell. Use working_directory or inline cd within a single script.
Code Signing
See references/code-signing.md for complete iOS and Android code signing workflows.
Artifacts
Specify files to save after the build:
artifacts: - build/ios/ipa/*.ipa - build/app/outputs/flutter-apk/*.apk - build/**/*.aab - $HOME/Library/Developer/Xcode/DerivedData/**/Build/**/*.dSYM
Paths can be relative (to clone directory) or absolute. Use glob patterns for flexibility.
Publishing
Configure where to publish build artifacts:
publishing: email: recipients: - user@example.com - team@example.com notify: success: true failure: true
Slack
publishing: slack: channel: '#builds' notify_on_build_start: true notify: success: true failure: true
App Store Connect
publishing: app_store_connect: api_key: $APP_STORE_CONNECT_PRIVATE_KEY key_id: $APP_STORE_CONNECT_KEY_IDENTIFIER issuer_id: $APP_STORE_CONNECT_ISSUER_ID submit_to_testflight: true
Google Play
publishing: google_play: credentials: $GCLOUD_SERVICE_ACCOUNT_CREDENTIALS track: internal # internal, alpha, beta, production submit_as_draft: false
Firebase App Distribution
publishing: firebase: firebase_token: $FIREBASE_TOKEN android: app_id: $FIREBASE_ANDROID_APP_ID groups: - testers ios: app_id: $FIREBASE_IOS_APP_ID groups: - testers
Custom Publishing Scripts
publishing: scripts: - name: Custom deployment script: | if [ -f "build/app.ipa" ]; then ./deploy.sh build/app.ipa fi
Advanced Features
YAML Anchors for Reusability
Define reusable sections with
&anchor and reference with *anchor:
definitions: instance_mac: &instance_mac instance_type: mac_mini_m2 max_build_duration: 120 flutter_env: &flutter_env flutter: stable xcode: latest cocoapods: default setup_script: &setup_script name: Setup script: | flutter pub get pod install workflows: ios-release: name: iOS Release <<: *instance_mac environment: <<: *flutter_env scripts: - *setup_script - name: Build script: flutter build ios android-release: name: Android Release instance_type: linux environment: <<: *flutter_env scripts: - *setup_script - name: Build script: flutter build apk
Build Inputs
Allow runtime parameters for flexible builds:
workflows: flexible-build: name: Flexible Build build_inputs: - name: build_flavor type: choice description: Select build flavor required: true choices: - dev - staging - production - name: run_tests type: boolean description: Run tests before build default: true scripts: - name: Build with flavor script: | flutter build apk --flavor $build_flavor
Labels
Add labels for workflow organization:
workflows: my-workflow: name: My Workflow labels: - QA - ${TENANT_NAME} - v${APP_VERSION}
Common Patterns
Flutter Workflow Template
workflows: flutter-workflow: name: Flutter Build instance_type: mac_mini_m2 max_build_duration: 60 environment: flutter: stable xcode: latest groups: - app_store_credentials vars: BUNDLE_ID: "com.example.app" triggering: events: - push branch_patterns: - pattern: 'main' include: true scripts: - name: Get dependencies script: flutter pub get - name: Run tests script: flutter test - name: Build iOS script: flutter build ipa --release - name: Build Android script: flutter build apk --release artifacts: - build/ios/ipa/*.ipa - build/app/outputs/flutter-apk/*.apk publishing: email: recipients: - team@example.com
iOS Native Workflow
See references/ios-workflow.md
Android Native Workflow
See references/android-workflow.md
Monorepo Setup
Validation and Testing
Schema Validation
Use JSON schema for IDE validation:
# yaml-language-server: $schema=https://codemagic.io/codemagic-schema.json
Local Validation
Check for common issues:
- YAML syntax errors
- Missing required fields
- Invalid instance types
- Incorrect environment variable references
Debugging
Add debug script to inspect environment:
scripts: - name: Debug environment script: | set -ex printenv flutter --version xcodebuild -version
Troubleshooting
Build not triggering:
- Verify webhook configuration
- Check branch/tag patterns match
- Review changeset filters
- Ensure codemagic.yaml is in root directory
- Check if [skip ci] is in commit message
Environment variable not found:
- Verify variable group names match UI
- Check variable name spelling
- Ensure secret variables are marked as such
- Use
to list available variablesprintenv
Scripts failing:
- Check exit codes with
set -e - Review logs for error messages
- Verify tool versions are correct
- Test scripts locally first
Code signing issues:
- Verify certificates are uploaded to Codemagic
- Check provisioning profile validity
- Ensure bundle IDs match
- Review code signing identity references
Cache not working:
- Verify cache paths exist
- Check cache size limits
- Ensure paths are not symlinks
- Review cache age (expires after 7 days of inactivity)
Best Practices
- Use variable groups for sensitive data instead of hardcoding
- Enable cancel_previous_builds to save build minutes
- Use changeset filtering for monorepos to avoid unnecessary builds
- Cache dependencies to speed up builds
- Use YAML anchors to reduce duplication
- Add conditional steps to optimize workflow execution
- Test locally before committing changes
- Use semantic versioning for tags
- Keep scripts focused - one responsibility per script
- Document complex workflows with inline comments