Skip to content

[pull] main from expo:main - #1198

Merged
pull[bot] merged 10 commits into
code:mainfrom
expo:main
Aug 31, 2026
Merged

[pull] main from expo:main#1198
pull[bot] merged 10 commits into
code:mainfrom
expo:main

Conversation

@pull

@pull pull Bot commented Aug 31, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

claude Bot and others added 10 commits August 31, 2026 12:21
…ws (#49518)

<!-- ccr-slack-attribution -->
_Requested by **Keith Kurak** · [Slack
thread](https://exponent-internal.slack.com/archives/D0BSRLHKD7V/p1787979054839969)_

# Why

While building an agentic workflow triggered by PR events, Claude got
hung up on whether someone could run workflows on my EAS account without
my permissions by forking my public repo and opening PR's. However,
internally, it's been noted that this is not possible:
expo/universe#28147

# How

Added a note indicating that forks can't trigger PR events with EAS
Workflows

# Test Plan

Documentation-only change. The diff adds two lines to
`docs/pages/eas/workflows/syntax.mdx` and touches no code or package
sources, so there is nothing to test at runtime.

- The `vale` and `docs-pr` checks pass on the head commit (`7e7594c`).
- A reviewer can check the rendered page by running the docs site
locally — `pnpm install && pnpm dev` in `docs/` — and opening
http://localhost:3002/eas/workflows/syntax/, where the new note appears
under the `pull_request` trigger section.

# Checklist

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [x] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Keith Kurak <keith@expo.dev>
…grouping (#49386)

# Why

We had two bugs in the `et github-metrics` command that caused the CI
health report to be wrong.

1. Success rate counted unresolved runs as failures.
2. Workflow breakdown grouped by name - breaks when workflow sets
dynamic name.

# How

1. Fixed by moving the denominator: `computeRunConclusionCounts` now
returns `resolvedRuns = successfulRuns + failedRuns + cancelledRuns` and
divides by that.
2. Runs are grouped by `workflow_id` and not name anymore

# Test Plan

✅ Unit tests (`tools/src/commands/GitHubMetricsCommand.test.ts` covers
both fixes)

# Checklist

- [x] Builds, type-checks, lints, and tests pass (the three checks in
`tools/AGENTS.md`, which is what `.github/workflows/expotools.yml`
runs).
- [x] Conforms to the documentation style guide.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
# Why

`Grid` and `GridItem` in `ui/components/Authentication/` have no
importers anywhere in the docs; the only page using this folder imports
`ASSETS` and `Box`. Found during the border-radius migration
(ENG-26237).

# How

- Delete `Grid.tsx` and `GridItem.tsx` and drop their exports from the
folder index. `Box`, `Icon`, and `CreateAppButton` stay in use on
/guides/authentication/.

# Test Plan

<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

N/A

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
…49439)

# Why

Fix ENG-26229 ENG-26230 ENG-26231 ENG-26236

<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->

# How

<!--
How did you build this feature or fix this bug and why?
-->

- Add `Vary: Accept` to negotiated markdown responses in
`public/_worker.js` so caches key on the `Accept` header (ENG-26229)
- Return a markdown 404 body linking `llms.txt`, `sitemap.xml`, and the
docs home instead of a plain `Not found` (ENG-26230)
- Pass 3xx responses through to markdown requests so moved pages
redirect instead of returning 404 (ENG-26231)
- Replace the `text/markdown` substring match with an `acceptsMarkdown`
q-value parser: markdown is served only when explicitly listed, above
zero, and at or above HTML's quality (ENG-26236)
- Cover all four behaviors in `scripts/test-worker.ts`

# Test Plan

<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

`pnpm test:worker` should pass.

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
# Why

Fixes - #47883,
#48059

Fixes the layout loops that happens in some cases when `Host` and
`RNHostView` has `matchContents` and child of `RNHostView` depends upon
parent on sizing. Explained it in more detail here -
#48059 (comment)

<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->

# How

Set `RNHostView` node as a leaf and measurable node using shadow node
traits. This removes it from the yoga layout hierarchy (shadow node
hierarchy is still preserved). Override `measureContent` and `layout`
shadow node functions for `RNHostView`. The `measureContent` is called
by Yoga during layout and `layout` is called during commit.

A better fix would be if Yoga supports `max-content` so we could just do
`<RNHostView style={{ width: "max-content", height: "max-content" }} />`
if someone passes `matchContents`. Made a PR in Yoga for that
react/yoga#2012

<!--
How did you build this feature or fix this bug and why?
-->

# Test Plan

Added regression testcases for RNHostView which leads to loops.



<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
…pProcedure (#49374)

# Why
`start` ran BuildData.ensureBuildDataIsConsistent synchronously on the
caller's thread, which is the main thread when apps call
UpdatesController.initialize from `onCreate`. Room opens the database
lazily on first query, so this also ran the database open and every
migration on the main thread during cold start. It is the only
production code path that queries the updates database on the main
thread.

# How
Moved the call into the top of StartupProcedure.run(), keeping the
hasUpdatesOverride guard. The state machine's serial executor queue runs
procedures on Dispatchers.IO and guarantees the check completes before
any other procedure touches the database. This matches iOS, where
ensureBuildDataIsConsistentAsync already dispatches to the database
queue.

# Test Plan
New test `StartupProcedureTest`
…se (#49375)

# Why
The database was built with allowMainThreadQueries(), which hides
regressions. With the build data check moved off the main thread in the
previous PR, no production code path queries on main anymore, so the
escape hatch can go.

# How
Removed .allowMainThreadQueries() from the builder in
UpdatesDatabase.getInstance. Any future main-thread query now throws
immediately instead of janking startup. Tests are unaffected because
they build their own in-memory databases.

# Test Plan
CI and local runs
…ectly (#49376)

# Why
DatabaseHolder claimed to serialize high-level database operations, but
its database property acquired and released the mutex before returning,
so no caller ever held the lock during a query. It also ran runBlocking
on every access, which could stall the main thread if a withDatabase
block ever held the mutex. The real serialization mechanism is the state
machine's serial procedure queue.

# How
Deleted the class. Controllers, procedures, and LoaderTask now take
UpdatesDatabase directly, and the two withDatabase launch-count updates
became direct DAO calls inside the existing IO coroutines. Updated Expo
Go's NativeModuleDepsProvider and ExpoUpdatesAppLoader to inject
UpdatesDatabase instead. Updated the UpdatesDatabase doc comment to
describe the actual concurrency model.

# Test Plan
CI
E2E, instrumentation, and unit tests all pass
…e` to 0.2.0 (#49241)

# Why

`oxlint-config-universe` 0.2.0 is out and requires `oxlint` 1.79, so
this updates both.

# How

oxlint 1.79 turns on a set of React Compiler-derived rules by default
and the repo has a few hundred pre-existing findings (mostly in
expo-router), so the base config keeps them off to make this update
behavior-neutral. We can re-enable them rule by rule as the findings get
triaged; the stacked #49242 starts with the five cheapest ones.

A few more adjustments in the base config: `no-inner-declarations`
started flagging exported functions inside TS namespaces, which the new
`namespaces: 'allow'` option fixes without losing the rule. The
`no-did-mount-set-state` / `no-did-update-set-state` pair is off because
oxlint (unlike ESLint's default mode) also flags `setState` inside async
callbacks, hitting the common fetch-on-mount pattern. The TS overrides
that 0.2.0 now applies itself (or no longer enables) are dropped.

Source changes are small and mechanical: two useless `export {}`
statements flagged by the newly enabled
`typescript/no-useless-empty-export` are removed (an expo-observe test
and an `@expo/cli` e2e helper), the LogBox DOM polyfill's inline
disables now also cover `import/namespace` (oxlint 1.79 newly reports
assignments to namespace-import members), and expo-router's navigation
tree reducer gets inline disables where the stricter `rules-of-hooks`
rejects effect-event calls made outside of effects it recognizes (event
handlers and a custom effect wrapper).

# Test Plan

Linted all 130 oxlint packages plus the three oxlint apps: no errors
anywhere, and the only warnings are in `@expo/metro-config` test
fixtures and exist on main as well. `et check-packages` passes for the
touched packages, including the expo-observe and expo-router jest
suites.

<!-- disable:changelog-checks -->
# Why

Fixes #49534.

`TextView` is one of the Expo UI views that applies common modifiers
internally so that concatenated children remain a native `SwiftUI.Text`.
The widget renderer currently wraps it in `UIBaseView`, which applies
the same modifiers a second time. A modifier such as `padding` or
`strokeBorder` therefore appears twice in iOS widgets.
`WidgetsDynamicView` is also used by Live Activities, so they share the
same behavior.

The public minimal reproduction is available at
https://github.com/gee1k/expo-widgets-text-modifier-repro.

# How

Added an opt-out to `WidgetsDynamicView.render` for views that already
handle common modifiers, and use it only for `TextView`. All other
widget views continue to render through `UIBaseView` unchanged.

Also added the fix to the unpublished `expo-widgets` changelog.

# Test Plan

The reproduction renders the same `padding` and `strokeBorder` values in
two ways: on an `HStack` (green) and directly on `Text` (red).

| Before | After |
| --- | --- |
| ![Before: the Text has two nested red
borders](https://raw.githubusercontent.com/gee1k/expo-widgets-text-modifier-repro/main/screenshots/before.png)
| ![After: the Text has one red
border](https://raw.githubusercontent.com/gee1k/expo-widgets-text-modifier-repro/main/screenshots/after.png)
|

Local verification on an iPhone 17 Pro Max Simulator running iOS 26.5:

- `npx expo-doctor@latest`: 21/21 checks passed.
- `./node_modules/.bin/tsc --noEmit`: passed in the reproduction.
- Built and installed the unmodified `expo-widgets@57.0.15` reproduction
with `npx expo run:ios`; observed two nested red borders.
- Rebuilt the same project with this `DynamicView.swift`; build
completed with 0 errors and 0 warnings, and the red `Text` rendered one
border with the expected padding.
- `git diff --check`: passed.

There is currently no native `WidgetsDynamicView` test target; the
package's existing automated tests cover the JavaScript bundle and
configuration layer, so the regression is demonstrated with the minimal
native reproduction and before/after Simulator evidence.

# Checklist

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [x] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
(not applicable; no documentation changes)

---------

Co-authored-by: Codex <codex@openai.com>
@pull pull Bot locked and limited conversation to collaborators Aug 31, 2026
@pull pull Bot added the ⤵️ pull label Aug 31, 2026
@pull
pull Bot merged commit 9886c0c into code:main Aug 31, 2026
19 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants