App Ops Desk · Issue #11
CI vs local archive drift
“Works on my machine” becomes “fails only in CI” becomes a lost week. Drift is usually Xcode version, signing secrets, scheme config, or dependency resolution — not cosmic rays.
One action this week: Write one sentence: “Production archives come from ___ (local / CI job name) using Xcode ___.” If you cannot finish the sentence, pick a single source of truth this week.
Pick one ship factory
Either:
- Local ship: you archive on a labeled ship machine; CI is tests only
- CI ship: CI archives and uploads; local is for development
Hybrid without rules is how two “build 240”s mean different git trees.
Drift checklist
- Different Xcode major/minor than local
- Different scheme / configuration (Debug flags sneaking into Release)
- Resolved package versions not locked
- Signing cert only on one machine
- Environment plist values injected only in CI
- Cached DerivedData vs clean CI workspace
Make archives comparable
Always log: git SHA xcodebuild -version scheme + configuration TEAM_ID / bundle id dependency lock hash (Package.resolved / Podfile.lock) export options / upload destination
If CI and local disagree, compare this block before comparing crash logs.
Practical solo default
If you are truly alone and CI is flaky: ship from local with a written Xcode pin, and keep CI as unit/UI tests. Add CI archives only when the log above is automated.
Bottom line
One ship factory. Same Xcode lane, same locks, same signing inputs. Everything else is debugging two products that share a name.
Resources hub → Reading order and jump-by-symptom links. Join the App Ops Desk waitlist Weekly release ops for people who ship alone.