Skip to content

Commit 4dbd6a9

Browse files
aapelivclaude
andcommitted
mobile: generate the OTA QR in the build job, keep the comment job pure
Generate the dev-launcher QR PNG in build:mobile-ota (npx qrcode, so it stays out of the fingerprint sources) and upload it with the existing aws s3 cp in preview:mobile-ota, next to the bundle. The PR-comment job no longer touches S3 (no boto3) - it only assembles markdown referencing the hosted qr.png and upserts the GitHub comment. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 215e915 commit 4dbd6a9

2 files changed

Lines changed: 15 additions & 35 deletions

File tree

app/.gitlab-ci.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,9 @@ build:mobile-ota:
865865
RV=$(npx expo-updates fingerprint:generate --platform "$P" 2>/dev/null | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>process.stdout.write(JSON.parse(s).hash))')
866866
echo "fingerprint($P) = $RV"
867867
node scripts/ota-stage.mjs --platform "$P" --runtime-version "$RV" --base-url "https://$CI_COMMIT_SHORT_SHA--ota.$PREVIEW_DOMAIN" --dist dist --out ota-out --expo-config ota-expo-config.json
868+
# QR encodes the dev-launcher deep link so the PR comment can show a scannable image.
869+
# npx (not a package.json dep) keeps it out of the fingerprint sources.
870+
npx --yes qrcode -o "ota-out/$P/qr.png" "couchers-devtool://expo-development-client/?url=https%3A%2F%2F$CI_COMMIT_SHORT_SHA--ota.$PREVIEW_DOMAIN%2F$P%2Fmanifest" < /dev/null
868871
done
869872
artifacts:
870873
paths:
@@ -898,6 +901,7 @@ preview:mobile-ota:
898901
aws s3 cp "$D/manifest" "s3://$AWS_PREVIEW_BUCKET/ota/$CI_COMMIT_SHORT_SHA/$P/manifest" --content-type "$CT"
899902
aws s3 cp "$D/bundle.hbc" "s3://$AWS_PREVIEW_BUCKET/ota/$CI_COMMIT_SHORT_SHA/$P/bundle.hbc" --content-type application/javascript
900903
aws s3 cp "$D/assets/" "s3://$AWS_PREVIEW_BUCKET/ota/$CI_COMMIT_SHORT_SHA/$P/assets/" --recursive
904+
aws s3 cp "$D/qr.png" "s3://$AWS_PREVIEW_BUCKET/ota/$CI_COMMIT_SHORT_SHA/$P/qr.png" --content-type image/png
901905
echo "Done $P. Manifest: https://$CI_COMMIT_SHORT_SHA--ota.$PREVIEW_DOMAIN/$P/manifest"
902906
echo " deep link: couchers-devtool://expo-development-client/?url=https%3A%2F%2F$CI_COMMIT_SHORT_SHA--ota.$PREVIEW_DOMAIN%2F$P%2Fmanifest"
903907
done
@@ -925,7 +929,7 @@ preview:pr-comment:
925929
variables:
926930
OTA_PLATFORMS: "ios"
927931
script:
928-
- pip install --quiet --no-cache-dir "qrcode[pil]" requests boto3
932+
- pip install --quiet --no-cache-dir requests
929933
- python app/scripts/pr_preview_comment.py
930934
rules:
931935
- if: ($BUILD_MOBILE == "true") && ($CI_COMMIT_BRANCH == $RELEASE_BRANCH)

app/scripts/pr_preview_comment.py

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
#!/usr/bin/env python3
22
"""Post (or update) a sticky preview comment on the GitHub PR for this pipeline.
33
4-
Runs in GitLab CI after the preview/upload jobs so every link it posts is already
5-
live. Currently surfaces the per-branch mobile Dev Tool OTA preview (QR + deep
6-
link); each preview is a section, so web/coverage/etc. can be appended as the
7-
pipeline grows. No-ops (exit 0) when there is no token or no open PR, so it never
8-
turns a pipeline red.
4+
Runs in GitLab CI after the upload jobs so every link it posts is already live.
5+
Each preview is a section, so web/coverage/etc. can be appended as the pipeline
6+
grows. The mobile QR PNG is generated and uploaded by the OTA build/upload jobs;
7+
this script only assembles markdown and talks to the GitHub API. No-ops (exit 0)
8+
when there is no token or no open PR, so it never turns a pipeline red.
99
"""
1010

11-
import io
1211
import os
1312
import sys
1413
import urllib.parse
1514

16-
import boto3
17-
import qrcode
1815
import requests
1916

2017
MARKER = "<!-- couchers-preview-bot -->"
@@ -42,39 +39,21 @@ def deep_link(manifest_url):
4239
)
4340

4441

45-
def make_qr_png(data):
46-
qr = qrcode.QRCode(
47-
border=2, box_size=8, error_correction=qrcode.constants.ERROR_CORRECT_M
48-
)
49-
qr.add_data(data)
50-
qr.make(fit=True)
51-
buf = io.BytesIO()
52-
qr.make_image(fill_color="black", back_color="white").save(buf, format="PNG")
53-
return buf.getvalue()
54-
55-
56-
def mobile_ota_section(s3, bucket, short_sha, domain, platforms):
42+
def mobile_ota_section(short_sha, domain, platforms):
5743
lines = [
5844
"### Mobile Dev Tool preview",
5945
"",
6046
"Scan with your phone camera (or tap the deep link on the device) to open this "
6147
"branch in the installed **Dev Tool** dev client.",
6248
]
6349
for platform in platforms:
64-
manifest_url = f"https://{short_sha}--ota.{domain}/{platform}/manifest"
65-
link = deep_link(manifest_url)
66-
s3.put_object(
67-
Bucket=bucket,
68-
Key=f"ota/{short_sha}/{platform}/qr.png",
69-
Body=make_qr_png(link),
70-
ContentType="image/png",
71-
)
72-
qr_url = f"https://{short_sha}--ota.{domain}/{platform}/qr.png"
50+
base = f"https://{short_sha}--ota.{domain}/{platform}"
51+
link = deep_link(f"{base}/manifest")
7352
lines += [
7453
"",
7554
f"**{platform}**",
7655
"",
77-
f'<img src="{qr_url}" alt="QR to open the {platform} build" width="180" height="180" />',
56+
f'<img src="{base}/qr.png" alt="QR to open the {platform} build" width="180" height="180" />',
7857
"",
7958
"<details><summary>Deep link</summary>",
8059
"",
@@ -154,10 +133,7 @@ def main():
154133
print(f"No open PR for {sha} - skipping preview comment.")
155134
return
156135

157-
s3 = boto3.client("s3")
158-
bucket = env("AWS_PREVIEW_BUCKET", required=True)
159-
160-
sections = [mobile_ota_section(s3, bucket, short_sha, domain, platforms)]
136+
sections = [mobile_ota_section(short_sha, domain, platforms)]
161137
url = upsert_comment(repo, pr, build_body(sections, sha, pipeline_url), token)
162138
print(f"Posted preview comment to PR #{pr}: {url}")
163139

0 commit comments

Comments
 (0)