Skip to content

Commit fe2e81a

Browse files
feat: Add GitHub Actions workflow for automatic Railway deployment
- Create production deployment workflow (triggers on push to main/master) - Create preview deployment workflow (triggers on pull requests) - Add Railway configuration file (railway.json) - Add setup script for easy Railway deployment configuration - Add Railway deployment documentation - Add npm scripts for Railway operations (setup, deploy, logs) - Include environment variable template for Railway This enables automatic deployments to Railway when code is pushed to GitHub.
1 parent a29412e commit fe2e81a

8 files changed

Lines changed: 480 additions & 1 deletion

File tree

.env.railway

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Railway Environment Variables Template
2+
# Copy this to Railway dashboard environment variables
3+
4+
# Redis (Railway Redis addon)
5+
REDIS_URL=redis://default:password@host:port
6+
7+
# Database (Railway PostgreSQL addon)
8+
DATABASE_URL=postgresql://user:password@host:port/database
9+
10+
# ChromaDB
11+
CHROMADB_API_KEY=
12+
CHROMADB_TENANT=
13+
CHROMADB_DATABASE=stackmemory
14+
15+
# Linear Integration
16+
LINEAR_API_KEY=
17+
LINEAR_TEAM_ID=stackmemory
18+
LINEAR_ORGANIZATION=stackmemoryai
19+
20+
# Storage (GCS for cold tier)
21+
GCS_BUCKET_NAME=stackmemory-cold-storage
22+
GCS_PROJECT_ID=
23+
GCS_CLIENT_EMAIL=
24+
GCS_PRIVATE_KEY=
25+
26+
# Application
27+
NODE_ENV=production
28+
PORT=3000
29+
LOG_LEVEL=info
30+
31+
# Optional: Monitoring
32+
SENTRY_DSN=
33+
DATADOG_API_KEY=
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: Deploy to Railway
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- master
8+
workflow_dispatch:
9+
10+
env:
11+
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
12+
13+
jobs:
14+
deploy:
15+
name: Deploy to Railway
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
22+
- name: Setup Node.js
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: '20'
26+
cache: 'npm'
27+
28+
- name: Install dependencies
29+
run: npm ci
30+
31+
- name: Run tests
32+
run: npm test
33+
continue-on-error: true
34+
35+
- name: Build project
36+
run: npm run build
37+
38+
- name: Install Railway CLI
39+
run: npm install -g @railway/cli
40+
41+
- name: Deploy to Railway
42+
run: |
43+
railway link ${{ secrets.RAILWAY_PROJECT_ID }}
44+
railway up --detach
45+
env:
46+
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
47+
48+
- name: Get deployment URL
49+
id: deployment
50+
run: |
51+
echo "url=$(railway status --json | jq -r '.url')" >> $GITHUB_OUTPUT
52+
continue-on-error: true
53+
54+
- name: Comment on commit
55+
uses: actions/github-script@v7
56+
with:
57+
script: |
58+
const deployment_url = '${{ steps.deployment.outputs.url }}';
59+
const message = deployment_url
60+
? `✅ Deployed to Railway: ${deployment_url}`
61+
: '✅ Deployed to Railway successfully';
62+
63+
github.rest.repos.createCommitComment({
64+
owner: context.repo.owner,
65+
repo: context.repo.repo,
66+
commit_sha: context.sha,
67+
body: message
68+
});
69+
continue-on-error: true
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: Railway Preview Deployment
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened]
6+
7+
env:
8+
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
9+
10+
jobs:
11+
preview:
12+
name: Deploy Preview to Railway
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v4
18+
19+
- name: Setup Node.js
20+
uses: actions/setup-node@v4
21+
with:
22+
node-version: '20'
23+
cache: 'npm'
24+
25+
- name: Install dependencies
26+
run: npm ci
27+
28+
- name: Run tests
29+
run: npm test
30+
continue-on-error: true
31+
32+
- name: Build project
33+
run: npm run build
34+
35+
- name: Install Railway CLI
36+
run: npm install -g @railway/cli
37+
38+
- name: Deploy Preview Environment
39+
id: deploy
40+
run: |
41+
railway link ${{ secrets.RAILWAY_PROJECT_ID }}
42+
railway environment create pr-${{ github.event.pull_request.number }} || true
43+
railway environment pr-${{ github.event.pull_request.number }}
44+
railway up --detach
45+
echo "environment=pr-${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
46+
env:
47+
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
48+
49+
- name: Get preview URL
50+
id: preview
51+
run: |
52+
echo "url=$(railway status --json | jq -r '.url')" >> $GITHUB_OUTPUT
53+
continue-on-error: true
54+
55+
- name: Comment on PR
56+
uses: actions/github-script@v7
57+
with:
58+
script: |
59+
const preview_url = '${{ steps.preview.outputs.url }}';
60+
const environment = '${{ steps.deploy.outputs.environment }}';
61+
const message = preview_url
62+
? `🚀 Preview deployed to Railway\n\nEnvironment: \`${environment}\`\nURL: ${preview_url}\n\n_This preview will be automatically cleaned up when the PR is merged or closed._`
63+
: `🚀 Preview deployed to Railway\n\nEnvironment: \`${environment}\`\n\n_This preview will be automatically cleaned up when the PR is merged or closed._`;
64+
65+
github.rest.issues.createComment({
66+
issue_number: context.issue.number,
67+
owner: context.repo.owner,
68+
repo: context.repo.repo,
69+
body: message
70+
});
71+
continue-on-error: true

