GitHub Actions Workflows Reference
Complete reference for all 14 GitHub Actions workflows and 3 custom actions included in Caracal.
Caracal comes with 14 production-ready GitHub Actions workflows and 3 reusable custom actions that automate quality checks, testing, building, releasing, and maintenance tasks.
Overview
All workflows are self-documented with detailed comments inside each YAML file, making them easy to understand and customize without switching between files.
Location:
- Workflows:
.github/workflows/ - Custom actions:
.github/actions/
Each workflow file includes:
- Links: Source file URL and related documentation
- Description: What the workflow does and when it runs
- Secrets Required: GitHub secrets needed (if any)
- Usage Examples: How to trigger or use the workflow
Workflow Categories
| Category | Workflows | Total |
|---|---|---|
| Quality Checks | Lint, Type Check, Expo Doctor | 3 |
| Testing | Unit Tests, E2E Tests (3 variants) | 4 |
| Building | EAS Build QA, EAS Build Prod | 2 |
| Releasing | New App Version, New GitHub Release | 2 |
| Maintenance | Compress Images, Stale Issues/PRs | 2 |
| Documentation | Deploy Docs to GitHub Pages | 1 |
| TOTAL | 14 |
Custom Actions (Reusable)
Custom actions encapsulate common tasks and can be reused across multiple workflows, reducing duplication and improving maintainability.
1. Setup Node + pnpm + Install Dependencies
Purpose: Sets up Node.js, pnpm package manager, and installs project dependencies with caching.
Location: .github/actions/setup-node-pnpm-install/action.yml
Used in: Almost every workflow (lint, type-check, test, build, etc.)
Benefits:
- Centralized Node.js and pnpm version management
- Automatic dependency caching for faster runs
- Single place to update package manager across all workflows
Usage:
- name: Setup Node + PNPM + install deps
uses: ./.github/actions/setup-node-pnpm-install2. Setup JDK & Generate APK
Purpose: Sets up Java Development Kit and generates Android APK for testing.
Location: .github/actions/setup-jdk-generate-apk/action.yml
Used in: E2E Android testing workflows
What it does:
- Sets up JDK (Java 17)
- Configures Gradle caching
- Runs prebuild for Android
- Generates debug APK
- Outputs APK path for testing
Usage:
- name: Setup JDK & Generate APK
uses: ./.github/actions/setup-jdk-generate-apk
id: apk
- name: Use APK path
run: echo "APK at ${{ steps.apk.outputs.apk-path }}"3. EAS Build
Purpose: Triggers Expo Application Services (EAS) build for iOS or Android.
Location: .github/actions/eas-build/action.yml
Used in: EAS Build workflows (QA, Production)
Inputs:
platform: iOS or Androidprofile: Build profile fromeas.json(e.g.,qa,production)
Secrets Required:
EXPO_TOKEN: EAS authentication token
Usage:
- name: EAS Build Android
uses: ./.github/actions/eas-build
with:
platform: android
profile: qa
env:
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}Quality Check Workflows
Lint TS (ESLint + Prettier)
File: .github/workflows/lint-ts.yml
Triggers:
- Push to
main/masterbranches - Pull requests targeting
main/master
What it does:
- Runs ESLint and Prettier checks
- On PR: Annotates code with errors/warnings via Reviewdog
- On push: Fails if linting errors exist
Secrets: None required
Fix linting issues:
pnpm lint:fixType Check (TypeScript)
File: .github/workflows/type-check.yml
Triggers:
- Push to
main/masterbranches - Pull requests targeting
main/master
What it does:
- Runs TypeScript compiler in check mode
- Verifies type safety across entire codebase
- Fails on type errors
Secrets: None required
Run type check locally:
pnpm type-checkExpo Doctor
File: .github/workflows/expo-doctor.yml
Triggers:
- Push to
main/masterbranches - Pull requests targeting
main/master
What it does:
- Runs
expo-doctorto check project health - Validates Expo configuration
- Checks for common setup issues
- Verifies dependency compatibility
Secrets: None required
Run doctor locally:
pnpm doctorTesting Workflows
Unit Tests + Coverage
File: .github/workflows/test.yml
Triggers:
- Push to
main/masterbranches - Pull requests targeting
main/master
What it does:
- Runs Jest unit tests
- Generates coverage report
- Uploads coverage to Codecov (optional)
- Fails if tests fail or coverage drops below threshold
Secrets:
CODECOV_TOKEN(optional): For coverage reporting
Run tests locally:
pnpm test # Run all tests
pnpm test:watch # Watch mode
pnpm test:coverage # With coverage reportE2E Testing (3 Variants)
Caracal includes 3 different E2E testing workflows to support various testing strategies.
Variant 1: E2E Android (Local Emulator)
File: .github/workflows/e2e-android.yml
Triggers: Manual via workflow_dispatch
What it does:
- Sets up Android emulator on GitHub runner
- Generates debug APK
- Installs Maestro
- Runs Maestro tests locally
- Uploads test results as artifacts
Best for: CI/CD pipelines with self-hosted runners
Secrets: None required
Variant 2: E2E Android Maestro Cloud
File: .github/workflows/e2e-android-maestro.yml
Triggers: Manual via workflow_dispatch
What it does:
- Generates debug APK
- Uploads APK to Maestro Cloud
- Runs tests on Maestro Cloud infrastructure
- Returns test results
Best for: Teams using Maestro Cloud (faster, no emulator setup)
Secrets:
MAESTRO_CLOUD_API_KEY: Maestro Cloud authentication
Variant 3: E2E Android with EAS Build
File: .github/workflows/e2e-android-eas-build.yml
Triggers: Manual via workflow_dispatch
What it does:
- Triggers EAS build for Android
- Waits for build to complete
- Downloads APK from EAS
- Uploads to Maestro Cloud
- Runs tests on cloud infrastructure
Best for: Testing production-like builds on Maestro Cloud
Secrets:
EXPO_TOKEN: EAS authenticationMAESTRO_CLOUD_API_KEY: Maestro Cloud authentication
Choose the right variant:
| Variant | Use Case | Pros | Cons |
|---|---|---|---|
| Local Emulator | Self-hosted runners | Free, full control | Slow, requires powerful runners |
| Maestro Cloud | Fast feedback | Very fast, no emulator setup | Requires Maestro Cloud subscription |
| EAS + Maestro | Production testing | Tests real builds | Slowest (build + upload time) |
Building Workflows
EAS Build QA
File: .github/workflows/eas-build-qa.yml
Triggers: Manual via workflow_dispatch
Inputs:
platform: Choose iOS, Android, or both
What it does:
- Triggers EAS build using
qaprofile fromeas.json - Builds development/staging version of the app
- Suitable for internal testing
Secrets:
EXPO_TOKEN: EAS authentication token
Trigger manually:
- Go to Actions tab in GitHub
- Select "EAS Build QA"
- Click "Run workflow"
- Choose platform (iOS, Android, or both)
EAS Build Production
File: .github/workflows/eas-build-prod.yml
Triggers: Manual via workflow_dispatch
Inputs:
platform: Choose iOS, Android, or both
What it does:
- Triggers EAS build using
productionprofile - Builds release/store version of the app
- Optimized for App Store and Google Play submission
Secrets:
EXPO_TOKEN: EAS authentication token
Production builds use release configuration and may require additional setup:
- iOS: Apple Developer account and certificates
- Android: Play Store signing keys
- Configure secrets in EAS:
eas secret:create
Releasing Workflows
New App Version
File: .github/workflows/new-app-version.yml
Triggers: Manual via workflow_dispatch
Inputs:
release-type: Choose patch, minor, or major
What it does:
- Bumps version in
package.jsonbased on release type - Runs
pnpm prebuildto sync version with native code - Creates Git tag with new version
- Pushes tag to repository
- Triggers other workflows (like builds)
Secrets:
GH_TOKEN: GitHub Personal Access Token with write access
Versioning:
- Patch (1.0.0 → 1.0.1): Bug fixes
- Minor (1.0.0 → 1.1.0): New features, backward compatible
- Major (1.0.0 → 2.0.0): Breaking changes
How to use:
- Go to Actions → New App Version
- Click "Run workflow"
- Select release type (patch/minor/major)
- Workflow creates version bump and tag
- Check releases page for new tag
New GitHub Release
File: .github/workflows/new-github-release.yml
Triggers: When a new tag is pushed (usually by the New App Version workflow)
What it does:
- Detects new version tag
- Extracts changelog from
CHANGELOG.md - Creates GitHub Release with notes
- Marks as pre-release if version contains
-beta,-alpha, etc.
Secrets: None required (uses GITHUB_TOKEN)
Maintenance Workflows
Compress Images
File: .github/workflows/compress-images.yml
Triggers:
- Pull requests that modify image files (
.png,.jpg,.jpeg,.gif)
What it does:
- Detects image changes in PR
- Compresses images using calibreapp/image-actions
- Commits optimized images back to PR
- Reduces bundle size automatically
Secrets: None required
Compression settings:
- PNG: Lossless compression
- JPEG: Quality 80%
- GIF: Optimized without losing animation
Stale Issues and PRs
File: .github/workflows/stale.yml
Triggers: Daily at midnight (cron: 0 0 * * *)
What it does:
- Marks issues/PRs stale after 60 days of inactivity
- Adds label:
no-issue-activityorno-pr-activity - Posts comment warning about closure
- Closes stale items after 14 more days
Secrets: None required (uses GITHUB_TOKEN)
Prevent closure:
- Comment on the issue/PR
- Remove the stale label
- Push new commits (for PRs)
Customize by editing .github/workflows/stale.yml:
days-before-stale: Days before marking stale (default: 60)days-before-close: Days before closing after stale (default: 14)
Documentation Workflow
Deploy Docs to GitHub Pages
File: .github/workflows/deploy-docs.yml
Triggers:
- Push to
masterbranch with changes indocs/** - Manual via
workflow_dispatch
What it does:
- Builds the documentation site
- Uploads to GitHub Pages
- Deploys to configured URL
- Automatically updates live docs
Secrets: None required (uses built-in GITHUB_TOKEN)
Setup GitHub Pages:
- Go to Settings → Pages
- Source: GitHub Actions
- Push to
docs/folder - Docs deploy automatically
Local development:
cd docs
pnpm install
pnpm dev # Start dev server
pnpm build # Build for productionWorkflow Triggers Reference
| Trigger | Description | Example Workflows |
|---|---|---|
| push | On push to specific branches | lint-ts, type-check, test, deploy-docs |
| pull_request | On PR to specific branches | lint-ts, type-check, test, expo-doctor |
| workflow_dispatch | Manual trigger from Actions tab | eas-build-qa, eas-build-prod, new-app-version |
| schedule | Cron-based schedule | stale (daily) |
| push (tags) | On new tag creation | new-github-release |
Required GitHub Secrets
Configure these secrets in Settings → Secrets and variables → Actions.
Required for EAS Builds
EXPO_TOKEN
- Used in: eas-build-qa, eas-build-prod, e2e-android-eas-build
- How to get: Create token at
https://expo.dev/accounts/[account]/settings/access-tokens - Permissions: Build and submit apps
Required for Versioning
GH_TOKEN
- Used in: new-app-version
- How to get: GitHub Settings → Developer settings → Personal access tokens → Generate new token (classic)
- Permissions:
repo(Full control of private repositories)
Optional for E2E Testing
MAESTRO_CLOUD_API_KEY
- Used in: e2e-android-maestro, e2e-android-eas-build
- How to get: Maestro Cloud dashboard → API Keys
- Required: Only if using Maestro Cloud
Optional for Coverage
CODECOV_TOKEN
- Used in: test (optional)
- How to get: Codecov.io dashboard
- Required: Only if uploading coverage reports
Best Practices
1. Enable Required Workflows
Mark critical workflows as required in branch protection:
Settings → Branches → Branch protection rules → Add rule
Required checks:
- Lint TS
- Type Check
- Unit Tests
- Expo Doctor
This prevents merging PRs with failing checks.
2. Customize Workflow Triggers
# Run only on specific branches
on:
push:
branches: [main, develop]
# Run only on specific file changes
on:
push:
paths:
- 'src/**'
- 'package.json'
# Exclude documentation changes
on:
push:
paths-ignore:
- 'docs/**'
- '**.md'3. Use Concurrency Controls
Prevent multiple runs of the same workflow:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true4. Cache Dependencies
All workflows use pnpm caching via the custom action. When adding new workflows:
- name: Setup Node + pnpm + install
uses: ./.github/actions/setup-node-pnpm-installTroubleshooting
Workflow Fails: "Resource not accessible by integration"
Problem: Workflow lacks required permissions.
Solution: Add permissions to workflow:
permissions:
contents: write
pull-requests: writeEAS Build Fails: "Invalid Expo token"
Problem: EXPO_TOKEN secret not configured or expired.
Solution:
- Generate new token at
https://expo.dev/accounts/[account]/settings/access-tokens - Add to GitHub secrets: Settings → Secrets → New repository secret
- Name:
EXPO_TOKEN, Value: token from Expo
New App Version Fails: "Permission denied"
Problem: GH_TOKEN lacks write permissions.
Solution: Generate new GitHub PAT with repo scope and update the secret.
Maestro E2E Fails: "APK not found"
Problem: APK path incorrect or build failed.
Solution:
- Check "Setup JDK & Generate APK" step succeeded
- Verify APK path:
android/app/build/outputs/apk/debug/app-debug.apk - Check Android build logs for errors
Type Check Fails Locally but Passes in CI
Solution:
# Clear TypeScript cache
rm -rf node_modules/.cache
# Reinstall dependencies
pnpm install --frozen-lockfile
# Run type check
pnpm type-checkWorkflow Execution Order
For a typical release process:
1. Development
├─ [On every commit/PR]
│ ├─ Lint TS
│ ├─ Type Check
│ ├─ Unit Tests
│ └─ Expo Doctor
2. Ready to Release
├─ [Manual] New App Version
│ ├─ Bumps version
│ └─ Creates git tag
3. Automatic on Tag
├─ New GitHub Release
│ └─ Creates release with changelog
4. Build for Distribution
├─ [Manual] EAS Build Prod
│ ├─ iOS Build
│ └─ Android Build
5. E2E Testing (Optional)
└─ [Manual] E2E Android Maestro
└─ Validates build qualityAdditional Resources
- GitHub Actions Documentation
- EAS Build Documentation
- Maestro Documentation
- Expo Application Services
- App Releasing Process
- CI/CD Overview
Summary
14 Workflows Included:
| # | Workflow | Trigger | Purpose |
|---|---|---|---|
| 1 | Lint TS | PR/Push | Code quality (ESLint + Prettier) |
| 2 | Type Check | PR/Push | TypeScript type safety |
| 3 | Expo Doctor | PR/Push | Expo configuration health |
| 4 | Unit Tests | PR/Push | Jest tests + coverage |
| 5 | E2E Android | Manual | E2E tests (local emulator) |
| 6 | E2E Maestro Cloud | Manual | E2E tests (Maestro Cloud) |
| 7 | E2E EAS + Maestro | Manual | E2E tests (production build) |
| 8 | EAS Build QA | Manual | QA/staging builds |
| 9 | EAS Build Prod | Manual | Production builds |
| 10 | New App Version | Manual | Version bumps + tags |
| 11 | New GitHub Release | Tag push | GitHub releases |
| 12 | Compress Images | PR | Image optimization |
| 13 | Stale Issues/PRs | Daily | Housekeeping |
| 14 | Deploy Docs | Push | Documentation site |
3 Custom Actions:
- Setup Node + pnpm + Install
- Setup JDK & Generate APK
- EAS Build