serverless-ircd 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/.github/workflows/deploy-aws.yml +156 -32
  2. package/.github/workflows/deploy-cf-tcp.yml +11 -9
  3. package/.github/workflows/deploy-cf.yml +14 -14
  4. package/CHANGELOG.md +305 -0
  5. package/README.md +134 -41
  6. package/apps/aws-stack/README.md +3 -5
  7. package/apps/aws-stack/bin/aws.ts +82 -9
  8. package/apps/aws-stack/cdk.json +0 -3
  9. package/apps/aws-stack/package.json +3 -4
  10. package/apps/aws-stack/src/aws-stack.ts +177 -52
  11. package/apps/aws-stack/src/static-site.ts +323 -0
  12. package/apps/aws-stack/tests/smoke-helpers.test.ts +1 -1
  13. package/apps/aws-stack/tests/stack.test.ts +267 -92
  14. package/apps/aws-stack/tests/static-site.test.ts +491 -0
  15. package/apps/aws-stack/tests/synth-no-bundle.test.ts +0 -1
  16. package/apps/cf-tcp-container/package.json +2 -3
  17. package/apps/cf-tcp-container/src/container-server.ts +12 -9
  18. package/apps/cf-tcp-container/wrangler.toml +1 -10
  19. package/apps/cf-worker/package.json +3 -4
  20. package/apps/cf-worker/wrangler.toml +12 -71
  21. package/apps/local-cli/package.json +1 -1
  22. package/apps/local-cli/src/server.ts +21 -17
  23. package/apps/web/landing/favicon.ico +0 -0
  24. package/apps/web/landing/index.html +1 -0
  25. package/apps/web/package.json +2 -2
  26. package/apps/web/scripts/build.mjs +66 -4
  27. package/apps/web/src/build-env.ts +125 -4
  28. package/apps/web/src/config-schema.ts +20 -6
  29. package/apps/web/static/{config.staging.json → config.prod-aws.json} +3 -2
  30. package/apps/web/tests/build-env.test.ts +210 -9
  31. package/apps/web/tests/build-smoke.test.ts +2 -2
  32. package/apps/web/tests/config-schema.test.ts +149 -25
  33. package/docs/AWS-Deployment.md +670 -96
  34. package/docs/AWS-TCP-Deployment.md +20 -45
  35. package/docs/Cloudflare-Deployment-Guide.md +87 -113
  36. package/docs/Cloudflare-TCP-Deployment.md +25 -49
  37. package/docs/Release-Process.md +27 -23
  38. package/docs/Services.md +69 -22
  39. package/docs/WebClientGuide.md +35 -26
  40. package/package.json +7 -10
  41. package/packages/aws-adapter/package.json +1 -1
  42. package/packages/aws-adapter/src/cdk-table-defs.ts +6 -11
  43. package/packages/aws-adapter/src/config-loader.ts +19 -2
  44. package/packages/aws-adapter/src/dynamo-services-store.ts +7 -0
  45. package/packages/aws-adapter/src/handlers/connect.ts +26 -0
  46. package/packages/aws-adapter/src/handlers/default.ts +190 -123
  47. package/packages/aws-adapter/src/handlers/index.ts +67 -23
  48. package/packages/aws-adapter/src/handlers/nlb-stream.ts +3 -6
  49. package/packages/aws-adapter/src/index.ts +5 -7
  50. package/packages/aws-adapter/src/origin-allowlist.ts +94 -0
  51. package/packages/aws-adapter/src/serialize.ts +15 -0
  52. package/packages/aws-adapter/src/tables.ts +2 -12
  53. package/packages/aws-adapter/tests/aws-harness.ts +0 -1
  54. package/packages/aws-adapter/tests/config-loader.test.ts +66 -0
  55. package/packages/aws-adapter/tests/connect.test.ts +124 -1
  56. package/packages/aws-adapter/tests/default-occ.test.ts +219 -0
  57. package/packages/aws-adapter/tests/dynamo-services-store-unit.test.ts +11 -0
  58. package/packages/aws-adapter/tests/handlers.test.ts +117 -11
  59. package/packages/aws-adapter/tests/migrate-accounts-to-services.test.ts +164 -0
  60. package/packages/aws-adapter/tests/origin-allowlist.test.ts +110 -0
  61. package/packages/aws-adapter/tests/ping-checker.test.ts +0 -1
  62. package/packages/aws-adapter/tests/stats.test.ts +0 -3
  63. package/packages/aws-adapter/tests/sweeper.test.ts +0 -1
  64. package/packages/aws-adapter/tests/tables.test.ts +1 -8
  65. package/packages/aws-adapter/tests/transactions.test.ts +0 -1
  66. package/packages/cf-adapter/package.json +1 -5
  67. package/packages/cf-adapter/src/cf-runtime.ts +59 -8
  68. package/packages/cf-adapter/src/channel-do.ts +13 -3
  69. package/packages/cf-adapter/src/connection-do.ts +266 -109
  70. package/packages/cf-adapter/src/d1-services-store.ts +63 -26
  71. package/packages/cf-adapter/src/env.ts +11 -10
  72. package/packages/cf-adapter/src/index.ts +0 -6
  73. package/packages/cf-adapter/tests/cf-runtime.test.ts +101 -1
  74. package/packages/cf-adapter/tests/channel-do.test.ts +118 -1
  75. package/packages/cf-adapter/tests/connection-do-coverage.test.ts +460 -0
  76. package/packages/cf-adapter/tests/connection-do-pure.test.ts +95 -54
  77. package/packages/cf-adapter/tests/connection-do-sasl-d1.test.ts +62 -38
  78. package/packages/cf-adapter/tests/d1-services-store.test.ts +53 -2
  79. package/packages/cf-adapter/tests/serialize.test.ts +25 -0
  80. package/packages/in-memory-runtime/package.json +1 -1
  81. package/packages/irc-core/package.json +1 -1
  82. package/packages/irc-core/src/account-migration.ts +140 -0
  83. package/packages/irc-core/src/commands/account-auth.ts +16 -19
  84. package/packages/irc-core/src/commands/memoserv.ts +1 -1
  85. package/packages/irc-core/src/commands/nickserv.ts +122 -11
  86. package/packages/irc-core/src/commands/registration.ts +2 -2
  87. package/packages/irc-core/src/commands/sasl.ts +22 -31
  88. package/packages/irc-core/src/config.ts +35 -9
  89. package/packages/irc-core/src/credential-hashing.ts +11 -54
  90. package/packages/irc-core/src/index.ts +1 -0
  91. package/packages/irc-core/src/ports.ts +159 -179
  92. package/packages/irc-core/src/types.ts +38 -10
  93. package/packages/irc-core/tests/account-migration.test.ts +133 -0
  94. package/packages/irc-core/tests/commands/markread.test.ts +54 -0
  95. package/packages/irc-core/tests/commands/memoserv.test.ts +19 -0
  96. package/packages/irc-core/tests/commands/nickserv.test.ts +237 -1
  97. package/packages/irc-core/tests/commands/oper.test.ts +15 -0
  98. package/packages/irc-core/tests/commands/registration.test.ts +140 -133
  99. package/packages/irc-core/tests/commands/sasl.test.ts +159 -178
  100. package/packages/irc-core/tests/commands/unified-account.test.ts +102 -84
  101. package/packages/irc-core/tests/credential-hashing.test.ts +0 -78
  102. package/packages/irc-core/tests/message-store.test.ts +5 -0
  103. package/packages/irc-core/tests/persistent-services-store.test.ts +71 -12
  104. package/packages/irc-core/tests/ports.test.ts +71 -0
  105. package/packages/irc-core/tests/services-store.test.ts +204 -0
  106. package/packages/irc-core/vitest.config.ts +6 -1
  107. package/packages/irc-server/package.json +1 -1
  108. package/packages/irc-server/src/actor.ts +0 -14
  109. package/packages/irc-server/tests/actor.test.ts +19 -47
  110. package/packages/irc-test-support/package.json +1 -1
  111. package/pnpm-workspace.yaml +1 -0
  112. package/scripts/__tests__/deploy-web-aws.test.ts +491 -0
  113. package/scripts/deploy-web-aws.mjs +290 -0
  114. package/scripts/package.json +23 -0
  115. package/scripts/tsconfig.test.json +12 -0
  116. package/scripts/vitest.config.ts +19 -0
  117. package/tools/ci-hardening/package.json +1 -1
  118. package/tools/ci-hardening/src/index.ts +2 -0
  119. package/tools/ci-hardening/src/validate.ts +57 -0
  120. package/tools/ci-hardening/tests/deploy-aws-oidc.test.ts +96 -0
  121. package/tools/ci-hardening/tests/validate.test.ts +42 -0
  122. package/tools/load-test/package.json +1 -1
  123. package/tools/migrate-accounts-to-services.ts +270 -0
  124. package/tools/package.json +2 -1
  125. package/tools/seed-aws-accounts.ts +35 -10
  126. package/tools/seed-cf-accounts.ts +42 -9
  127. package/tools/tcp-ws-forwarder/package.json +1 -1
  128. package/packages/aws-adapter/src/account-store.ts +0 -121
  129. package/packages/aws-adapter/src/dynamo-account-store.ts +0 -95
  130. package/packages/aws-adapter/tests/account-store-dynamo.test.ts +0 -223
  131. package/packages/aws-adapter/tests/account-store.test.ts +0 -276
  132. package/packages/cf-adapter/src/d1-account-store.ts +0 -198
  133. package/packages/cf-adapter/tests/d1-account-store.test.ts +0 -274
  134. package/packages/irc-core/tests/account-store.test.ts +0 -131
