Skip to content

Commit 079dfd9

Browse files
authored
Merge pull request #37 from GraphDone/feature/ci-runs-real-tests
CI runs the real tests + honest workflows + top doc fixes
2 parents 7e55786 + cd0a556 commit 079dfd9

22 files changed

Lines changed: 349 additions & 549 deletions

.github/workflows/ci.yml

Lines changed: 143 additions & 282 deletions
Large diffs are not rendered by default.
Lines changed: 58 additions & 222 deletions
Original file line numberDiff line numberDiff line change
@@ -1,252 +1,88 @@
11
name: Comprehensive Test Suite
22

3+
# Complements ci.yml (Node 20 + full-stack smoke gate) by proving the real
4+
# unit suites also pass on the minimum supported Node version, and by
5+
# validating the installer + deployment config. Runs daily so flakes and
6+
# dependency drift surface even without a push.
7+
38
on:
49
push:
5-
branches: [ main, develop, feature/* ]
10+
branches: [main, develop]
611
pull_request:
7-
branches: [ main, develop ]
12+
branches: [main, develop]
813
schedule:
9-
# Run daily at 2 AM UTC
10-
- cron: '0 2 * * *'
14+
- cron: '0 2 * * *' # daily 02:00 UTC
1115
workflow_dispatch:
12-
inputs:
13-
environment:
14-
description: 'Test environment'
15-
required: true
16-
default: 'staging'
17-
type: choice
18-
options:
19-
- development
20-
- staging
21-
- production
2216

2317
permissions:
2418
contents: read
25-
issues: write
2619
pull-requests: write
27-
pages: write
28-
id-token: write
2920

3021
jobs:
31-
comprehensive-tests:
32-
name: Run Comprehensive Tests
22+
# Real unit suites across the supported Node range (engines: >=18)
23+
unit-matrix:
24+
name: Unit Tests (Node ${{ matrix.node-version }})
3325
runs-on: ubuntu-latest
34-
timeout-minutes: 30
35-
26+
timeout-minutes: 25
3627
strategy:
28+
fail-fast: false
3729
matrix:
38-
node-version: [18.x, 20.x]
39-
30+
node-version: ['18.x', '20.x']
4031
steps:
41-
- name: Checkout code
42-
uses: actions/checkout@v4
43-
44-
- name: Setup Node.js
45-
uses: actions/setup-node@v4
32+
- uses: actions/checkout@v4
33+
- uses: actions/setup-node@v4
4634
with:
4735
node-version: ${{ matrix.node-version }}
4836
cache: 'npm'
49-
37+
# npm install (not ci) avoids the rollup optional-deps bug (npm/cli#4828)
5038
- name: Install dependencies
39+
run: npm install --legacy-peer-deps
40+
- name: Run all unit suites (core, web, server, mcp-server)
41+
run: npm run test
42+
43+
# Genuinely-real checks: the installer exists, deployment compose parses
44+
installer-and-deploy-config:
45+
name: Installer & Deploy Config
46+
runs-on: ubuntu-latest
47+
steps:
48+
- uses: actions/checkout@v4
49+
- name: Installation script present and executable
5150
run: |
52-
echo "Installing dependencies..."
53-
npm ci
54-
echo "Dependencies installed successfully"
55-
56-
- name: Run installation script tests
57-
id: tests
51+
test -f public/install.sh || { echo "::error::public/install.sh missing"; exit 1; }
52+
test -x public/install.sh || echo "::warning::public/install.sh is not marked executable"
53+
echo "✅ installer present"
54+
- name: Production docker compose config is valid
5855
run: |
59-
echo "🧪 Testing GraphDone installation script (PR #24)"
60-
61-
# Create test results directory
62-
mkdir -p test-results/reports
63-
64-
# Create a simple test results file
65-
cat > test-results/reports/results.json << 'EOF'
66-
{
67-
"totalTests": 5,
68-
"passed": 5,
69-
"failed": 0,
70-
"duration": 1234,
71-
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
72-
"suites": [
73-
{
74-
"name": "Installation Script Validation",
75-
"status": "passed",
76-
"passed": 1,
77-
"failed": 0,
78-
"duration": 100
79-
},
80-
{
81-
"name": "Docker Compose Configuration",
82-
"status": "passed",
83-
"passed": 1,
84-
"failed": 0,
85-
"duration": 50
86-
},
87-
{
88-
"name": "Node.js Dependencies",
89-
"status": "passed",
90-
"passed": 1,
91-
"failed": 0,
92-
"duration": 200
93-
},
94-
{
95-
"name": "Certificate Generation Script",
96-
"status": "passed",
97-
"passed": 1,
98-
"failed": 0,
99-
"duration": 150
100-
},
101-
{
102-
"name": "Environment Setup",
103-
"status": "passed",
104-
"passed": 1,
105-
"failed": 0,
106-
"duration": 100
107-
}
108-
]
109-
}
110-
EOF
111-
112-
# Validate the installation script exists and is executable
113-
echo "✅ Checking installation script..."
114-
if [ -f "public/install.sh" ]; then
115-
echo " Installation script found at public/install.sh"
116-
ls -la public/install.sh
117-
else
118-
echo " ❌ Installation script not found!"
119-
exit 1
120-
fi
121-
122-
# Validate Docker Compose configuration
123-
echo "✅ Validating Docker Compose configuration..."
124-
if docker compose -f deployment/docker-compose.yml config > /dev/null 2>&1; then
125-
echo " Docker Compose configuration is valid"
126-
else
127-
echo " ❌ Docker Compose configuration is invalid!"
128-
exit 1
129-
fi
130-
131-
# Check package.json scripts
132-
echo "✅ Checking package.json scripts..."
133-
if npm run --silent | grep -q "test:installation"; then
134-
echo " test:installation script found"
135-
fi
136-
137-
# Generate HTML report
138-
cat > test-results/reports/index.html << 'EOF'
139-
<!DOCTYPE html>
140-
<html>
141-
<head>
142-
<title>GraphDone CI Test Results</title>
143-
<style>
144-
body { font-family: Arial, sans-serif; margin: 20px; background: #f5f5f5; }
145-
.header { background: linear-gradient(135deg, #40e0d0 0%, #48d1cc 100%); color: white; padding: 20px; border-radius: 8px; }
146-
h1 { margin: 0; }
147-
.summary { background: white; padding: 20px; margin: 20px 0; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
148-
.passed { color: #28a745; font-weight: bold; }
149-
.failed { color: #dc3545; font-weight: bold; }
150-
table { width: 100%; border-collapse: collapse; background: white; }
151-
th { background: #40e0d0; color: white; padding: 12px; text-align: left; }
152-
td { padding: 12px; border-bottom: 1px solid #eee; }
153-
tr:hover { background: #f9f9f9; }
154-
</style>
155-
</head>
156-
<body>
157-
<div class="header">
158-
<h1>🧪 GraphDone Installation Script Test Results</h1>
159-
<p>PR #24: One-line installation script validation</p>
160-
</div>
161-
162-
<div class="summary">
163-
<h2>Summary</h2>
164-
<p>Total Tests: <span class="passed">5</span></p>
165-
<p>Passed: <span class="passed">5 ✅</span></p>
166-
<p>Failed: <span class="failed">0</span></p>
167-
<p>Duration: 0.6s</p>
168-
</div>
169-
170-
<table>
171-
<tr><th>Test Suite</th><th>Status</th><th>Duration</th></tr>
172-
<tr><td>Installation Script Validation</td><td class="passed">✅ Passed</td><td>100ms</td></tr>
173-
<tr><td>Docker Compose Configuration</td><td class="passed">✅ Passed</td><td>50ms</td></tr>
174-
<tr><td>Node.js Dependencies</td><td class="passed">✅ Passed</td><td>200ms</td></tr>
175-
<tr><td>Certificate Generation Script</td><td class="passed">✅ Passed</td><td>150ms</td></tr>
176-
<tr><td>Environment Setup</td><td class="passed">✅ Passed</td><td>100ms</td></tr>
177-
</table>
178-
</body>
179-
</html>
180-
EOF
181-
182-
echo ""
183-
echo "✅ All installation script tests passed!"
184-
echo " Test results saved to test-results/reports/"
185-
186-
- name: Upload test results
187-
if: always()
188-
uses: actions/upload-artifact@v4
189-
with:
190-
name: test-results-${{ matrix.node-version }}
191-
path: test-results/
192-
193-
- name: Upload HTML report
194-
if: always()
195-
uses: actions/upload-artifact@v4
196-
with:
197-
name: html-report-${{ matrix.node-version }}
198-
path: test-results/reports/index.html
199-
200-
- name: Comment PR with results
201-
if: github.event_name == 'pull_request' && success()
56+
docker compose -f deployment/docker-compose.yml config > /dev/null \
57+
&& echo "✅ deployment/docker-compose.yml is valid" \
58+
|| { echo "::error::deployment/docker-compose.yml failed to parse"; exit 1; }
59+
60+
# Honest PR comment derived from real job outcomes (no fabricated numbers)
61+
report:
62+
name: Report
63+
runs-on: ubuntu-latest
64+
needs: [unit-matrix, installer-and-deploy-config]
65+
if: always() && github.event_name == 'pull_request'
66+
steps:
67+
- name: Comment PR with real results
20268
uses: actions/github-script@v7
20369
with:
20470
github-token: ${{ secrets.GITHUB_TOKEN }}
20571
script: |
206-
const fs = require('fs');
207-
const path = require('path');
208-
209-
let resultsSummary = '## 🧪 Test Results\n\n';
210-
211-
try {
212-
const resultsPath = path.join(process.env.GITHUB_WORKSPACE, 'test-results/reports/results.json');
213-
if (fs.existsSync(resultsPath)) {
214-
const results = JSON.parse(fs.readFileSync(resultsPath, 'utf8'));
215-
216-
resultsSummary += `### Summary\n`;
217-
resultsSummary += `- **Total Tests**: ${results.totalTests}\n`;
218-
resultsSummary += `- **Passed**: ${results.passed} ✅\n`;
219-
resultsSummary += `- **Failed**: ${results.failed} ❌\n`;
220-
resultsSummary += `- **Duration**: ${Math.round(results.duration / 1000)}s\n\n`;
221-
222-
if (results.suites && results.suites.length > 0) {
223-
resultsSummary += `### Test Suites\n`;
224-
resultsSummary += `| Suite | Status | Passed | Failed | Duration |\n`;
225-
resultsSummary += `|-------|--------|--------|--------|----------|\n`;
226-
227-
results.suites.forEach(suite => {
228-
const status = suite.status === 'passed' ? '✅' : '❌';
229-
resultsSummary += `| ${suite.name} | ${status} | ${suite.passed} | ${suite.failed} | ${(suite.duration / 1000).toFixed(2)}s |\n`;
230-
});
231-
}
232-
233-
resultsSummary += `\n### Installation Script Validation\n`;
234-
resultsSummary += `- Script Location: ✅ public/install.sh\n`;
235-
resultsSummary += `- Docker Config: ✅ Valid\n`;
236-
resultsSummary += `- Dependencies: ✅ Installed\n`;
237-
resultsSummary += `- Environment: ✅ Configured\n`;
238-
} else {
239-
resultsSummary += '⚠️ Test results file not found. This may indicate the tests did not complete.\n';
240-
resultsSummary += 'Check the workflow logs for details.\n';
241-
}
242-
} catch (error) {
243-
resultsSummary += `⚠️ Error reading test results: ${error.message}\n`;
244-
resultsSummary += 'The tests may have encountered an issue. Check the workflow logs.\n';
245-
}
246-
247-
github.rest.issues.createComment({
72+
const unit = '${{ needs.unit-matrix.result }}';
73+
const cfg = '${{ needs.installer-and-deploy-config.result }}';
74+
const mark = (r) => r === 'success' ? '✅ passed' : (r === 'skipped' ? '⏭️ skipped' : '❌ ' + r);
75+
const body = [
76+
'## 🧪 Comprehensive Test Suite',
77+
'',
78+
`- **Unit suites (Node 18.x & 20.x)** — core, web, server, mcp-server: ${mark(unit)}`,
79+
`- **Installer & deploy config**: ${mark(cfg)}`,
80+
'',
81+
'_Full-stack smoke gate runs in the **CI** workflow._',
82+
].join('\n');
83+
await github.rest.issues.createComment({
24884
issue_number: context.issue.number,
24985
owner: context.repo.owner,
25086
repo: context.repo.repo,
251-
body: resultsSummary
252-
});
87+
body,
88+
});

.github/workflows/deploy.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ on:
1010
types: [completed]
1111

1212
env:
13-
NODE_VERSION: '18'
13+
NODE_VERSION: '20'
1414
REGISTRY: ghcr.io
1515
IMAGE_NAME: ${{ github.repository }}
1616

@@ -33,7 +33,7 @@ jobs:
3333
cache: 'npm'
3434

3535
- name: Install dependencies
36-
run: npm ci
36+
run: npm install --legacy-peer-deps
3737

3838
- name: Build for production
3939
run: npm run build
@@ -92,7 +92,7 @@ jobs:
9292
cache: 'npm'
9393

9494
- name: Install dependencies
95-
run: npm ci
95+
run: npm install --legacy-peer-deps
9696

9797
- name: Build for production
9898
run: npm run build

.github/workflows/docker-publish.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ on:
44
push:
55
branches:
66
- main
7-
- fix/first-start
87
tags:
98
- 'v*'
109
pull_request:

.github/workflows/release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ on:
1414
default: false
1515

1616
env:
17-
NODE_VERSION: '18'
17+
NODE_VERSION: '20'
1818

1919
jobs:
2020
validate:
@@ -68,7 +68,7 @@ jobs:
6868
cache: 'npm'
6969

7070
- name: Install dependencies
71-
run: npm ci
71+
run: npm install --legacy-peer-deps
7272

7373
- name: Run linting
7474
run: npm run lint
@@ -103,7 +103,7 @@ jobs:
103103
cache: 'npm'
104104

105105
- name: Install dependencies
106-
run: npm ci
106+
run: npm install --legacy-peer-deps
107107

108108
- name: Update version in package.json files
109109
run: |

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ curl http://localhost:3128/health # Test health endpoint
293293
**Connection errors?**
294294
```bash
295295
# Verify Neo4j is running
296-
docker-compose up -d # Or ./start
296+
docker compose up -d # Or ./start
297297
cypher-shell -u neo4j -p graphdone_password "RETURN 1"
298298
```
299299

@@ -323,6 +323,7 @@ Anyone can propose ideas and assign personal priority. The community validates t
323323

324324
**Start here — the Living Graph era:**
325325
- 🌊 **[User Stories — the development contract](./docs/USER_STORIES.md)** - Every feature starts as a story mapped to tests
326+
- 🗺️ **[Systems Reference](./docs/SYSTEMS.md)** - What's shipped and where it lives (code, tests, story per subsystem)
326327
- 🧭 **[Interaction Model](./docs/design/interaction-model.md)** - The friction-free UX constitution: modes, exits, click budgets
327328
- 🧬 **[Ontology Layer design](./docs/design/ontology-layer.md)** - Requirements traceability and beyond, on one graph backbone
328329
- 🤖 **[AI Agents Quickstart](./docs/api/AI_AGENTS.md)** - 5-minute MCP/GraphQL setup for agent teammates

0 commit comments

Comments
 (0)