CLAUDE.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,6 @@
6262
- `npm_*` - NPM tokens
6363
- Any base64 encoded strings that look like tokens
6464
- Hardcoded URLs with embedded credentials
65-
- # Never use emojis and speak in plain developer english for comments not AI comments
65+
- # Never use emojis and speak in plain developer english for comments not AI comments
66+
- Ask 1-3 questions for clarity for any command given that is complex, go question by question
67+
- Ask questions one at a time before moving on allow user to skip

docs/RAILWAY_DEPLOYMENT.md

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# Railway Deployment Guide
2+
3+
## Automatic Deployment Setup
4+
5+
StackMemory includes automated deployment to Railway via GitHub Actions.
6+
7+
### Quick Setup
8+
9+
1. **Run the setup script:**
10+
```bash
11+
npm run railway:setup
12+
```
13+
This will:
14+
- Install Railway CLI
15+
- Link your Railway project
16+
- Generate required tokens
17+
- Guide you through GitHub secrets setup
18+
19+
2. **Add GitHub Secrets:**
20+
Go to your repository Settings → Secrets → Actions and add:
21+
- `RAILWAY_TOKEN` - Your Railway API token
22+
- `RAILWAY_PROJECT_ID` - Your Railway project ID
23+
24+
3. **Deploy:**
25+
Deployments happen automatically when you:
26+
- Push to `main` or `master` branch → Production deployment
27+
- Open a pull request → Preview deployment
28+
29+
### Manual Deployment
30+
31+
```bash
32+
# Deploy current branch
33+
npm run railway:deploy
34+
35+
# View logs
36+
npm run railway:logs
37+
```
38+
39+
## GitHub Actions Workflows
40+
41+
### Production Deployment (.github/workflows/railway-deploy.yml)
42+
- Triggers on push to main/master
43+
- Runs tests before deploying
44+
- Posts deployment status as commit comment
45+
- Deploys to production environment
46+
47+
### Preview Deployments (.github/workflows/railway-preview.yml)
48+
- Triggers on pull requests
49+
- Creates isolated preview environment
50+
- Posts preview URL as PR comment
51+
- Auto-cleans up when PR is closed
52+
53+
## Railway Configuration
54+
55+
### railway.json
56+
Configures build and deploy settings:
57+
- Build command: `npm run build`
58+
- Start command: `npm start`
59+
- Health check endpoint: `/health`
60+
- Auto-restart on failure (max 3 retries)
61+
62+
### Environment Variables
63+
Set these in Railway dashboard:
64+
65+
#### Required
66+
- `REDIS_URL` - Redis connection (use Railway Redis addon)
67+
- `LINEAR_API_KEY` - Linear API key for task sync
68+
- `CHROMADB_API_KEY` - ChromaDB for vector storage
69+
70+
#### Optional
71+
- `DATABASE_URL` - PostgreSQL connection (use Railway PostgreSQL addon)
72+
- `GCS_BUCKET_NAME` - Google Cloud Storage for cold tier
73+
- `SENTRY_DSN` - Error tracking
74+
- `PORT` - Server port (Railway sets automatically)
75+
76+
### Railway Addons
77+
78+
1. **Redis** (Required for hot tier storage)
79+
- Add via Railway dashboard
80+
- Auto-populates `REDIS_URL`
81+
82+
2. **PostgreSQL** (Optional)
83+
- For persistent metadata
84+
- Auto-populates `DATABASE_URL`
85+
86+
## Storage Tiers on Railway
87+
88+
StackMemory uses a 3-tier storage system optimized for Railway:
89+
90+
1. **Hot Tier (Redis)**
91+
- Recent traces (<24 hours)
92+
- High-score traces
93+
- Railway Redis addon
94+
- LRU eviction, 100MB limit
95+
96+
2. **Warm Tier (Railway Volumes)**
97+
- Mid-age traces (1-30 days)
98+
- Railway persistent volumes
99+
- Compressed storage
100+
101+
3. **Cold Tier (GCS)**
102+
- Old traces (>30 days)
103+
- Google Cloud Storage Coldline
104+
- $0.004/GB/month
105+
106+
## Monitoring
107+
108+
### Health Check
109+
Railway monitors `/health` endpoint:
110+
```javascript
111+
// Automatically included in deployment
112+
app.get('/health', (req, res) => {
113+
res.json({
114+
status: 'healthy',
115+
redis: redisClient.isReady,
116+
storage: storageSystem.status
117+
});
118+
});
119+
```
120+
121+
### Logs
122+
```bash
123+
# View live logs
124+
npm run railway:logs
125+
126+
# Via Railway CLI
127+
railway logs --tail
128+
129+
# Filter by service
130+
railway logs --service stackmemory
131+
```
132+
133+
## Troubleshooting
134+
135+
### Deployment Fails
136+
1. Check GitHub Actions logs
137+
2. Verify secrets are set correctly
138+
3. Ensure tests pass locally: `npm test`
139+
4. Check Railway dashboard for errors
140+
141+
### Redis Connection Issues
142+
1. Verify Redis addon is provisioned
143+
2. Check `REDIS_URL` in environment variables
144+
3. Test locally with Railway proxy:
145+
```bash
146+
railway run npm start
147+
```
148+
149+
### Preview Deployments Not Working
150+
1. Ensure `RAILWAY_TOKEN` has project access
151+
2. Check PR has no merge conflicts
152+
3. Verify GitHub Actions are enabled
153+
154+
## Cost Optimization
155+
156+
### Railway Free Tier
157+
- 500 hours/month execution time
158+
- 100GB bandwidth
159+
- Suitable for development
160+
161+
### Production Recommendations
162+
- Use Railway Pro for production
163+
- Enable auto-scaling for traffic spikes
164+
- Monitor resource usage in dashboard
165+
- Use Redis maxmemory policies
166+
167+
## Security
168+
169+
### Secrets Management
170+
- Never commit `.env` files
171+
- Use Railway's environment variables
172+
- Rotate tokens regularly
173+
- Use read-only tokens where possible
174+
175+
### Network Security
176+
- Railway provides HTTPS by default
177+
- Private networking between services
178+
- IP allowlisting available on Pro plan
179+
180+
## Support
181+
182+
- Railway Discord: https://discord.gg/railway
183+
- Railway Docs: https://docs.railway.app
184+
- StackMemory Issues: https://github.com/stackmemoryai/stackmemory/issues

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@
6262
"status": "node dist/scripts/status.js",
6363
"linear:sync": "node scripts/sync-linear-graphql.js",
6464
"linear:mirror": "node scripts/sync-linear-graphql.js --mirror",
65+
"railway:setup": "./scripts/setup-railway-deployment.sh",
66+
"railway:deploy": "railway up --detach",
67+
"railway:logs": "railway logs",
6568
"tui": "npm run build && node dist/features/tui/index.js",
6669
"tui:dev": "./scripts/dev-tui.sh",
6770
"tui:watch": "npm run build && nodemon --watch src/features/tui --watch src/cli --watch src/skills -e ts --exec 'npm run build && node dist/features/tui/index.js'",

0 commit comments

Comments
 (0)