@@ -2,30 +2,31 @@ name: deploy-aws
2
2
 
3
3
  # AWS CDK deploy pipeline.
4
4
  #
5
- # On every push to `main`:
5
+ # This workflow is `workflow_dispatch`-only — there is no automatic
6
+ # push-to-main trigger. A maintainer runs it by hand to ship the single
7
+ # AWS stack target (`apps/aws-stack`):
6
8
  # 1. Install deps (frozen lockfile).
7
9
  # 2. Build the aws-adapter + irc-core/irc-server so the CDK stack
8
10
  # typechecks against real workspace packages.
9
11
  # 3. `cdk deploy --all` the `apps/aws-stack` stack (API Gateway v2
10
- # WebSocket API, Lambda, DynamoDB tables) to the staging AWS
11
- # account/region.
12
+ # WebSocket API, Lambda, DynamoDB tables).
12
13
  # 4. Replay the smoke e2e (`scripts/smoke.mjs`) against the deployed
13
14
  # WebSocket endpoint — CONNECT/REGISTER/JOIN/PRIVMSG/QUIT. Failure
14
15
  # blocks the merge (the deploy job is required on `main`).
15
16
  #
16
17
  # Secrets / variables (configure under repo Settings → Secrets and
17
18
  # variables → Actions):
18
- # AWS_ACCESS_KEY_ID Static AWS access key with permission to deploy
19
- # the stack (IAM, APIGW, Lambda, DynamoDB).
20
- # Required unless OIDC is used (see below).
21
- # AWS_SECRET_ACCESS_KEY Companion secret key. Required unless OIDC.
22
- # AWS_DEPLOY_ROLE_ARN Optional. When set, the job assumes this role
23
- # via OIDC web identity instead of using static
24
- # access keys. Requires `permissions.id-token:
25
- # write` (declared below) and an OIDC trust
26
- # policy on the role granting
27
- # `sts:AssumeRoleWithWebIdentity` to this repo's
28
- # GitHub OIDC provider.
19
+ # AWS_DEPLOY_ROLE_ARN REQUIRED. ARN of the IAM role the workflow
20
+ # assumes via GitHub OIDC web identity. The
21
+ # role's trust policy MUST condition on
22
+ # `token.actions.githubusercontent.com:sub`
23
+ # = `repo:<owner>/<repo>:ref:refs/heads/main`
24
+ # (see docs/AWS-Deployment.md §17 for the
25
+ # trust-policy snippet). Long-lived access
26
+ # keys (`AWS_ACCESS_KEY_ID` /
27
+ # `AWS_SECRET_ACCESS_KEY`) are NOT accepted
28
+ # a single exfil vector against them is full
29
+ # AWS account takeover.
29
30
  # AWS_REGION AWS region to deploy into (e.g. us-east-1).
