Skip to content

Commit 4e7ad87

Browse files
Initial public release
0 parents  commit 4e7ad87

File tree

123 files changed

+46856
-0
lines changed

Some content is hidden

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

123 files changed

+46856
-0
lines changed

.devcontainer/Dockerfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM mcr.microsoft.com/devcontainers/javascript-node:1-22-bookworm
2+
3+
ENV DEBIAN_FRONTEND=noninteractive
4+
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
5+
6+
RUN apt-get update \
7+
&& apt-get install -y --no-install-recommends \
8+
ca-certificates \
9+
curl \
10+
jq \
11+
sqlite3 \
12+
&& rm -rf /var/lib/apt/lists/*
13+
14+
RUN corepack enable
15+
16+
WORKDIR /workspaces/request-bot

.devcontainer/devcontainer.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "request-bot",
3+
"build": {
4+
"dockerfile": "Dockerfile",
5+
"context": ".."
6+
},
7+
"remoteUser": "node",
8+
"features": {
9+
"ghcr.io/devcontainers/features/git:1": {},
10+
"ghcr.io/devcontainers/features/github-cli:1": {}
11+
},
12+
"forwardPorts": [6666, 8787],
13+
"portsAttributes": {
14+
"6666": {
15+
"label": "TanStack Start app",
16+
"onAutoForward": "notify"
17+
},
18+
"8787": {
19+
"label": "Wrangler dev",
20+
"onAutoForward": "notify"
21+
}
22+
},
23+
"containerEnv": {
24+
"PLAYWRIGHT_BROWSERS_PATH": "/ms-playwright",
25+
"CI": "true"
26+
},
27+
"postCreateCommand": "bash .devcontainer/scripts/post-create.sh",
28+
"postStartCommand": "bash .devcontainer/scripts/post-start.sh",
29+
"customizations": {
30+
"vscode": {
31+
"settings": {
32+
"terminal.integrated.defaultProfile.linux": "bash",
33+
"typescript.tsdk": "node_modules/typescript/lib",
34+
"editor.formatOnSave": true
35+
},
36+
"extensions": [
37+
"dbaeumer.vscode-eslint",
38+
"esbenp.prettier-vscode",
39+
"ms-playwright.playwright",
40+
"bradlc.vscode-tailwindcss"
41+
]
42+
}
43+
}
44+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
if [ ! -f .env ]; then
5+
cp .env.example .env
6+
fi
7+
8+
if [ ! -f package.json ]; then
9+
exit 0
10+
fi
11+
12+
npm install
13+
npx playwright install --with-deps chromium
14+
15+
if [ -f wrangler.jsonc ]; then
16+
npm run cf-typegen || true
17+
fi
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
if [ ! -f .env ]; then
5+
cp .env.example .env
6+
fi

.env.deploy.example

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
APP_URL=https://your-app.workers.dev
2+
CLOUDFLARE_D1_DATABASE_ID=
3+
CLOUDFLARE_SESSION_KV_ID=
4+
TWITCH_CLIENT_ID=
5+
TWITCH_CLIENT_SECRET=
6+
TWITCH_EVENTSUB_SECRET=
7+
SESSION_SECRET=
8+
ADMIN_TWITCH_USER_IDS=
9+
TWITCH_BOT_USERNAME=requestbot
10+
TWITCH_SCOPES=openid user:read:moderated_channels channel:bot

.env.example

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
APP_URL=http://localhost:9000
2+
# Allowed hosts for local development - eg. your cloudflare tunnel domain
3+
VITE_ALLOWED_HOSTS=
4+
TWITCH_CLIENT_ID=
5+
TWITCH_CLIENT_SECRET=
6+
# Generate with `openssl rand -hex 32`
7+
TWITCH_EVENTSUB_SECRET=local-dev-eventsub-secret
8+
# Generate with `openssl rand -hex 32`
9+
SESSION_SECRET=local-dev-session-secret
10+
# Twitch user IDs for initial admins - comma separated, no quotation marks, like this: 1234567,2345678
11+
ADMIN_TWITCH_USER_IDS=
12+
# The username of the shared bot account
13+
TWITCH_BOT_USERNAME=requestbot
14+
# Scopes for the shared bot account
15+
TWITCH_SCOPES=openid user:read:moderated_channels channel:bot

.github/workflows/ci.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- "codex/**"
8+
pull_request:
9+
10+
jobs:
11+
verify:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v5
16+
17+
- uses: actions/setup-node@v5
18+
with:
19+
node-version: 22
20+
cache: npm
21+
22+
- uses: actions/setup-python@v5
23+
with:
24+
python-version: "3.x"
25+
26+
- name: Install dependencies
27+
run: npm ci
28+
29+
- name: Apply local migrations
30+
run: npm run db:migrate
31+
32+
- name: Lint
33+
run: npm run lint
34+
35+
- name: Typecheck
36+
run: npm run typecheck
37+
38+
- name: Test
39+
run: npm run test
40+
41+
- name: Build
42+
run: npm run build
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
name: Deploy Preview
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened]
6+
7+
permissions:
8+
contents: read
9+
pull-requests: write
10+
11+
concurrency:
12+
group: deploy-preview-${{ github.event.pull_request.number }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
deploy-preview:
17+
runs-on: ubuntu-latest
18+
19+
env:
20+
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
21+
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
22+
CLOUDFLARE_D1_DATABASE_ID: ${{ secrets.CLOUDFLARE_D1_DATABASE_ID }}
23+
CLOUDFLARE_SESSION_KV_ID: ${{ secrets.CLOUDFLARE_SESSION_KV_ID }}
24+
TWITCH_BOT_USERNAME: ${{ vars.TWITCH_BOT_USERNAME }}
25+
TWITCH_SCOPES: ${{ vars.TWITCH_SCOPES }}
26+
PREVIEW_SUFFIX: pr-${{ github.event.pull_request.number }}
27+
CLOUDFLARE_WORKERS_SUBDOMAIN: ${{ secrets.CLOUDFLARE_WORKERS_SUBDOMAIN }}
28+
29+
steps:
30+
- uses: actions/checkout@v5
31+
32+
- uses: actions/setup-node@v5
33+
with:
34+
node-version: 22
35+
cache: npm
36+
37+
- name: Install dependencies
38+
run: npm ci
39+
40+
- name: Build preview app URL
41+
id: preview-url
42+
shell: bash
43+
run: |
44+
if [ -n "${CLOUDFLARE_WORKERS_SUBDOMAIN}" ]; then
45+
echo "app_url=https://request-bot-${PREVIEW_SUFFIX}.${CLOUDFLARE_WORKERS_SUBDOMAIN}.workers.dev" >> "$GITHUB_OUTPUT"
46+
else
47+
echo "app_url=" >> "$GITHUB_OUTPUT"
48+
fi
49+
50+
- name: Build app
51+
run: npm run build
52+
53+
- name: Generate preview Wrangler configs
54+
run: >
55+
node scripts/write-deploy-configs.mjs
56+
--mode preview
57+
--artifact build
58+
--suffix "${{ env.PREVIEW_SUFFIX }}"
59+
--app-url "${{ steps.preview-url.outputs.app_url || 'https://example.workers.dev' }}"
60+
61+
- name: Deploy preview backend
62+
shell: bash
63+
run: |
64+
for attempt in 1 2 3; do
65+
if npx wrangler deploy --config .generated/wrangler.aux.preview.jsonc; then
66+
exit 0
67+
fi
68+
69+
if [ "$attempt" -lt 3 ]; then
70+
echo "Preview backend deploy failed on attempt $attempt. Retrying in 15 seconds..."
71+
sleep 15
72+
fi
73+
done
74+
75+
echo "Preview backend deploy failed after 3 attempts."
76+
exit 1
77+
78+
- name: Deploy preview frontend
79+
shell: bash
80+
run: |
81+
for attempt in 1 2 3; do
82+
if npx wrangler deploy --config .generated/wrangler.preview.jsonc; then
83+
exit 0
84+
fi
85+
86+
if [ "$attempt" -lt 3 ]; then
87+
echo "Preview frontend deploy failed on attempt $attempt. Retrying in 15 seconds..."
88+
sleep 15
89+
fi
90+
done
91+
92+
echo "Preview frontend deploy failed after 3 attempts."
93+
exit 1
94+
95+
- name: Comment preview details
96+
if: ${{ steps.preview-url.outputs.app_url != '' }}
97+
uses: actions/github-script@v7
98+
with:
99+
script: |
100+
const body = [
101+
"Preview deployment updated.",
102+
"",
103+
`App: ${{ steps.preview-url.outputs.app_url }}`,
104+
`Frontend worker: request-bot-${process.env.PREVIEW_SUFFIX}`,
105+
`Backend worker: request-bot-backend-${process.env.PREVIEW_SUFFIX}`,
106+
].join("\n");
107+
github.rest.issues.createComment({
108+
owner: context.repo.owner,
109+
repo: context.repo.repo,
110+
issue_number: context.issue.number,
111+
body,
112+
});
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Deploy Production
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: read
10+
11+
concurrency:
12+
group: deploy-production
13+
cancel-in-progress: true
14+
15+
jobs:
16+
deploy-production:
17+
runs-on: ubuntu-latest
18+
environment: production
19+
20+
env:
21+
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
22+
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
23+
CLOUDFLARE_D1_DATABASE_ID: ${{ secrets.CLOUDFLARE_D1_DATABASE_ID }}
24+
CLOUDFLARE_SESSION_KV_ID: ${{ secrets.CLOUDFLARE_SESSION_KV_ID }}
25+
APP_URL: ${{ secrets.APP_URL }}
26+
TWITCH_BOT_USERNAME: ${{ vars.TWITCH_BOT_USERNAME }}
27+
TWITCH_SCOPES: ${{ vars.TWITCH_SCOPES }}
28+
29+
steps:
30+
- uses: actions/checkout@v5
31+
32+
- uses: actions/setup-node@v5
33+
with:
34+
node-version: 22
35+
cache: npm
36+
37+
- name: Install dependencies
38+
run: npm ci
39+
40+
- name: Run CI checks
41+
run: |
42+
npm run lint
43+
npm run typecheck
44+
npm run test
45+
npm run build
46+
47+
- name: Generate production Wrangler configs
48+
run: npm run deploy:prepare
49+
50+
- name: Deploy production backend
51+
shell: bash
52+
run: |
53+
for attempt in 1 2 3; do
54+
if npx wrangler deploy --config .generated/wrangler.aux.production.jsonc; then
55+
exit 0
56+
fi
57+
58+
if [ "$attempt" -lt 3 ]; then
59+
echo "Backend deploy failed on attempt $attempt. Retrying in 15 seconds..."
60+
sleep 15
61+
fi
62+
done
63+
64+
echo "Backend deploy failed after 3 attempts."
65+
exit 1
66+
67+
- name: Deploy production frontend
68+
shell: bash
69+
run: |
70+
for attempt in 1 2 3; do
71+
if npx wrangler deploy --config .generated/wrangler.production.jsonc; then
72+
exit 0
73+
fi
74+
75+
if [ "$attempt" -lt 3 ]; then
76+
echo "Frontend deploy failed on attempt $attempt. Retrying in 15 seconds..."
77+
sleep 15
78+
fi
79+
done
80+
81+
echo "Frontend deploy failed after 3 attempts."
82+
exit 1

.gitignore

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
node_modules
2+
.tanstack
3+
.wrangler
4+
dist
5+
coverage
6+
playwright-report
7+
test-results
8+
routeTree.gen.ts
9+
.env
10+
.env.deploy
11+
.dev.vars
12+
.generated
13+
.private
14+
.vscode
15+
.DS_Store
16+
Thumbs.db
17+
*.log
18+
*.err
19+
*.out
20+
*.sqlite

0 commit comments

Comments
 (0)