@decocms/start 2.30.0 → 3.0.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.
@@ -13,8 +13,8 @@ const REQUIRED_FILES = [
13
13
  "package.json",
14
14
  "tsconfig.json",
15
15
  "vite.config.ts",
16
- // wrangler.jsonc is INTENTIONALLY absent -- D6: it lives in decocms/deco-start
17
- // under deploy/sites/<repo>.jsonc and is generated locally by `deco-wrangler gen`.
16
+ // wrangler.jsonc is INTENTIONALLY absent -- D6.2: it's generated from
17
+ // decocms/deco-start's deploy/wrangler-template.jsonc by `deco-wrangler gen`.
18
18
  ".github/workflows/deploy.yml",
19
19
  ".github/workflows/preview.yml",
20
20
  ".github/workflows/regen-blocks.yml",
@@ -1,33 +1,51 @@
1
- // Caller workflow stubs for new sites. Each stub delegates to a reusable
2
- // workflow under `decocms/deco-start/.github/workflows/` -- the customer repo
3
- // holds no deploy/build logic of its own. See D6 in
4
- // `.cursor/rules/migration-tooling-policy.mdc` and the `deploy/` directory
5
- // for the central registry contract.
1
+ // Caller workflow stubs for new sites (v3, D6.2 architecture). Each stub mints
2
+ // a short-lived `decocms-deployer` GitHub App installation token and uses it
3
+ // to call the corresponding reusable workflow under
4
+ // `decocms/deco-start/.github/workflows/`. The customer repo holds no deploy
5
+ // logic of its own AND no Cloudflare credentials -- only the App ID + private
6
+ // key as deco-sites org-level secrets (`DECOCMS_DEPLOYER_APP_ID` and
7
+ // `DECOCMS_DEPLOYER_APP_PRIVATE_KEY`).
8
+ //
9
+ // See `deploy/README.md` and the migration-tooling-policy rule (D6.2) for the
10
+ // full trust model.
6
11
 
7
12
  const DEPLOY_YML = `name: Deploy
8
13
 
9
- # Thin caller for decocms/deco-start's central deploy workflow.
14
+ # Triggers decocms/deco-start's central deploy workflow via App-token.
10
15
 
11
16
  on:
12
17
  push:
13
18
  branches: [main]
14
19
 
15
20
  permissions:
16
- contents: write
21
+ contents: read
17
22
 
18
23
  jobs:
19
- deploy:
20
- uses: decocms/deco-start/.github/workflows/deploy.yml@v2
21
- secrets: inherit
24
+ trigger:
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/create-github-app-token@v1
28
+ id: app-token
29
+ with:
30
+ app-id: \${{ secrets.DECOCMS_DEPLOYER_APP_ID }}
31
+ private-key: \${{ secrets.DECOCMS_DEPLOYER_APP_PRIVATE_KEY }}
32
+ owner: decocms
33
+ repositories: deco-start
34
+ - env:
35
+ GH_TOKEN: \${{ steps.app-token.outputs.token }}
36
+ run: |
37
+ gh workflow run deploy.yml \\
38
+ --repo decocms/deco-start \\
39
+ --ref v3 \\
40
+ -f site_owner=\${GITHUB_REPOSITORY%%/*} \\
41
+ -f site_name=\${GITHUB_REPOSITORY##*/}
22
42
  `;
23
43
 
24
44
  const PREVIEW_YML = `name: Preview
25
45
 
26
- # Thin caller for decocms/deco-start's central preview workflow.
46
+ # Triggers decocms/deco-start's central preview workflow via App-token.
27
47
 
28
48
  on:
29
- repository_dispatch:
30
- types: [preview-deploy]
31
49
  pull_request:
32
50
  types: [opened, synchronize, reopened]
33
51
  push:
@@ -35,18 +53,46 @@ on:
35
53
 
36
54
  permissions:
37
55
  contents: read
38
- pull-requests: write
39
- statuses: write
40
56
 
41
57
  jobs:
42
- preview:
43
- uses: decocms/deco-start/.github/workflows/preview.yml@v2
44
- secrets: inherit
58
+ trigger:
59
+ runs-on: ubuntu-latest
60
+ steps:
61
+ - id: meta
62
+ run: |
63
+ if [ "\${{ github.event_name }}" = "pull_request" ]; then
64
+ echo "alias=pr-\${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT"
65
+ echo "sha=\${{ github.event.pull_request.head.sha }}" >> "$GITHUB_OUTPUT"
66
+ else
67
+ REF="\${GITHUB_REF#refs/heads/env/}"
68
+ echo "alias=$(echo "$REF" | sed 's|[^a-z0-9-]|-|g')" >> "$GITHUB_OUTPUT"
69
+ echo "sha=\${{ github.sha }}" >> "$GITHUB_OUTPUT"
70
+ fi
71
+ - uses: actions/create-github-app-token@v1
72
+ id: app-token
73
+ with:
74
+ app-id: \${{ secrets.DECOCMS_DEPLOYER_APP_ID }}
75
+ private-key: \${{ secrets.DECOCMS_DEPLOYER_APP_PRIVATE_KEY }}
76
+ owner: decocms
77
+ repositories: deco-start
78
+ - env:
79
+ GH_TOKEN: \${{ steps.app-token.outputs.token }}
80
+ run: |
81
+ gh workflow run preview.yml \\
82
+ --repo decocms/deco-start \\
83
+ --ref v3 \\
84
+ -f site_owner=\${GITHUB_REPOSITORY%%/*} \\
85
+ -f site_name=\${GITHUB_REPOSITORY##*/} \\
86
+ -f site_sha=\${{ steps.meta.outputs.sha }} \\
87
+ -f alias=\${{ steps.meta.outputs.alias }} \\
88
+ -f pr_number=\${{ github.event.pull_request.number || '' }}
45
89
  `;
46
90
 
47
91
  const REGEN_BLOCKS_YML = `name: Regenerate blocks.gen.json
48
92
 
49
93
  # Thin caller for decocms/deco-start's central regen-blocks workflow.
94
+ # This one stays as workflow_call: it runs in the caller's runner context
95
+ # (writes back to the storefront repo) and needs no Cloudflare credentials.
50
96
 
51
97
  on:
52
98
  push:
@@ -59,13 +105,15 @@ permissions:
59
105
 
60
106
  jobs:
61
107
  regen:
62
- uses: decocms/deco-start/.github/workflows/regen-blocks.yml@v2
108
+ uses: decocms/deco-start/.github/workflows/regen-blocks.yml@v3
63
109
  secrets: inherit
64
110
  `;
65
111
 
66
112
  const SYNC_SECRETS_YML = `name: Sync worker secrets
67
113
 
68
- # Thin caller for decocms/deco-start's central sync-secrets workflow.
114
+ # Triggers decocms/deco-start's central sync-secrets workflow via App-token.
115
+ # The actual SECRET_* values live in deco-start's '\${repo-basename}-secrets'
116
+ # environment, NOT in this repo. See deco-start's deploy/README.md.
69
117
 
70
118
  on:
71
119
  workflow_dispatch:
@@ -81,11 +129,24 @@ permissions:
81
129
  contents: read
82
130
 
83
131
  jobs:
84
- sync:
85
- uses: decocms/deco-start/.github/workflows/sync-secrets.yml@v2
86
- with:
87
- mode: \${{ inputs.mode }}
88
- secrets: inherit
132
+ trigger:
133
+ runs-on: ubuntu-latest
134
+ steps:
135
+ - uses: actions/create-github-app-token@v1
136
+ id: app-token
137
+ with:
138
+ app-id: \${{ secrets.DECOCMS_DEPLOYER_APP_ID }}
139
+ private-key: \${{ secrets.DECOCMS_DEPLOYER_APP_PRIVATE_KEY }}
140
+ owner: decocms
141
+ repositories: deco-start
142
+ - env:
143
+ GH_TOKEN: \${{ steps.app-token.outputs.token }}
144
+ run: |
145
+ gh workflow run sync-secrets.yml \\
146
+ --repo decocms/deco-start \\
147
+ --ref v3 \\
148
+ -f site_name=\${GITHUB_REPOSITORY##*/} \\
149
+ -f mode=\${{ inputs.mode }}
89
150
  `;
90
151
 
91
152
  export function generateGithubWorkflows(): Record<string, string> {
@@ -1,7 +0,0 @@
1
- // Per-site overrides for `als-tanstack` (immutable repo->worker binding).
2
- // Renaming `worker_name` is a breaking change: it points the next deploy at a
3
- // different Cloudflare worker. Only the platform team can change this file
4
- // (CODEOWNERS-protected).
5
- {
6
- "worker_name": "als-tanstack"
7
- }
@@ -1,4 +0,0 @@
1
- // Per-site overrides for `americanas-tanstack`.
2
- {
3
- "worker_name": "americanas-tanstack"
4
- }
@@ -1,4 +0,0 @@
1
- // Per-site overrides for `baggagio-tanstack`.
2
- {
3
- "worker_name": "baggagio-tanstack"
4
- }
@@ -1,11 +0,0 @@
1
- // Per-site overrides for `casaevideo-storefront`.
2
- //
3
- // NOTE: `kv_namespaces[].id` is shared with `lebiscuit-tanstack`. Verify this
4
- // is intentional before promoting this registry to v1. R4 in the central-deploy
5
- // plan adds a CI check that flags shared KV ids as a copy-paste smell.
6
- {
7
- "worker_name": "casaevideo-tanstack",
8
- "kv_namespaces": [
9
- { "binding": "SITES_KV", "id": "ad0b74fc4d9341c9af9149c4ab85132f" }
10
- ]
11
- }
@@ -1,19 +0,0 @@
1
- // Per-site overrides for `lebiscuit-tanstack`.
2
- //
3
- // NOTE: `kv_namespaces[].id` is shared with `casaevideo-storefront`. See the
4
- // note in casaevideo's site file. R4 will add CI validation for this.
5
- //
6
- // `version_metadata` and `analytics_engine_datasets` are consumed by
7
- // @decocms/start's `instrumentWorker`:
8
- // - version_metadata populates `service.version` on the OTel resource.
9
- // - analytics_engine_datasets is the dual-emit metrics target.
10
- {
11
- "worker_name": "lebiscuit-tanstack",
12
- "kv_namespaces": [
13
- { "binding": "SITES_KV", "id": "ad0b74fc4d9341c9af9149c4ab85132f" }
14
- ],
15
- "version_metadata": { "binding": "CF_VERSION_METADATA" },
16
- "analytics_engine_datasets": [
17
- { "binding": "DECO_METRICS", "dataset": "deco_metrics_lebiscuit" }
18
- ]
19
- }
@@ -1,8 +0,0 @@
1
- // Per-site overrides for `miess-01-tanstack`.
2
- //
3
- // Worker name keeps the historical `miess-tanstack` (no "-01") so the deploy
4
- // continues to land on the existing Cloudflare worker. The repo name has the
5
- // `-01-` suffix; the worker name does not.
6
- {
7
- "worker_name": "miess-tanstack"
8
- }
@@ -1,58 +0,0 @@
1
- #!/usr/bin/env node
2
- // resolve-site.mjs
3
- //
4
- // Validates that the calling repository has a registered site manifest in
5
- // deco-start, and emits the resolved fields to GITHUB_OUTPUT for downstream
6
- // steps (wrangler tail, status comments, etc.).
7
- //
8
- // Required env:
9
- // DECO_START_PATH - path to a checked-out deco-start (e.g. ".deco-start")
10
- // SITE_NAME - typically `${GITHUB_REPOSITORY#*/}` set by the workflow
11
- //
12
- // Optional env:
13
- // GITHUB_OUTPUT - if set, emit `key=value` lines here (CI mode).
14
- // If unset, prints a human-readable summary to stdout.
15
-
16
- import { appendFileSync } from "node:fs";
17
- import { loadSiteManifest } from "./site-registry.mjs";
18
-
19
- function fail(message) {
20
- console.error(`::error::${message}`);
21
- process.exit(1);
22
- }
23
-
24
- const decoStartPath = process.env.DECO_START_PATH;
25
- const siteName = process.env.SITE_NAME;
26
- const ghOutput = process.env.GITHUB_OUTPUT;
27
-
28
- if (!decoStartPath) fail("DECO_START_PATH env var is required");
29
- if (!siteName) fail("SITE_NAME env var is required");
30
-
31
- let manifest;
32
- try {
33
- manifest = loadSiteManifest(decoStartPath, siteName);
34
- } catch (err) {
35
- fail(err instanceof Error ? err.message : String(err));
36
- }
37
-
38
- const summary = {
39
- site_name: siteName,
40
- worker_name: manifest.worker_name,
41
- has_routes: String(Array.isArray(manifest.routes) && manifest.routes.length > 0),
42
- has_kv: String(Array.isArray(manifest.kv_namespaces) && manifest.kv_namespaces.length > 0),
43
- has_analytics: String(
44
- Array.isArray(manifest.analytics_engine_datasets) &&
45
- manifest.analytics_engine_datasets.length > 0,
46
- ),
47
- has_version_metadata: String(Boolean(manifest.version_metadata)),
48
- };
49
-
50
- if (ghOutput) {
51
- const lines = Object.entries(summary).map(([k, v]) => `${k}=${v}`);
52
- appendFileSync(ghOutput, `${lines.join("\n")}\n`);
53
- }
54
-
55
- console.log(`Resolved site "${siteName}" -> worker "${manifest.worker_name}"`);
56
- for (const [k, v] of Object.entries(summary)) {
57
- console.log(` ${k}: ${v}`);
58
- }