30
31
  #
31
32
  # Repo variable (Settings → Secrets and variables → Variables):
@@ -38,22 +39,23 @@ name: deploy-aws
38
39
  # behaviour).
39
40
 
40
41
  on:
41
- # Automatic push trigger disabled; deploy only runs manually.
42
42
  workflow_dispatch:
43
43
 
44
- # OIDC web identity requires id-token write; contents:read for checkout.
44
+ # GitHub OIDC web identity: id-token write so Actions can mint a JWT
45
+ # for `sts:AssumeRoleWithWebIdentity`; contents:read for checkout.
46
+ # Least-privilege — no other GITHUB_TOKEN permissions granted.
45
47
  permissions:
46
48
  id-token: write
47
49
  contents: read
48
50
 
49
51
  # Prevent two deploys racing the same CloudFormation stack.
50
52
  concurrency:
51
- group: aws-staging
53
+ group: aws-deploy
52
54
  cancel-in-progress: false
53
55
 
54
56
  jobs:
55
- deploy-staging:
56
- name: cdk deploy --all (staging)
57
+ deploy:
58
+ name: cdk deploy --all
57
59
  runs-on: ubuntu-latest
58
60
  timeout-minutes: 10
59
61
  steps:
@@ -81,20 +83,55 @@ jobs:
81
83
  - name: Test
