Release-rutiner
Denne siden beskriver hele release-flyten for Impulse AI: fra feature branch til produksjon.
Oversikt
heading.anchorLabelDB + API (tett koblet)
heading.anchorLabelFeature branch → PR → CI Gate → main → Staging (auto) → /deploy-prod → Production| Komponent | Staging-deploy | Produksjons-deploy |
|---|---|---|
| API | Railway auto-deploy fra main | Railway auto-deploy fra production branch |
| Database | supabase db push via CI (auto) | supabase db push ved push til production |
iOS (separat release-syklus)
heading.anchorLabelfastlane ios bump → git tag v* → TestFlight (auto) → App Store (manuell promote)| Komponent | Staging-deploy | Produksjons-deploy |
|---|---|---|
| iOS | TestFlight via fastlane ios beta | App Store via fastlane ios promote |
Web (uavhengig)
heading.anchorLabel| Komponent | Staging-deploy | Produksjons-deploy |
|---|---|---|
| Web | Vercel preview deploy (auto) | Vercel auto-deploy fra main |
Railway-miljoer
heading.anchorLabel| Miljo | Branch | URL |
|---|---|---|
| Staging | main | api-stg.impulseai.app |
| Production | production | api.impulseai.app |
CI Pipeline
heading.anchorLabelCI kjoerer automatisk paa alle PR-er og push til main/develop. Kun endrede deler bygges.
| Endring i | Jobb | Workflow | Kjoretid |
|---|---|---|---|
packages/database/ | db-check (migrasjoner + typer) | ci-backend.yml | ~2 min |
apps/api/ eller packages/shared/ | api-check (lint + types + test + build) | ci-backend.yml | ~1 min |
apps/mobile-kmp/shared/ eller iosApp/ | ios-preflight (KMP + Xcode build) | ci-ios.yml | ~5 min |
apps/mobile-kmp/shared/ eller androidApp/ | android-preflight (KMP + Gradle) | ci-ios.yml | ~3 min |
| Ingen match | Bare ci-gate/ios-gate (instant) | begge | ~5 sek |
CI Gate (ci-backend.yml) og iOS Gate (ci-ios.yml) er satt som required status checks i GitHub branch protection. Ingenting merges til main uten at begge passerer.
Release-syklus
heading.anchorLabelAnbefalt ritme
heading.anchorLabelMandag-Torsdag: Utvikling Push → CI preflight (automatisk) PR → ci-gate maa passere foer merge
Fredag: Release DB + API 1. Merge feature-branch → main 2. CI passerer → Railway auto-deployer API til staging 3. Database: staging-migrasjoner kjoeres automatisk 4. Test staging 5. /deploy-prod → promoter til production
Fredag: iOS-release (separat) 6. fastlane ios bump type:patch → git tag → TestFlight 7. Test i TestFlight over helgen
Mandag: Promoter iOS 8. /promote → App StoreVersjonering
heading.anchorLabeliOS-versjonen bumpes med Fastlane:
cd apps/mobile-kmp/iosApp
# Bump versjonbundle exec fastlane ios bump type:patch # 1.0.0 → 1.0.1bundle exec fastlane ios bump type:minor # 1.0.0 → 1.1.0bundle exec fastlane ios bump type:major # 1.0.0 → 2.0.0
# Push versjon + taggit push && git push --tagsbump laner committer versjonsendringen og oppretter en git tag (v1.0.1).
iOS Release
heading.anchorLabel3 ruter til TestFlight
heading.anchorLabel| Rute | Naar | Kommando |
|---|---|---|
| 1. ios-release.yml (primaer) | Normal release med ny versjon | fastlane ios bump → git push --tags → ios-release.yml workflow_dispatch |
| 2. Tag-trigger (automatisk) | Backup — trigger via deploy-production.yml | fastlane ios bump → git push --tags |
| 3. Lokal build (noedloesning) | CI er nede, haster med hotfix | doppler run lokalt |
Rute 1: ios-release.yml workflow_dispatch (anbefalt)
heading.anchorLabelcd apps/mobile-kmp/iosApp
# 1. Bump versjon (committer + tagger automatisk)bundle exec fastlane ios bump type:patch # 1.0.0 → 1.0.1
# 2. Push commit og taggit push && git push --tags
# 3. Trigger build via GitHub Actions# Actions → "iOS Release" → Run workflow → lane: betaHva som skjer i CI (ios-release.yml eller deploy-production.yml):
- Job kjoerer paa
macos-26(Xcode 26, iOS 26 SDK) - Ruby gems installeres til
$RUNNER_TEMP/bundle(unngaar at Xcode scannervendor/) - Doppler henter secrets (
DOPPLER_TOKEN_PRD) fastlane ios betakjoerer:- Signing:
setup_ci→ installerer WWDR G3-sertifikat →match appstore→update_code_signing_settings(Manual for app target) - Build number: Auto-inkrementerer fra TestFlight — ingen commit tilbake til main
- KMP framework:
kmp_release_frameworkbygger arm64 release og kopierer til baadexcode-frameworks/og PBXGroup-path (iosSimulatorArm64/debugFramework) - Archive: Bygger med manual signing override +
SUPPORTED_PLATFORMS=iphoneos(stripper iphonesimulator) - Upload: Laster opp til TestFlight
- Signing:
Rute 2: Tag-trigger (automatisk fallback)
heading.anchorLabelTag v* trigger ogsaa deploy-production.yml sin deploy-ios job. Men denne kan misse hvis andre commits pushes samtidig til en non-production branch.
Som backup kan du ogsaa bruke deploy-production.yml workflow_dispatch med target: ios.
Rute 3: Lokal build
heading.anchorLabelcd apps/mobile-kmp/iosAppdoppler run --config prd -- bundle exec fastlane ios betaKrever lokalt: Xcode 26, Match-sertifikater, Doppler CLI med tilgang til prd.
App Store (promote)
heading.anchorLabelEtter TestFlight-testing, promoter til App Store:
# Via GitHub Actions (anbefalt):# Actions → "iOS Release" (ios-release.yml) → Run workflow → lane: promote
# Eller lokalt:cd apps/mobile-kmp/iosAppdoppler run --config prd -- bundle exec fastlane ios promoteProduksjons-deploy (DB + API)
heading.anchorLabelDB og API promoteres til production ved a pushe main til production-branchen:
# Via Claude Code (anbefalt):/deploy-prod
# Manuelt:git push origin main:productionDette trigger:
- DB:
supabase db pushmot produksjons-Supabase - API: Railway auto-deployer fra
production-branchen
API Deploy
heading.anchorLabelStaging
heading.anchorLabelRailway staging overvaker main branch og auto-deployer. Ingen manuell handling noedvendig.
URL: api-stg.impulseai.app
Sikkerhet: Branch protection sikrer at ci-gate passerer foer merge til main — Railway deployer aldri broken kode.
Production
heading.anchorLabelRailway production overvaker production branch og auto-deployer.
URL: api.impulseai.app
# Promoter staging til production:/deploy-prod# eller: git push origin main:productionDatabase-migrasjoner
heading.anchorLabelStaging (automatisk)
heading.anchorLabelNaar DB-endringer merges til main, kjoerer CI automatisk supabase db push mot staging-prosjektet.
Production
heading.anchorLabelTo alternativer:
Automatisk via git tag:
git tag v1.2.3 && git push --tags# deploy-production.yml kjoerer supabase db push mot prodManuelt via GitHub Actions:
# Actions → "DB Deploy (manual)" → Run workflow# 1. Velg environment: staging eller production# 2. Velg action: dry-run (foerst!) eller migrateMigrasjon-workflow
heading.anchorLabel1. Opprett migrering lokalt: pnpm db:migrate:new din_migrering
2. Skriv SQL i packages/database/supabase/migrations/
3. Test lokalt: pnpm db:reset
4. Generer TypeScript-typer: pnpm db:types
5. Commit og push → CI validerer
6. Merge til main → staging auto-deploy
7. Verifiser i staging → /deploy-prod → prod deployWeb Deploy (Vercel)
heading.anchorLabelVercel deployer automatisk:
- Preview: Hver PR faar sin egen preview-URL
- Production: Auto-deploy fra
mainfor landing (impulseai.app) og console (console.impulseai.app)
Ingen manuell handling noedvendig.
Rollback
heading.anchorLabelSe Rollback-prosedyrer for detaljerte instruksjoner.
Hurtigreferanse:
| Komponent | Rollback-metode | Tid |
|---|---|---|
| API | Railway: redeploy forrige versjon | ~30 sek |
| Database | Ny migrering som reverser endringen | Minutter |
| iOS | Ikke mulig — push ny versjon | Timer/dager |
| Web | Vercel: instant rollback i dashboard | ~5 sek |
Fastlane-oversikt
heading.anchorLabelAlle iOS-operasjoner gaar gjennom Fastlane. GitHub Actions er bare en tynn wrapper.
| Lane | Jobb | Trigger |
|---|---|---|
preflight | KMP compile + iOS simulator build | Automatisk (CI) |
test | Kjoer iOS-tester | Manuelt |
beta | sync_signing → auto build number → KMP release framework → archive (manual signing + iphoneos) → TestFlight | workflow_dispatch / git tag |
promote | Siste TestFlight → App Store metadata | workflow_dispatch |
release | Full: beta + App Store submit | workflow_dispatch |
bump | Versjonering (patch/minor/major) + git tag | Manuelt (lokalt) |
doctor | Sjekk toolchain | Manuelt |
Lokal Fastlane-bruk
heading.anchorLabelcd apps/mobile-kmp/iosApp
# Installer Ruby-deps (foerste gang):bundle install
# Sjekk at alt fungerer:bundle exec fastlane ios doctor
# Sjekk kompilering:bundle exec fastlane ios preflightGitHub Actions Workflows
heading.anchorLabel| Workflow | Fil | Trigger | Hva |
|---|---|---|---|
| CI Backend | ci-backend.yml | Push/PR til main | DB-check, api-check, CI Gate |
| CI iOS | ci-ios.yml | Push/PR til main | iOS preflight, iOS Gate |
| iOS Release | ios-release.yml | workflow_dispatch (lane: beta/promote/release) | Primaer iOS pipeline — macos-26 runner |
| Deploy Production | deploy-production.yml | Push til production ELLER workflow_dispatch | DB+API deploy kun — iOS er separat |
| DB Deploy | db-deploy.yml | Manuell | dry-run eller migrate mot staging/prod |
Claude Code Slash Commands
heading.anchorLabel| Kommando | Hva den gjoer |
|---|---|
/release ios patch | Safety checks → fastlane ios bump → push → trigger ios-release.yml beta |
/release api | Safety checks → git push origin main:production → monitor deploy |
/promote | Trigger ios-release.yml promote → App Store Connect |
/deploy-prod | Push main → production branch (DB + API) |
/deploy-status | Dashboard: CI, iOS release, production deploy status |
Feilsoeking
heading.anchorLabel”No signing certificate found"
heading.anchorLabelbundle exec fastlane match appstore --force # Regenerer sertifikater"Build number already exists on TestFlight”
heading.anchorLabelBuild-nummeret auto-inkrementeres. Hvis det feiler, har du sannsynligvis et lokalt bygg med hoeyere nummer. Sjekk i App Store Connect.
Preflight feiler i CI
heading.anchorLabel# Sjekk at Gradle wrapper er committert:git ls-files apps/mobile-kmp/gradlew# Skal vise filen. Hvis ikke: git add apps/mobile-kmp/gradlewKMP-endringer kompilerer lokalt men ikke i CI
heading.anchorLabelCI bruker cached Gradle. Push en tom commit eller vent til cache utloeper.
Nokkelrotasjon
heading.anchorLabelNar API-klientnokkelen (X-API-Key) ma byttes ut — ved mistanke om misbruk, teamendringer, eller rutinemessig.
Prosedyre
heading.anchorLabel| Steg | Handling | Verktoy |
|---|---|---|
| 1 | Generer ny nokkel | openssl rand -hex 32 |
| 2 | Legg til ny nokkel | Doppler: API_CLIENT_KEY = gammel,ny |
| 3 | Deploy API | Railway resyncer automatisk |
| 4 | Oppdater Environment.kt | Bytt apiClientKey for riktig miljo |
| 5 | Ship app-oppdatering | fastlane ios beta |
| 6 | Sett minimum versjon | Doppler: MIN_APP_VERSION_IOS = X.Y.Z |
| 7 | Monitorer | Sjekk keyPrefix i Railway logs |
| 8 | Fjern gammel nokkel | Doppler: API_CLIENT_KEY = ny |
Frekvens
heading.anchorLabel- Ved hendelse (lekkasje, misbruk): Umiddelbart
- Rutinemessig: Arlig er tilstrekkelig — noklene er ikke hemmelige (synlige i app-binary)
Force-update
heading.anchorLabelNar du ma tvinge brukere til a oppdatere appen — f.eks. ved nokkelrotasjon, breaking API-endringer, eller kritiske feilrettinger.
Aktivering
heading.anchorLabelSett minimum versjon i Doppler:
# Alle brukere pa iOS under v1.2.0 ser fullskjerm "Oppdater nå"MIN_APP_VERSION_IOS=1.2.0
# Valgfritt: soft nudge for brukere under nyesteLATEST_APP_VERSION_IOS=1.3.0Railway resyncer automatisk — ingen deploy nodvendig.
Deaktivering
heading.anchorLabelSett tilbake til 0.0.0 eller fjern variabelen.
Brukeropplevelse
heading.anchorLabel| Situasjon | Resultat |
|---|---|
App-versjon < MIN_APP_VERSION | Fullskjerm-blokk, kun “Oppdater nå”-knapp |
App-versjon < LATEST_APP_VERSION | Dismissbar dialog med “Oppdater” / “Senere” |
| Config-kall feiler (nettverk) | Normal oppstart — aldri blokker pa feil |