diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c9527e1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,52 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +jobs: + verify: + name: Test and typecheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + cache: npm + - run: npm ci + - run: npm run typecheck + - run: npm test + + deploy: + name: Deploy to Cloudflare + # Only merged code on main reaches production, and only after verify passes. + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: verify + runs-on: ubuntu-latest + environment: production + # Never run two deploys at once; a newer push waits for the running one. + concurrency: + group: deploy-production + cancel-in-progress: false + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + cache: npm + - run: npm ci + # Migrations run before the new code goes live, so the Worker never + # queries a schema that does not exist yet. Migrations must therefore + # stay backward compatible with the previously deployed Worker. + - name: Apply D1 migrations + run: npx wrangler d1 migrations apply hack-bot-db --remote + - name: Deploy Worker + run: npx wrangler deploy diff --git a/wrangler.jsonc b/wrangler.jsonc index 6f56d5b..021cbcb 100644 --- a/wrangler.jsonc +++ b/wrangler.jsonc @@ -14,8 +14,13 @@ { "binding": "DB", "database_name": "hack-bot-db", - "database_id": "00000000-0000-0000-0000-000000000000", + "database_id": "d4ba5860-cc66-4cf2-a871-3fb5f6fcd7cc", "migrations_dir": "migrations" } - ] + ], + // Public getMe result, cached so grammY never calls getMe per request. + // Not a secret; the token-bearing values are Worker secrets. + "vars": { + "BOT_INFO": "{\"id\":8808165755,\"is_bot\":true,\"first_name\":\"Hack Bot\",\"username\":\"hackZK_bot\",\"can_join_groups\":true,\"can_read_all_group_messages\":false,\"supports_inline_queries\":false,\"can_connect_to_business\":false,\"has_main_web_app\":false}" + } }