82
84
  run: pnpm test
83
85
 
84
- # When AWS_DEPLOY_ROLE_ARN is set, assume it via OIDC web identity
85
- # (ignores the static access keys). Otherwise fall back to the
86
- # static access-key pair. Both shapes are handled by the action:
87
- # an empty role-to-assume is treated as unset.
86
+ # Fail fast before any AWS call if the OIDC role ARN is missing.
87
+ # `AWS_DEPLOY_ROLE_ARN` is the ONLY accepted credential source
88
+ # long-lived access keys are intentionally not wired in.
89
+ - name: Assert OIDC deploy role ARN is set
90
+ if: env.AWS_DEPLOY_ROLE_ARN == ''
91
+ env:
92
+ AWS_DEPLOY_ROLE_ARN: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}
93
+ run: |
94
+ echo "::error::AWS_DEPLOY_ROLE_ARN secret is empty — configure the GitHub OIDC IAM role trust before deploying (see docs/AWS-Deployment.md §17)."
95
+ exit 1
96
+
97
+ # OIDC-only: assume the configured role via web identity. No
98
+ # static access keys are accepted; if the role ARN is empty the
99
+ # step above has already failed the job.
88
100
  - name: Configure AWS credentials
89
101
  uses: aws-actions/configure-aws-credentials@v4
90
102
  with:
91
103
  aws-region: ${{ secrets.AWS_REGION }}
92
104
  role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}
93
- aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
94
- aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
95
105
 
96
- - name: Deploy to staging
97
- run: pnpm deploy:aws:staging -- -c environmentName=staging
106
+ # Defence-in-depth: confirm sts:AssumeRoleWithWebIdentity actually
107
+ # minted the configured role and the job is NOT running on
108
+ # ambient static credentials. Aborts before any `cdk deploy`.
109
+ - name: Assert assumed role matches AWS_DEPLOY_ROLE_ARN
110
+ env:
111
+ AWS_DEPLOY_ROLE_ARN: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}
112
+ run: |
113
+ set -euo pipefail
114
+ CALLER_ARN=$(aws sts get-caller-identity --query 'Arn' --output text)
115
+ ASSUMED_ROLE_ARN="${AWS_DEPLOY_ROLE_ARN}"
116
+ # The caller ARN for an OIDC-assumed role looks like
117
+ # arn:aws:sts::<account>:assumed-role/<role-name>/GitHubActions
118
+ # while AWS_DEPLOY_ROLE_ARN is the role ARN
119
+ # arn:aws:iam::<account>:role/<role-name>
120
+ # Compare by role-name + account-id so the two shapes match.
121
+ CALLER_ROLE=$(echo "$CALLER_ARN" | sed -n 's#.*assumed-role/\([^/]*\).*#\1#p')
122
+ CALLER_ACCT=$(echo "$CALLER_ARN" | sed -n 's#arn:aws:sts::\([0-9]*\).*#\1#p')
123
+ CONFIG_ROLE=$(echo "$ASSUMED_ROLE_ARN" | sed -n 's#.*/role/\([^/]*\)#\1#p')
124
+ CONFIG_ACCT=$(echo "$ASSUMED_ROLE_ARN" | sed -n 's#arn:aws:iam::\([0-9]*\).*#\1#p')
125
+ if [ -z "$CALLER_ROLE" ] || [ -z "$CONFIG_ROLE" ] \
126
+ || [ "$CALLER_ROLE" != "$CONFIG_ROLE" ] \
127
+ || [ "$CALLER_ACCT" != "$CONFIG_ACCT" ]; then
128
+ echo "::error::STS caller-identity does not match AWS_DEPLOY_ROLE_ARN (got '$CALLER_ARN', expected role '$CONFIG_ROLE' in account '$CONFIG_ACCT'). OIDC did not mint the configured role — aborting before cdk deploy."
129
+ exit 1
130
+ fi
131
+ echo "OIDC role assertion passed: $CALLER_ROLE in account $CALLER_ACCT"
132
+
133
+ - name: Deploy stack
134
+ run: pnpm deploy:aws
98
135
 
