Skip to content

EAS Workflows reports SKIPPED jobs as GitHub commit status "success" #4185

Description

@Powers-RC

Build/Submit details page URL

https://expo.dev/accounts/propertymeld/projects/meldmobile/workflows/019ff80f-2c9e-795b-b6e0-8c6cff5914a1

Summary

EAS Workflows reports jobs that were internally marked SKIPPED (because their if condition evaluated to false) to GitHub as commit status state: success — identical to a job that actually ran and passed. Since GitHub's Commit Status API has no "skipped" state, a skipped job and a genuinely-completed job are visually indistinguishable in the GitHub PR checks list. This is especially misleading around require-approval gates: while a require-approval job is still pending (correctly reported as state: pending), sibling/downstream jobs that get skipped as a side effect can show up as green "✓ success" checks even though they never ran, making a PR look fully deployed/released when it isn't.

Managed or bare?

Bare

Environment

expo-env-info 2.1.0 environment info:
System:
OS: macOS 26.5.1
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.20.0 - /.nvm/versions/node/v20.20.0/bin/node
Yarn: 1.22.22 - /opt/homebrew/bin/yarn
npm: 11.16.0 - /.nvm/versions/node/v20.20.0/bin/npm
Watchman: 2026.01.12.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.16.2 - /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 25.5, iOS 26.5, macOS 26.5, tvOS 26.5, visionOS 26.5, watchOS 26.5
IDEs:
Android Studio: 2026.1 AI-261.23567.138.2611.15646644
Xcode: 26.5/17F42 - /usr/bin/xcodebuild
npmPackages:
expo: ~54.0.34 => 54.0.34
expo-router: ~6.0.23 => 6.0.23
expo-updates: ~29.0.17 => 29.0.17
react: 19.1.0 => 19.1.0
react-dom: 19.1.0 => 19.1.0
react-native: 0.81.5 => 0.81.5
react-native-web: ~0.21.2 => 0.21.2
npmGlobalPackages:
eas-cli: 21.8.0
Expo Workflow: bare

Error output

Not applicable — this is not a crash/error, but a status-reporting inconsistency between EAS's internal job state and the GitHub commit status it publishes.

Reproducible demo or steps to reproduce from a blank project

  1. Create an EAS Workflow with:
    • a require-approval job (e.g. approval_gate),
    • a second, independent job whose if condition is only true when a build already exists (e.g. if: ${{ needs.get_ios_build.outputs.build_id || needs.get_android_build.outputs.build_id }}), plus one or more jobs after it (e.g. two update-type jobs that publish an OTA update once that job succeeds).
  2. Trigger the workflow on a commit where no existing build matches the current fingerprint, so the conditional branch's if evaluates to false and those jobs are marked SKIPPED by EAS, while approval_gate is left ACTION_REQUIRED (pending human approval).
  3. Compare EAS's own record of job state against what's published to GitHub for the same commit:
    • eas workflow:view <run-id> --json → the skipped jobs show "status": "SKIPPED".
    • gh api repos/{owner}/{repo}/commits/{sha}/statuses (or the PR's checks list in the GitHub UI) → the same jobs show "state": "success" (with "description": "Job has been skipped.").
  4. Expected: a job EAS itself considers SKIPPED should not be reported to GitHub as success, since that's indistinguishable from a job that actually ran and passed. Actual: it's reported as success.

Example observed in one of our production workflow runs (details anonymized):

Job (role) EAS status (eas workflow:view) GitHub commit status
conditional approval gate, skipped because no build existed yet SKIPPED state: success, "Job has been skipped."
downstream update-publish job (Android) SKIPPED state: success, "Job has been skipped."
downstream update-publish job (iOS) SKIPPED state: success, "Job has been skipped."
primary require-approval gate, awaiting a human click ACTION_REQUIRED state: pending, "Job requires user action." (correct)

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs reviewIssue is ready to be reviewed by a maintainer

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions