Skip to content

Commit d1d5487

Browse files
authored
docs: Critical documentation refactor - VitePress site with MCP install badges (#133)
* docs: migrate README to VitePress static site with MCP install badges (#24) - Add VitePress with docs:dev/build/preview scripts - Create full documentation site: guide, security, advanced, cli, tools - Migrate all README sections to dedicated pages - Add GitHub Actions workflow for docs deployment to Pages - Add MCP one-click install badges (VS Code, VS Code Insiders) - Create CONTRIBUTING.md with dev setup, testing, and PR guidelines - Reduce README from 1125 to 129 lines (links to docs site) - Fix outdated tool count: 62 → 47 (post-CQRS consolidation) - Remove outdated per-tool listings (replaced by auto-generated TOOLS.md) * ci(docs): unified Pages deployment with release trigger * ci(docs): conditional coverage on release only * docs: clean up README and fix MCP install badge URLs Remove duplicate author attribution, streamline README structure, and fix VS Code one-click install deeplinks to use correct URL-encoded JSON format. * docs(config): configurable base path and canonical domain links * ci(docs): set DOCS_BASE=/ for custom domain, add continue-on-error * ci(docs): add yarn.lock to workflow path triggers The docs deploy workflow uses `yarn install --immutable` which depends on yarn.lock. Include it in path filters so lockfile changes trigger a rebuild. * docs: clarify opt-in tool groups and read-only exceptions - Note manage_context exception in read-only mode docs - Add 'opt-in' label to disabled-by-default feature flags - Add section header explaining opt-in groups reduce tool count * docs: fix feature flag defaults, add /register endpoint, set DOCS_BASE - All feature flags default to true (code uses !== "false" pattern) - Add /register (Dynamic Client Registration) to OAuth endpoints - Set DOCS_BASE=/ in local VitePress scripts for correct local preview * docs: add missing feature flags and fix tool categorization - Add USE_RELEASES, USE_REFS, USE_MEMBERS, USE_SEARCH to all docs - Move gated tools out of "Core (Always Available)" into own sections - Fix Docker example to forward all USE_* flags - Fix npm example with all 15 feature flags
1 parent fd8e8ca commit d1d5487

24 files changed

Lines changed: 3568 additions & 1358 deletions
Lines changed: 52 additions & 281 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,14 @@
1-
# GitHub Actions Workflow: Deploy Coverage Reports to GitHub Pages
1+
# GitHub Actions Workflow: Coverage Reports for Pull Requests
22
#
3-
# This workflow runs tests with coverage, generates HTML reports, and deploys
4-
# them to GitHub Pages for easy viewing of test coverage metrics.
3+
# This workflow runs tests with coverage on PRs and comments the results.
4+
# Actual deployment to GitHub Pages is handled by docs.yml workflow.
55
#
6-
# The coverage reports will be available at:
6+
# Coverage reports on the live site:
77
# https://structured-world.github.io/gitlab-mcp/coverage/
8-
#
9-
# Triggers:
10-
# - Push to main branch (updates coverage reports)
11-
# - Pull requests (generates preview but doesn't deploy)
12-
# - Manual workflow dispatch
138

14-
name: Deploy Coverage to GitHub Pages
9+
name: Coverage Report
1510

1611
on:
17-
# Trigger on pushes to main branch
18-
push:
19-
branches:
20-
- main
21-
# Only run if relevant files changed
22-
paths:
23-
- "src/**"
24-
- "package.json"
25-
- "yarn.lock"
26-
- "tsconfig.json"
27-
- "jest.config.*"
28-
- ".github/workflows/coverage-pages.yml"
29-
30-
# Trigger on pull requests for preview
3112
pull_request:
3213
branches:
3314
- main
@@ -38,312 +19,102 @@ on:
3819
- "tsconfig.json"
3920
- "jest.config.*"
4021

41-
# Allow manual triggering
42-
workflow_dispatch:
43-
44-
# Ensure only one deployment runs at a time
4522
concurrency:
46-
group: pages-${{ github.ref }}
23+
group: coverage-${{ github.ref }}
4724
cancel-in-progress: true
4825

49-
# Set permissions for GitHub Pages deployment and PR comments
5026
permissions:
5127
contents: read
52-
pages: write
53-
id-token: write
5428
pull-requests: write
5529
issues: write
56-
actions: read
5730

5831
jobs:
59-
# Job 1: Generate coverage reports
6032
coverage:
61-
name: Generate Coverage Reports
33+
name: Generate Coverage Report
6234
runs-on: ubuntu-latest
63-
64-
# Set outputs for use in deployment job
65-
outputs:
66-
coverage-percentage: ${{ steps.coverage.outputs.percentage }}
67-
should-deploy: ${{ steps.should-deploy.outputs.result }}
68-
6935
steps:
70-
# Step 1: Check out the repository
7136
- name: Checkout repository
72-
uses: actions/checkout@v6
37+
uses: actions/checkout@v4
7338
with:
7439
fetch-depth: 0
7540

76-
# Step 2: Set up Node.js environment
7741
- name: Set up Node.js
7842
uses: actions/setup-node@v4
7943
with:
80-
node-version: "22"
81-
# Don't cache yarn yet - enable corepack first
44+
node-version: 24
8245

83-
# Step 3: Enable Corepack for Yarn 4
8446
- name: Enable Corepack
8547
run: corepack enable
8648

87-
# Step 4: Install dependencies
8849
- name: Install dependencies
8950
run: yarn install --immutable
9051

91-
# Step 5: Run tests with coverage
9252
- name: Run tests with coverage
9353
run: yarn test:cov
9454

95-
# Step 6: Extract coverage percentage for badge/display
9655
- name: Extract coverage percentage
9756
id: coverage
9857
run: |
99-
# Extract coverage percentage from Jest output
10058
COVERAGE=$(cat coverage/lcov-report/index.html | grep -o 'class="strong">[0-9.]*%' | head -1 | grep -o '[0-9.]*')
10159
echo "percentage=${COVERAGE:-0}" >> $GITHUB_OUTPUT
102-
echo "Coverage: ${COVERAGE:-0}%"
103-
104-
# Step 7: Create coverage summary for PR comments
105-
- name: Generate coverage summary
106-
if: github.event_name == 'pull_request'
107-
run: |
108-
# Extract coverage metrics from JSON summary (more reliable than HTML parsing)
109-
if [ -f coverage/coverage-summary.json ]; then
110-
STATEMENTS=$(jq -r '.total.statements.pct' coverage/coverage-summary.json)
111-
BRANCHES=$(jq -r '.total.branches.pct' coverage/coverage-summary.json)
112-
FUNCTIONS=$(jq -r '.total.functions.pct' coverage/coverage-summary.json)
113-
LINES=$(jq -r '.total.lines.pct' coverage/coverage-summary.json)
114-
else
115-
STATEMENTS="N/A"
116-
BRANCHES="N/A"
117-
FUNCTIONS="N/A"
118-
LINES="N/A"
119-
fi
120-
121-
OVERALL="${{ steps.coverage.outputs.percentage }}"
122-
123-
# Format percentages (add % only if value is numeric)
124-
format_pct() {
125-
if [[ "$1" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
126-
echo "${1}%"
127-
elif [[ "$1" == "null" ]]; then
128-
echo "N/A"
129-
else
130-
echo "$1"
131-
fi
132-
}
133-
134-
STATEMENTS_FMT=$(format_pct "$STATEMENTS")
135-
BRANCHES_FMT=$(format_pct "$BRANCHES")
136-
FUNCTIONS_FMT=$(format_pct "$FUNCTIONS")
137-
LINES_FMT=$(format_pct "$LINES")
138-
139-
# Create a markdown summary of coverage
140-
cat > coverage-summary.md << EOF
141-
## 📊 Test Coverage Report
14260
143-
**Overall Coverage:** ${OVERALL}%
144-
145-
### Coverage Details
146-
| Metric | Percentage |
147-
|--------|------------|
148-
| Statements | ${STATEMENTS_FMT} |
149-
| Branches | ${BRANCHES_FMT} |
150-
| Functions | ${FUNCTIONS_FMT} |
151-
| Lines | ${LINES_FMT} |
152-
153-
**Coverage Report:** [View detailed coverage report](https://structured-world.github.io/gitlab-mcp/coverage/)
154-
155-
> This report was generated automatically from your PR changes.
156-
EOF
157-
158-
# Step 8: Comment coverage summary on PR
15961
- name: Comment coverage on PR
160-
if: github.event_name == 'pull_request'
62+
continue-on-error: true
16163
uses: actions/github-script@v7
16264
with:
16365
github-token: ${{ secrets.GITHUB_TOKEN }}
16466
script: |
16567
const fs = require('fs');
166-
const summary = fs.readFileSync('coverage-summary.md', 'utf8');
68+
let summary;
16769
16870
try {
169-
// Find existing coverage comment
170-
const comments = await github.rest.issues.listComments({
71+
const json = JSON.parse(fs.readFileSync('coverage/coverage-summary.json', 'utf8'));
72+
const t = json.total;
73+
summary = [
74+
'## Test Coverage Report',
75+
'',
76+
`**Overall Coverage:** ${t.lines.pct}%`,
77+
'',
78+
'| Metric | Percentage |',
79+
'|--------|------------|',
80+
`| Statements | ${t.statements.pct}% |`,
81+
`| Branches | ${t.branches.pct}% |`,
82+
`| Functions | ${t.functions.pct}% |`,
83+
`| Lines | ${t.lines.pct}% |`,
84+
'',
85+
'[View detailed coverage report](https://structured-world.github.io/gitlab-mcp/coverage/)',
86+
].join('\n');
87+
} catch {
88+
summary = `## Test Coverage Report\n\n**Coverage:** ${{ steps.coverage.outputs.percentage }}%`;
89+
}
90+
91+
const comments = await github.rest.issues.listComments({
92+
owner: context.repo.owner,
93+
repo: context.repo.repo,
94+
issue_number: context.issue.number,
95+
});
96+
97+
const existing = comments.data.find(c => c.body.includes('## Test Coverage Report'));
98+
99+
if (existing) {
100+
await github.rest.issues.updateComment({
101+
owner: context.repo.owner,
102+
repo: context.repo.repo,
103+
comment_id: existing.id,
104+
body: summary
105+
});
106+
} else {
107+
await github.rest.issues.createComment({
171108
owner: context.repo.owner,
172109
repo: context.repo.repo,
173110
issue_number: context.issue.number,
111+
body: summary
174112
});
175-
176-
const existingComment = comments.data.find(comment =>
177-
comment.body.includes('## 📊 Test Coverage Report')
178-
);
179-
180-
if (existingComment) {
181-
// Update existing comment
182-
await github.rest.issues.updateComment({
183-
owner: context.repo.owner,
184-
repo: context.repo.repo,
185-
comment_id: existingComment.id,
186-
body: summary
187-
});
188-
console.log('Updated existing coverage comment');
189-
} else {
190-
// Create new comment
191-
await github.rest.issues.createComment({
192-
owner: context.repo.owner,
193-
repo: context.repo.repo,
194-
issue_number: context.issue.number,
195-
body: summary
196-
});
197-
console.log('Created new coverage comment');
198-
}
199-
} catch (error) {
200-
console.log('Failed to comment on PR (this may be due to organization permissions):', error.message);
201-
// Don't fail the workflow if commenting fails
202113
}
203114
204-
# Step 9: Prepare coverage reports for deployment
205-
- name: Prepare coverage for deployment
206-
run: |
207-
# Create deployment directory
208-
mkdir -p pages-deploy/coverage
209-
210-
# Copy coverage reports to match expected URL structure
211-
cp -r coverage/* pages-deploy/coverage/
212-
213-
# Create index.html that redirects to coverage report
214-
cat > pages-deploy/index.html << 'EOF'
215-
<!DOCTYPE html>
216-
<html lang="en">
217-
<head>
218-
<meta charset="UTF-8">
219-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
220-
<title>Project Nexus MCP - Coverage Reports</title>
221-
<meta http-equiv="refresh" content="0; url=./coverage/lcov-report/">
222-
<style>
223-
body {
224-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
225-
max-width: 800px;
226-
margin: 2rem auto;
227-
padding: 2rem;
228-
line-height: 1.6;
229-
}
230-
.header {
231-
text-align: center;
232-
margin-bottom: 2rem;
233-
}
234-
.coverage-badge {
235-
display: inline-block;
236-
padding: 0.5rem 1rem;
237-
background: #28a745;
238-
color: white;
239-
border-radius: 4px;
240-
text-decoration: none;
241-
font-weight: bold;
242-
}
243-
.links {
244-
margin-top: 2rem;
245-
}
246-
.links a {
247-
display: inline-block;
248-
margin: 0.5rem 1rem 0.5rem 0;
249-
padding: 0.5rem 1rem;
250-
background: #007bff;
251-
color: white;
252-
text-decoration: none;
253-
border-radius: 4px;
254-
}
255-
.links a:hover {
256-
background: #0056b3;
257-
}
258-
</style>
259-
</head>
260-
<body>
261-
<div class="header">
262-
<h1>Project Nexus MCP</h1>
263-
<h2>Test Coverage Reports</h2>
264-
<div class="coverage-badge">
265-
Coverage: ${{ steps.coverage.outputs.percentage }}%
266-
</div>
267-
</div>
268-
269-
<p>You will be automatically redirected to the coverage report. If not, click the link below:</p>
270-
271-
<div class="links">
272-
<a href="./coverage/lcov-report/">📊 View Coverage Report</a>
273-
<a href="https://github.com/structured-world/gitlab-mcp">📁 View Source Code</a>
274-
<a href="https://github.com/structured-world/gitlab-mcp/actions">🔄 View CI/CD</a>
275-
</div>
276-
277-
<div style="margin-top: 2rem; padding: 1rem; background: #f8f9fa; border-radius: 4px;">
278-
<h3>About This Report</h3>
279-
<p>This coverage report is automatically generated from the latest tests on the main branch.
280-
It shows which parts of the codebase are covered by tests and helps identify areas that may need additional testing.</p>
281-
282-
<p><strong>Last Updated:</strong> ${{ steps.coverage.outputs.timestamp || 'Unknown' }}</p>
283-
<p><strong>Generated by:</strong> Jest + GitHub Actions</p>
284-
</div>
285-
</body>
286-
</html>
287-
EOF
288-
289-
# Add timestamp
290-
echo "timestamp=$(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_OUTPUT
291-
292-
# Step 10: Determine if we should deploy (only on main branch pushes)
293-
- name: Determine deployment
294-
id: should-deploy
295-
run: |
296-
if [[ "${{ github.ref }}" == "refs/heads/main" && "${{ github.event_name }}" == "push" ]]; then
297-
echo "result=true" >> $GITHUB_OUTPUT
298-
else
299-
echo "result=false" >> $GITHUB_OUTPUT
300-
fi
301-
302-
# Step 11: Upload coverage artifacts for PR preview
303115
- name: Upload coverage artifacts
304-
uses: actions/upload-artifact@v6
116+
uses: actions/upload-artifact@v4
305117
with:
306118
name: coverage-reports-${{ github.sha }}
307-
path: pages-deploy/
308-
retention-days: 30
309-
310-
# Step 12: Upload pages artifact (for deployment)
311-
- name: Upload Pages artifact
312-
if: steps.should-deploy.outputs.result == 'true'
313-
uses: actions/upload-pages-artifact@v4
314-
with:
315-
path: pages-deploy/
316-
317-
# Job 2: Deploy to GitHub Pages (only on main branch)
318-
deploy:
319-
name: Deploy to GitHub Pages
320-
runs-on: ubuntu-latest
321-
needs: coverage
322-
if: needs.coverage.outputs.should-deploy == 'true'
323-
324-
# Deploy to the github-pages environment
325-
environment:
326-
name: github-pages
327-
url: ${{ steps.deployment.outputs.page_url }}
328-
329-
steps:
330-
# Step 1: Deploy to GitHub Pages
331-
- name: Deploy to GitHub Pages
332-
id: deployment
333-
uses: actions/deploy-pages@v4
334-
335-
# Step 2: Create deployment summary
336-
- name: Create deployment summary
337-
run: |
338-
echo "## 🚀 Coverage Report Deployed" >> $GITHUB_STEP_SUMMARY
339-
echo "" >> $GITHUB_STEP_SUMMARY
340-
echo "**Coverage Percentage:** ${{ needs.coverage.outputs.coverage-percentage }}%" >> $GITHUB_STEP_SUMMARY
341-
echo "" >> $GITHUB_STEP_SUMMARY
342-
echo "**📊 Live Coverage Report:** ${{ steps.deployment.outputs.page_url }}" >> $GITHUB_STEP_SUMMARY
343-
echo "" >> $GITHUB_STEP_SUMMARY
344-
echo "The coverage report has been successfully deployed and is now available at the link above." >> $GITHUB_STEP_SUMMARY
345-
echo "" >> $GITHUB_STEP_SUMMARY
346-
echo "### Quick Links" >> $GITHUB_STEP_SUMMARY
347-
echo "- [Coverage Report](${{ steps.deployment.outputs.page_url }})" >> $GITHUB_STEP_SUMMARY
348-
echo "- [Detailed Coverage](${{ steps.deployment.outputs.page_url }}coverage/lcov-report/)" >> $GITHUB_STEP_SUMMARY
349-
echo "- [Repository](https://github.com/${{ github.repository }})" >> $GITHUB_STEP_SUMMARY
119+
path: coverage/
120+
retention-days: 14

0 commit comments

Comments
 (0)