Skip to content

Commit d31e62e

Browse files
mcp-tool-shopclaude
andcommitted
ci: GitHub Actions workflow + prettier formatting
CI pipeline enforces on every push/PR: 1. prettier --check (format consistency) 2. validate.mjs (schema + invariant checks) 3. gen-lock.mjs --check (lockfile drift detection) Workflow uses ubuntu-latest, Node 22, paths filter, concurrency groups. All existing files formatted with prettier. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 95937cc commit d31e62e

8 files changed

Lines changed: 102 additions & 60 deletions

File tree

.github/workflows/ci.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "marketing/**"
8+
- "package.json"
9+
- "package-lock.json"
10+
- ".prettierrc"
11+
- ".github/workflows/**"
12+
pull_request:
13+
branches: [main]
14+
paths:
15+
- "marketing/**"
16+
- "package.json"
17+
- "package-lock.json"
18+
- ".prettierrc"
19+
- ".github/workflows/**"
20+
workflow_dispatch:
21+
22+
concurrency:
23+
group: ${{ github.workflow }}-${{ github.ref }}
24+
cancel-in-progress: true
25+
26+
jobs:
27+
validate:
28+
runs-on: ubuntu-latest
29+
steps:
30+
- uses: actions/checkout@v4
31+
32+
- uses: actions/setup-node@v4
33+
with:
34+
node-version: 22
35+
cache: npm
36+
37+
- name: Install dependencies
38+
run: npm ci
39+
40+
- name: Format check
41+
run: npm run fmt:check
42+
43+
- name: Schema + invariant validation
44+
run: npm run validate
45+
46+
- name: Lockfile drift check
47+
run: npm run lock:check

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ These rules are non-negotiable. CI enforces them.
1818

1919
Every claim has a `status`:
2020

21-
| Status | Meaning |
22-
|--------|---------|
23-
| `proven` | Backed by at least one `evidenceRef` |
21+
| Status | Meaning |
22+
| -------------- | ---------------------------------------- |
23+
| `proven` | Backed by at least one `evidenceRef` |
2424
| `aspirational` | Believed true, evidence not yet captured |
25-
| `deprecated` | No longer valid — kept for audit trail |
25+
| `deprecated` | No longer valid — kept for audit trail |
2626

2727
**Proven claims require evidence.** If a claim is `proven`, it must reference at least one entry in the evidence manifest. CI rejects proven claims with zero evidence.
2828

marketing/data/campaigns/zmm-launch.json

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,24 @@
33
"id": "camp.zip-meta-map.launch",
44
"name": "zip-meta-map Launch",
55
"toolRef": "tool.zip-meta-map",
6-
"audienceRefs": [
7-
"aud.ci-maintainers",
8-
"aud.llm-toolchain-devs"
9-
],
6+
"audienceRefs": ["aud.ci-maintainers", "aud.llm-toolchain-devs"],
107
"phases": [
118
{
129
"name": "Soft launch",
1310
"channels": ["readme", "web"],
14-
"messageRefs": [
15-
"msg.zip-meta-map.readme-snippet",
16-
"msg.zip-meta-map.web-blurb"
17-
],
11+
"messageRefs": ["msg.zip-meta-map.readme-snippet", "msg.zip-meta-map.web-blurb"],
1812
"notes": "Get the tool page and README polished before any external promotion."
1913
},
2014
{
2115
"name": "Community launch",
2216
"channels": ["hn", "x"],
23-
"messageRefs": [
24-
"msg.zip-meta-map.hn-post",
25-
"msg.zip-meta-map.x-post"
26-
],
17+
"messageRefs": ["msg.zip-meta-map.hn-post", "msg.zip-meta-map.x-post"],
2718
"notes": "HN Show + X post. Time for weekday morning US-East."
2819
},
2920
{
3021
"name": "Professional outreach",
3122
"channels": ["linkedin"],
32-
"messageRefs": [
33-
"msg.zip-meta-map.linkedin-post"
34-
],
23+
"messageRefs": ["msg.zip-meta-map.linkedin-post"],
3524
"notes": "LinkedIn post targeting engineering leaders and DevOps."
3625
}
3726
]
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
{
22
"schemaVersion": "1.0.0",
3-
"tools": [
4-
{ "ref": "tools/zip-meta-map.json" }
5-
],
3+
"tools": [{ "ref": "tools/zip-meta-map.json" }],
64
"audiences": [
75
{ "ref": "audiences/ci-maintainers.json" },
86
{ "ref": "audiences/llm-toolchain-devs.json" }
97
],
10-
"campaigns": [
11-
{ "ref": "campaigns/zmm-launch.json" }
12-
]
8+
"campaigns": [{ "ref": "campaigns/zmm-launch.json" }]
139
}

