Skip to content

Commit cb077d2

Browse files
authored
Merge pull request #3 from devakone/develop
Release: develop → main
2 parents b7ef6e9 + 9d1ac8b commit cb077d2

163 files changed

Lines changed: 37887 additions & 4677 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
## Summary
2+
3+
<!-- Brief description of what this PR does -->
4+
5+
## Type of Change
6+
7+
- [ ] 🐛 Bug fix (non-breaking change that fixes an issue)
8+
- [ ] ✨ New feature (non-breaking change that adds functionality)
9+
- [ ] 💥 Breaking change (fix or feature that would cause existing functionality to change)
10+
- [ ] 📚 Documentation update
11+
- [ ] 🔧 Configuration/infrastructure change
12+
- [ ] ♻️ Refactor (no functional changes)
13+
14+
## Changes
15+
16+
<!-- List the key changes made -->
17+
18+
-
19+
20+
## Testing
21+
22+
<!-- How was this tested? -->
23+
24+
- [ ] Tested locally
25+
- [ ] Tested on Preview deployment
26+
27+
## Database Migrations
28+
29+
<!-- If applicable, list any new migrations -->
30+
31+
- [ ] No migrations
32+
- [ ] Migration: `00XXX_name.sql`
33+
34+
## Checklist
35+
36+
- [ ] Code follows project conventions
37+
- [ ] Self-reviewed my own code
38+
- [ ] Lint passes (`npm run lint`)
39+
- [ ] Type check passes (`npm run type-check`)
40+
- [ ] Build passes (`npm run build`)
41+
- [ ] Updated documentation (if needed)
42+
43+
## Screenshots
44+
45+
<!-- If UI changes, add screenshots -->
46+
47+
## Related Issues
48+
49+
<!-- Link any related issues: Fixes #123, Closes #456 -->
50+

.github/workflows/ci.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- develop
7+
- main
8+
pull_request:
9+
branches:
10+
- develop
11+
- main
12+
13+
jobs:
14+
lint-and-build:
15+
runs-on: ubuntu-latest
16+
env:
17+
NEXT_PUBLIC_SUPABASE_URL: https://example.supabase.co
18+
NEXT_PUBLIC_SUPABASE_ANON_KEY: stub-anon-key
19+
SUPABASE_SERVICE_ROLE_KEY: stub-service-role-key
20+
POSTMARK_SERVER_TOKEN: stub-postmark-token
21+
POSTMARK_FROM_EMAIL: noreply@example.com
22+
POSTMARK_REPLY_TO_DOMAIN: reply.example.com
23+
LLM_ENCRYPTION_KEY: stub-llm-encryption-key
24+
OPENAI_MODEL: gpt-4o-mini
25+
LINKEDIN_CLIENT_ID: stub-linkedin-client-id
26+
LINKEDIN_CLIENT_SECRET: stub-linkedin-client-secret
27+
LINKEDIN_REDIRECT_URI: https://example.com
28+
NEXT_PUBLIC_VAPID_PUBLIC_KEY: stub-vapid-public-key
29+
VAPID_PUBLIC_KEY: stub-vapid-public-key
30+
VAPID_PRIVATE_KEY: stub-vapid-private-key
31+
VAPID_SUBJECT: mailto:example@example.com
32+
NOTIFICATION_SCHEDULER_TOKEN: stub-scheduler-token
33+
TWILIO_ACCOUNT_SID: stub-twilio-sid
34+
TWILIO_AUTH_TOKEN: stub-twilio-token
35+
TWILIO_PHONE_NUMBER: +15555555555
36+
37+
steps:
38+
- name: Checkout repository
39+
uses: actions/checkout@v4
40+
with:
41+
fetch-depth: 0
42+
fetch-tags: true
43+
44+
- name: Set up Node
45+
uses: actions/setup-node@v4
46+
with:
47+
node-version: 22.13.0
48+
cache: 'npm'
49+
50+
- name: Install dependencies
51+
run: npm ci
52+
53+
- name: Build
54+
run: npm run build
55+
56+
- name: Lint
57+
run: npm run lint
58+
59+
- name: Type check
60+
run: npm run type-check
61+
62+
- name: Test
63+
run: npm run test
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Release Please
2+
3+
on:
4+
push:
5+
branches:
6+
- develop
7+
- main
8+
9+
permissions:
10+
contents: write
11+
pull-requests: write
12+
13+
jobs:
14+
release-please:
15+
runs-on: ubuntu-latest
16+
outputs:
17+
releases_created: ${{ steps.release.outputs.releases_created }}
18+
web_release_created: ${{ steps.release.outputs['apps/web--release_created'] }}
19+
web_tag_name: ${{ steps.release.outputs['apps/web--tag_name'] }}
20+
web_version: ${{ steps.release.outputs['apps/web--version'] }}
21+
worker_release_created: ${{ steps.release.outputs['apps/worker--release_created'] }}
22+
worker_tag_name: ${{ steps.release.outputs['apps/worker--tag_name'] }}
23+
worker_version: ${{ steps.release.outputs['apps/worker--version'] }}
24+
root_release_created: ${{ steps.release.outputs['release_created'] }}
25+
root_tag_name: ${{ steps.release.outputs['tag_name'] }}
26+
root_version: ${{ steps.release.outputs['version'] }}
27+
28+
steps:
29+
- name: Determine config and manifest files
30+
id: config-file
31+
run: |
32+
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
33+
echo "config_file=release-please-config.json" >> $GITHUB_OUTPUT
34+
echo "manifest_file=.release-please-manifest.json" >> $GITHUB_OUTPUT
35+
elif [[ "${{ github.ref }}" == "refs/heads/develop" ]]; then
36+
echo "config_file=release-please-config.develop.json" >> $GITHUB_OUTPUT
37+
echo "manifest_file=.release-please-manifest.develop.json" >> $GITHUB_OUTPUT
38+
else
39+
echo "config_file=release-please-config.json" >> $GITHUB_OUTPUT
40+
echo "manifest_file=.release-please-manifest.json" >> $GITHUB_OUTPUT
41+
fi
42+
43+
- name: Release Please
44+
id: release
45+
uses: googleapis/release-please-action@v4
46+
with:
47+
token: ${{ secrets.GITHUB_TOKEN }}
48+
config-file: ${{ steps.config-file.outputs.config_file }}
49+
manifest-file: ${{ steps.config-file.outputs.manifest_file }}
50+
target-branch: ${{ github.ref_name }}
51+
52+
- name: Log release info
53+
if: ${{ steps.release.outputs.releases_created == 'true' }}
54+
run: |
55+
echo "🚀 Release created!"
56+
echo "Web release: ${{ steps.release.outputs['apps/web--release_created'] }}"
57+
echo "Web version: ${{ steps.release.outputs['apps/web--version'] }}"
58+
echo "Worker release: ${{ steps.release.outputs['apps/worker--release_created'] }}"
59+
echo "Worker version: ${{ steps.release.outputs['apps/worker--version'] }}"
60+
echo "Root release: ${{ steps.release.outputs['release_created'] }}"
61+
echo "Root version: ${{ steps.release.outputs['version'] }}"

