Repository navigation
feat(deploy): one command from a fresh clone to a live Railway project - #76
Merged
Merged
Conversation
make railway-setup creates the project, environments, services, databases, domains and secrets (generated or placeholders), deploys, and waits until every /healthz answers. No dashboard or GitHub step first: - project and repo default to auto (the checkout's origin); --project, --workspace, --environments, --admin, --region, --repo (or PLATFORM_*) are written into platform.yaml, comments and layout kept byte for byte - GitHub: if Railway can't read the repo yet, services are created without a source and the checkout is deployed by upload, with the GitHub app install link as the next step; a re-run after installing connects the repo (serviceConnect is the access check) and switches to deploy-on-push, no duplicate services - --yes, --json summary (project, source, per-environment URLs, health, next steps) and exit codes 0-5; make railway-doctor preflight (login, workspace, SSH key, GitHub, Doppler) with fixes - RESEND_API_KEY placeholder so production boots on day one - Railway's 32-char project limit; the DB password fix uses the local socket; failed uploads are reported, not fatal - AGENTS.md "Deploy to Railway (for agents)", README quick start, three new Railway issue drafts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jayleaton
marked this pull request as ready for review
October 22, 2026 13:38
jayleaton
added a commit
that referenced
this pull request
Oct 22, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jayleaton
added a commit
that referenced
this pull request
Oct 22, 2026
…-loop bench (#74) * perf(devloop): make bench-devloop prints build, generate, lint, probe and per-package test timings Adds scripts/bench-devloop.sh (cold + warm), the Bench dev loop workflow (manual, or push a bench/* branch) and scripts/testbudget, which renders go test -json as plain go test output, lists the slowest tests and enforces per-package and per-test time budgets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(test): every test runs in parallel, no sleeps, crawl checks each body once paralleltest + tparallel make t.Parallel() the rule (no exceptions were needed) and forbidigo bans time.Sleep in tests (synctest fake-clock sleeps go through one documented helper). Fixes that made it safe: the UI crawls no longer share a package-level crawlMethod, admin render tests stop mutating templ's global buffer size, TestDopplerErrors and the web services table get per-case fakes and controllers, and packages/auth migrates a template once and clones it (shared database and newDatabase) instead of migrating per database. The crawls split into parallel subtests and memoize the body-only checks: static assets come back byte-identical in every state, and re-scanning them was most of the crawl's time under -race. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(ci): test-time budgets, slowest tests in every run, probes reuse the test profile make test and CI pipe go test -json through scripts/testbudget: plain go test output, the slowest tests, and a failure when a package runs over 30s or a leaf test over 5s (make lint-tests proves both trip). The coverage probes plant their uncovered statements in the real profile instead of recompiling three packages under -race (CI runs them after the tests). AGENTS.md "Fast tests" documents the rules; make bench-devloop the measurements. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(devloop): bench-devloop's warm test run compiles nothing The cold run uses a throwaway cache, so the warm run was compiling every -race variant; an untimed run now primes the cache first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(devloop): make ci hands its coverage profile to the probes, as CI does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(test): tests added by the UI overhaul and deploy run in parallel too Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(test): crawl one subtest per state; bench A/B against a base ref on one machine Per-route crawl subtests built a handler and mock set each: twice the CPU of the serial crawl, which 2 vCPUs cannot pay back. One parallel subtest per state (web: and method) keeps the setup at main's level and still uses both CPUs. Separate CI runs of identical code varied by up to 50%, so the bench gains BENCH_BASE: base and HEAD test runs alternate on the same machine and their medians are compared (the workflow compares with main). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(test): crawl routes as parallel subtests sharing one handler per state and method Per-state crawl subtests ran 6-11s each on CI's single job and tripped the 5s test budget. Routes are subtests again, now sharing their state's handler: at GOMAXPROCS=2 the crawls use main's CPU or less and finish 29-38% sooner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): test-time budgets at about twice today's slowest (60s package, 10s test) 5s flaked on a CPU-bound scrypt test (5.28s) while a cold build cache compiled on the same 2 vCPUs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(test): deploy tests added in #76 run in parallel Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A fresh clone of the template now reaches a live Railway project in one command, with no manual Railway or GitHub step first. Previously, the first
make railway-applydead-ended on "You don't have access to the GitHub repo" until the Railway GitHub app was installed.--yes, plus--json: one object on stdout (ok,project.{id,url},source, each env's serviceurl/deployment/health,nextSteps) with logs on stderr.--yes, 4 preflight failed, 5 unhealthy.RESEND_API_KEYplaceholder, and the next steps tell the user to replace it.docs/railway-go-iac-issues.md(scratch: CI warm-run measurement (do not merge) #15–fix(auth): cheap argon2 in test binaries so -race suites stay small #17):Evidence
Run in JJ's account (workspace "JJ Eaton's Projects", Pro), CLI 5.71.0, one throwaway project. The brief's name
go-fast-stack-bootstrap-test-20261022is 37 characters, and Railway rejects names over 32 (Project names must be between 1 and 32 characters.), so the project wasgo-fast-stack-boot-test-261022(0490dac3-…5403).repo: jayleaton/ai-patterns-go, environmentsstaging,production.make railway-applyon a repo Railway can't read:You don't have access to the GitHub repo jayleaton/ai-patterns-go…, apply failed, nothing deployed (PR feat(deploy): one-config Railway setup with Go IaC (deploy/platform.yaml) #39 test).--yes --json(12:14→12:32)serviceConnectsucceeded and both envs deployed from GitHub (8b120a3). The production DB got Railway's literalsecret(…)password, and setup replaced it./healthz200 on both.ok:true exitCode:0 source:"github"no changesin both envs, no new deployments, both healthy, exit 0--repo jayleaton/railway-bootstrap-no-access-probe(doesn't exist, so Railway can't read it)serviceConnect→User does not have access to the repo. Setup deployed byrailway up, and both envs endedhealth ok, deployment SUCCESSwithsource:"upload".nextSteps[0]:Install Railway's GitHub app … https://github.com/apps/railway-app/installations/new/permissions?target_id=58495321 …, then re-run make railway-apply. The re-run didn't redeploy the already-live staging.--repo jayleaton/ai-patterns-goagain (stands in for "after installing")GitHub: connected …; switching every service to deploy-on-push. Still exactly 2 services (postgres,web). Both envs' latest deployments come from GitHub (7fcc091),/healthzok, exit 0. The nextplanreportspendingChanges: 0.--jsondev-box-workers-behind-api); without--yesand with no TTY, apply exits 3 before creating anythingThe fallback test turned up two problems:
authKeyrows and the re-run recovered. A from-zero project can't hit this.Cost: the test project cost $0.0045 (Railway usage). It was deleted after matching its exact name and ID; Railway scheduled the removal. Railway's 2026-10-21 incident was still open (deploy queueing for Pro): one deployment sat in
DEPLOYINGuntil the 15-minute wait ran out, while/healthzstayed ok.Checks (pre-push, per COMMON.md): gofmt clean,
go vet(module +.railway/railway.go), golangci-lint ondeploy/0 issues,deploy/platformtests (new:Resolve, byte-preservingEdit,ForceUpload, 32-char names), actionlint. Full CI on GitHub Actions.Not verified: a real GitHub app install. Railway could already read this repo, so the switch was shown with a nonexistent repo and then the real one. The admin path wasn't run in this test.
Merge Danger
Door: two-way. Nothing touches Railway on merge.
platform.yamlnow defaultsproject/repotoauto, so a fork whose origin isowner/namegets projectnameinstead of the old hardcodedai-patterns-go. Revert to restore.Blast Radius: deployment.
deploy/(its own module), the railway Make targets (now@-silent, built intobin/railway-setup), README and AGENTS. App code is unchanged.🤖 Generated with Claude Code