Skip to content

Commit 37e6fe0

Browse files
committed
fix(web): preserve changes visibility when merging main
2 parents 1d34eb6 + aa11ef6 commit 37e6fe0

646 files changed

Lines changed: 37840 additions & 5300 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.agents/skills/test-t3-mobile/SKILL.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ This installs the dev client for the checkout's native fingerprint: from the
3838
device, the local cache, or the shared cache in seconds, building once only
3939
when no machine has that fingerprint yet (5-15 minutes, logged to the file it
4040
names). The device id may be omitted when exactly one device is booted. It
41-
prints one JSON line; on failure it names the next command. Authorized mobile
42-
verification includes that step unless the user prohibits it.
41+
prints one JSON line; on failure it names the next command. Mobile verification
42+
includes that step unless the user prohibits it.
4343

4444
For a device you opened in an agent-device session elsewhere (a device pool,
4545
cloud, or remote host), run `vp run mobile:install <ios|android> --session <s>`

‎.github/VOUCHED.td‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ github:myacoub91
5959
github:naMqe-h
6060
github:nateEc
6161
github:naveed949
62+
github:nexxeln
6263
github:nmggithub
6364
github:Noojuno
6465
github:notkainoa

‎.github/workflows/agent-context-budget.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,5 @@ jobs:
5151
echo "Accepted by the agent-context-increase label."
5252
exit 0
5353
fi
54-
echo "::error file=$BUDGET::Agent context grew compared to main. Cut the added text, or ask a maintainer to add the agent-context-increase label."
54+
echo "::error file=$BUDGET::Agent context grew compared to main. Cut the added text and rerun the evals that cover it (evals/README.md), or ask a maintainer to add the agent-context-increase label."
5555
exit 1