99
136
  - name: Resolve smoke URL
100
137
  id: smoke-url
@@ -105,16 +142,15 @@ jobs:
105
142
  echo "url=$AWS_SMOKE_URL" >> "$GITHUB_OUTPUT"
106
143
  else
107
144
  # Fall back to the stack's ConnectUrl CloudFormation output.
108
- # Stack name is `IrcAwsStack-<environmentName>`; staging
109
- # `IrcAwsStack-staging`.
145
+ # Stack name is `IrcAwsStack` (single target, no env suffix).
110
146
  URL=$(aws cloudformation describe-stacks \
111
- --stack-name IrcAwsStack-staging \
147
+ --stack-name IrcAwsStack \
112
148
  --query 'Stacks[0].Outputs[?OutputKey==`ConnectUrl`].OutputValue' \
113
149
  --output text 2>/dev/null || true)
114
150
  if [ -n "$URL" ]; then
115
151
  echo "url=$URL" >> "$GITHUB_OUTPUT"
116
152
  else
117
- echo "::warning::Unable to resolve the staging WebSocket URL (set the AWS_SMOKE_URL repo variable or check the stack ConnectUrl output); smoke step will be skipped."
153
+ echo "::warning::Unable to resolve the WebSocket URL (set the AWS_SMOKE_URL repo variable or check the stack ConnectUrl output); smoke step will be skipped."
118
154
  echo "url=" >> "$GITHUB_OUTPUT"
119
155
  fi
120
156
  fi
@@ -123,4 +159,92 @@ jobs:
123
159
  if: steps.smoke-url.outputs.url != ''
124
160
  env:
125
161
  SMOKE_URL: ${{ steps.smoke-url.outputs.url }}
