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 | Kjoretid |
|---|---|---|
packages/database/ | db-check (migrasjoner + typer) | ~2 min |
apps/api/ eller packages/shared/ | api-check (lint + types + test + build) | ~1 min |
apps/mobile-kmp/shared/ eller iosApp/ | ios-preflight (KMP + Xcode build) | ~5 min |
apps/mobile-kmp/shared/ eller androidApp/ | android-preflight (KMP + Gradle) | ~3 min |
| Ingen match | Bare ci-gate (instant) | ~5 sek |
ci-gate er satt som required status check i GitHub branch protection. Ingenting merges til main uten at CI 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.anchorLabelTestFlight (beta)
heading.anchorLabel# Lokalt:cd apps/mobile-kmp/iosAppbundle exec fastlane ios beta
# Eller via GitHub Actions:# Actions → "iOS Release" → Run workflow → "beta"Hva beta gjoer:
- Synker signing-sertifikater (Match)
- Auto-inkrementerer build number fra TestFlight
- Bygger KMP release framework
- Arkiverer iOS-appen
- Laster opp til TestFlight
- Committer versjon-bump og tagger
App Store (promote)
heading.anchorLabel# Promoter siste TestFlight-bygg til App Store Connect:bundle exec fastlane ios promote
# Eller via GitHub Actions:# Actions → "iOS Release" → Run workflow → "promote"Full Release
heading.anchorLabel# Bygger nytt + sender til App Store Connect:bundle exec fastlane ios releaseDette kjoerer beta + promote i sekvens.
Produksjons-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 | Build → TestFlight | Manuelt / git tag |
promote | Siste TestFlight → App Store metadata | Manuelt |
release | Full: beta + App Store submit | Manuelt |
bump | Versjonering (patch/minor/major) | Manuelt |
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 |
|---|---|---|
| CI | ci.yml | Push/PR til main |
| Deploy Production | deploy-production.yml | Push til production branch |
| iOS Release (manual) | ios-release.yml | Git tag v* / manuell (promote/beta/release) |
| DB Deploy (manual) | db-deploy.yml | Manuell (dry-run/migrate) |
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 |