‎.github/workflows/desktop-macos-preview-publish.yml‎

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,19 @@ jobs:
7777
return;
7878
}
7979
80-
// workflow_run.pull_requests is empty for fork PRs, so resolve the
81-
// PR from the built commit instead and require exactly one open PR
82-
// from the same head repository and branch. The build baked its
80+
// workflow_run.pull_requests and the commit-to-PR lookup are both
81+
// empty for fork PRs, so list open PRs by head owner and branch
82+
// and require exactly one at the built commit. The build baked its
8383
// PR number into the version, so two candidates would mean the
8484
// asset name could belong to either.
85-
const associated = await github.paginate(
86-
github.rest.repos.listPullRequestsAssociatedWithCommit,
87-
{ owner, repo, commit_sha: run.head_sha, per_page: 100 },
88-
);
89-
const matching = associated.filter(
85+
const open = await github.paginate(github.rest.pulls.list, {
86+
owner,
87+
repo,
88+
state: "open",
89+
head: `${run.head_repository?.owner?.login}:${run.head_branch}`,
90+
per_page: 100,
91+
});
92+
const matching = open.filter(
9093
(candidate) =>
9194
candidate.state === "open" &&
9295
candidate.head.sha === run.head_sha &&
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
name: Mobile EAS Preview (Fork)
2+
3+
# EAS previews for fork PRs. This runs the PR's code with an Expo token: the
4+
# app config and plugins run on this runner, and native builds run on EAS
5+
# with preview signing credentials. The label is the maintainer's sign-off
6+
# that they reviewed that code, so it covers exactly the commit it was applied
7+
# to: this pins that commit and consumes the label before running anything. A
8+
# later push deploys nothing until the label is applied again.
9+
#
10+
# Same-repo PRs deploy on every push while labeled, via mobile-eas-preview.yml.
11+
12+
on:
13+
pull_request_target:
14+
types: [labeled]
15+
16+
permissions:
17+
contents: read
18+
19+
jobs:
20+
preview:
21+
name: EAS Preview
22+
if: >-
23+
github.event.pull_request.head.repo.full_name != github.repository &&
24+
github.event.label.name == '🚀 Mobile Continuous Deployment'
25+
runs-on: blacksmith-8vcpu-ubuntu-2404
26+
concurrency:
27+
group: mobile-eas-preview-fork-${{ github.event.pull_request.number }}
28+
cancel-in-progress: true
29+
permissions:
30+
contents: read
31+
pull-requests: write
32+
env:
33+
APP_VARIANT: preview
34+
NODE_OPTIONS: --max-old-space-size=8192
35+
MOBILE_VERSION_POLICY: fingerprint
36+
steps:
37+
# If a maintainer removed the label first, that removal wins.
38+
- id: consume
39+
name: Consume the deployment label
40+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
41+
with:
42+
script: |
43+
try {
44+
await github.rest.issues.removeLabel({
45+
owner: context.repo.owner,
46+
repo: context.repo.repo,
47+
issue_number: context.payload.pull_request.number,
48+
name: context.payload.label.name,
49+
});
50+
core.setOutput("consumed", "true");
51+
} catch (error) {
52+
if (error.status !== 404) throw error;
53+
core.info("The label was removed before this run could consume it. Skipping.");
54+
core.setOutput("consumed", "false");
55+
}
56+
57+
- id: expo-token
58+
name: Check for EXPO_PREVIEW_TOKEN
59+
if: steps.consume.outputs.consumed == 'true'
60+
env:
61+
EXPO_TOKEN: ${{ secrets.EXPO_PREVIEW_TOKEN }}
62+
run: |
63+
if [ -n "$EXPO_TOKEN" ]; then
64+
echo "present=true" >> "$GITHUB_OUTPUT"
65+
else
66+
echo "present=false" >> "$GITHUB_OUTPUT"
67+
echo "EXPO_PREVIEW_TOKEN is not set; skipping EAS preview."
68+
fi
69+
70+
# The head SHA from the label event, not the branch, so a push after the
71+
# label cannot swap in unreviewed code. No credentials stay in .git for
72+
# the PR's scripts to read.
73+
- name: Checkout reviewed commit
74+
if: steps.expo-token.outputs.present == 'true'
75+
uses: actions/checkout@v6
76+
with:
77+
ref: ${{ github.event.pull_request.head.sha }}
78+
fetch-depth: 0
79+
persist-credentials: false
80+
# No sparse-checkout: see mobile-eas-preview.yml.
81+
82+
# No caches: pull_request_target saves them under main's scope, where
83+
# trusted workflows with other secrets would restore what PR code wrote.
84+
- name: Setup Vite+
85+
if: steps.expo-token.outputs.present == 'true'
86+
uses: voidzero-dev/setup-vp@v1
87+
with:
88+
node-version-file: package.json
89+
cache: false
90+
run-install: |
91+
args:
92+
- --filter=@t3tools/mobile...
93+
94+
- name: Expose pnpm
95+
if: steps.expo-token.outputs.present == 'true'
96+
run: |
97+
pnpm_version="$(node --print "require('./package.json').packageManager.split('@').pop()")"
98+
vp_pnpm_bin="$HOME/.vite-plus/package_manager/pnpm/$pnpm_version/pnpm/bin"
99+
echo "$vp_pnpm_bin" >> "$GITHUB_PATH"
100+
"$vp_pnpm_bin/pnpm" --version
101+
102+
- name: Setup EAS
103+
if: steps.expo-token.outputs.present == 'true'
104+
uses: expo/expo-github-action@v8
105+
with:
106+
# Pinned and installed with npm for the same reasons as mobile-eas-preview.yml.
107+
eas-version: 21.8.0
108+
eas-cache: false
109+
token: ${{ secrets.EXPO_PREVIEW_TOKEN }}
110+
packager: npm
111+
112+
- name: Pull preview environment variables
113+
if: steps.expo-token.outputs.present == 'true'
114+
working-directory: apps/mobile
115+
env:
116+
EXPO_TOKEN: ${{ secrets.EXPO_PREVIEW_TOKEN }}
117+
run: |
118+
eas env:pull preview --non-interactive
119+
# See mobile-eas-preview.yml: keeps Android build and OTA fingerprints matching.
120+
node --input-type=module <<'NODE'
121+
import { appendFileSync, readFileSync } from "node:fs";
122+
import { parseEnv } from "node:util";
123+
const env = parseEnv(readFileSync(".env.local", "utf8"));
124+
const googleServicesFile = env.T3CODE_ANDROID_GOOGLE_SERVICES_FILE;
125+
if (googleServicesFile) {
126+
appendFileSync(process.env.GITHUB_ENV, `T3CODE_ANDROID_GOOGLE_SERVICES_FILE=${googleServicesFile}\n`);
127+
}
128+
NODE
129+
130+
- name: Deploy with fingerprint check
131+
if: steps.expo-token.outputs.present == 'true'
132+
uses: expo/expo-github-action/continuous-deploy-fingerprint@main
133+
env:
134+
EXPO_TOKEN: ${{ secrets.EXPO_PREVIEW_TOKEN }}
135+
RUNNER_DEBUG: "1"
136+
# The action only comments for pull_request events; this hook gives
137+
# it the PR under pull_request_target. Without it, it skips the comment.
138+
EXPO_TEST_GITHUB_PULL: ${{ github.event.pull_request.number }}
139+
with:
140+
profile: preview:dev
141+
branch: pr-${{ github.event.pull_request.number }}
142+
platform: all
143+
environment: preview
144+
working-directory: apps/mobile
145+
github-token: ${{ secrets.GITHUB_TOKEN }}

‎.github/workflows/mobile-eas-preview.yml‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ on:
77
jobs:
88
preview:
99
name: EAS Preview
10+
# Fork PRs deploy one reviewed commit per label through mobile-eas-preview-fork.yml.
1011
if: |
12+
github.event.pull_request.head.repo.full_name == github.repository &&
1113
contains(github.event.pull_request.labels.*.name, '🚀 Mobile Continuous Deployment') &&
1214
(github.event.action != 'labeled' || github.event.label.name == '🚀 Mobile Continuous Deployment')
1315
runs-on: blacksmith-8vcpu-ubuntu-2404
@@ -23,15 +25,15 @@ jobs:
2325
MOBILE_VERSION_POLICY: fingerprint
2426
steps:
2527
- id: expo-token
26-
name: Check for EXPO_TOKEN
28+
name: Check for EXPO_PREVIEW_TOKEN
2729
env:
28-
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
30+
EXPO_TOKEN: ${{ secrets.EXPO_PREVIEW_TOKEN }}
2931
run: |
3032
if [ -n "$EXPO_TOKEN" ]; then
3133
echo "present=true" >> "$GITHUB_OUTPUT"
3234
else
3335
echo "present=false" >> "$GITHUB_OUTPUT"
34-
echo "EXPO_TOKEN is not available; skipping EAS preview."
36+
echo "EXPO_PREVIEW_TOKEN is not available; skipping EAS preview."
3537
fi
3638
3739
- name: Checkout
@@ -70,7 +72,7 @@ jobs:
7072
# continuous-deploy-fingerprint still reads `build.project.ownerAccount`.
7173
# Unpin once https://github.com/expo/expo-github-action/issues/358 is fixed.
7274
eas-version: 21.8.0
73-
token: ${{ secrets.EXPO_TOKEN }}
75+
token: ${{ secrets.EXPO_PREVIEW_TOKEN }}
7476
# npm, not pnpm: this only installs eas-cli into the action's own
7577
# tool dir, and pnpm 11 hard-fails that install on dtrace-provider's
7678
# ignored build script (no allowBuilds config outside the repo).
@@ -80,7 +82,7 @@ jobs:
8082
if: steps.expo-token.outputs.present == 'true'
8183
working-directory: apps/mobile
8284
env:
83-
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
85+
EXPO_TOKEN: ${{ secrets.EXPO_PREVIEW_TOKEN }}
8486
run: |
8587
eas env:pull preview --non-interactive
8688
# EAS Update disables dotenv loading. Keep the downloaded native config
@@ -99,7 +101,7 @@ jobs:
99101
if: steps.expo-token.outputs.present == 'true'
100102
uses: expo/expo-github-action/continuous-deploy-fingerprint@main
101103
env:
102-
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
104+
EXPO_TOKEN: ${{ secrets.EXPO_PREVIEW_TOKEN }}
103105
# The Expo action otherwise suppresses the EAS command's failure output.
104106
RUNNER_DEBUG: "1"
105107
with:

‎.github/workflows/mobile-eas-production.yml‎

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,13 @@ jobs:
9797
- id: expo-token
9898
name: Check for EXPO_TOKEN
9999
env:
100-
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
100+
EXPO_TOKEN: ${{ secrets.EXPO_PRODUCTION_TOKEN }}
101101
run: |
102102
if [ -n "$EXPO_TOKEN" ]; then
103103
echo "present=true" >> "$GITHUB_OUTPUT"
104104
else
105105
echo "present=false" >> "$GITHUB_OUTPUT"
106-
echo "EXPO_TOKEN is not available; skipping EAS production job."
106+
echo "EXPO_PRODUCTION_TOKEN is not available; skipping EAS production job."
107107
fi
108108
109109
- id: version_app_token
@@ -149,7 +149,7 @@ jobs:
149149
uses: expo/expo-github-action@v8
150150
with:
151151
eas-version: latest
152-
token: ${{ secrets.EXPO_TOKEN }}
152+
token: ${{ secrets.EXPO_PRODUCTION_TOKEN }}
153153
# npm, not pnpm: this only installs eas-cli into the action's own
154154
# tool dir, and pnpm 11 hard-fails that install on dtrace-provider's
155155
# ignored build script (no allowBuilds config outside the repo).
@@ -159,8 +159,21 @@ jobs:
159159
if: steps.expo-token.outputs.present == 'true'
160160
working-directory: apps/mobile
161161
env:
162-
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
163-
run: eas env:pull production --non-interactive
162+
EXPO_TOKEN: ${{ secrets.EXPO_PRODUCTION_TOKEN }}
163+
run: |
164+
eas env:pull production --non-interactive
165+
# EAS commands skip dotenv, and the Android fingerprint hashes this
166+
# file. Without it every merge misses the build's hash and rebuilds.
167+
node --input-type=module <<'NODE'
168+
import { appendFileSync, readFileSync } from "node:fs";
169+
import { parseEnv } from "node:util";
170+
const env = parseEnv(readFileSync(".env.local", "utf8"));
171+
const googleServicesFile = env.T3CODE_ANDROID_GOOGLE_SERVICES_FILE;
172+
if (!googleServicesFile) {
173+
throw new Error("T3CODE_ANDROID_GOOGLE_SERVICES_FILE is missing from the production environment");
174+
}
175+
appendFileSync(process.env.GITHUB_ENV, `T3CODE_ANDROID_GOOGLE_SERVICES_FILE=${googleServicesFile}\n`);
176+
NODE
164177
165178
- name: Apply manual version override
166179
if: steps.version_app_token.outcome == 'success'
@@ -231,7 +244,7 @@ jobs:
231244
if: steps.expo-token.outputs.present == 'true' && github.event_name == 'workflow_dispatch' && inputs.mode == 'build'
232245
working-directory: apps/mobile
233246
env:
234-
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
247+
EXPO_TOKEN: ${{ secrets.EXPO_PRODUCTION_TOKEN }}
235248
MOBILE_BUILD_PROFILE: ${{ inputs.profile || 'production' }}
236249
run: eas build --platform ${{ inputs.platform }} --profile "$MOBILE_BUILD_PROFILE" --auto-submit --non-interactive --no-wait
237250

@@ -242,7 +255,7 @@ jobs:
242255
if: steps.expo-token.outputs.present == 'true' && (github.event_name == 'push' || inputs.mode == 'update')
243256
working-directory: apps/mobile
244257
env:
245-
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
258+
EXPO_TOKEN: ${{ secrets.EXPO_PRODUCTION_TOKEN }}
246259
PLATFORM: ${{ inputs.platform || 'all' }}
247260
run: |
248261
if [ "$PLATFORM" = "all" ]; then platforms="ios android"; else platforms="$PLATFORM"; fi
@@ -262,7 +275,7 @@ jobs:
262275
if: steps.expo-token.outputs.present == 'true' && github.event_name == 'workflow_dispatch' && inputs.mode == 'update'
263276
working-directory: apps/mobile
264277
env:
265-
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
278+
EXPO_TOKEN: ${{ secrets.EXPO_PRODUCTION_TOKEN }}
266279
MOBILE_BUILD_PROFILE: ${{ inputs.profile || 'production' }}
267280
OTA_MESSAGE: ${{ inputs.message || format('Production OTA ({0})', github.sha) }}
268281
run: |
@@ -286,7 +299,7 @@ jobs:
286299
if: steps.expo-token.outputs.present == 'true' && github.event_name == 'push'
287300
working-directory: apps/mobile
288301
env:
289-
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
302+
EXPO_TOKEN: ${{ secrets.EXPO_PRODUCTION_TOKEN }}
290303
run: |
291304
failed=0
292305
message="$(git log -1 --pretty=%s | head -c 120) ($(git rev-parse --short=9 HEAD))"

0 commit comments

Comments
 (0)