Skip to content

Commit dafe09f

Browse files
authored
Merge pull request #62 from aicodingstack/develop
chore: build deploy workflow
2 parents 7fa4933 + 6100784 commit dafe09f

File tree

7 files changed

+245
-123
lines changed

7 files changed

+245
-123
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Cleanup Preview
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
7+
jobs:
8+
cleanup:
9+
name: Delete Preview Deployment
10+
runs-on: ubuntu-latest
11+
permissions:
12+
pull-requests: write
13+
14+
steps:
15+
- name: Delete Preview Deployment
16+
uses: cloudflare/wrangler-action@v3
17+
with:
18+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
19+
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
20+
command: delete --name aicodingstack-pr-${{ github.event.pull_request.number }} --force
21+
continue-on-error: true
22+
23+
- name: Comment Cleanup Status
24+
uses: actions/github-script@v7
25+
with:
26+
script: |
27+
const prNumber = context.payload.pull_request.number;
28+
29+
await github.rest.issues.createComment({
30+
owner: context.repo.owner,
31+
repo: context.repo.repo,
32+
issue_number: prNumber,
33+
body: `### Preview deployment cleaned up\n\nThe preview deployment for PR #${prNumber} has been removed.`
34+
});

.github/workflows/deploy-preview.yml

Lines changed: 102 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,57 @@ name: Deploy Preview
22

33
on:
44
pull_request:
5-
branches: [main]
5+
push:
6+
branches-ignore: [main, develop]
67

78
concurrency:
8-
group: preview-${{ github.ref }}
9+
group: preview-${{ github.event.pull_request.number || github.ref_name }}
910
cancel-in-progress: true
1011

1112
jobs:
12-
deploy-preview:
13-
name: Deploy Preview to Cloudflare Pages
13+
deploy:
14+
name: Deploy Preview to Cloudflare Workers
1415
runs-on: ubuntu-latest
1516
permissions:
1617
contents: read
1718
pull-requests: write
19+
deployments: write
20+
1821
steps:
1922
- name: Checkout code
2023
uses: actions/checkout@v6
2124

25+
- name: Compute preview identifiers
26+
id: preview_meta
27+
run: |
28+
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
29+
CF_BRANCH="pr-${{ github.event.pull_request.number }}"
30+
CONTEXT_LABEL="PR #${{ github.event.pull_request.number }}"
31+
else
32+
RAW_BRANCH="${{ github.ref_name }}"
33+
SLUG="$(echo "$RAW_BRANCH" | tr '[:upper:]' '[:lower:]' | sed -E 's#[^a-z0-9]+#-#g; s#(^-+|-+$)##g' | cut -c1-40)"
34+
if [[ -z "$SLUG" ]]; then
35+
SLUG="branch"
36+
fi
37+
CF_BRANCH="br-$SLUG"
38+
CONTEXT_LABEL="Branch $RAW_BRANCH"
39+
fi
40+
41+
# Cloudflare Preview URLs (aliased) format:
42+
# <ALIAS>-<WORKER_NAME>.<SUBDOMAIN>.workers.dev
43+
# See: https://developers.cloudflare.com/workers/configuration/previews/
44+
PREVIEW_ALIAS="$CF_BRANCH"
45+
WORKER_NAME="aicodingstack"
46+
PREVIEW_URL="https://${PREVIEW_ALIAS}-${WORKER_NAME}.pr-preview.workers.dev"
47+
48+
{
49+
echo "cf_branch=$CF_BRANCH"
50+
echo "worker_name=$WORKER_NAME"
51+
echo "preview_alias=$PREVIEW_ALIAS"
52+
echo "preview_url=$PREVIEW_URL"
53+
echo "context_label=$CONTEXT_LABEL"
54+
} >> "$GITHUB_OUTPUT"
55+
2256
- name: Setup Node.js
2357
uses: actions/setup-node@v6
2458
with:
@@ -28,61 +62,72 @@ jobs:
2862
- name: Install dependencies
2963
run: npm ci
3064

31-
- name: Run validation tests
32-
run: npm run test:validate
33-
34-
- name: Generate manifests and metadata
35-
run: |
36-
npm run generate:manifests
37-
npm run generate:metadata
65+
- name: Run CI tests
66+
run: npm run test:ci
3867