126
- run: pnpm smoke:aws:staging -- --url "$SMOKE_URL"
162
+ run: pnpm smoke:aws -- --url "$SMOKE_URL"
163
+
164
+ # ---------------------------------------------------------------------------
165
+ # deploy-web — AWS web client two-phase deploy (s3 sync + CloudFront
166
+ # invalidation, stack-output-driven).
167
+ #
168
+ # The SPA lives in S3 behind CloudFront (provisioned by the StaticSite
169
+ # construct in apps/aws-stack). It ships SEPARATELY from the runtime
170
+ # stack because the deploy pipeline needs the stack's CloudFormation
171
+ # outputs (the API Gateway WebSocket URL, the S3 bucket name, the
172
+ # CloudFront distribution ID) to exist BEFORE it can bake the SPA —
173
+ # `cdk deploy` therefore runs first (the `deploy` job above), then this
174
+ # job reads the outputs and:
175
+ # 1. `aws cloudformation describe-stacks --stack-name IrcAwsStack`
176
+ # reads `ConnectUrl`, `WebsiteBucketName`, `WebsiteDistributionId`.
177
+ # 2. `pnpm --filter @serverless-ircd/web run build:prod-aws -- --api-url <url>`
178
+ # bakes the SPA with the real wss URL (no hardcoded URLs in the repo).
179
+ # 3. `aws s3 sync apps/web/dist s3://<bucket> --delete` uploads the
180
+ # build (the CLI skips unchanged objects via etag comparison).
181
+ # 4. `aws cloudfront create-invalidation --distribution-id <id> --paths /*`
182
+ # busts the edge cache.
183
+ #
184
+ # Why a script instead of CDK `BucketDeployment`: the script reads
185
+ # post-deploy outputs that do not exist at synth time, avoids
186
+ # re-synth-on-every-deploy, and is faster. See
187
+ # `scripts/deploy-web-aws.mjs` and `docs/AWS-Deployment.md`.
188
+ #
189
+ # Staleness note: T170 collapsed the staging/prod split — there is no
190
+ # `staging` branch and this job is `workflow_dispatch`-only on the
191
+ # current branch, mirroring the parent pipeline. A maintainer runs the
192
+ # workflow by hand to ship the AWS web client.
193
+ # ---------------------------------------------------------------------------
194
+ deploy-web:
195
+ name: web deploy (s3 sync + CloudFront invalidation)
196
+ needs: deploy
197
+ runs-on: ubuntu-latest
198
+ timeout-minutes: 15
199
+ steps:
200
+ - name: Checkout
201
+ uses: actions/checkout@v4
202
+ with:
203
+ # The web client build requires the Kiwi IRC upstream submodule
204
+ # and the docs/ submodule (rendered into dist/docs/ by build.mjs).
205
+ submodules: recursive
206
+
207
+ - name: Checkout submodules (worktree-safe fallback)
208
+ run: |
209
+ # `submodules: recursive` covers the normal case; this fallback
210
+ # ensures the Kiwi + docs submodules are present even when the
211
+ # checkout action's recursive flag was a no-op (older runners /
212
+ # path-filter configurations).
213
+ git submodule update --init --recursive
214
+
215
+ - name: Setup pnpm
216
+ uses: pnpm/action-setup@v4
217
+
218
+ - name: Setup Node
219
+ uses: actions/setup-node@v4
220
+ with:
221
+ node-version: 24
222
+ cache: pnpm
223
+
224
+ - name: Install dependencies
225
+ run: pnpm install --frozen-lockfile
226
+
227
+ # Fail fast before any AWS call if the OIDC role ARN is missing.
228
+ # Mirrors the guard in the `deploy` job — the `deploy-web` job
229
+ # also assumes the role via OIDC and accepts no static keys.
230
+ - name: Assert OIDC deploy role ARN is set
231
+ if: env.AWS_DEPLOY_ROLE_ARN == ''
232
+ env:
233
+ AWS_DEPLOY_ROLE_ARN: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}
234
+ run: |
235
+ echo "::error::AWS_DEPLOY_ROLE_ARN secret is empty — configure the GitHub OIDC IAM role trust before deploying (see docs/AWS-Deployment.md §17)."
236
+ exit 1
237
+
238
+ - name: Configure AWS credentials
239
+ uses: aws-actions/configure-aws-credentials@v4
240
+ with:
241
+ aws-region: ${{ secrets.AWS_REGION }}
242
+ role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}
243
+
244
+ # Two-phase deploy: describe-stacks → bake (--api-url) → s3 sync →
245
+ # create-invalidation. Implemented in scripts/deploy-web-aws.mjs;
246
+ # exits non-zero with a clear message if any required stack output
247
+ # is missing (i.e. the parent `deploy` job did not run first or the
248
+ # stack's `webSite` prop is not configured).
249
+ - name: Deploy web client (bake + s3 sync + CloudFront invalidation)
250
+ run: node scripts/deploy-web-aws.mjs
@@ -6,8 +6,11 @@ name: deploy-cf-tcp
6
6
  # Containers and applies the Spectrum TLS config (terraform). Spectrum
7
7
  # terminates TLS on :6697 and forwards plaintext TCP to the container.
8
8
  #
9
- # This pipeline runs alongside deploy-cf.yml (the WebSocket path). The two
10
- # are independent: a deployment can enable either or both transports.
9
+ # This pipeline is `workflow_dispatch`-only there is no automatic
10
+ # push-to-main trigger. A maintainer runs it by hand to ship the single
11
+ # TCP container target. It runs alongside deploy-cf.yml (the WebSocket
12
+ # path); the two are independent, so a deployment can enable either or
13
+ # both transports.
11
14
  #
12
15
  # Secrets (configure under repo Settings → Secrets and variables → Actions):
13
16
  # CLOUDFLARE_API_TOKEN Spectrum/Containers API token.
@@ -16,16 +19,15 @@ name: deploy-cf-tcp
16
19
  # CF_TCP_ORIGIN_ADDRESS Hostname/IP of the container origin.
17
20
 
18
21
  on:
19
- # Automatic push trigger disabled; deploy only runs manually.
20
22
  workflow_dispatch:
21
23
 
22
24
  concurrency:
23
- group: cf-tcp-staging
25
+ group: cf-tcp-deploy
24
26
  cancel-in-progress: false
25
27
 
26
28
  jobs:
27
- deploy-staging:
28
- name: deploy cf-tcp staging
29
+ deploy:
30
+ name: deploy cf-tcp
29
31
  runs-on: ubuntu-latest
30
32
  timeout-minutes: 15
31
33
  steps:
@@ -53,19 +55,19 @@ jobs:
53
55
  - name: Test
54
56
  run: pnpm --filter '@serverless-ircd/cf-tcp-container' test
55
57
 
