◉RORK LABJP
●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SONNET 4.5 — Retires on the Claude API on 11/30, 36 days left. If your app calls it, check the migration target●SDK 58 ISSUE — Early reports include Android widgets not refreshing on a schedule and Stripe linking statically●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SONNET 4.5 — Retires on the Claude API on 11/30, 36 days left. If your app calls it, check the migration target●SDK 58 ISSUE — Early reports include Android widgets not refreshing on a schedule and Stripe linking statically●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…
Articles/App Dev
◇ App Dev/2026-09-10Intermediate

Your First EAS Workflow in a Rork Repo, and the Alert That Goes Missing Exactly When You Need It

Putting two files into .eas/workflows in a repo exported from Rork, and why a notification wired with needs stays silent on exactly the nights it fails — with the output of a small local checker I actually ran.

EAS WorkflowsExpo227CI/CD8TestFlight16indie development42Rork600

✦ Premium Article

Kick off a build late at night, wait for it to pass, then type the submit command. When you keep a handful of apps going on your own, that order settles into your fingers. It's not worth writing down, and yet getting it wrong costs you half an hour — and that little routine repeats once per app.

The other day, after shipping an update to one of my wallpaper apps, I found myself typing the same sequence again and thinking: this order is exactly the thing that shouldn't live in my fingers.

A repo exported from Rork is, at that point, an ordinary Expo project. If you have eas.json next to your source and the repo is on GitHub, one configuration file is enough to hand that order over.

The first one I wrote was wrong, though. It parses. eas accepts it. And it stays silent in the one situation where I actually want to hear from it.

Where the file goes, and two limits that bite early

Workflow files live in .eas/workflows/. The .eas directory sits at the same level as eas.json. Put it one level off and the command simply won't find anything.

my-app
  .eas
    workflows
      pr-preview.yml
      release.yml
  eas.json
  app.json

The extension has to be .yml or .yaml, and a workflow file must be 16 KiB or smaller. You won't hit 16 KiB writing normally, but you will notice it the day you decide to consolidate every job into one file. Splitting by purpose ages better.

There's a second thing worth knowing before you type anything. The trigger defaults empty out whichever list you leave unwritten. If on.push has neither branches nor tags, you get branches: ['*'] and tags: []. But write only one of them and the other becomes []. Delete the branches line while adding tags and branch pushes stop firing entirely. That may be what you want — it wasn't what I meant the first time.

Getting a preview update out when a pull request opens

The first file publishes a preview update when a pull request opens. It replaces an eas update I used to type by hand, and since nothing reaches production, it's a safe place to start.

# .eas/workflows/pr-preview.yml
name: PR preview
on:
  pull_request:
    branches: ['*']
    paths:
      - app/**
      - package.json
      - '!**/*.md'
 
jobs:
  publish_preview:
    type: update
    environment: preview
    params:
      branch: pr-${{ github.event.pull_request.number }}
      message: ${{ github.event.pull_request.title }}
    hooks:
      before_update:
        - name: Typecheck before anything ships
          run: npx tsc --noEmit

A quick read-through. paths narrows what counts as a change, and a leading ! excludes. Not burning a run on a README-only pull request is a small thing that adds up. branches defaults to ['*'], so that line is optional — I keep it for the version of me who reads this in six months.

type: update maps to eas update. You can set branch or channel, never both; here the branch name comes from the pull request number, so branch it is.

Then there's hooks. That's where I got stuck first.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦You'll be able to put two YAML files in your own repo so a pull request publishes a preview update and a tag carries a build all the way to TestFlight
✦You'll be able to avoid building a pipeline that stays quiet on precisely the nights it breaks, before you ever ship it
✦You'll be able to catch the needs-versus-after mix-up, the jobs that can't take steps, and the jobs where env silently does nothing, all from your own machine before you push
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

◇ App Dev2026-10-22
Expo SDK 58 With Stripe: pod install Stops, and Whether to Turn Off Precompiled Modules or Wait
useFrameworks is already dynamic, yet pod install says Stripe is static and the SDK 58 iOS build stops. The reported conditions, three ways out, and a small script to check your own project first.
◇ App Dev2026-10-14
App Review Says "Guideline 2.1, Blank Screen": Three Places to Look in an Expo Release Build
It opens fine in TestFlight, yet review rejects it for a blank screen. Here is the order I check things in an Expo + EAS release build: which environment holds your variables, secret visibility during config resolution, and what the reviewer's device does differently.
◇ App Dev2026-09-18
The three lines I check when prebuild stops on the standard SDK 57 Swift AppDelegate error
Turning on ios.enableSceneSupport for iOS 27 can stop prebuild cold. The cause was not my SDK version but the shape of AppDelegate.swift. Here are the three lines to check, and why copying the SDK 58 migration steps by hand will break your build.