Skip to content

Commit d24a466

Browse files
chore: add install smoke test job to CI pipeline (#9)
* feat: add install smoke test job to CI pipeline Test npm pack, CLI commands, and install/uninstall flows for apex, lwc, and all profiles. Verifies correct files are installed per profile and extended content is excluded from non-full installs. * fix: fix smoke test and document local testing workflow Remove dev-only commands (doctor, status, plan, list-installed) from smoke test β€” they are not in npm package files field. Add local smoke test script (scripts/ci/smoke-test.sh). Document in CLAUDE.md and README.md.
1 parent a2dab5d commit d24a466

4 files changed

Lines changed: 373 additions & 1 deletion

File tree

β€Ž.github/workflows/ci.ymlβ€Ž

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,200 @@ jobs:
4545

4646
- name: Skills health check
4747
run: node scripts/dev/skills-health.js
48+
49+
install-smoke-test:
50+
runs-on: ubuntu-latest
51+
needs: build-and-test
52+
strategy:
53+
matrix:
54+
node-version: [20]
55+
56+
steps:
57+
- uses: actions/checkout@v6
58+
59+
- name: Setup Node.js ${{ matrix.node-version }}
60+
uses: actions/setup-node@v6
61+
with:
62+
node-version: ${{ matrix.node-version }}
63+
64+
- name: Install dependencies
65+
run: npm ci
66+
67+
- name: Build
68+
run: npm run build
69+
70+
# ── Pack tarball (simulates npm publish) ──────────────────────────
71+
- name: Create npm tarball
72+
run: |
73+
npm pack
74+
echo "TARBALL=$(ls scc-universal-*.tgz)" >> $GITHUB_ENV
75+
76+
- name: Verify tarball exists and is non-empty
77+
run: |
78+
test -f "$TARBALL"
79+
SIZE=$(stat --format=%s "$TARBALL")
80+
echo "Tarball size: ${SIZE} bytes"
81+
test "$SIZE" -gt 100000 # Must be > 100KB
82+
83+
# ── CLI help and version ──────────────────────────────────────────
84+
- name: Test CLI --help
85+
run: |
86+
node scripts/scc.js --help 2>&1 | grep -q "SCC β€” Salesforce Claude Code CLI"
87+
88+
- name: Test CLI --version
89+
run: |
90+
VERSION=$(node scripts/scc.js --version 2>&1)
91+
echo "Version output: $VERSION"
92+
echo "$VERSION" | grep -qE "^[0-9]+\.[0-9]+\.[0-9]+"
93+
94+
# ── Create dummy Salesforce project ───────────────────────────────
95+
- name: Create test project
96+
run: |
97+
mkdir -p /tmp/test-project/force-app/main/default/classes
98+
echo '{ "packageDirectories": [{ "path": "force-app", "default": true }] }' > /tmp/test-project/sfdx-project.json
99+
100+
# ── Install from tarball into test project ────────────────────────
101+
- name: Install tarball into test project
102+
run: |
103+
cd /tmp/test-project
104+
npm init -y > /dev/null 2>&1
105+
npm install "$GITHUB_WORKSPACE/$TARBALL"
106+
107+
# ── Test: scc install apex ────────────────────────────────────────
108+
- name: Test scc install apex
109+
run: |
110+
cd /tmp/test-project
111+
npx scc install apex
112+
113+
- name: Verify apex install β€” core agents
114+
run: |
115+
test -f /tmp/test-project/.claude/agents/sf-blueprint-planner.md
116+
test -f /tmp/test-project/.claude/agents/sf-code-reviewer.md
117+
test -f /tmp/test-project/.claude/agents/sf-tdd-guide.md
118+
119+
- name: Verify apex install β€” apex agents
120+
run: |
121+
test -f /tmp/test-project/.claude/agents/sf-apex-reviewer.md
122+
test -f /tmp/test-project/.claude/agents/sf-trigger-architect.md
123+
test -f /tmp/test-project/.claude/agents/sf-performance-optimizer.md
124+
125+
- name: Verify apex install β€” security agent
126+
run: |
127+
test -f /tmp/test-project/.claude/agents/sf-security-reviewer.md
128+
129+
- name: Verify apex install β€” devops agent
130+
run: |
131+
test -f /tmp/test-project/.claude/agents/sf-devops-deployment.md
132+
133+
- name: Verify apex install β€” core skills
134+
run: |
135+
test -f /tmp/test-project/.claude/skills/sf-help/SKILL.md
136+
test -f /tmp/test-project/.claude/skills/sf-quickstart/SKILL.md
137+
test -f /tmp/test-project/.claude/skills/model-route/SKILL.md
138+
139+
- name: Verify apex install β€” apex skills
140+
run: |
141+
test -f /tmp/test-project/.claude/skills/sf-trigger-frameworks/SKILL.md
142+
test -f /tmp/test-project/.claude/skills/sf-apex-async-patterns/SKILL.md
143+
test -f /tmp/test-project/.claude/skills/sf-apex-testing/SKILL.md
144+
test -f /tmp/test-project/.claude/skills/sf-apex-best-practices/SKILL.md
145+
test -f /tmp/test-project/.claude/skills/sf-apex-constraints/SKILL.md
146+
test -f /tmp/test-project/.claude/skills/sf-soql-constraints/SKILL.md
147+
148+
- name: Verify apex install β€” security skills
149+
run: |
150+
test -f /tmp/test-project/.claude/skills/sf-security/SKILL.md
151+
test -f /tmp/test-project/.claude/skills/sf-governor-limits/SKILL.md
152+
test -f /tmp/test-project/.claude/skills/sf-soql-optimization/SKILL.md
153+
154+
- name: Verify apex install β€” devops skills
155+
run: |
156+
test -f /tmp/test-project/.claude/skills/sf-deployment/SKILL.md
157+
test -f /tmp/test-project/.claude/skills/sf-deployment-constraints/SKILL.md
158+
159+
- name: Verify apex install β€” hooks
160+
run: |
161+
test -f /tmp/test-project/.claude/hooks/hooks.json
162+
163+
- name: Verify apex install β€” reference files
164+
run: |
165+
test -d /tmp/test-project/.claude/skills/_reference
166+
test -f /tmp/test-project/.claude/skills/_reference/GOVERNOR_LIMITS.md
167+
168+
- name: Verify apex install β€” NO extended content (should not be installed)
169+
run: |
170+
test ! -f /tmp/test-project/.claude/agents/sf-agentforce-builder.md
171+
test ! -f /tmp/test-project/.claude/agents/sf-flow-reviewer.md
172+
test ! -f /tmp/test-project/.claude/skills/sf-flow-development/SKILL.md
173+
174+
# ── Test: scc uninstall ───────────────────────────────────────────
175+
- name: Test scc uninstall
176+
run: |
177+
cd /tmp/test-project
178+
npx scc uninstall --yes
179+
180+
- name: Verify uninstall removed files
181+
run: |
182+
test ! -f /tmp/test-project/.claude/agents/sf-apex-reviewer.md
183+
test ! -f /tmp/test-project/.claude/skills/sf-apex-testing/SKILL.md
184+
185+
# ── Test: scc install all (full profile) ──────────────────────────
186+
- name: Test scc install all
187+
run: |
188+
cd /tmp/test-project
189+
npx scc install all
190+
191+
- name: Verify full install β€” extended agents present
192+
run: |
193+
test -f /tmp/test-project/.claude/agents/sf-agentforce-builder.md
194+
test -f /tmp/test-project/.claude/agents/sf-flow-reviewer.md
195+
test -f /tmp/test-project/.claude/agents/sf-visualforce-reviewer.md
196+
test -f /tmp/test-project/.claude/agents/sf-aura-reviewer.md
197+
test -f /tmp/test-project/.claude/agents/sf-admin.md
198+
199+
- name: Verify full install β€” extended skills present
200+
run: |
201+
test -f /tmp/test-project/.claude/skills/sf-flow-development/SKILL.md
202+
test -f /tmp/test-project/.claude/skills/sf-agentforce-development/SKILL.md
203+
test -f /tmp/test-project/.claude/skills/sf-visualforce-development/SKILL.md
204+
test -f /tmp/test-project/.claude/skills/sf-aura-development/SKILL.md
205+
test -f /tmp/test-project/.claude/skills/sf-experience-cloud/SKILL.md
206+
207+
- name: Verify full install β€” platform agents present
208+
run: |
209+
test -f /tmp/test-project/.claude/agents/deep-researcher.md
210+
test -f /tmp/test-project/.claude/agents/sf-integration-architect.md
211+
test -f /tmp/test-project/.claude/agents/sf-build-resolver.md
212+
213+
- name: Verify full install β€” platform skills present
214+
run: |
215+
test -f /tmp/test-project/.claude/skills/sf-apex-cursor/SKILL.md
216+
test -f /tmp/test-project/.claude/skills/sf-data-modeling/SKILL.md
217+
test -f /tmp/test-project/.claude/skills/sf-debugging/SKILL.md
218+
219+
# ── Test: scc install lwc (after clean uninstall) ─────────────────
220+
- name: Clean uninstall before lwc test
221+
run: |
222+
cd /tmp/test-project
223+
npx scc uninstall --yes
224+
225+
- name: Test scc install lwc
226+
run: |
227+
cd /tmp/test-project
228+
npx scc install lwc
229+
230+
- name: Verify lwc install β€” lwc agent and skills present
231+
run: |
232+
test -f /tmp/test-project/.claude/agents/sf-lwc-reviewer.md
233+
test -f /tmp/test-project/.claude/skills/sf-lwc-development/SKILL.md
234+
test -f /tmp/test-project/.claude/skills/sf-lwc-testing/SKILL.md
235+
test -f /tmp/test-project/.claude/skills/sf-lwc-constraints/SKILL.md
236+
237+
- name: Verify lwc install β€” NO apex-specific agents
238+
run: |
239+
test ! -f /tmp/test-project/.claude/agents/sf-apex-reviewer.md
240+
test ! -f /tmp/test-project/.claude/agents/sf-trigger-architect.md
241+
242+
# ── Summary ───────────────────────────────────────────────────────
243+
- name: Smoke test passed
244+
run: echo "All install smoke tests passed successfully"

β€ŽCLAUDE.mdβ€Ž

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ npx markdownlint '**/*.md' --ignore node_modules --fix
4444
# Coverage (80% lines/functions/branches/statements required)
4545
npm run coverage
4646

47+
# Smoke test (tests npm pack + install/uninstall in a temp project)
48+
bash scripts/ci/smoke-test.sh
49+
4750
# SCC CLI
4851
npx scc install <target> # Install SCC content (apex, lwc, all)
4952
npx scc doctor # Diagnose missing/drifted files

β€ŽREADME.mdβ€Ž

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,9 @@ Contributions are welcome! Please follow these guidelines:
487487
git clone <repo>
488488
cd salesforce-claude-code
489489
npm install
490-
npm test
490+
git config core.hooksPath .githooks # Enable pre-commit checks
491+
npm test # Build + lint + validate + tests
492+
bash scripts/ci/smoke-test.sh # Pack + install/uninstall smoke test
491493
```
492494

493495
---

β€Žscripts/ci/smoke-test.shβ€Ž

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#!/usr/bin/env bash
2+
# Local smoke test β€” mirrors the CI install-smoke-test job.
3+
# Run from repo root: bash scripts/ci/smoke-test.sh
4+
set -euo pipefail
5+
6+
RED='\033[0;31m'
7+
GREEN='\033[0;32m'
8+
CYAN='\033[0;36m'
9+
NC='\033[0m'
10+
11+
PASS=0
12+
FAIL=0
13+
TEST_DIR=$(mktemp -d)
14+
15+
pass() { echo -e " ${GREEN}PASS${NC} $1"; PASS=$((PASS + 1)); }
16+
fail() { echo -e " ${RED}FAIL${NC} $1"; FAIL=$((FAIL + 1)); }
17+
section() { echo -e "\n${CYAN}── $1 ──${NC}"; }
18+
19+
cleanup() {
20+
rm -rf "$TEST_DIR"
21+
rm -f scc-universal-*.tgz
22+
}
23+
trap cleanup EXIT
24+
25+
REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
26+
cd "$REPO_ROOT"
27+
28+
# ── Pack ────────────────────────────────────────────────────────────────────
29+
section "npm pack"
30+
31+
npm pack --quiet > /dev/null 2>&1
32+
TARBALL=$(ls scc-universal-*.tgz 2>/dev/null | head -1)
33+
34+
if [ -n "$TARBALL" ] && [ -f "$TARBALL" ]; then
35+
SIZE=$(stat -f%z "$TARBALL" 2>/dev/null || stat --format=%s "$TARBALL" 2>/dev/null)
36+
if [ "$SIZE" -gt 100000 ]; then
37+
pass "tarball created (${SIZE} bytes)"
38+
else
39+
fail "tarball too small (${SIZE} bytes)"
40+
fi
41+
else
42+
fail "tarball not created"
43+
fi
44+
45+
# ── CLI help & version ──────────────────────────────────────────────────────
46+
section "CLI commands"
47+
48+
if node scripts/scc.js --help 2>&1 | grep -q "SCC β€” Salesforce Claude Code CLI"; then
49+
pass "scc --help"
50+
else
51+
fail "scc --help"
52+
fi
53+
54+
if node scripts/scc.js --version 2>&1 | grep -qE "^[0-9]+\.[0-9]+\.[0-9]+"; then
55+
pass "scc --version"
56+
else
57+
fail "scc --version"
58+
fi
59+
60+
# ── Create test project ────────────────────────────────────────────────────
61+
section "Setup test project"
62+
63+
mkdir -p "$TEST_DIR/force-app/main/default/classes"
64+
echo '{ "packageDirectories": [{ "path": "force-app", "default": true }] }' > "$TEST_DIR/sfdx-project.json"
65+
cd "$TEST_DIR"
66+
npm init -y > /dev/null 2>&1
67+
npm install "$REPO_ROOT/$TARBALL" > /dev/null 2>&1
68+
pass "test project created and tarball installed"
69+
70+
# ── Install apex ────────────────────────────────────────────────────────────
71+
section "scc install apex"
72+
73+
npx scc install apex > /dev/null 2>&1
74+
75+
# Core agents
76+
for f in sf-blueprint-planner.md sf-code-reviewer.md sf-tdd-guide.md; do
77+
if [ -f ".claude/agents/$f" ]; then pass "core agent: $f"; else fail "core agent: $f"; fi
78+
done
79+
80+
# Apex agents
81+
for f in sf-apex-reviewer.md sf-trigger-architect.md sf-performance-optimizer.md; do
82+
if [ -f ".claude/agents/$f" ]; then pass "apex agent: $f"; else fail "apex agent: $f"; fi
83+
done
84+
85+
# Security + devops agents
86+
if [ -f ".claude/agents/sf-security-reviewer.md" ]; then pass "security agent"; else fail "security agent"; fi
87+
if [ -f ".claude/agents/sf-devops-deployment.md" ]; then pass "devops agent"; else fail "devops agent"; fi
88+
89+
# Core skills
90+
for f in sf-help sf-quickstart model-route; do
91+
if [ -f ".claude/skills/$f/SKILL.md" ]; then pass "core skill: $f"; else fail "core skill: $f"; fi
92+
done
93+
94+
# Apex skills
95+
for f in sf-trigger-frameworks sf-apex-async-patterns sf-apex-testing sf-apex-best-practices sf-apex-constraints sf-soql-constraints; do
96+
if [ -f ".claude/skills/$f/SKILL.md" ]; then pass "apex skill: $f"; else fail "apex skill: $f"; fi
97+
done
98+
99+
# Security skills
100+
for f in sf-security sf-governor-limits sf-soql-optimization; do
101+
if [ -f ".claude/skills/$f/SKILL.md" ]; then pass "security skill: $f"; else fail "security skill: $f"; fi
102+
done
103+
104+
# Devops skills
105+
for f in sf-deployment sf-deployment-constraints; do
106+
if [ -f ".claude/skills/$f/SKILL.md" ]; then pass "devops skill: $f"; else fail "devops skill: $f"; fi
107+
done
108+
109+
# Hooks
110+
if [ -f ".claude/hooks/hooks.json" ]; then pass "hooks installed"; else fail "hooks installed"; fi
111+
112+
# Reference files
113+
if [ -d ".claude/skills/_reference" ]; then pass "reference dir exists"; else fail "reference dir exists"; fi
114+
115+
# Negative: no extended content
116+
if [ ! -f ".claude/agents/sf-agentforce-builder.md" ]; then pass "no extended agent (correct)"; else fail "extended agent leaked into apex profile"; fi
117+
if [ ! -f ".claude/skills/sf-flow-development/SKILL.md" ]; then pass "no extended skill (correct)"; else fail "extended skill leaked into apex profile"; fi
118+
119+
# ── Uninstall ───────────────────────────────────────────────────────────────
120+
section "scc uninstall"
121+
122+
npx scc uninstall --yes > /dev/null 2>&1
123+
124+
if [ ! -f ".claude/agents/sf-apex-reviewer.md" ]; then pass "uninstall removed agents"; else fail "uninstall did not remove agents"; fi
125+
if [ ! -f ".claude/skills/sf-apex-testing/SKILL.md" ]; then pass "uninstall removed skills"; else fail "uninstall did not remove skills"; fi
126+
127+
# ── Install all ─────────────────────────────────────────────────────────────
128+
section "scc install all"
129+
130+
npx scc install all > /dev/null 2>&1
131+
132+
# Extended agents
133+
for f in sf-agentforce-builder.md sf-flow-reviewer.md sf-visualforce-reviewer.md sf-aura-reviewer.md sf-admin.md; do
134+
if [ -f ".claude/agents/$f" ]; then pass "extended agent: $f"; else fail "extended agent: $f"; fi
135+
done
136+
137+
# Extended skills
138+
for f in sf-flow-development sf-agentforce-development sf-visualforce-development sf-aura-development sf-experience-cloud; do
139+
if [ -f ".claude/skills/$f/SKILL.md" ]; then pass "extended skill: $f"; else fail "extended skill: $f"; fi
140+
done
141+
142+
# Platform agents
143+
for f in deep-researcher.md sf-integration-architect.md sf-build-resolver.md; do
144+
if [ -f ".claude/agents/$f" ]; then pass "platform agent: $f"; else fail "platform agent: $f"; fi
145+
done
146+
147+
# ── Install lwc (after clean) ──────────────────────────────────────────────
148+
section "scc install lwc"
149+
150+
npx scc uninstall --yes > /dev/null 2>&1
151+
npx scc install lwc > /dev/null 2>&1
152+
153+
if [ -f ".claude/agents/sf-lwc-reviewer.md" ]; then pass "lwc agent"; else fail "lwc agent"; fi
154+
for f in sf-lwc-development sf-lwc-testing sf-lwc-constraints; do
155+
if [ -f ".claude/skills/$f/SKILL.md" ]; then pass "lwc skill: $f"; else fail "lwc skill: $f"; fi
156+
done
157+
158+
# Negative: no apex agents in lwc profile
159+
if [ ! -f ".claude/agents/sf-apex-reviewer.md" ]; then pass "no apex agent in lwc (correct)"; else fail "apex agent leaked into lwc profile"; fi
160+
if [ ! -f ".claude/agents/sf-trigger-architect.md" ]; then pass "no trigger agent in lwc (correct)"; else fail "trigger agent leaked into lwc profile"; fi
161+
162+
# ── Summary ─────────────────────────────────────────────────────────────────
163+
echo ""
164+
echo "════════════════════════════════════════════════════════"
165+
echo -e "Results: ${GREEN}${PASS} passed${NC}, ${RED}${FAIL} failed${NC} ($((PASS + FAIL)) total)"
166+
echo "════════════════════════════════════════════════════════"
167+
168+
if [ "$FAIL" -gt 0 ]; then
169+
exit 1
170+
fi

0 commit comments

Comments
Β (0)