GitHub Actions for automatic deployments
Deployment Automation
Automate deployments with GitHub Actions.
Flow: git push → Build → Deploy → Invalidate CDN
GitHub Actions Workflows
- Basic Deploy
- Multi-Environment
Create .github/workflows/deploy.yml:
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Install Dependencies
run: yarn install
- name: Build Site
run: ./bin/astrolock build
- name: Configure AWS
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy
run: ./bin/astrolock deploy aws --executeDeploy to stage on PR, live on merge:
name: Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
deploy-stage:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Install and Build
run: |
yarn install
./bin/astrolock build
- name: Configure AWS
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to Stage
run: ./bin/astrolock deploy aws --stage --execute
deploy-live:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Install and Build
run: |
yarn install
./bin/astrolock build
- name: Configure AWS
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to Live
run: ./bin/astrolock deploy aws --live --executeCreate .github/workflows/deploy.yml:
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Install Dependencies
run: yarn install
- name: Build Site
run: ./bin/astrolock build
- name: Configure AWS
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy
run: ./bin/astrolock deploy aws --executeDeploy to stage on PR, live on merge:
name: Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
deploy-stage:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Install and Build
run: |
yarn install
./bin/astrolock build
- name: Configure AWS
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to Stage
run: ./bin/astrolock deploy aws --stage --execute
deploy-live:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Install and Build
run: |
yarn install
./bin/astrolock build
- name: Configure AWS
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to Live
run: ./bin/astrolock deploy aws --live --executeRequired Secrets
Add these in GitHub repository Settings → Secrets and variables → Actions:
- AWS
- Netlify
- Vercel
| Secret | Description |
|---|---|
AWS_ACCESS_KEY_ID | IAM user access key |
AWS_SECRET_ACCESS_KEY | IAM user secret key |
| Secret | Description |
|---|---|
NETLIFY_AUTH_TOKEN | Personal access token |
NETLIFY_SITE_ID | Site ID from Netlify dashboard |
| Secret | Description |
|---|---|
VERCEL_TOKEN | Personal access token |
VERCEL_ORG_ID | Organization ID |
VERCEL_PROJECT_ID | Project ID |
| Secret | Description |
|---|---|
AWS_ACCESS_KEY_ID | IAM user access key |
AWS_SECRET_ACCESS_KEY | IAM user secret key |
| Secret | Description |
|---|---|
NETLIFY_AUTH_TOKEN | Personal access token |
NETLIFY_SITE_ID | Site ID from Netlify dashboard |
| Secret | Description |
|---|---|
VERCEL_TOKEN | Personal access token |
VERCEL_ORG_ID | Organization ID |
VERCEL_PROJECT_ID | Project ID |
Platform-Specific Workflows
name: Deploy to Netlify
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Install and Build
run: |
yarn install
./bin/astrolock build
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v2
with:
publish-dir: './dist'
production-branch: main
deploy-message: "Deploy from GitHub Actions"
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}name: Deploy to Vercel
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Install and Build
run: |
yarn install
./bin/astrolock build
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
working-directory: ./distUse the Astrolock Docker image for consistent builds:
name: Deploy (Docker)
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
container:
image: astrolock/astrolock:latest
steps:
- uses: actions/checkout@v4
- name: Build Site
run: astrolock build
- name: Configure AWS
run: |
mkdir -p ~/.aws
echo "[default]" > ~/.aws/credentials
echo "aws_access_key_id=${{ secrets.AWS_ACCESS_KEY_ID }}" >> ~/.aws/credentials
echo "aws_secret_access_key=${{ secrets.AWS_SECRET_ACCESS_KEY }}" >> ~/.aws/credentials
- name: Deploy
run: astrolock deploy aws --executeIAM User for CI/CD
Info
Create a dedicated IAM user for GitHub Actions with minimal permissions.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
]
},
{
"Effect": "Allow",
"Action": [
"cloudfront:CreateInvalidation"
],
"Resource": "arn:aws:cloudfront::*:distribution/*"
}
]
}Setup Steps
- Create IAM user in AWS Console
- Attach policy with permissions above
- Create access key for the user
- Add to GitHub Secrets as
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY
Caching for Faster Builds
Add caching to speed up subsequent builds:
- name: Cache Node Modules
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install Dependencies
run: yarn install --frozen-lockfileTroubleshooting
- Build Fails
- Permission Denied
- CloudFront Not Updating
- Workflow Not Triggering
# Add verbose output
- name: Build Site
run: ./bin/astrolock build --verboseCheck:
- IAM user has correct permissions
- Bucket name matches in policy
- Secrets are correctly set in GitHub
Ensure invalidation is included:
./bin/astrolock deploy aws --execute
# This automatically invalidates CloudFrontCheck:
- Workflow file is in
.github/workflows/ - Branch name matches trigger
- YAML syntax is valid
# Add verbose output
- name: Build Site
run: ./bin/astrolock build --verboseCheck:
- IAM user has correct permissions
- Bucket name matches in policy
- Secrets are correctly set in GitHub
Ensure invalidation is included:
./bin/astrolock deploy aws --execute
# This automatically invalidates CloudFrontCheck:
- Workflow file is in
.github/workflows/ - Branch name matches trigger
- YAML syntax is valid