Files
BizGaze_Remote/codemagic.yaml
T
Sravan 0a2c7376b9 feat(share): "Biz Connect" in the iOS share sheet — share a photo/file into a chat
Adds the reverse direction: share FROM Photos/Files/Safari INTO a Biz Connect
conversation. An app can only appear in the iOS share sheet as an app-extension
target, so this is real native work, not a web change.

Pieces:
- mobile/ios-share/ShareViewController.swift: a UI-less Share Extension. It stages
  the shared items into the App Group container and opens bizconnect://share. It
  deliberately does NOT reimplement the chat picker — that lives in the app, which
  already has the chat list, search and upload progress. Appends to the manifest
  (never overwrites), so sharing twice before opening the app loses nothing.
- mobile/scripts/add-share-extension.rb: injects the extension target into the
  Capacitor-generated Xcode project on every CI build (Codemagic checks out fresh),
  using the xcodeproj gem that ships with CocoaPods. Embeds it, sets the bundle id
  <app>.share, and MERGES the App Group into the app's entitlements rather than
  clobbering them (push's aps-environment must survive). Idempotent.
- mobile/plugins/share-inbox: getPending()/clear() to read that manifest — the App
  Group container isn't one of Filesystem's known directories, so it needs a bridge.
- home.html: on bizconnect://share (and every resume, and cold-launch), read the
  inbox and show a "Send to…" picker over the chat list; chosen files run the SAME
  upload + /api/messages send as an in-app attachment. Reuses convertFileSrc to read
  the staged bytes with no base64 marshalling.
- ios-patch.sh registers the bizconnect URL scheme; codemagic.yaml fetches a profile
  for the .share bundle id too.

One-time manual gate (CI cannot toggle App capabilities): the App Group
group.com.bizgaze.connect must be created and enabled on both App IDs in the Apple
portal — documented in mobile/IOS_SETUP.md. Without it the two processes can't see
each other's files and sharing silently no-ops; everything else still works.

Validated cross-file: pod-name/jsName/method wiring for all three plugins, App
Group id identical in all 4 files, URL scheme consistent across extension/plist/web,
entitlement-merge preserves push. Needs a new iOS build (new targets + plugins).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 22:58:08 +05:30

125 lines
7.0 KiB
YAML

# Codemagic CI/CD — builds the Biz Connect iOS app (Capacitor shell over the live web UI) and uploads it
# to TestFlight / App Store Connect. No Mac needed: this runs on Codemagic's macOS cloud instances.
#
# The app is a thin Capacitor wrapper that loads https://remote.bizgaze.com, so there's no bundled web
# code to build here — we generate the iOS project, patch its privacy strings, sign, archive and upload.
#
# ── One-time setup (see mobile/IOS_SETUP.md for the click-by-click) ────────────────────────────────
# 1. App Store Connect: create the app with bundle id com.bizgaze.connect
# 2. Codemagic → Teams/Integrations → App Store Connect: add your ASC API key (issuer id, key id, .p8).
# Name the integration exactly: BizGaze App Store Connect
# 3. That's it — automatic code signing fetches/creates the distribution cert + profile from that key.
workflows:
ios-testflight:
name: Biz Connect iOS → TestFlight
max_build_duration: 60
instance_type: mac_mini_m2
integrations:
app_store_connect: BizGaze App Store Connect # ← must match the integration name you create
environment:
# NOTE: we deliberately do NOT use an `ios_signing:` block here. That block makes Codemagic
# try to *fetch an existing* provisioning profile at build startup — it never creates one — so on
# a brand-new app it fails init with "No matching profiles found …". Instead the "Set up code
# signing" script below runs `fetch-signing-files … --create`, which creates the distribution
# certificate + profile on first run, then `xcode-project use-profiles` wires them into the project.
groups:
- ios_signing # ← Codemagic variable group holding CERTIFICATE_PRIVATE_KEY (secure). See below.
vars:
BUNDLE_ID: "com.bizgaze.connect"
XCODE_WORKSPACE: "mobile/ios/App/App.xcworkspace"
XCODE_SCHEME: "App"
node: 20
xcode: latest
cocoapods: default
scripts:
- name: Install JS dependencies
script: |
cd mobile
# npm install (not ci): the dependency set changed to Capacitor 7 + the safe-area/keyboard
# plugins, so we let npm resolve a fresh tree rather than require a pre-synced lockfile.
npm install
- name: Generate the iOS project (Capacitor)
script: |
cd mobile
# `cap add ios` scaffolds ios/App; safe to re-run — it no-ops if it already exists.
if [ ! -d "ios" ]; then npx cap add ios; fi
npx cap sync ios
# App icon + splash from resources/icon.png & resources/splash*.png (1024x1024 icon, 2732² splash).
npx capacitor-assets generate --ios || echo "asset generation skipped"
- name: Patch Info.plist (App-Review privacy strings) + bundle id
script: |
bash mobile/scripts/ios-patch.sh
- name: Add the Share Extension target
script: |
# Inject the second target (Biz Connect in the iOS share sheet) into the freshly-generated
# Xcode project. Uses the `xcodeproj` gem that ships with CocoaPods, so no extra install.
# Runs BEFORE pod install: the extension uses no pods, and this way the workspace that pods
# generates already contains the new target.
ruby mobile/scripts/add-share-extension.rb
- name: Set up code signing
script: |
# Create the distribution certificate + provisioning profile from the ASC API key and add the
# cert to the keychain. NOTE: `xcode-project use-profiles` is intentionally NOT here — it must
# run AFTER `pod install` generates the workspace, otherwise it fails to wire the profile into
# the App target and the archive dies with "App requires a provisioning profile".
#
# --certificate-key is REQUIRED for reusable signing: without it, --create makes a throwaway
# distribution cert whose private key dies with the build machine, so the next build finds a
# cert it has no key for ("Cannot save Signing Certificates without certificate private key").
# By passing our own fixed private key (CERTIFICATE_PRIVATE_KEY, a secure var in the
# `ios_signing` group), the cert is created once from that key and reused by every build.
#
# TWO bundle ids now need signing: the app AND the share extension (<app>.share). Each gets its
# own App Store profile. The App Group capability (group.com.bizgaze.connect) must be enabled on
# BOTH App IDs in the Apple Developer portal — see mobile/IOS_SETUP.md. fetch-signing-files
# registers a missing bundle id and creates its profile, but does NOT toggle the App Group
# capability, so that stays a one-time manual step.
keychain initialize
app-store-connect fetch-signing-files "$BUNDLE_ID" \
--type IOS_APP_STORE \
--certificate-key="@env:CERTIFICATE_PRIVATE_KEY" \
--create
app-store-connect fetch-signing-files "${BUNDLE_ID}.share" \
--type IOS_APP_STORE \
--certificate-key="@env:CERTIFICATE_PRIVATE_KEY" \
--create
keychain add-certificates
- name: Install CocoaPods
script: |
cd mobile/ios/App
pod install
- name: Build the signed IPA
script: |
# Apply the fetched provisioning profile(s) to the Xcode project NOW that the workspace exists,
# then archive. use-profiles scans for **/*.xcodeproj under the repo root and sets manual
# signing (team + profile specifier) on the matching App target.
xcode-project use-profiles
xcode-project build-ipa \
--workspace "$XCODE_WORKSPACE" \
--scheme "$XCODE_SCHEME"
artifacts:
- build/ios/ipa/*.ipa
- /tmp/xcodebuild_logs/*.log
publishing:
app_store_connect:
auth: integration
# Upload the build to App Store Connect. It is immediately usable for INTERNAL TestFlight testing
# (no Apple review). We keep external-beta submission OFF for now: submit_to_testflight=true would
# push the build to EXTERNAL beta review, which requires the Test Information (feedback email +
# beta review contact + a demo login, since our app needs sign-in) to be filled in first, and
# fails the build until then. Flip to true (and add `beta_groups:` + fill Test Information at
# App Store Connect → TestFlight → Test Information) when you want outside testers.
submit_to_testflight: false
# Flip this to true (and add a `submit_to_app_store` group with reviewer notes) once you're ready
# to push a build to public App Store review instead of only TestFlight.
# submit_to_app_store: false
# No email recipients here on purpose — build status is watched on the Codemagic dashboard. Add
# per-user notifications in the Codemagic UI (or a `publishing.email` block) later if you want them.