.github/workflows/release-pr.yml

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
name: Sync Release Pull Request
2+
3+
on:
4+
push:
5+
branches:
6+
- develop
7+
8+
jobs:
9+
sync-release-pr:
10+
name: Create or update develop → main PR
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: write
14+
pull-requests: write
15+
steps:
16+
- uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
20+
- name: Open or update release PR
21+
env:
22+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23+
PR_TITLE: "Release: develop → main"
24+
PR_TEMPLATE: .github/PULL_REQUEST_TEMPLATE.md
25+
run: |
26+
set -euo pipefail
27+
28+
if [ ! -f "$PR_TEMPLATE" ]; then
29+
echo "Pull request template not found at $PR_TEMPLATE"
30+
exit 1
31+
fi
32+
33+
git fetch origin main --prune
34+
35+
BODY_FILE="$(mktemp)"
36+
export BODY_FILE
37+
38+
python3 - <<'PY'
39+
import os
40+
import re
41+
import subprocess
42+
43+
template_path = os.environ["PR_TEMPLATE"]
44+
body_file_path = os.environ["BODY_FILE"]
45+
46+
# Get commits that are in develop but not in main
47+
log = subprocess.check_output(
48+
["git", "log", "--pretty=format:%s (%h)", "origin/main..HEAD", "--no-merges"],
49+
text=True,
50+
).strip().splitlines()
51+
52+
# Filter out empty lines
53+
log = [line for line in log if line.strip()]
54+
55+
max_items = 60
56+
items = log[:max_items]
57+
extra = max(len(log) - len(items), 0)
58+
59+
if items:
60+
bullets = [f"- {line}" for line in items]
61+
if extra:
62+
bullets.append(f"- …and {extra} more commits")
63+
else:
64+
bullets = ["- No new changes since last release"]
65+
66+
with open(template_path, "r", encoding="utf-8") as f:
67+
content = f.read()
68+
lines = content.splitlines()
69+
70+
# Find the Changes section and replace the placeholder
71+
if "## Changes" in lines:
72+
header_index = lines.index("## Changes")
73+
74+
# Find the next section header
75+
end_index = len(lines)
76+
for i in range(header_index + 1, len(lines)):
77+
if lines[i].startswith("## "):
78+
end_index = i
79+
break
80+
81+
# Extract section content
82+
section = lines[header_index + 1 : end_index]
83+
84+
# Find and replace the placeholder bullet point
85+
replaced = False
86+
for idx, line in enumerate(section):
87+
# Match empty bullet point (with optional whitespace)
88+
if re.fullmatch(r"-\s*", line.strip()) or line.strip() == "-":
89+
section = section[:idx] + bullets + section[idx + 1 :]
90+
replaced = True
91+
break
92+
93+
if not replaced:
94+
# If no placeholder found, insert bullets after empty lines/comments
95+
insert_idx = 0
96+
for idx, line in enumerate(section):
97+
if line.strip() and not line.strip().startswith("<!--"):
98+
insert_idx = idx
99+
break
100+
insert_idx = idx + 1
101+
section = section[:insert_idx] + bullets + section[insert_idx:]
102+
103+
final_lines = lines[: header_index + 1] + section + lines[end_index:]
104+
else:
105+
# If no Changes section exists, append one
106+
final_lines = lines + ["", "## Changes", ""] + bullets
107+
108+
with open(body_file_path, "w", encoding="utf-8") as f:
109+
f.write("\n".join(final_lines).rstrip() + "\n")
110+
111+
# Debug: print the generated body
112+
print("Generated PR body:")
113+
print("-" * 40)
114+
with open(body_file_path, "r") as f:
115+
print(f.read())
116+
print("-" * 40)
117+
PY
118+
119+
PR_NUMBER="$(gh pr list --base main --head develop --state open --json number --jq '.[0].number // empty')"
120+
121+
if [ -n "$PR_NUMBER" ]; then
122+
echo "Updating existing PR #$PR_NUMBER"
123+
gh pr edit "$PR_NUMBER" \
124+
--title "$PR_TITLE" \
125+
--body-file "$BODY_FILE"
126+
else
127+
echo "Creating new release PR"
128+
gh pr create \
129+
--base main \
130+
--head develop \
131+
--title "$PR_TITLE" \
132+
--body-file "$BODY_FILE"
133+
fi
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Supabase Migrations
2+
3+
on:
4+
push:
5+
branches:
6+
- develop
7+
- main
8+
paths:
9+
- 'supabase/migrations/**'
10+
11+
jobs:
12+
run-migrations:
13+
runs-on: ubuntu-latest
14+
environment: ${{ github.ref == 'refs/heads/main' && 'Production' || 'Preview' }}
15+
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0 # Need full history to check for migration changes
21+
22+
- name: Check for migration changes
23+
id: check-migrations
24+
run: |
25+
if git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -q '^supabase/migrations/'; then
26+
echo "migrations_changed=true" >> $GITHUB_OUTPUT
27+
echo "Migration files changed, will run migrations"
28+
else
29+
echo "migrations_changed=false" >> $GITHUB_OUTPUT
30+
echo "No migration files changed, skipping"
31+
fi
32+
33+
- name: Fail if DB URL missing
34+
if: steps.check-migrations.outputs.migrations_changed == 'true'
35+
run: |
36+
if [ -z "${{ secrets.SUPABASE_DB_URL }}" ]; then
37+
echo "SUPABASE_DB_URL is not set. Please configure the secret in the GitHub environment." >&2
38+
exit 1
39+
fi
40+
41+
- name: Apply migrations
42+
if: steps.check-migrations.outputs.migrations_changed == 'true'
43+
run: npx --yes supabase@2.72.8 migration up --db-url "${{ secrets.SUPABASE_DB_URL }}" --include-all

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ next-env.d.ts
5353
.vercel
5454

5555
# Testing
56-
/coverage/
56+
coverage/
5757
.nyc_output/
5858

5959
# Misc
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
".": "0.1.0-alpha.1",
3+
"apps/web": "0.1.0-alpha.1",
4+
"apps/worker": "0.1.0-alpha.1"
5+
}

.release-please-manifest.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
".": "0.1.0",
3+
"apps/web": "0.1.0",
4+
"apps/worker": "0.1.0"
5+
}

0 commit comments

Comments
 (0)