56
- - name: Deploy container to staging
58
+ - name: Deploy container
57
59
  working-directory: apps/cf-tcp-container
58
60
  env:
59
61
  CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
60
62
  CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
61
- run: wrangler deploy --env staging
63
+ run: wrangler deploy
62
64
 
63
65
  - name: Apply Spectrum TLS config
64
66
  working-directory: apps/cf-tcp-container/terraform
65
67
  env:
66
68
  TF_VAR_zone_id: ${{ secrets.CF_ZONE_ID }}
67
69
  TF_VAR_origin_address: ${{ secrets.CF_TCP_ORIGIN_ADDRESS }}
68
- TF_VAR_hostname: irc-staging.example.com
70
+ TF_VAR_hostname: irc.example.com
69
71
  run: |
70
72
  terraform init
71
73
  terraform apply -auto-approve
@@ -2,12 +2,13 @@ name: deploy-cf
2
2
 
3
3
  # Cloudflare Workers deploy pipeline.
4
4
  #
5
- # On every push to `main`:
5
+ # This workflow is `workflow_dispatch`-only — there is no automatic
6
+ # push-to-main trigger. A maintainer runs it by hand to ship the single
7
+ # Cloudflare Worker target (`apps/cf-worker`):
6
8
  # 1. Install deps (frozen lockfile).
7
9
  # 2. Build the cf-adapter + irc-core/irc-server so the Worker entry
8
10
  # typechecks against real workspace packages.
9
- # 3. `wrangler deploy --env staging` the `apps/cf-worker` worker to the
10
- # `serverless-ircd-staging` Worker + DO namespace.
11
+ # 3. `wrangler deploy` the `apps/cf-worker` worker.
11
12
  # 4. Replay the smoke e2e (`scripts/smoke.mjs`) against the deployed
12
13
  # URL — CONNECT/REGISTER/JOIN/PRIVMSG/QUIT. Failure blocks the
13
14
  # merge (the deploy job is required on `main`).
@@ -19,23 +20,22 @@ name: deploy-cf
19
20
  # CLOUDFLARE_ACCOUNT_ID Optional; required if the token's account
20
21
  # context is ambiguous.
21
22
  #
22
- # The smoke URL is derived from the staging Worker name
23
- # (`serverless-ircd-staging`) plus the deployer's account subdomain.
24
- # Override by setting `CF_SMOKE_URL` in the repo Variables store when
25
- # custom routes are wired.
23
+ # The smoke URL is derived from the Worker name (`serverless-ircd`)
24
+ # plus the deployer's account subdomain. Override by setting
25
+ # `CF_SMOKE_URL` in the repo Variables store when custom routes are
26
+ # wired.
26
27
 
27
28
  on:
28
- # Automatic push trigger disabled; deploy only runs manually.
29
29
  workflow_dispatch:
30
30
 
31
31
  # Prevent two deploys racing the same DO namespace.
32
32
  concurrency:
33
- group: cf-staging
33
+ group: cf-deploy
34
34
  cancel-in-progress: false
35
35
 
36
36
  jobs:
37
- deploy-staging:
38
- name: wrangler deploy --env staging
37
+ deploy:
38
+ name: wrangler deploy
39
39
  runs-on: ubuntu-latest
40
40
  timeout-minutes: 10
41
41
  steps:
@@ -63,12 +63,12 @@ jobs:
63
63
  - name: Test
64
64
  run: pnpm test
65
65
 
66
- - name: Deploy to staging
66
+ - name: Deploy Worker
67
67
  working-directory: apps/cf-worker
68
68
  env:
69
69
  CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
70
70
  CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
71
- run: pnpm deploy:staging
71
+ run: pnpm run deploy
72
72
 
73
73
  - name: Resolve smoke URL
74
74
  id: smoke-url
@@ -82,7 +82,7 @@ jobs:
82
82
  # The subdomain is per-account; if CF_SMOKE_URL isn't set we
83
83
  # fall back to a workers.dev route that the deployer must
84
84
  # configure once via the Cloudflare dashboard.
85
- echo "::warning::CF_SMOKE_URL repo variable is not set; smoke step will be skipped. Set it to the staging Worker's wss:// URL."
85
+ echo "::warning::CF_SMOKE_URL repo variable is not set; smoke step will be skipped. Set it to the Worker's wss:// URL."
86
86
  echo "url=" >> "$GITHUB_OUTPUT"
87
87
  fi
88
88