marketing/data/tools/zip-meta-map.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@
1111
"JSON Schema-validated output with 246 tests backing correctness"
1212
]
1313
},
14-
"audienceRefs": [
15-
"aud.ci-maintainers",
16-
"aud.llm-toolchain-devs"
17-
],
14+
"audienceRefs": ["aud.ci-maintainers", "aud.llm-toolchain-devs"],
1815
"claims": [
1916
{
2017
"id": "claim.zip-meta-map.deterministic-output",
Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,42 @@
11
{
22
"schemaVersion": "1.0.0",
3-
"generatedAt": "2026-02-15T12:30:00.000Z",
4-
"generator": "manual",
3+
"generatedAt": "2026-02-15T21:12:01.885Z",
4+
"generator": "gen-lock.mjs",
55
"files": [
6-
{
7-
"path": "marketing/schema/marketing.schema.json",
8-
"sha256": "975c3929d45570f1fb6fa4af7911f4abab6513fc3a4597eefdf1a2d25a656159",
9-
"bytes": 9881
10-
},
11-
{
12-
"path": "marketing/data/marketing.index.json",
13-
"sha256": "85b7a170ecd701196c2fe66fefe36624644c106cdd8ad89cc31f95fd0b185024",
14-
"bytes": 289
15-
},
166
{
177
"path": "marketing/data/audiences/ci-maintainers.json",
18-
"sha256": "55521aa57f741bef8689a36bde35f8faf611cc620422aedac159b3bde56364d3",
19-
"bytes": 569
8+
"sha256": "23c72f87076ad2e24aef2946d1822ca6a57cde35df0138ddb29b8eda559e433c",
9+
"bytes": 557
2010
},
2111
{
2212
"path": "marketing/data/audiences/llm-toolchain-devs.json",
23-
"sha256": "5939bbaaaa7625b089380b91eaedc218d8af19437f2d02162b68e91a754eea4c",
24-
"bytes": 556
13+
"sha256": "554cade261636daf117dd171360d358fe01c8256da50eb7121b8b8e963cc5273",
14+
"bytes": 544
2515
},
2616
{
2717
"path": "marketing/data/campaigns/zmm-launch.json",
28-
"sha256": "9818fb121380f2395bdddd7b8e34233ef71cf923339dc5dd2f4e6e7679a05331",
29-
"bytes": 1026
18+
"sha256": "34d1a30c4c707d41c9148b1f4cd61015ebbff5517a75bbfe8cc67c2876fdab95",
19+
"bytes": 912
20+
},
21+
{
22+
"path": "marketing/data/marketing.index.json",
23+
"sha256": "9137efb54803bab72c54f07bd3844e45d14ba5907e8533ae6ab1ee61d035630e",
24+
"bytes": 260
3025
},
3126
{
3227
"path": "marketing/data/tools/zip-meta-map.json",
33-
"sha256": "11d0ffd15020c8d058ce06ec26c4e3165b2f744b146bcd46b21839bcd4d6cace",
34-
"bytes": 5673
28+
"sha256": "5977b2dd52eb636ec13c9d1f994ec121372060bf3547bfd11345ab48eb2e9598",
29+
"bytes": 5526
3530
},
3631
{
3732
"path": "marketing/manifests/evidence.manifest.json",
38-
"sha256": "4f00f47e797bbed860d9ab7c08dd526e75269c9a918f15693a41b7aad81dbd77",
39-
"bytes": 2287
33+
"sha256": "31012157847f80e1fb4e60a90b2786a9250001f1178166669f6de01d37e60cbd",
34+
"bytes": 2230
35+
},
36+
{
37+
"path": "marketing/schema/marketing.schema.json",
38+
"sha256": "d0afc0bc75064139a00e9acd2bee16f9f6e07bb300592492aaf41587a5294390",
39+
"bytes": 9579
4040
}
4141
]
4242
}

marketing/schema/marketing.schema.json

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,16 @@
145145

146146
"tool": {
147147
"type": "object",
148-
"required": ["schemaVersion", "id", "name", "positioning", "audienceRefs", "claims", "antiClaims", "messages"],
148+
"required": [
149+
"schemaVersion",
150+
"id",
151+
"name",
152+
"positioning",
153+
"audienceRefs",
154+
"claims",
155+
"antiClaims",
156+
"messages"
157+
],
149158
"properties": {
150159
"schemaVersion": { "$ref": "#/$defs/schemaVersion" },
151160
"id": { "$ref": "#/$defs/toolId" },
@@ -261,10 +270,7 @@
261270
}
262271
},
263272
"additionalProperties": false,
264-
"anyOf": [
265-
{ "required": ["path"] },
266-
{ "required": ["url"] }
267-
]
273+
"anyOf": [{ "required": ["path"] }, { "required": ["url"] }]
268274
},
269275

270276
"campaignPhase": {

marketing/scripts/validate.mjs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ const evidenceManifest = JSON.parse(evidenceText);
8787
const evidenceIds = new Set();
8888
for (const entry of evidenceManifest.entries) {
8989
if (!validateEvidence(entry)) {
90-
for (const e of validateEvidence.errors) fail(`evidence ${entry.id}: ${e.instancePath} ${e.message}`);
90+
for (const e of validateEvidence.errors)
91+
fail(`evidence ${entry.id}: ${e.instancePath} ${e.message}`);
9192
}
9293
checkUniqueId(entry.id, "evidence.manifest.json");
9394
evidenceIds.add(entry.id);
@@ -115,7 +116,9 @@ for (const { ref } of index.tools) {
115116
if (claim.evidenceRefs) {
116117
for (const evRef of claim.evidenceRefs) {
117118
if (!evidenceIds.has(evRef)) {
118-
fail(`${ref}: claim ${claim.id} references evidence ${evRef} which is not in the manifest`);
119+
fail(
120+
`${ref}: claim ${claim.id} references evidence ${evRef} which is not in the manifest`,
121+
);
119122
}
120123
}
121124
}
@@ -126,7 +129,9 @@ for (const { ref } of index.tools) {
126129
checkUniqueId(msg.id, ref);
127130
for (const claimRef of msg.claimRefs) {
128131
if (!claimIds.has(claimRef)) {
129-
fail(`${ref}: message ${msg.id} references claim ${claimRef} which is not in this tool's claims`);
132+
fail(
133+
`${ref}: message ${msg.id} references claim ${claimRef} which is not in this tool's claims`,
134+
);
130135
}
131136
}
132137
}
@@ -170,7 +175,9 @@ for (const { ref } of index.campaigns) {
170175
if (phase.messageRefs) {
171176
for (const msgRef of phase.messageRefs) {
172177
if (!toolMsgIds.has(msgRef)) {
173-
fail(`${ref}: phase "${phase.name}" references message ${msgRef} which is not in tool ${campaign.toolRef}`);
178+
fail(
179+
`${ref}: phase "${phase.name}" references message ${msgRef} which is not in tool ${campaign.toolRef}`,
180+
);
174181
}
175182
}
176183
}

0 commit comments

Comments
 (0)