Skip to content

Autodeployment Improvements #8

Autodeployment Improvements

Autodeployment Improvements #8

Workflow file for this run

name: Deploy to SST
on:
push:
branches: [main]
pull_request:
types: [opened, synchronize, reopened, closed]
permissions:
contents: read
pull-requests: write
issues: write
jobs:
deploy-production:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
environment: production
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Configure AWS credentials
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: ${{ secrets.AWS_REGION }}
- name: Deploy to production
run: |
npx sst deploy --stage production
deploy-preview:
if: github.event_name == 'pull_request' && github.event.action != 'closed'
environment:
name: preview
url: ${{ steps.get-url.outputs.url }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Configure AWS credentials
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: ${{ secrets.AWS_REGION }}
- name: Deploy preview
id: deploy
run: |
npx sst deploy --stage pr-${{ github.event.number }}
- name: Get deployment URL
id: get-url
run: |
# Extract the URL from SST state export
URL=$(npx sst state export --stage pr-${{ github.event.number }} | jq -r '.latest.resources[] | select(.type == "sst:aws:Nextjs") | .outputs._metadata.url')
echo "url=$URL" >> $GITHUB_OUTPUT
- name: Create/Update GitHub Deployment
uses: actions/github-script@v7
with:
script: |
const ref = context.payload.pull_request.head.sha;
const { data: dep } = await github.rest.repos.createDeployment({
owner: context.repo.owner, repo: context.repo.repo, ref,
environment: 'preview', auto_merge: false, required_contexts: []
});
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner, repo: context.repo.repo,
deployment_id: dep.id, state: 'success',
environment_url: '${{ steps.get-url.outputs.url }}'
});
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
// Find existing bot comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('## Preview Deployment')
);
const commentBody = `## Preview Deployment
| Property | Value |
|----------|-------|
| Status | Deployed successfully |
| Preview URL | [${{ steps.get-url.outputs.url }}](${{ steps.get-url.outputs.url }}) |
| Stage | \`pr-${{ github.event.number }}\` |
This preview deployment will be automatically removed when the PR is closed.`;
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: commentBody
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: commentBody
});
}
remove-preview:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
environment: preview
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Configure AWS credentials
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: ${{ secrets.AWS_REGION }}
- name: Remove preview deployment
run: |
npx sst remove --stage pr-${{ github.event.number }}
- name: Mark Deployment Inactive (best-effort)
uses: actions/github-script@v7
with:
script: |
try {
const { data: deployments } = await github.rest.repos.listDeployments({
owner: context.repo.owner, repo: context.repo.repo, environment: 'preview',
sha: context.payload.pull_request?.head?.sha
});
for (const d of deployments) {
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner, repo: context.repo.repo,
deployment_id: d.id, state: 'inactive'
});
}
} catch (e) { core.warning(String(e)); }
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
// Find existing bot comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('## Preview Deployment')
);
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: `## Preview Deployment
| Property | Value |
|----------|-------|
| Status | Removed |
| Stage | \`pr-${{ github.event.number }}\` |
| Cleanup | Completed |
The preview deployment has been automatically removed.`
});
}