[object Object]

← back to Exo

chore(app): hardcode bug report presigned-URL endpoint (#1971)

45248c5c85e1ea35b7770f4ea6c06e12facada61 · 2026-04-23 15:08:16 +0100 · Alex Cheema

## Motivation

The bug-report presigned-URL endpoint
(`https://reports.exolabs.net/presigned-urls`) was injected at build
time from the `EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT` GitHub Actions
secret into `Info.plist`, then read at runtime by `BugReportService`. It
isn't actually a secret — the POST body is just `{"keys":[...]}` with no
credential (see `app/EXO/EXO/Services/BugReportService.swift:136-142`),
abuse prevention lives server-side on the lambda, and the URL is already
visible in every publicly-distributed DMG's `Info.plist`. Treating it as
a repo secret added plumbing with no security benefit and broke local
dev builds — hitting **Send Bug Report** on an uncustomised `just
build-app` raised "Bug report endpoint is invalid".

## Changes

- `app/EXO/EXO/Info.plist`: replace
`$(EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT)` with the literal URL.
- `.github/workflows/build-app.yml`: drop the
`EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT` job-level env var and the
xcodebuild build-setting passthrough. No other workflow changes.

Swift code is unchanged — `BugReportService` still reads from
`Info.plist`, which leaves an escape hatch if anyone ever needs to
override via `xcodebuild EXOBugReportPresignedUrlEndpoint=...` without
recompiling.

Follow-up: the `EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT` repo secret can
now be deleted in the GitHub Actions settings UI.

## Why It Works

`Info.plist` variable substitution turns `$(FOO)` into whatever build
setting `FOO` resolves to. CI was setting `FOO` via xcodebuild; local
dev wasn't, so the key resolved to an empty string, which
`BugReportService.fetchPresignedUploadUrls` rejects via the
`!trimmedEndpointString.isEmpty` guard at `BugReportService.swift:131`.
Hardcoding the literal string removes the substitution entirely, so
every build — local or CI — gets the right value.

## Test Plan

### Manual Testing
<!-- Hardware: MacBook Pro (macOS app build via Xcode) -->
- `just build-app` with no extra env vars (reproduces the failure path
on `main`).
- `/usr/libexec/PlistBuddy -c "Print :EXOBugReportPresignedUrlEndpoint"
app/EXO/build/Build/Products/Debug/EXO.app/Contents/Info.plist` →
returns `https://reports.exolabs.net/presigned-urls` (was empty before
this change).
- `open app/EXO/build/Build/Products/Debug/EXO.app` → menubar → **Debug
Info** → **Send Bug Report** → type a description → **Send** → upload
succeeds and the **Create GitHub Issue** button appears (was failing
with "Bug report endpoint is invalid" before).
- Cross-check on the Slack side that the uploaded `report.json` lands
under `reports/YYYY/MM/DD/<ts>/` as before.

### Automated Testing
<!-- Describe changes to automated tests, or how existing tests cover
this change -->
- No new tests. This is a single-string change to `Info.plist` plus a
workflow cleanup. `nix flake check` in CI verifies formatting/lint for
the rest of the tree.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

Files touched

Diff

commit 45248c5c85e1ea35b7770f4ea6c06e12facada61
Author: Alex Cheema <41707476+AlexCheema@users.noreply.github.com>
Date:   Thu Apr 23 15:08:16 2026 +0100

    chore(app): hardcode bug report presigned-URL endpoint (#1971)
    
    ## Motivation
    
    The bug-report presigned-URL endpoint
    (`https://reports.exolabs.net/presigned-urls`) was injected at build
    time from the `EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT` GitHub Actions
    secret into `Info.plist`, then read at runtime by `BugReportService`. It
    isn't actually a secret — the POST body is just `{"keys":[...]}` with no
    credential (see `app/EXO/EXO/Services/BugReportService.swift:136-142`),
    abuse prevention lives server-side on the lambda, and the URL is already
    visible in every publicly-distributed DMG's `Info.plist`. Treating it as
    a repo secret added plumbing with no security benefit and broke local
    dev builds — hitting **Send Bug Report** on an uncustomised `just
    build-app` raised "Bug report endpoint is invalid".
    
    ## Changes
    
    - `app/EXO/EXO/Info.plist`: replace
    `$(EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT)` with the literal URL.
    - `.github/workflows/build-app.yml`: drop the
    `EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT` job-level env var and the
    xcodebuild build-setting passthrough. No other workflow changes.
    
    Swift code is unchanged — `BugReportService` still reads from
    `Info.plist`, which leaves an escape hatch if anyone ever needs to
    override via `xcodebuild EXOBugReportPresignedUrlEndpoint=...` without
    recompiling.
    
    Follow-up: the `EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT` repo secret can
    now be deleted in the GitHub Actions settings UI.
    
    ## Why It Works
    
    `Info.plist` variable substitution turns `$(FOO)` into whatever build
    setting `FOO` resolves to. CI was setting `FOO` via xcodebuild; local
    dev wasn't, so the key resolved to an empty string, which
    `BugReportService.fetchPresignedUploadUrls` rejects via the
    `!trimmedEndpointString.isEmpty` guard at `BugReportService.swift:131`.
    Hardcoding the literal string removes the substitution entirely, so
    every build — local or CI — gets the right value.
    
    ## Test Plan
    
    ### Manual Testing
    <!-- Hardware: MacBook Pro (macOS app build via Xcode) -->
    - `just build-app` with no extra env vars (reproduces the failure path
    on `main`).
    - `/usr/libexec/PlistBuddy -c "Print :EXOBugReportPresignedUrlEndpoint"
    app/EXO/build/Build/Products/Debug/EXO.app/Contents/Info.plist` →
    returns `https://reports.exolabs.net/presigned-urls` (was empty before
    this change).
    - `open app/EXO/build/Build/Products/Debug/EXO.app` → menubar → **Debug
    Info** → **Send Bug Report** → type a description → **Send** → upload
    succeeds and the **Create GitHub Issue** button appears (was failing
    with "Bug report endpoint is invalid" before).
    - Cross-check on the Slack side that the uploaded `report.json` lands
    under `reports/YYYY/MM/DD/<ts>/` as before.
    
    ### Automated Testing
    <!-- Describe changes to automated tests, or how existing tests cover
    this change -->
    - No new tests. This is a single-string change to `Info.plist` plus a
    workflow cleanup. `nix flake check` in CI verifies formatting/lint for
    the rest of the tree.
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
 .github/workflows/build-app.yml | 2 --
 app/EXO/EXO/Info.plist          | 2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/.github/workflows/build-app.yml b/.github/workflows/build-app.yml
index 4c5e0cd3..e8874422 100644
--- a/.github/workflows/build-app.yml
+++ b/.github/workflows/build-app.yml
@@ -32,7 +32,6 @@ jobs:
       SPARKLE_ED25519_PRIVATE: ${{ secrets.SPARKLE_ED25519_PRIVATE }}
       SPARKLE_S3_BUCKET: ${{ secrets.SPARKLE_S3_BUCKET }}
       SPARKLE_S3_PREFIX: ${{ secrets.SPARKLE_S3_PREFIX }}
-      EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT: ${{ secrets.EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT }}
       AWS_REGION: ${{ secrets.AWS_REGION }}
       EXO_BUILD_NUMBER: ${{ github.run_number }}
       EXO_LIBP2P_NAMESPACE: ${{ github.ref_name }}
@@ -347,7 +346,6 @@ jobs:
             EXO_BUILD_COMMIT="$GITHUB_SHA" \
             SPARKLE_FEED_URL="$SPARKLE_FEED_URL" \
             SPARKLE_ED25519_PUBLIC="$SPARKLE_ED25519_PUBLIC" \
-            EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT="$EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT" \
             CODE_SIGNING_IDENTITY="$SIGNING_IDENTITY" \
             CODE_SIGN_INJECT_BASE_ENTITLEMENTS=YES
           mkdir -p ../../output
diff --git a/app/EXO/EXO/Info.plist b/app/EXO/EXO/Info.plist
index 575170a6..9993a0fb 100644
--- a/app/EXO/EXO/Info.plist
+++ b/app/EXO/EXO/Info.plist
@@ -9,7 +9,7 @@
 	<key>EXOBuildCommit</key>
 	<string>$(EXO_BUILD_COMMIT)</string>
 	<key>EXOBugReportPresignedUrlEndpoint</key>
-	<string>$(EXO_BUG_REPORT_PRESIGNED_URL_ENDPOINT)</string>
+	<string>https://reports.exolabs.net/presigned-urls</string>
 	<key>NSLocalNetworkUsageDescription</key>
 	<string>EXO needs local network access to discover and connect to other devices in your cluster for distributed AI inference.</string>
 	<key>NSBonjourServices</key>

← 290e3fd9 Keep image cache fresh (temporary fix) (#1961)  ·  back to Exo  ·  Add more model cards (#1970) fd707de3 →