CI/CD for Serverless with GitHub Actions
Automate your serverless deployments using GitHub Actions. This guide covers setting up continuous integration and deployment pipelines for staging, production, and preview environments.
Prerequisites
Before setting up CI/CD, you'll need:
- Personal Access Token (PAT) from Boltic Console
- Account ID from your Boltic account settings
- A GitHub repository with your serverless code
- A working serverless function (see Build an API with Boltic Tables)
Step 1: Generate a Personal Access Token
- Go to Boltic Console > Settings > Access Tokens
- Click Generate New Token
- Give it a descriptive name (e.g.,
github-actions-deploy) - Set appropriate expiration
- Copy the token (you won't see it again)
Step 2: Configure GitHub Secrets
Add the following secrets to your GitHub repository:
- Go to Repository > Settings > Secrets and variables > Actions
- Click New repository secret
- Add these secrets:
| Secret Name | Description |
|---|---|
BOLTIC_TOKEN | Your Personal Access Token |
BOLTIC_ACCOUNT_ID | Your Boltic Account ID |
DATABASE_URL | PostgreSQL connection string (optional) |
Step 3: Basic Deployment Workflow
Create .github/workflows/deploy.yml in your repository:
name: Deploy Serverless
on:
push:
branches:
- main
workflow_dispatch: # Allow manual triggers
env:
NODE_VERSION: '20'
SERVERLESS_NAME: 'tasks-api'
jobs:
deploy:
name: Deploy to Boltic
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Install Boltic CLI
run: npm install -g @boltic/cli
- name: Authenticate with Boltic
run: boltic login --token ${{ secrets.BOLTIC_TOKEN }} --account-id ${{ secrets.BOLTIC_ACCOUNT_ID }}
- name: Deploy serverless function
run: boltic serverless publish
- name: Verify deployment
run: |
echo "Waiting for deployment to be ready..."
sleep 10
boltic serverless status --name ${{ env.SERVERLESS_NAME }} --watch
Step 4: Multi-Environment Workflow
For teams with staging and production environments, use this comprehensive workflow.
Create .github/workflows/deploy-environments.yml:
name: Deploy Serverless (Multi-Environment)
on:
push:
branches:
- main # Deploy to production
- develop # Deploy to staging
pull_request:
branches:
- main
types: [opened, synchronize]
env:
NODE_VERSION: '20'
jobs:
# ============================================================================
# Lint and Test
# ============================================================================
test:
name: Lint & Test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint --if-present
- name: Run tests
run: npm test --if-present
# ============================================================================
# Deploy to Staging
# ============================================================================
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/heads/develop' && github.event_name == 'push'
environment:
name: staging
url: https://tasks-api-staging.boltic.app
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Install Boltic CLI
run: npm install -g @boltic/cli
- name: Authenticate with Boltic
run: boltic login --token ${{ secrets.BOLTIC_TOKEN }} --account-id ${{ secrets.BOLTIC_ACCOUNT_ID }}
- name: Update config for staging
run: |
# Update serverless name for staging
sed -i 's/Name: "tasks-api"/Name: "tasks-api-staging"/' boltic.yaml
sed -i 's/app: "tasks-api"/app: "tasks-api-staging"/' boltic.yaml
- name: Deploy to staging
run: boltic serverless publish
- name: Wait for deployment
run: |
echo "Waiting for staging deployment..."
for i in {1..30}; do
STATUS=$(boltic serverless status --name tasks-api-staging 2>/dev/null | grep -i "status" | head -1 || echo "pending")
if echo "$STATUS" | grep -qi "running"; then
echo "✓ Staging deployment successful!"
exit 0
fi
echo "Attempt $i/30: $STATUS"
sleep 10
done
echo "Deployment did not reach running state"
exit 1
- name: Health check
run: |
HEALTH_URL="https://tasks-api-staging.boltic.app/health"
echo "Checking health at $HEALTH_URL"
curl -sf "$HEALTH_URL" || (echo "Health check failed" && exit 1)
echo "✓ Health check passed!"
# ============================================================================
# Deploy to Production
# ============================================================================
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
environment:
name: production
url: https://tasks-api.boltic.app
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Install Boltic CLI
run: npm install -g @boltic/cli
- name: Authenticate with Boltic
run: boltic login --token ${{ secrets.BOLTIC_TOKEN }} --account-id ${{ secrets.BOLTIC_ACCOUNT_ID }}
- name: Deploy to production
run: boltic serverless publish
- name: Wait for deployment
run: |
echo "Waiting for production deployment..."
for i in {1..30}; do
STATUS=$(boltic serverless status --name tasks-api 2>/dev/null | grep -i "status" | head -1 || echo "pending")
if echo "$STATUS" | grep -qi "running"; then
echo "✓ Production deployment successful!"
exit 0
fi
echo "Attempt $i/30: $STATUS"
sleep 10
done
echo "Deployment did not reach running state"
exit 1
- name: Health check
run: |
HEALTH_URL="https://tasks-api.boltic.app/health"
echo "Checking health at $HEALTH_URL"
curl -sf "$HEALTH_URL" || (echo "Health check failed" && exit 1)
echo "✓ Health check passed!"
- name: Notify on success
if: success()
run: echo "🚀 Production deployment completed successfully!"
- name: Notify on failure
if: failure()
run: echo "❌ Production deployment failed!"
Step 5: Pull Request Preview Deployments
Deploy preview environments for each pull request.
Create .github/workflows/preview.yml:
name: Preview Deployment
on:
pull_request:
types: [opened, synchronize, reopened]
env:
NODE_VERSION: '20'
jobs:
deploy-preview:
name: Deploy Preview
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Install Boltic CLI
run: npm install -g @boltic/cli
- name: Authenticate with Boltic
run: boltic login --token ${{ secrets.BOLTIC_TOKEN }} --account-id ${{ secrets.BOLTIC_ACCOUNT_ID }}
- name: Create preview deployment
id: preview
run: |
PREVIEW_NAME="tasks-api-pr-${{ github.event.pull_request.number }}"
echo "preview_name=$PREVIEW_NAME" >> $GITHUB_OUTPUT
# Update config for preview
sed -i "s/Name: \"tasks-api\"/Name: \"$PREVIEW_NAME\"/" boltic.yaml
sed -i "s/app: \"tasks-api\"/app: \"$PREVIEW_NAME\"/" boltic.yaml
# Deploy preview
boltic serverless publish
echo "preview_url=https://$PREVIEW_NAME.boltic.app" >> $GITHUB_OUTPUT
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 🚀 Preview Deployment Ready!
| Environment | URL |
|-------------|-----|
| Preview | [${{ steps.preview.outputs.preview_name }}](${{ steps.preview.outputs.preview_url }}) |
### Test endpoints:
- Health: \`${{ steps.preview.outputs.preview_url }}/health\`
- Tasks: \`${{ steps.preview.outputs.preview_url }}/tasks\`
_This preview will be automatically cleaned up when the PR is closed._`
})
# Cleanup preview on PR close
cleanup-preview:
name: Cleanup Preview
runs-on: ubuntu-latest
if: github.event.action == 'closed'
steps:
- name: Install Boltic CLI
run: npm install -g @boltic/cli
- name: Authenticate with Boltic
run: boltic login --token ${{ secrets.BOLTIC_TOKEN }} --account-id ${{ secrets.BOLTIC_ACCOUNT_ID }}
- name: Delete preview deployment
run: |
PREVIEW_NAME="tasks-api-pr-${{ github.event.pull_request.number }}"
echo "Cleaning up preview: $PREVIEW_NAME"
# Note: Add delete command when available
# boltic serverless delete --name $PREVIEW_NAME
Step 6: Scheduled Deployments
For scheduled deployments (e.g., nightly builds).
Create .github/workflows/scheduled-deploy.yml:
name: Scheduled Deployment
on:
schedule:
# Run at 2 AM UTC every day
- cron: '0 2 * * *'
workflow_dispatch:
jobs:
scheduled-deploy:
name: Nightly Deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: main
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Install Boltic CLI
run: npm install -g @boltic/cli
- name: Authenticate with Boltic
run: boltic login --token ${{ secrets.BOLTIC_TOKEN }} --account-id ${{ secrets.BOLTIC_ACCOUNT_ID }}
- name: Deploy
run: boltic serverless publish
- name: Verify deployment
run: boltic serverless status --name tasks-api
Workflow Triggers Summary
| Trigger | Workflow | Environment |
|---|---|---|
Push to main | deploy-environments.yml | Production |
Push to develop | deploy-environments.yml | Staging |
| Pull Request | preview.yml | Preview (ephemeral) |
| Manual | deploy.yml | Configurable |
| Scheduled (cron) | scheduled-deploy.yml | Production |
Best Practices
1. Use GitHub Environments
- Configure environment protection rules
- Require approvals for production deployments
- Set environment-specific secrets
2. Implement Health Checks
- Always verify deployments with health endpoints
- Fail the pipeline if health checks don't pass
3. Version Your Deployments
- Tag releases with semantic versioning
- Include commit SHA in deployment metadata
4. Monitor Build Logs
# View build logs in case of failures
boltic serverless builds --name tasks-api
boltic serverless build logs --name tasks-api --build <BUILD_ID>
5. Rollback Strategy
- Keep previous deployments available
- Document rollback procedures
- Consider blue-green deployments for zero-downtime
Troubleshooting
Authentication Failures
Error: Authentication failed
Solutions:
- Verify
BOLTIC_TOKENsecret is correct and not expired - Check
BOLTIC_ACCOUNT_IDmatches your account - Regenerate PAT if needed
Deployment Timeouts
Error: Deployment did not reach running state
Solutions:
- Check build logs:
boltic serverless builds --name <name> - Increase wait time in workflow
- Verify
boltic.yamlconfiguration
Permission Errors
Error: Insufficient permissions
Solutions:
- Verify PAT has deployment permissions
- Check account access levels
- Contact your Boltic administrator
CLI Commands Reference
# Authentication (for CI/CD)
boltic login --token <PAT> --account-id <ACCOUNT_ID>
# Deploy
boltic serverless publish
# Check status
boltic serverless status --name <name>
# View logs
boltic serverless logs --name <name>
# View builds
boltic serverless builds --name <name>
boltic serverless build logs --name <name> --build <BUILD_ID>