3968
- name: Build with OpenNext
4069
run: npm run build
4170
env:
42-
BUILD_TIME: ${{ github.event.pull_request.updated_at }}
43-
44-
# TODO: Configure Cloudflare Pages deployment
45-
# You'll need to add these secrets to your repository:
46-
# - CLOUDFLARE_API_TOKEN
47-
# - CLOUDFLARE_ACCOUNT_ID
48-
#
49-
# Uncomment the steps below after adding the secrets:
50-
#
51-
# - name: Deploy to Cloudflare Pages (Preview)
52-
# id: deploy
53-
# uses: cloudflare/wrangler-action@v3
54-
# with:
55-
# apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
56-
# accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
57-
# command: pages deploy .open-next --project-name=aicodingstack --branch=preview-${{ github.event.pull_request.number }}
58-
#
59-
# - name: Comment preview URL
60-
# uses: actions/github-script@v7
61-
# with:
62-
# script: |
63-
# const previewUrl = '${{ steps.deploy.outputs.deployment-url }}';
64-
# const comment = `## 🚀 Preview Deployment
65-
#
66-
# Preview is ready!
67-
#
68-
# **Preview URL:** ${previewUrl}
69-
#
70-
# ### Build Details
71-
# - **Commit:** ${context.sha.substring(0, 7)}
72-
# - **Build Time:** ${{ github.event.pull_request.updated_at }}
73-
#
74-
# The preview will be automatically deleted when this PR is merged or closed.`;
75-
#
76-
# github.rest.issues.createComment({
77-
# issue_number: context.issue.number,
78-
# owner: context.repo.owner,
79-
# repo: context.repo.repo,
80-
# body: comment
81-
# });
82-
83-
- name: Preview deployment placeholder
71+
BUILD_TIME: ${{ github.event.pull_request.updated_at || github.event.head_commit.timestamp }}
72+
73+
- name: Deploy Preview
74+
uses: cloudflare/wrangler-action@v3
75+
with:
76+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
77+
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
78+
command: versions upload --preview-alias ${{ steps.preview_meta.outputs.preview_alias }}
79+
80+
- name: Comment Preview URL
81+
if: github.event_name == 'pull_request'
82+
uses: actions/github-script@v7
83+
env:
84+
PREVIEW_URL: ${{ steps.preview_meta.outputs.preview_url }}
85+
with:
86+
script: |
87+
const prNumber = context.payload.pull_request.number;
88+
const previewUrl = process.env.PREVIEW_URL;
89+
const commitSha = context.sha.substring(0, 7);
90+
91+
// Find existing bot comment
92+
const { data: comments } = await github.rest.issues.listComments({
93+
owner: context.repo.owner,
94+
repo: context.repo.repo,
95+
issue_number: prNumber,
96+
});
97+
98+
const botComment = comments.find(c =>
99+
c.user.type === 'Bot' && c.body.includes('Preview deployment')
100+
);
101+
102+
const body = `### Preview deployment
103+
104+
| Status | URL |
105+
|--------|-----|
106+
| Ready | [${previewUrl}](${previewUrl}) |
107+
108+
**Commit:** \`${commitSha}\`
109+
**Updated:** ${new Date().toISOString()}`;
110+
111+
if (botComment) {
112+
await github.rest.issues.updateComment({
113+
owner: context.repo.owner,
114+
repo: context.repo.repo,
115+
comment_id: botComment.id,
116+
body
117+
});
118+
} else {
119+
await github.rest.issues.createComment({
120+
owner: context.repo.owner,
121+
repo: context.repo.repo,
122+
issue_number: prNumber,
123+
body
124+
});
125+
}
126+
127+
- name: Deployment summary
84128
run: |
85-
echo "⚠️ Preview deployment not yet configured"
86-
echo "To enable preview deployments:"
87-
echo "1. Add CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID to repository secrets"
88-
echo "2. Uncomment the deployment steps in .github/workflows/deploy-preview.yml"
129+
echo "### Preview Deployment" >> $GITHUB_STEP_SUMMARY
130+
echo "" >> $GITHUB_STEP_SUMMARY
131+
echo "- **Context:** ${{ steps.preview_meta.outputs.context_label }}" >> $GITHUB_STEP_SUMMARY
132+
echo "- **URL:** ${{ steps.preview_meta.outputs.preview_url }}" >> $GITHUB_STEP_SUMMARY
133+
echo "- **Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY

.github/workflows/deploy-production.yml

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,20 @@ on:
55
branches: [main]
66

77
concurrency:
8-
group: production
8+
group: production-deploy
99
cancel-in-progress: false
1010

