Skip to content

Commit b95158b

Browse files
aapelivclaude
andcommitted
Rename OTA manifest RPC to GetNativeUpdateManifest and simplify header reads
Follow-up cleanups to #8791: rename the RPC from GetMobileUpdateManifest to GetNativeUpdateManifest for consistency with the /native/ota/manifest route, and drop the per-RPC header helper (the bytes branch was dead code, since the expo-* headers are never binary metadata) in favour of reading context.headers directly, matching the convention elsewhere. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 5e91fd9 commit b95158b

4 files changed

Lines changed: 14 additions & 18 deletions

File tree

app/backend/src/couchers/servicers/bugs.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,18 +116,14 @@ def GetDescriptors(
116116
data=get_descriptors_pb(),
117117
)
118118

119-
def GetMobileUpdateManifest(
119+
def GetNativeUpdateManifest(
120120
self, request: httpbody_pb2.HttpBody, context: CouchersContext, session: Session
121121
) -> httpbody_pb2.HttpBody:
122-
def header(name: str) -> str:
123-
value = context.headers.get(name, "")
124-
return value.decode() if isinstance(value, bytes) else value
125-
126122
# Expo rejects the manifest without these; Envoy forwards them as HTTP response headers.
127123
context.set_response_headers([("expo-protocol-version", "1"), ("expo-sfv-version", "0")])
128124

129-
platform = header("expo-platform") or "ios"
130-
runtime_version = header("expo-runtime-version")
125+
platform = cast(str, context.headers.get("expo-platform", "")) or "ios"
126+
runtime_version = cast(str, context.headers.get("expo-runtime-version", ""))
131127

132128
bundles: dict[str, Any] = context.get_object_value("native_ota_bundles", {})
133129
bundle = bundles.get(platform)

app/backend/src/tests/test_bugs.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,10 @@ def _multipart_part_json(body, name):
417417
}
418418

419419

420-
def test_mobile_update_manifest(db, feature_flags):
420+
def test_native_update_manifest(db, feature_flags):
421421
feature_flags.set("native_ota_bundles", _OTA_BUNDLES)
422422
with real_bugs_session() as (bugs, metadata_interceptor):
423-
res = bugs.GetMobileUpdateManifest(
423+
res = bugs.GetNativeUpdateManifest(
424424
httpbody_pb2.HttpBody(),
425425
metadata=(("expo-platform", "ios"), ("expo-runtime-version", "my-fingerprint")),
426426
)
@@ -440,10 +440,10 @@ def test_mobile_update_manifest(db, feature_flags):
440440
assert metadata_interceptor.latest_headers["expo-sfv-version"] == "0"
441441

442442

443-
def test_mobile_update_manifest_android(db, feature_flags):
443+
def test_native_update_manifest_android(db, feature_flags):
444444
feature_flags.set("native_ota_bundles", _OTA_BUNDLES)
445445
with real_bugs_session() as (bugs, _metadata_interceptor):
446-
res = bugs.GetMobileUpdateManifest(
446+
res = bugs.GetNativeUpdateManifest(
447447
httpbody_pb2.HttpBody(),
448448
metadata=(("expo-platform", "android"), ("expo-runtime-version", "fp")),
449449
)
@@ -452,9 +452,9 @@ def test_mobile_update_manifest_android(db, feature_flags):
452452
assert manifest["launchAsset"]["url"].endswith("/android/bundle.hbc")
453453

454454

455-
def test_mobile_update_manifest_without_runtime_version_returns_directive(db):
455+
def test_native_update_manifest_without_runtime_version_returns_directive(db):
456456
with real_bugs_session() as (bugs, metadata_interceptor):
457-
res = bugs.GetMobileUpdateManifest(
457+
res = bugs.GetNativeUpdateManifest(
458458
httpbody_pb2.HttpBody(),
459459
metadata=(("expo-platform", "ios"),),
460460
)

app/proto/bugs.proto

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ service Bugs {
3838
};
3939
}
4040

41-
rpc GetMobileUpdateManifest(google.api.HttpBody) returns (google.api.HttpBody) {
42-
// Serves the Expo Updates protocol (v1) manifest for the mobile app
41+
rpc GetNativeUpdateManifest(google.api.HttpBody) returns (google.api.HttpBody) {
42+
// Serves the Expo Updates protocol (v1) manifest for the native app
4343
option (google.api.http) = {
4444
get : "/native/ota/manifest"
4545
};

docs/native-prod-ota.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ delivers `set-cookie`).
132132
> **Note — the route-scoped Envoy approach does NOT work here.** A `match: { path:
133133
> "/native/ota/manifest" }` route with `response_headers_to_add` never matches,
134134
> because `grpc_json_transcoder` rewrites the request `:path` to the gRPC method
135-
> path (`/org.couchers.bugs.Bugs/GetMobileUpdateManifest`) *before* route
135+
> path (`/org.couchers.bugs.Bugs/GetNativeUpdateManifest`) *before* route
136136
> selection, so the request falls through to the catch-all `prefix: "/"` route.
137137
> The servicer-metadata path sidesteps this entirely and needs no `envoy.yaml`
138138
> change — only the regenerated `descriptors.pb` (so the route transcodes at all).
@@ -219,15 +219,15 @@ check would bucket every install on `id="None"` — no per-user rollout split.
219219
220220
---
221221

222-
## 6. The manifest endpoint (`Bugs.GetMobileUpdateManifest`)
222+
## 6. The manifest endpoint (`Bugs.GetNativeUpdateManifest`)
223223

224224
Add to `app/proto/bugs.proto` (the `Bugs` service is already `AUTH_LEVEL_OPEN`
225225
and already Envoy-allowlisted):
226226

227227
```proto
228228
import "google/api/httpbody.proto";
229229
230-
rpc GetMobileUpdateManifest(google.api.HttpBody) returns (google.api.HttpBody) {
230+
rpc GetNativeUpdateManifest(google.api.HttpBody) returns (google.api.HttpBody) {
231231
option (google.api.http) = { get : "/native/ota/manifest" };
232232
}
233233
```

0 commit comments

Comments
 (0)