codebyplan 1.5.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +4462 -748
- package/package.json +5 -1
- package/templates/.gitkeep +0 -0
- package/templates/README.md +20 -0
- package/templates/agents/cbp-cc-executor.md +213 -0
- package/templates/agents/cbp-database-agent.md +229 -0
- package/templates/agents/cbp-improve-claude.md +245 -0
- package/templates/agents/cbp-improve-round.md +284 -0
- package/templates/agents/cbp-mechanical-edits.md +111 -0
- package/templates/agents/cbp-research.md +282 -0
- package/templates/agents/cbp-round-executor.md +604 -0
- package/templates/agents/cbp-security-agent.md +134 -0
- package/templates/agents/cbp-task-check.md +213 -0
- package/templates/agents/cbp-task-planner.md +582 -0
- package/templates/agents/cbp-test-e2e-agent.md +363 -0
- package/templates/agents/cbp-testing-qa-agent.md +400 -0
- package/templates/context/mcp-docs.md +139 -0
- package/templates/hooks/README.md +236 -0
- package/templates/hooks/cbp-auto-test-hooks.sh +44 -0
- package/templates/hooks/cbp-lint-format-on-edit.sh +159 -0
- package/templates/hooks/cbp-maestro-yaml-validate.sh +100 -0
- package/templates/hooks/cbp-mcp-migration-guard.sh +32 -0
- package/templates/hooks/cbp-mcp-round-sync.sh +79 -0
- package/templates/hooks/cbp-mcp-worktree-inject.sh +76 -0
- package/templates/hooks/cbp-notify.sh +68 -0
- package/templates/hooks/cbp-plugin-dispatch.sh +29 -0
- package/templates/hooks/cbp-pre-commit-quality-gate.sh +204 -0
- package/templates/hooks/cbp-statusline.sh +347 -0
- package/templates/hooks/cbp-subagent-statusline.sh +182 -0
- package/templates/hooks/cbp-test-coverage-gate.sh +144 -0
- package/templates/hooks/cbp-test-hooks.sh +320 -0
- package/templates/hooks/hooks.json +85 -0
- package/templates/hooks/validate-context-usage.sh +59 -0
- package/templates/hooks/validate-git-commit.sh +78 -0
- package/templates/hooks/validate-git-stash-deny.sh +32 -0
- package/templates/hooks/validate-structure-lengths.sh +57 -0
- package/templates/hooks/validate-structure-lib.sh +104 -0
- package/templates/hooks/validate-structure-patterns.sh +54 -0
- package/templates/hooks/validate-structure-scope.sh +33 -0
- package/templates/hooks/validate-structure-smoke.sh +95 -0
- package/templates/hooks/validate-structure-templates.sh +34 -0
- package/templates/hooks/validate-structure.sh +69 -0
- package/templates/rules/.gitkeep +0 -0
- package/templates/rules/README.md +47 -0
- package/templates/rules/context-file-loading.md +52 -0
- package/templates/rules/scope-vocabulary.md +64 -0
- package/templates/rules/todo-backend.md +109 -0
- package/templates/settings.project.base.json +55 -0
- package/templates/settings.user.base.json +25 -0
- package/templates/skills/cbp-build-cc-agent/SKILL.md +139 -0
- package/templates/skills/cbp-build-cc-agent/examples/read-only-reviewer.md +32 -0
- package/templates/skills/cbp-build-cc-agent/examples/with-hooks.md +41 -0
- package/templates/skills/cbp-build-cc-agent/examples/with-skills-preload.md +25 -0
- package/templates/skills/cbp-build-cc-agent/reference/cbp-quality.md +153 -0
- package/templates/skills/cbp-build-cc-agent/reference/frontmatter-fields.md +37 -0
- package/templates/skills/cbp-build-cc-agent/reference/permission-modes.md +18 -0
- package/templates/skills/cbp-build-cc-agent/scripts/validate-agent.sh +67 -0
- package/templates/skills/cbp-build-cc-agent/templates/agent.md +66 -0
- package/templates/skills/cbp-build-cc-claude-file/SKILL.md +178 -0
- package/templates/skills/cbp-build-cc-claude-file/examples/minimal-project.md +33 -0
- package/templates/skills/cbp-build-cc-claude-file/examples/monorepo-with-imports.md +39 -0
- package/templates/skills/cbp-build-cc-claude-file/reference/imports.md +72 -0
- package/templates/skills/cbp-build-cc-claude-file/reference/what-belongs.md +39 -0
- package/templates/skills/cbp-build-cc-claude-file/templates/project-claude-md.md +48 -0
- package/templates/skills/cbp-build-cc-claude-file/templates/user-claude-md.md +22 -0
- package/templates/skills/cbp-build-cc-memory/SKILL.md +201 -0
- package/templates/skills/cbp-build-cc-memory/examples/feedback-memory.md +11 -0
- package/templates/skills/cbp-build-cc-memory/examples/project-memory.md +11 -0
- package/templates/skills/cbp-build-cc-memory/examples/reference-memory.md +13 -0
- package/templates/skills/cbp-build-cc-memory/examples/user-memory.md +14 -0
- package/templates/skills/cbp-build-cc-memory/reference/memory-types.md +59 -0
- package/templates/skills/cbp-build-cc-memory/reference/when-to-save.md +62 -0
- package/templates/skills/cbp-build-cc-memory/templates/MEMORY-index.md +4 -0
- package/templates/skills/cbp-build-cc-memory/templates/memory-entry.md +15 -0
- package/templates/skills/cbp-build-cc-mode/SKILL.md +99 -0
- package/templates/skills/cbp-build-cc-rule/SKILL.md +176 -0
- package/templates/skills/cbp-build-cc-rule/examples/global-rule.md +19 -0
- package/templates/skills/cbp-build-cc-rule/examples/scoped-rule.md +41 -0
- package/templates/skills/cbp-build-cc-rule/reference/paths-patterns.md +48 -0
- package/templates/skills/cbp-build-cc-rule/templates/rule.md +32 -0
- package/templates/skills/cbp-build-cc-settings/SKILL.md +220 -0
- package/templates/skills/cbp-build-cc-settings/examples/hooks-config.json +64 -0
- package/templates/skills/cbp-build-cc-settings/examples/permissions-config.json +34 -0
- package/templates/skills/cbp-build-cc-settings/examples/sandbox-config.json +42 -0
- package/templates/skills/cbp-build-cc-settings/reference/cbp-conventions.md +104 -0
- package/templates/skills/cbp-build-cc-settings/reference/permission-rules.md +61 -0
- package/templates/skills/cbp-build-cc-settings/reference/scope-precedence.md +73 -0
- package/templates/skills/cbp-build-cc-settings/reference/settings-fields.md +166 -0
- package/templates/skills/cbp-build-cc-settings/templates/settings.json +23 -0
- package/templates/skills/cbp-build-cc-settings/templates/settings.local.json +10 -0
- package/templates/skills/cbp-build-cc-skill/SKILL.md +154 -0
- package/templates/skills/cbp-build-cc-skill/examples/dynamic-context.md +31 -0
- package/templates/skills/cbp-build-cc-skill/examples/fork-skill.md +22 -0
- package/templates/skills/cbp-build-cc-skill/examples/knowledge-skill.md +25 -0
- package/templates/skills/cbp-build-cc-skill/examples/task-skill.md +29 -0
- package/templates/skills/cbp-build-cc-skill/reference/cbp-quality.md +157 -0
- package/templates/skills/cbp-build-cc-skill/reference/frontmatter-fields.md +35 -0
- package/templates/skills/cbp-build-cc-skill/reference/string-substitutions.md +60 -0
- package/templates/skills/cbp-build-cc-skill/scripts/validate-skill.sh +90 -0
- package/templates/skills/cbp-build-cc-skill/templates/skill.md +51 -0
- package/templates/skills/cbp-checkpoint-check/SKILL.md +156 -0
- package/templates/skills/cbp-checkpoint-complete/SKILL.md +109 -0
- package/templates/skills/cbp-checkpoint-create/SKILL.md +287 -0
- package/templates/skills/cbp-checkpoint-end/SKILL.md +241 -0
- package/templates/skills/cbp-checkpoint-update/SKILL.md +115 -0
- package/templates/skills/cbp-frontend-a11y/SKILL.md +109 -0
- package/templates/skills/cbp-frontend-a11y/reference/aria-roles-states.md +130 -0
- package/templates/skills/cbp-frontend-a11y/reference/contrast-visual.md +122 -0
- package/templates/skills/cbp-frontend-a11y/reference/keyboard-patterns.md +154 -0
- package/templates/skills/cbp-frontend-a11y/reference/semantic-html.md +111 -0
- package/templates/skills/cbp-frontend-design/SKILL.md +145 -0
- package/templates/skills/cbp-frontend-design/reference/nextjs-scss.md +118 -0
- package/templates/skills/cbp-frontend-design/reference/rn-expo.md +101 -0
- package/templates/skills/cbp-frontend-design/reference/tauri-react.md +82 -0
- package/templates/skills/cbp-frontend-ui/SKILL.md +262 -0
- package/templates/skills/cbp-frontend-ui/reference/ui-label-maps.md +42 -0
- package/templates/skills/cbp-frontend-ui/reference/ui-layout-patterns.md +105 -0
- package/templates/skills/cbp-frontend-ui/reference/variant-defaults.md +149 -0
- package/templates/skills/cbp-frontend-ux/SKILL.md +181 -0
- package/templates/skills/cbp-git-branch-feat-create/SKILL.md +115 -0
- package/templates/skills/cbp-git-commit/SKILL.md +278 -0
- package/templates/skills/cbp-git-worktree-create/SKILL.md +226 -0
- package/templates/skills/cbp-git-worktree-remove/SKILL.md +145 -0
- package/templates/skills/cbp-merge-main/SKILL.md +228 -0
- package/templates/skills/cbp-round-check/SKILL.md +104 -0
- package/templates/skills/cbp-round-end/SKILL.md +183 -0
- package/templates/skills/cbp-round-end/reference/findings-presentation.md +44 -0
- package/templates/skills/cbp-round-end/reference/inline-fallback.md +35 -0
- package/templates/skills/cbp-round-execute/SKILL.md +211 -0
- package/templates/skills/cbp-round-execute/reference/inline-fallback.md +59 -0
- package/templates/skills/cbp-round-input/SKILL.md +165 -0
- package/templates/skills/cbp-round-start/SKILL.md +222 -0
- package/templates/skills/cbp-round-update/SKILL.md +163 -0
- package/templates/skills/cbp-session-end/SKILL.md +187 -0
- package/templates/skills/cbp-session-start/SKILL.md +155 -0
- package/templates/skills/cbp-ship/SKILL.md +332 -0
- package/templates/skills/cbp-ship/reference/changesets-overview.md +120 -0
- package/templates/skills/cbp-ship/reference/eas-cli-overview.md +60 -0
- package/templates/skills/cbp-ship/reference/gh-cli-overview.md +135 -0
- package/templates/skills/cbp-ship/reference/gh-cli-shipment-commands.md +283 -0
- package/templates/skills/cbp-ship/reference/npm-publish-monorepo.md +252 -0
- package/templates/skills/cbp-ship/reference/npm-publish-oidc-trusted.md +157 -0
- package/templates/skills/cbp-ship/reference/npm-publish-overview.md +171 -0
- package/templates/skills/cbp-ship/reference/preflight-checklist.md +88 -0
- package/templates/skills/cbp-ship/reference/railway-nestjs-deployment.md +169 -0
- package/templates/skills/cbp-ship/reference/railway-overview.md +120 -0
- package/templates/skills/cbp-ship/reference/railway-troubleshooting.md +168 -0
- package/templates/skills/cbp-ship/reference/release-please-overview.md +99 -0
- package/templates/skills/cbp-ship/reference/surface-expo-eas.md +155 -0
- package/templates/skills/cbp-ship/reference/surface-npm.md +180 -0
- package/templates/skills/cbp-ship/reference/surface-railway.md +152 -0
- package/templates/skills/cbp-ship/reference/surface-supabase.md +178 -0
- package/templates/skills/cbp-ship/reference/surface-tauri.md +138 -0
- package/templates/skills/cbp-ship/reference/surface-vercel.md +124 -0
- package/templates/skills/cbp-ship/reference/surface-vscode-ext.md +144 -0
- package/templates/skills/cbp-ship/reference/surfaces.md +60 -0
- package/templates/skills/cbp-ship/reference/testflight-automation.md +215 -0
- package/templates/skills/cbp-ship/reference/testflight-internal-vs-external.md +69 -0
- package/templates/skills/cbp-ship/reference/testflight-overview.md +98 -0
- package/templates/skills/cbp-ship/reference/versioning.md +116 -0
- package/templates/skills/cbp-ship/scripts/detect-surfaces.sh +217 -0
- package/templates/skills/cbp-ship/scripts/verify-expo-eas.sh +35 -0
- package/templates/skills/cbp-ship/scripts/verify-npm.sh +21 -0
- package/templates/skills/cbp-ship/scripts/verify-railway.sh +41 -0
- package/templates/skills/cbp-ship/scripts/verify-supabase.sh +19 -0
- package/templates/skills/cbp-ship/scripts/verify-tauri.sh +24 -0
- package/templates/skills/cbp-ship/scripts/verify-vercel.sh +32 -0
- package/templates/skills/cbp-ship/scripts/verify-vscode-ext.sh +25 -0
- package/templates/skills/cbp-ship/templates/eas.json +66 -0
- package/templates/skills/cbp-ship/templates/railway.toml +15 -0
- package/templates/skills/cbp-ship/templates/release-please-config.json +17 -0
- package/templates/skills/cbp-ship/templates/vercel.json +19 -0
- package/templates/skills/cbp-ship/templates/vscodeignore +21 -0
- package/templates/skills/cbp-ship/templates/workflow-changesets.yml +41 -0
- package/templates/skills/cbp-ship/templates/workflow-eas-submit.yml +53 -0
- package/templates/skills/cbp-ship/templates/workflow-npm-publish.yml +36 -0
- package/templates/skills/cbp-ship/templates/workflow-release-please.yml +21 -0
- package/templates/skills/cbp-ship/templates/workflow-tauri-release.yml +69 -0
- package/templates/skills/cbp-ship/templates/workflow-vsce-publish.yml +31 -0
- package/templates/skills/cbp-ship-configure/SKILL.md +296 -0
- package/templates/skills/cbp-ship-configure/reference/expo-mobile.md +204 -0
- package/templates/skills/cbp-ship-configure/reference/npm-package.md +165 -0
- package/templates/skills/cbp-ship-configure/reference/railway-backend.md +199 -0
- package/templates/skills/cbp-ship-configure/reference/supabase.md +200 -0
- package/templates/skills/cbp-ship-configure/reference/tauri-desktop.md +181 -0
- package/templates/skills/cbp-ship-configure/reference/vercel.md +117 -0
- package/templates/skills/cbp-ship-configure/reference/vscode-ext.md +155 -0
- package/templates/skills/cbp-ship-main/SKILL.md +65 -0
- package/templates/skills/cbp-supabase-branch-check/SKILL.md +337 -0
- package/templates/skills/cbp-supabase-branch-check/reference/dag-steps.md +29 -0
- package/templates/skills/cbp-supabase-migrate/SKILL.md +314 -0
- package/templates/skills/cbp-supabase-migrate/reference/advisor-triage.md +70 -0
- package/templates/skills/cbp-supabase-migrate/reference/cli-fallback.md +87 -0
- package/templates/skills/cbp-supabase-migrate/reference/preflight-dry-run.md +58 -0
- package/templates/skills/cbp-supabase-setup/SKILL.md +239 -0
- package/templates/skills/cbp-supabase-setup/reference/branching-setup.md +121 -0
- package/templates/skills/cbp-supabase-setup/reference/cli-fallback.md +109 -0
- package/templates/skills/cbp-task-check/SKILL.md +166 -0
- package/templates/skills/cbp-task-complete/SKILL.md +206 -0
- package/templates/skills/cbp-task-complete/reference/checkpoint-done-branching.md +48 -0
- package/templates/skills/cbp-task-complete/reference/next-step-heuristic.md +56 -0
- package/templates/skills/cbp-task-create/SKILL.md +167 -0
- package/templates/skills/cbp-task-start/SKILL.md +239 -0
- package/templates/skills/cbp-task-testing/SKILL.md +277 -0
- package/templates/skills/cbp-todo/SKILL.md +97 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Railway — NestJS Deployment
|
|
2
|
+
|
|
3
|
+
Concrete walkthrough for the canonical CodeByPlan backend shape: a NestJS app in `apps/backend` of a pnpm/Turborepo monorepo, talking to Supabase, deployed to Railway via GitHub auto-deploys. Read [railway-overview.md](./railway-overview.md) first for concept-level context.
|
|
4
|
+
|
|
5
|
+
## Build Strategy: Dockerfile vs Nixpacks/Railpack
|
|
6
|
+
|
|
7
|
+
Railway picks a builder in this order: **Dockerfile** at repo root (or `RAILWAY_DOCKERFILE_PATH`) → **Railpack** (Elixir, Ruby, Rust) → **Nixpacks** (auto-detect Node/Python/Go).
|
|
8
|
+
|
|
9
|
+
For CBP NestJS backends, **always use a Dockerfile**:
|
|
10
|
+
|
|
11
|
+
| Concern | Dockerfile | Nixpacks |
|
|
12
|
+
|---------|-----------|----------|
|
|
13
|
+
| Reproducible builds (pinned base) | Yes | Drifts on Nixpacks updates |
|
|
14
|
+
| pnpm workspace / monorepo | Explicit, scoped | Heuristics often misfire |
|
|
15
|
+
| Build caching | Predictable layers | Opaque |
|
|
16
|
+
| Multi-stage slim runtime | Easy | Not supported |
|
|
17
|
+
| Native deps (sharp, prisma) | Apt/apk control | Black-box failures |
|
|
18
|
+
|
|
19
|
+
The only case for Nixpacks is a single-package repo with no native deps — and CBP doesn't have any of those.
|
|
20
|
+
|
|
21
|
+
## Canonical NestJS Dockerfile (pnpm + Turborepo)
|
|
22
|
+
|
|
23
|
+
Place at `apps/backend/Dockerfile`, set `RAILWAY_DOCKERFILE_PATH=apps/backend/Dockerfile` on the service. Build context is the repo root.
|
|
24
|
+
|
|
25
|
+
```dockerfile
|
|
26
|
+
# syntax=docker/dockerfile:1.7
|
|
27
|
+
|
|
28
|
+
# ---- builder ----
|
|
29
|
+
FROM node:22-alpine AS builder
|
|
30
|
+
WORKDIR /repo
|
|
31
|
+
RUN corepack enable && corepack prepare pnpm@10.12.4 --activate
|
|
32
|
+
|
|
33
|
+
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json turbo.json ./
|
|
34
|
+
COPY apps/backend/package.json ./apps/backend/
|
|
35
|
+
COPY packages/auth/package.json ./packages/auth/
|
|
36
|
+
COPY packages/design-tokens/package.json ./packages/design-tokens/
|
|
37
|
+
|
|
38
|
+
RUN --mount=type=cache,id=s/pnpm-store,target=/root/.local/share/pnpm/store \
|
|
39
|
+
pnpm install --frozen-lockfile
|
|
40
|
+
|
|
41
|
+
COPY . .
|
|
42
|
+
RUN pnpm turbo run build --filter=@codebyplan/backend...
|
|
43
|
+
RUN pnpm --filter=@codebyplan/backend deploy --prod /out
|
|
44
|
+
|
|
45
|
+
# ---- runtime ----
|
|
46
|
+
FROM node:22-alpine AS runtime
|
|
47
|
+
WORKDIR /app
|
|
48
|
+
ENV NODE_ENV=production
|
|
49
|
+
RUN apk add --no-cache tini
|
|
50
|
+
|
|
51
|
+
COPY --from=builder /out/node_modules ./node_modules
|
|
52
|
+
COPY --from=builder /out/dist ./dist
|
|
53
|
+
COPY --from=builder /out/package.json ./package.json
|
|
54
|
+
|
|
55
|
+
EXPOSE 3000
|
|
56
|
+
ENTRYPOINT ["/sbin/tini", "--"]
|
|
57
|
+
CMD ["node", "dist/main.js"]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Notes: `--mount=type=cache,id=s/...` uses Railway's persistent build cache. `pnpm deploy --prod` produces a self-contained dir with hoisted prod deps (slim image). `tini` as PID 1 forwards SIGTERM cleanly so NestJS shuts down on rolling deploys. `EXPOSE 3000` is documentation only — Railway routes to whatever `$PORT` your process binds.
|
|
61
|
+
|
|
62
|
+
## $PORT Binding
|
|
63
|
+
|
|
64
|
+
Railway assigns `PORT` per deployment. NestJS bootstrap MUST honour it:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
// apps/backend/src/main.ts
|
|
68
|
+
import { NestFactory } from '@nestjs/core';
|
|
69
|
+
import { AppModule } from './app.module';
|
|
70
|
+
|
|
71
|
+
async function bootstrap() {
|
|
72
|
+
const app = await NestFactory.create(AppModule);
|
|
73
|
+
app.enableShutdownHooks(); // pairs with tini in the Dockerfile
|
|
74
|
+
const port = parseInt(process.env.PORT ?? '3000', 10);
|
|
75
|
+
await app.listen(port, '0.0.0.0'); // 0.0.0.0, NOT localhost
|
|
76
|
+
}
|
|
77
|
+
bootstrap();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Two extremely common failures: (1) listening on `localhost`/`127.0.0.1` — Railway's proxy can't reach you and the healthcheck times out; (2) hardcoding `3000` — works locally but Railway thinks the service never came up.
|
|
81
|
+
|
|
82
|
+
## Health Endpoint
|
|
83
|
+
|
|
84
|
+
Configure per service: `Settings → Deploy → Healthcheck Path` (e.g. `/health`) and timeout (default 100s, max 300s). On failure the new deployment never replaces the old — old keeps serving, new is marked CRASHED.
|
|
85
|
+
|
|
86
|
+
Use `@nestjs/terminus`:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
// apps/backend/src/health/health.module.ts
|
|
90
|
+
import { Module } from '@nestjs/common';
|
|
91
|
+
import { TerminusModule } from '@nestjs/terminus';
|
|
92
|
+
import { HealthController } from './health.controller';
|
|
93
|
+
|
|
94
|
+
@Module({ imports: [TerminusModule], controllers: [HealthController] })
|
|
95
|
+
export class HealthModule {}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
// apps/backend/src/health/health.controller.ts
|
|
100
|
+
import { Controller, Get } from '@nestjs/common';
|
|
101
|
+
import { HealthCheck, HealthCheckService, HttpHealthIndicator } from '@nestjs/terminus';
|
|
102
|
+
|
|
103
|
+
@Controller('health')
|
|
104
|
+
export class HealthController {
|
|
105
|
+
constructor(private health: HealthCheckService, private http: HttpHealthIndicator) {}
|
|
106
|
+
|
|
107
|
+
@Get()
|
|
108
|
+
@HealthCheck()
|
|
109
|
+
check() {
|
|
110
|
+
return this.health.check([
|
|
111
|
+
() => this.http.pingCheck('self', `http://localhost:${process.env.PORT ?? '3000'}/`),
|
|
112
|
+
]);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Keep healthchecks **cheap and dependency-free**. Don't ping Supabase here — a transient Supabase blip would mark every Railway deploy as failed and you'd be unable to ship. For "is my DB reachable" use a separate `/ready` endpoint that uptime monitors poll.
|
|
118
|
+
|
|
119
|
+
## Env Var Management
|
|
120
|
+
|
|
121
|
+
Three layers: **service vars** (`Settings → Variables`, default home for secrets) → **shared vars** (project-level, referenced as `${{ shared.NAME }}`) → **reference vars** (pull from another service: `${{ Postgres.DATABASE_URL }}`).
|
|
122
|
+
|
|
123
|
+
CBP convention for a NestJS-on-Supabase backend:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
# Shared (project-level)
|
|
127
|
+
SUPABASE_URL=https://<project>.supabase.co
|
|
128
|
+
SUPABASE_ANON_KEY=...
|
|
129
|
+
|
|
130
|
+
# Service-only (api service)
|
|
131
|
+
SUPABASE_SERVICE_ROLE_KEY=... # never share — staging/prod must differ
|
|
132
|
+
SENTRY_DSN=...
|
|
133
|
+
NODE_ENV=production
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Rules: `NODE_ENV=production` always — even in staging (differentiate via `RAILWAY_ENVIRONMENT_NAME`). Never put service-role secrets in shared. Use the dashboard "raw editor" for bulk paste; the UI input strips trailing newlines and occasionally mangles `=` in values.
|
|
137
|
+
|
|
138
|
+
## Multi-Service Projects
|
|
139
|
+
|
|
140
|
+
A typical CBP backend project:
|
|
141
|
+
|
|
142
|
+
| Service | Source | Purpose |
|
|
143
|
+
|---------|--------|---------|
|
|
144
|
+
| `api` | GitHub: `apps/backend` | NestJS HTTP API |
|
|
145
|
+
| `worker` | GitHub: `apps/backend` (different start cmd) | Queue/cron worker if needed |
|
|
146
|
+
| `postgres` | Railway template | Optional fallback DB (Supabase is primary) |
|
|
147
|
+
|
|
148
|
+
To run two services off one repo: create two services on the same GitHub repo, override `Settings → Deploy → Start Command` per service (`node dist/main.js` for api, `node dist/worker.js` for worker), set `RAILWAY_DOCKERFILE_PATH` the same on both.
|
|
149
|
+
|
|
150
|
+
Internal traffic uses `<service-name>.railway.internal:<port>` (IPv6) — no public hop, no egress cost.
|
|
151
|
+
|
|
152
|
+
## Custom Domains
|
|
153
|
+
|
|
154
|
+
`Settings → Networking → Custom Domain → Add`. Railway provisions Let's Encrypt automatically. DNS: subdomain via `CNAME api → <generated>.up.railway.app`; apex via Railway's CNAME flattening / ALIAS, or buy the domain via Railway and it auto-wires.
|
|
155
|
+
|
|
156
|
+
CBP convention: production `api.codebyplan.com` → Railway production env's api service. Staging stays on the generated `up.railway.app` domain unless there's a reason for a real subdomain.
|
|
157
|
+
|
|
158
|
+
## Build Caching
|
|
159
|
+
|
|
160
|
+
Two caches matter: (1) **layer cache** — Railway preserves Docker layers per service; order Dockerfile so manifest copy + install precedes source copy (canonical Dockerfile above does this); (2) **cache mounts** — `--mount=type=cache,id=s/<service id>-<path>,target=<path>` for pnpm store, npm cache. The `s/<service id>` prefix is Railway-specific and scopes the cache per service.
|
|
161
|
+
|
|
162
|
+
Clean rebuild (no cache): ~3-5 min for a typical CBP backend. Cached: ~30-60 sec — almost entirely the source COPY + turbo build steps.
|
|
163
|
+
|
|
164
|
+
## Sources
|
|
165
|
+
|
|
166
|
+
- https://docs.railway.com/guides/dockerfiles
|
|
167
|
+
- https://docs.railway.com/guides/healthchecks
|
|
168
|
+
- https://docs.railway.com/guides/variables
|
|
169
|
+
- https://docs.railway.com/reference/private-networking
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Railway Overview
|
|
2
|
+
|
|
3
|
+
Railway (railway.com, formerly railway.app) is the standard backend deployment target for the CodeByPlan family of repos. The `/cbp-ship` orchestrator's `railway-backend` surface targets it for NestJS API services, scheduled workers, and any long-running process that doesn't belong on Vercel's edge/serverless surface.
|
|
4
|
+
|
|
5
|
+
## What Railway Is
|
|
6
|
+
|
|
7
|
+
A platform-as-a-service that runs containers (or Nixpacks/Railpack-built images) from a GitHub repo or a CLI push. It handles:
|
|
8
|
+
|
|
9
|
+
- Build (Dockerfile, Nixpacks, or Railpack — auto-detected)
|
|
10
|
+
- Deploy (rolling, with healthcheck gating)
|
|
11
|
+
- Networking (public HTTPS endpoint + private `*.railway.internal` mesh)
|
|
12
|
+
- Env var management (per-service, per-environment, with shared groups)
|
|
13
|
+
- Logs / metrics / smart diagnosis
|
|
14
|
+
|
|
15
|
+
It is positioned as "Heroku, but you pay for what you use, with Docker as a first-class citizen."
|
|
16
|
+
|
|
17
|
+
## When to Pick Railway (vs Alternatives)
|
|
18
|
+
|
|
19
|
+
| Need | Pick |
|
|
20
|
+
|------|------|
|
|
21
|
+
| Long-running NestJS API, scheduled job, queue worker | **Railway** |
|
|
22
|
+
| WebSocket server, gRPC, raw TCP | **Railway** |
|
|
23
|
+
| Edge-rendered Next.js, ISR-heavy site | **Vercel** |
|
|
24
|
+
| Static site / Jamstack with form handlers | **Vercel** or Netlify |
|
|
25
|
+
| Self-host on a single $5 box, no CI/CD | Render or Fly.io |
|
|
26
|
+
| Multi-region with Anycast and global edge state | **Fly.io** |
|
|
27
|
+
| Already on Supabase + need adjacent worker | **Railway** (best Supabase neighbour — same VPC-style flow) |
|
|
28
|
+
|
|
29
|
+
CodeByPlan's rule of thumb: **NestJS = Railway, Next.js web = Vercel**. The desktop and VS Code apps don't deploy to Railway at all.
|
|
30
|
+
|
|
31
|
+
## Pricing Model (as of Apr 2026)
|
|
32
|
+
|
|
33
|
+
| Plan | Base | Includes | Usage |
|
|
34
|
+
|------|------|----------|-------|
|
|
35
|
+
| Hobby | $5/mo | $5 of usage credit | $0.000231/GB-hour RAM, $0.000463/vCPU-hour |
|
|
36
|
+
| Pro | $20/mo per seat | $20 of usage credit per seat | Same per-resource rates, no cap |
|
|
37
|
+
| Enterprise | Custom | SOC2, dedicated support | Custom |
|
|
38
|
+
|
|
39
|
+
The `$5/mo` Hobby fee **is** the $5 of usage — it's a credit, not a base + usage. A typical CBP NestJS backend (256 MB RAM, ~5% CPU avg) runs ~$3-4/mo, fitting inside Hobby.
|
|
40
|
+
|
|
41
|
+
Pro is required for: team seats, priority support, multi-region, committed spend discounts, Metal regions for production workloads.
|
|
42
|
+
|
|
43
|
+
See https://railway.com/pricing for the live rate card.
|
|
44
|
+
|
|
45
|
+
## Key Concepts
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
Project
|
|
49
|
+
└── Environment (e.g. production, staging, pr-42)
|
|
50
|
+
└── Service (e.g. api, worker, postgres)
|
|
51
|
+
└── Deployment (a build+release of one commit)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- **Project** — top-level container; usually one per repo or one per app family. CBP convention: one project per backend repo.
|
|
55
|
+
- **Environment** — a parallel copy of all services in a project. `production` is created by default. PR environments are auto-spawned via the GitHub integration if enabled.
|
|
56
|
+
- **Service** — one running thing (an API, a worker, a managed Postgres). Each service has its own image, env vars, domain, replicas.
|
|
57
|
+
- **Deployment** — one build of one service. Railway keeps deployment history; you can roll back via the dashboard or `railway redeploy`.
|
|
58
|
+
|
|
59
|
+
## CLI Auth Model
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm i -g @railway/cli # or pnpm add -g @railway/cli
|
|
63
|
+
railway login # opens browser, OAuths against your Railway account
|
|
64
|
+
railway link # binds CWD to a project + environment + service
|
|
65
|
+
railway up # tar-up CWD and push as a one-off deployment
|
|
66
|
+
railway run -- <cmd> # run <cmd> with the linked service's env vars
|
|
67
|
+
railway logs # tail logs for the linked service
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`railway login --browserless` produces a pairing code for headless/CI environments. CI typically uses `RAILWAY_TOKEN` (project token, scoped to one project) instead — set it as an env var and skip `login` entirely.
|
|
71
|
+
|
|
72
|
+
The `.railway/` directory in CWD stores the link (project ID, environment, service). It is gitignored by default — do not commit it.
|
|
73
|
+
|
|
74
|
+
## GitHub Auto-Deploys
|
|
75
|
+
|
|
76
|
+
Railway's GitHub integration is the production deploy path for every CBP backend. Mechanics:
|
|
77
|
+
|
|
78
|
+
1. Connect the repo to the service via the dashboard (one-time).
|
|
79
|
+
2. Pick a branch (CBP convention: `main` for production, `development` for staging if a staging environment exists).
|
|
80
|
+
3. Every push to that branch triggers a build → healthcheck → swap.
|
|
81
|
+
4. PRs against the configured branch can auto-spawn ephemeral environments (opt-in per project).
|
|
82
|
+
|
|
83
|
+
**Important:** the GitHub integration uses a webhook. If Railway shows "no deployment triggered" after a push, check the webhook delivery log on the GitHub side first — see [railway-troubleshooting.md](./railway-troubleshooting.md).
|
|
84
|
+
|
|
85
|
+
## How `/cbp-ship` Uses Railway
|
|
86
|
+
|
|
87
|
+
The `railway-backend` surface in `/cbp-ship`:
|
|
88
|
+
|
|
89
|
+
1. Confirms `apps/backend` (or whatever the NestJS app is) builds clean locally
|
|
90
|
+
2. Runs the test suite tied to the backend
|
|
91
|
+
3. Pushes the deploy branch (usually `main`) — Railway picks it up via webhook
|
|
92
|
+
4. Polls `railway logs` (or the GraphQL API via `RAILWAY_TOKEN`) for the new deployment
|
|
93
|
+
5. Verifies healthcheck passes and surfaces the deployment URL
|
|
94
|
+
6. Records the deploy outcome (deployment ID + commit SHA) on the round/task record
|
|
95
|
+
|
|
96
|
+
The orchestrator does NOT call `railway up` directly for production — that bypasses the GitHub history and breaks rollback. CLI push is reserved for one-off debugging.
|
|
97
|
+
|
|
98
|
+
## Recent Platform Changes Worth Knowing
|
|
99
|
+
|
|
100
|
+
(From https://railway.com/changelog — keep this short, prune when stale.)
|
|
101
|
+
|
|
102
|
+
- **Railway Metal** — dedicated-hardware regions, including EU (Amsterdam) and SE Asia, available on Pro+. Use for latency-sensitive prod.
|
|
103
|
+
- **Multi-region deployments** — single service can run replicas in multiple regions. Pro+.
|
|
104
|
+
- **One-click HA Postgres** — replicated managed Postgres without manual setup. Useful when CBP repos outgrow Supabase's free tier and want a Railway-native DB.
|
|
105
|
+
- **Buckets** — Railway-native object storage with CLI support. Alternative to S3/R2 when staying in-platform matters.
|
|
106
|
+
- **Railpack** — successor build system to Nixpacks for some languages (Elixir, Ruby, Rust). Auto-detected; no migration needed.
|
|
107
|
+
- **IPv6** — full IPv6 support across public + private networking.
|
|
108
|
+
- **Smart Diagnosis** — automated build/deploy failure analysis surfaced in the dashboard. Read its output before opening a support ticket.
|
|
109
|
+
|
|
110
|
+
## Sources
|
|
111
|
+
|
|
112
|
+
- https://docs.railway.com — primary reference
|
|
113
|
+
- https://railway.com/changelog — platform updates
|
|
114
|
+
- https://railway.com/pricing — current rate card
|
|
115
|
+
|
|
116
|
+
## See also
|
|
117
|
+
|
|
118
|
+
- [railway-nestjs-deployment.md](./railway-nestjs-deployment.md) — concrete CBP-shape walkthrough
|
|
119
|
+
- [railway-troubleshooting.md](./railway-troubleshooting.md) — failure-mode reference
|
|
120
|
+
- [surface-railway.md](./surface-railway.md) — `/cbp-ship` deploy steps for this surface
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Railway — Troubleshooting
|
|
2
|
+
|
|
3
|
+
Failure modes the `/cbp-ship` orchestrator and human operators have hit on Railway, with the actual fix. Ordered roughly by frequency.
|
|
4
|
+
|
|
5
|
+
For platform-level concept reference see [railway-overview.md](./railway-overview.md). For the canonical NestJS deployment shape see [railway-nestjs-deployment.md](./railway-nestjs-deployment.md).
|
|
6
|
+
|
|
7
|
+
## 1. Healthcheck Timeout — Service Marked CRASHED
|
|
8
|
+
|
|
9
|
+
**Symptom:** Build succeeds, deploy log shows `Starting Healthcheck` and then `Healthcheck failed!` after the configured timeout. New deployment never goes live; old one keeps serving.
|
|
10
|
+
|
|
11
|
+
**Causes (in order of likelihood):**
|
|
12
|
+
|
|
13
|
+
1. **App listening on `localhost`/`127.0.0.1` instead of `0.0.0.0`** — Railway's proxy is on a different interface and can't reach you.
|
|
14
|
+
2. **Hardcoded port** — app listens on `3000` but Railway assigned `PORT=8080`.
|
|
15
|
+
3. **Healthcheck path wrong** — configured `/health`, app exposes `/api/health`. Railway sees 404 → fail.
|
|
16
|
+
4. **Healthcheck depends on Supabase / external service that's down** — transient outage cascades into a broken deploy.
|
|
17
|
+
5. **Slow boot** — NestJS module init (e.g. running migrations on boot) takes longer than the healthcheck timeout (default 100s).
|
|
18
|
+
|
|
19
|
+
**Fix:**
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// Bind to 0.0.0.0, read $PORT
|
|
23
|
+
await app.listen(parseInt(process.env.PORT ?? '3000', 10), '0.0.0.0');
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Verify with: `railway logs` immediately after deploy — look for `Listening on 0.0.0.0:<port>` line.
|
|
27
|
+
|
|
28
|
+
For slow boot, raise the healthcheck timeout in `Settings → Deploy → Healthcheck Timeout` (max 300s). Better: defer migrations out of boot path.
|
|
29
|
+
|
|
30
|
+
For dependency-tainted healthcheck, see the "keep healthchecks cheap" guidance in [railway-nestjs-deployment.md](./railway-nestjs-deployment.md).
|
|
31
|
+
|
|
32
|
+
## 2. Build OOM — `Killed` or Exit Code 137
|
|
33
|
+
|
|
34
|
+
**Symptom:** Build log ends with `Killed` or `exit code 137` during `pnpm install` or `turbo build`. No useful stack.
|
|
35
|
+
|
|
36
|
+
**Cause:** Railway's default build runner has a memory cap (~8 GB on Hobby). Heavy monorepo builds — particularly with `next build` in the same image, or when sharp/prisma engines compile from source — exceed it.
|
|
37
|
+
|
|
38
|
+
**Fix:**
|
|
39
|
+
|
|
40
|
+
1. Slim the build context. Add a `.dockerignore`:
|
|
41
|
+
```
|
|
42
|
+
**/node_modules
|
|
43
|
+
**/.next
|
|
44
|
+
**/dist
|
|
45
|
+
**/.turbo
|
|
46
|
+
**/coverage
|
|
47
|
+
**/.git
|
|
48
|
+
```
|
|
49
|
+
2. Use multi-stage with `pnpm --filter=<pkg> deploy --prod /out` so the runtime image only carries one app's deps.
|
|
50
|
+
3. Avoid `pnpm install --recursive` — let `pnpm install` (workspace-aware) do it once.
|
|
51
|
+
4. If still OOMing on Hobby: upgrade to Pro (larger build runner) or move heavy compile steps to a CI step that publishes a prebuilt artefact.
|
|
52
|
+
|
|
53
|
+
## 3. $PORT Binding Errors
|
|
54
|
+
|
|
55
|
+
**Symptom:** `Error: listen EADDRINUSE` or `Error: Cannot find module 'PORT'` or app binds to literally the string `"$PORT"`.
|
|
56
|
+
|
|
57
|
+
**Causes:**
|
|
58
|
+
|
|
59
|
+
| Symptom | Cause |
|
|
60
|
+
|---------|-------|
|
|
61
|
+
| `listen EADDRINUSE: ::1:8080` | Two processes in the container both binding the same port (e.g. `tini` start script forking twice) |
|
|
62
|
+
| Listens on string `"$PORT"` | Shell-form CMD without shell expansion: `CMD node main.js --port=$PORT` won't expand. Use `CMD ["sh", "-c", "node main.js --port=$PORT"]` or read from env in code (preferred) |
|
|
63
|
+
| `parseInt(undefined)` → NaN | App didn't fall back; ensure `process.env.PORT ?? '3000'` |
|
|
64
|
+
|
|
65
|
+
## 4. GitHub Webhook Desync — "I Pushed and Nothing Happened"
|
|
66
|
+
|
|
67
|
+
**Symptom:** `git push` to the configured deploy branch lands on GitHub. No new deployment appears in Railway.
|
|
68
|
+
|
|
69
|
+
**Diagnosis:**
|
|
70
|
+
|
|
71
|
+
1. GitHub repo → `Settings → Webhooks` → find Railway's webhook → `Recent Deliveries` tab.
|
|
72
|
+
2. Look at the latest delivery for your push. If it's `200 OK`, problem is on Railway's side. If it's red (4xx/5xx) or missing, problem is on GitHub's side.
|
|
73
|
+
|
|
74
|
+
**Fixes:**
|
|
75
|
+
|
|
76
|
+
- **Webhook delivery missing** — your push didn't match the configured branch filter. Check `Settings → Source` on the Railway service.
|
|
77
|
+
- **Webhook 401/403** — Railway's GitHub App was uninstalled or its permissions were revoked. Reinstall: Railway dashboard → service → `Settings → Source → Reconnect`.
|
|
78
|
+
- **Webhook 200 but no Railway deploy** — webhook reached Railway but was filtered out. Check that the branch matches and that the commit doesn't only touch ignored paths (Railway has an optional path filter).
|
|
79
|
+
- **Last resort:** `Settings → Deploy → Trigger Deploy` manually.
|
|
80
|
+
|
|
81
|
+
## 5. Env Var Typo / Missing Var
|
|
82
|
+
|
|
83
|
+
**Symptom:** App boots, then crashes with `SUPABASE_URL is undefined` or similar. Deployment marked CRASHED.
|
|
84
|
+
|
|
85
|
+
**Diagnosis:**
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
railway variables # list all vars in current service
|
|
89
|
+
railway run -- printenv | grep SUPABASE
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Common gotchas:**
|
|
93
|
+
|
|
94
|
+
- Trailing newline or whitespace on a pasted value. Use the dashboard "raw editor" for multi-line values.
|
|
95
|
+
- Variable defined on the wrong environment (you set it on `staging` but deployed `production`).
|
|
96
|
+
- Reference variable broken: `${{ Postgres.DATABASE_URL }}` evaluates to empty string if the `Postgres` service was renamed.
|
|
97
|
+
- `NODE_ENV=development` accidentally inherited — check it's `production` everywhere.
|
|
98
|
+
|
|
99
|
+
**Fix:** Set the var, then redeploy. New env vars do NOT auto-restart the service — you must trigger a redeploy via dashboard or `railway redeploy`.
|
|
100
|
+
|
|
101
|
+
## 6. Deploy Stuck in BUILDING
|
|
102
|
+
|
|
103
|
+
**Symptom:** Deploy has been in `BUILDING` state for 15+ minutes with no log output, or logs frozen mid-build.
|
|
104
|
+
|
|
105
|
+
**Causes:**
|
|
106
|
+
|
|
107
|
+
1. Railway build runner is in a degraded region — check https://status.railway.com.
|
|
108
|
+
2. Network stall pulling base image or pnpm packages.
|
|
109
|
+
3. Cache mount corruption — rare, but happens when a build is killed mid-write.
|
|
110
|
+
|
|
111
|
+
**Fixes:**
|
|
112
|
+
|
|
113
|
+
1. Cancel the deployment from the dashboard (deployment row → kebab menu → Cancel).
|
|
114
|
+
2. Trigger a fresh deploy.
|
|
115
|
+
3. If second deploy stalls in the same place: clear build cache via `Settings → Danger → Clear build cache`, then redeploy.
|
|
116
|
+
4. If still stuck after cache clear: status page check, then support ticket. Do NOT keep retrying — you're burning build minutes.
|
|
117
|
+
|
|
118
|
+
## 7. Healthcheck Timeout Misconfiguration
|
|
119
|
+
|
|
120
|
+
**Symptom:** Healthcheck path returns 200 quickly when curled directly, but Railway still marks it failed.
|
|
121
|
+
|
|
122
|
+
**Diagnosis steps:**
|
|
123
|
+
|
|
124
|
+
1. `railway run -- curl -v http://localhost:$PORT/health` — does it work from inside the container?
|
|
125
|
+
2. If yes: Railway proxy timeout is too tight. Default is 100s for the *initial* healthcheck window. Bump to 300s if app boot is genuinely slow.
|
|
126
|
+
3. Healthcheck path field accepts a path only — not a full URL. `/health` correct, `http://localhost:3000/health` wrong.
|
|
127
|
+
4. HTTPS-only middleware (e.g. `helmet` with `hsts` redirect) can 301 the healthcheck. Whitelist the `/health` path from any redirect middleware.
|
|
128
|
+
|
|
129
|
+
## 8. Logs Inspection — What to Run
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
railway logs # tail current service logs (live)
|
|
133
|
+
railway logs --deployment <id> # logs for a specific past deployment
|
|
134
|
+
railway logs --build # build logs (vs runtime logs)
|
|
135
|
+
railway status # current service deployment + state
|
|
136
|
+
railway whoami # confirm you're logged in as the right account
|
|
137
|
+
railway environment # which env is linked
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
For programmatic access (CI, `/cbp-ship` polling), use the GraphQL API at `https://backboard.railway.com/graphql/v2` with `Authorization: Bearer $RAILWAY_TOKEN`. The `deployments` and `deploymentLogs` queries are the relevant ones — see the API explorer linked from https://docs.railway.com.
|
|
141
|
+
|
|
142
|
+
## 9. Private Networking Not Resolving
|
|
143
|
+
|
|
144
|
+
**Symptom:** `api` service can't reach `worker.railway.internal` — `getaddrinfo ENOTFOUND` or connection refused.
|
|
145
|
+
|
|
146
|
+
**Causes:**
|
|
147
|
+
|
|
148
|
+
1. Service name has changed; the internal hostname follows the *current* service name (lowercase, no spaces).
|
|
149
|
+
2. Calling code uses IPv4 socket but Railway internal mesh is IPv6-only. Node 18+ defaults are fine; if you've forced `family: 4` somewhere, drop it.
|
|
150
|
+
3. Both services must be in the same project AND environment. Cross-environment internal DNS is not a thing.
|
|
151
|
+
|
|
152
|
+
## 10. Rollback
|
|
153
|
+
|
|
154
|
+
**Symptom:** Last deploy broke production; need to revert in <60 seconds.
|
|
155
|
+
|
|
156
|
+
**Fix:**
|
|
157
|
+
|
|
158
|
+
1. Dashboard → service → deployments list → find the last good deployment → kebab → `Redeploy`.
|
|
159
|
+
2. Or CLI: `railway redeploy --deployment <id>`.
|
|
160
|
+
|
|
161
|
+
This re-runs the *same image* — no rebuild — so it lands in seconds. After rollback, fix the offending commit on GitHub; the next push will deploy normally.
|
|
162
|
+
|
|
163
|
+
## Sources
|
|
164
|
+
|
|
165
|
+
- https://docs.railway.com — primary reference
|
|
166
|
+
- https://railway.com/changelog — when behaviour changes here, update this file
|
|
167
|
+
- https://status.railway.com — platform status, check first when something is "weird"
|
|
168
|
+
- https://station.railway.com — community Q&A; useful for edge cases not in docs
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# release-please — Overview
|
|
2
|
+
|
|
3
|
+
`release-please` is a Google-maintained tool that automates semver releases by parsing Conventional Commits. It runs as a GitHub Action (`googleapis/release-please-action`), watches commits to a configured branch, opens a "Release PR" that bumps `package.json` version + updates `CHANGELOG.md`, and (when the Release PR merges) cuts a GH Release tag. Used by the `npm-package` surface in `/cbp-ship` for opt-in versioning automation, and optionally for `tauri-desktop`.
|
|
4
|
+
|
|
5
|
+
Upstream: https://github.com/googleapis/release-please
|
|
6
|
+
|
|
7
|
+
## How `/cbp-ship` uses it
|
|
8
|
+
|
|
9
|
+
The `npm-package` surface ([surface-npm.md](./surface-npm.md)) offers `release-please` as one of three versioning modes (manual, release-please, changesets). When a repo opts in via `/cbp-ship-configure`:
|
|
10
|
+
|
|
11
|
+
1. Configure scaffolds `.github/workflows/release-please.yml` from `templates/workflow-release-please.yml`
|
|
12
|
+
2. Devs commit using Conventional Commits (`feat:`, `fix:`, etc.)
|
|
13
|
+
3. release-please opens a Release PR on the watched branch (configured in .github/workflows/release-please.yml; typically `main`)
|
|
14
|
+
4. Maintainer reviews + merges the Release PR
|
|
15
|
+
5. release-please tags the release; `/cbp-ship` then publishes the bumped version to npm
|
|
16
|
+
|
|
17
|
+
The release-please-managed CHANGELOG.md is the source of truth for release notes.
|
|
18
|
+
|
|
19
|
+
## Commit message → version bump mapping
|
|
20
|
+
|
|
21
|
+
| Prefix | Action |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `feat:` | Minor bump in next release-please PR |
|
|
24
|
+
| `fix:` | Patch bump |
|
|
25
|
+
| `feat!:` / `fix!:` / `BREAKING CHANGE:` footer | Major bump |
|
|
26
|
+
| `chore:`, `docs:`, `refactor:`, `test:`, `style:`, `perf:`, `ci:` | No bump |
|
|
27
|
+
|
|
28
|
+
Reference: [versioning.md](./versioning.md) for the full rules including changesets and manual modes.
|
|
29
|
+
|
|
30
|
+
## Config shape
|
|
31
|
+
|
|
32
|
+
`release-please-config.json` (single-package):
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
|
|
37
|
+
"release-type": "node",
|
|
38
|
+
"include-component-in-tag": false,
|
|
39
|
+
"bump-minor-pre-major": true,
|
|
40
|
+
"bump-patch-for-minor-pre-major": false,
|
|
41
|
+
"draft": false,
|
|
42
|
+
"prerelease": false,
|
|
43
|
+
"packages": {
|
|
44
|
+
".": {
|
|
45
|
+
"package-name": "<your-package-name>",
|
|
46
|
+
"changelog-path": "CHANGELOG.md",
|
|
47
|
+
"release-type": "node"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`.release-please-manifest.json` tracks current versions:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{ ".": "1.4.2" }
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For monorepos, list each package in `packages` and use the `node-workspace` plugin to keep `workspace:*` deps in sync after bumps.
|
|
60
|
+
|
|
61
|
+
## Release-types
|
|
62
|
+
|
|
63
|
+
| release-type | Use for |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `node` | npm packages — bumps `package.json`, generates CHANGELOG |
|
|
66
|
+
| `python` | Python packages — bumps `pyproject.toml` / `setup.py` |
|
|
67
|
+
| `rust` | Cargo crates — bumps `Cargo.toml` |
|
|
68
|
+
| `go` | Go modules — tags only (no manifest file to bump) |
|
|
69
|
+
| `simple` | Tag + CHANGELOG only — for repos with no language manifest |
|
|
70
|
+
| `terraform-module` | Terraform modules |
|
|
71
|
+
|
|
72
|
+
CBP defaults: `node` for `npm-package` surface, `simple` if applied to `tauri-desktop` (Tauri version lives in `tauri.conf.json` which release-please can update via `extra-files`).
|
|
73
|
+
|
|
74
|
+
## Tokens + permissions
|
|
75
|
+
|
|
76
|
+
The default `secrets.GITHUB_TOKEN` is sufficient for most use cases. A PAT is required when:
|
|
77
|
+
|
|
78
|
+
- Release commits should re-trigger CI (default `GITHUB_TOKEN` doesn't trigger downstream workflows — this is a GH security feature)
|
|
79
|
+
- Cross-repo releases (rare for CBP)
|
|
80
|
+
- Repo has branch protections that exclude bots
|
|
81
|
+
|
|
82
|
+
Workflow permissions:
|
|
83
|
+
|
|
84
|
+
```yaml
|
|
85
|
+
permissions:
|
|
86
|
+
contents: write # to create tags + commit CHANGELOG
|
|
87
|
+
pull-requests: write # to open the Release PR
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Comparison vs Changesets
|
|
91
|
+
|
|
92
|
+
See [npm-publish-monorepo.md](./npm-publish-monorepo.md) "Changesets vs release-please" for the full decision matrix. Short version: release-please assumes Conventional Commits are enforced; changesets adds a per-PR ceremony but gives explicit per-PR intent.
|
|
93
|
+
|
|
94
|
+
## Pairs With
|
|
95
|
+
|
|
96
|
+
- [surface-npm.md](./surface-npm.md) — npm publish surface that consumes the bumped version
|
|
97
|
+
- [versioning.md](./versioning.md) — when to pick release-please vs changesets vs manual
|
|
98
|
+
- [npm-publish-monorepo.md](./npm-publish-monorepo.md) — release-please monorepo configuration with the `node-workspace` plugin
|
|
99
|
+
- `templates/release-please-config.json`, `templates/workflow-release-please.yml` — scaffolds the configure skill drops into the repo
|