1111
jobs:
1212
deploy-production:
13-
name: Deploy to Cloudflare Pages
13+
name: Deploy to Cloudflare Workers
1414
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
deployments: write
1518
environment:
1619
name: production
1720
url: https://aicodingstack.io
21+
1822
steps:
1923
- name: Checkout code
2024
uses: actions/checkout@v6
@@ -28,45 +32,25 @@ jobs:
2832
- name: Install dependencies
2933
run: npm ci
3034

31-
- name: Run validation tests
32-
run: npm run test:validate
33-
34-
- name: Generate manifests and metadata
35-
run: |
36-
npm run generate:manifests
37-
npm run generate:metadata
35+
- name: Run CI tests
36+
run: npm run test:ci
3837

3938
- name: Build with OpenNext
4039
run: npm run build
4140
env:
4241
BUILD_TIME: ${{ github.event.head_commit.timestamp }}
4342

44-
# TODO: Configure Cloudflare Pages deployment
45-
# You'll need to add these secrets to your repository:
46-
# - CLOUDFLARE_API_TOKEN
47-
# - CLOUDFLARE_ACCOUNT_ID
48-
#
49-
# Uncomment the steps below after adding the secrets:
50-
#
51-
# - name: Deploy to Cloudflare Pages (Production)
52-
# uses: cloudflare/wrangler-action@v3
53-
# with:
54-
# apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
55-
# accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
56-
# command: pages deploy .open-next --project-name=aicodingstack --branch=main
57-
#
58-
# - name: Notify deployment success
59-
# run: |
60-
# echo "✅ Production deployment successful!"
61-
# echo "🌐 Site: https://aicodingstack.io"
62-
# echo "📝 Commit: ${{ github.sha }}"
43+
- name: Deploy to Production
44+
uses: cloudflare/wrangler-action@v3
45+
with:
46+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
47+
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
48+
command: deploy --env production
6349

64-
- name: Production deployment placeholder
50+
- name: Deployment summary
6551
run: |
66-
echo "⚠️ Production deployment not yet configured"
67-
echo "To enable production deployments:"
68-
echo "1. Add CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID to repository secrets"
69-
echo "2. Uncomment the deployment steps in .github/workflows/deploy-production.yml"
70-
echo ""
71-
echo "Manual deployment command:"
72-
echo "npm run deploy"
52+
echo "### Production Deployment" >> $GITHUB_STEP_SUMMARY
53+
echo "" >> $GITHUB_STEP_SUMMARY
54+
echo "- **URL:** https://aicodingstack.io" >> $GITHUB_STEP_SUMMARY
55+
echo "- **Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
56+
echo "- **Time:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Deploy Staging
2+
3+
on:
4+
push:
5+
branches: [develop]
6+
7+
concurrency:
8+
group: staging-deploy
9+
cancel-in-progress: true
10+
11+
jobs:
12+
deploy-staging:
13+
name: Deploy to Cloudflare Workers (Staging)
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
deployments: write
18+
environment:
19+
name: staging
20+
url: https://staging.aicodingstack.io
21+
22+
steps:
23+
- name: Checkout code
24+
uses: actions/checkout@v6
25+
26+
- name: Setup Node.js
27+
uses: actions/setup-node@v6
28+
with:
29+
node-version: '22'
30+
cache: 'npm'
31+
32+
- name: Install dependencies
33+
run: npm ci
34+
35+
- name: Run CI tests
36+
run: npm run test:ci
37+
38+
- name: Build with OpenNext
39+
run: npm run build
40+
env:
41+
BUILD_TIME: ${{ github.event.head_commit.timestamp }}
42+
43+
- name: Deploy to Staging
44+
uses: cloudflare/wrangler-action@v3
45+
with:
46+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
47+
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
48+
command: deploy --env staging
49+
50+
- name: Deployment summary
51+
run: |
52+
echo "### Staging Deployment" >> $GITHUB_STEP_SUMMARY
53+
echo "" >> $GITHUB_STEP_SUMMARY
54+
echo "- **URL:** https://staging.aicodingstack.io" >> $GITHUB_STEP_SUMMARY
55+
echo "- **Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
56+
echo "- **Time:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ next-env.d.ts
4747
!.env.example
4848

4949
# claude settings
50-
.claude/settings.local.json
50+
.claude/settings.local*.json
5151

5252
# python cache
5353
__pycache__/

0 commit comments

Comments
 (0)