Skip to content

Commit 7123d52

Browse files
rubenmarcusclaude
andauthored
feat: add security scanning and code quality tools (#129)
* feat(docs): landing page improvements and new standalone pages - Add QuickStart section with 3-step installation guide - Add UseCases section showcasing Figma, GitHub, Linear, Notion workflows - Create /templates page with all 18 templates from ralph-templates repo - Create /use-cases page with detailed workflow explanations - Create /integrations page with setup guides for all sources - Add navbar links to new pages - Remove tooltips from ClientShowcase section - Fix robots.txt invalid syntax (orphaned directives) - Add Google Analytics 4 tracking (G-4HSM6GRG3R) - Update docs to use ralph-starter config commands instead of export - Add docs:dev, docs:build, docs:serve scripts to root package.json Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(docs): prevent subtitle line break in QuickStart section Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: update LLM provider configuration instructions - Add config commands for Anthropic, OpenAI, and OpenRouter - Update config.md with all provider keys and env variables - Fix storage location (config.json, not sources.json) - Add Figma token to documented config keys Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: link to ghuntley.com/ralph instead of inline explanation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: remove duplicate command tables and sections Removed redundant sections: - Integrations & Input Sources (duplicated main Integrations section) - Quick Setup table (duplicated integrations table) - Managing Integrations (duplicated integrations code examples) - Integration Commands (duplicated integrations section) - Source Commands (Legacy) (outdated) - Managing Config (duplicated Config Commands) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: streamline README structure - Fix Table of Contents to match actual sections - Remove redundant "Summary" header - Keep Key Features table in a cleaner position Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(git): add labels support to createPullRequest - Add labels field to PROptions interface - Auto-create labels using gh label create --force - Apply labels to PR using --label flags Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(git): add semantic PR title generator - Add generateSemanticPrTitle() function - Infer type from task: fix, test, docs, refactor, perf - Format: type(scope): lowercase description - Ensures title passes semantic PR validation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(git): add PR body formatter with issue linking - Add formatPrBody() function for proper markdown PR bodies - Include issue linking with Closes owner/repo#number format - Add task summary, commits list, and execution details - Properly detected by pr-issue-check.yml action Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(executor): use semantic titles and AUTO label for auto mode - Import new git utilities for title generation and body formatting - Add prLabels, prIssueRef, prType to LoopOptions interface - Generate semantic PR titles: feat(auto): description - Format PR body with proper markdown sections - Auto-add AUTO label when running in auto mode - Include issue reference for auto-close on merge Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(run): extract issue reference from source metadata - Import IssueRef type from git module - Extract owner/repo/number from GitHub source metadata - Pass prIssueRef and prLabels to loop executor - Remove hardcoded prTitle generation (let executor handle it) - AUTO label added for auto mode runs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: update CHANGELOG.md and auto-generate on release - Backfill CHANGELOG.md with all beta releases from 0.1.1-beta.1 to beta.15 - Update prepare-release workflow to auto-generate changelog entries - Use node script to avoid YAML parsing issues with markdown syntax Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: add security scanning and code quality tools - Add CodeRabbit config with custom review instructions - Add security.yml with CodeQL, Trivy, Gitleaks, OSSF Scorecard - Add SonarCloud integration for code quality metrics - Add bundle analysis workflow for PR size monitoring - Add stale workflow to keep issues/PRs clean - Add workflow to trigger CodeRabbit on all open PRs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: remove SonarCloud (not needed for now) * fix: remove invalid CodeRabbit properties and fix dependency-review * chore: add CodeRabbit as default reviewer in CODEOWNERS * feat: smart auto-labeling and auto-assign for PRs - Add auto-label.yml with intelligent label detection: - Labels based on changed files (core, docs, ci/cd, security, etc.) - Labels based on PR title (feat, fix, docs, etc.) - Only adds candidate-release for actual src changes - Auto-assign @rubenmarcus on PRs they create - Remove duplicate auto-label job from prepare-release.yml Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address CodeRabbit review feedback on workflows - bundle-analysis.yml: Add build failure handling, fix divide-by-zero, fix shell substitution in JS - coderabbit-review.yml: Use pagination for PRs, handle empty TS files, deduplicate issues - prepare-release.yml: Extract changelog logic to external script with dynamic insertion - security.yml: Remove redundant Trivy (have CodeQL + Dependency Review), fix scorecard permissions - stale.yml: Remove bug/enhancement from exempt labels, add release to exempt PR labels Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: add manual trigger to security scanning workflow * fix: migrate dependency-review to config file (fix deprecation warning) * fix(security): update dependencies to fix high/medium vulnerabilities - Fix @modelcontextprotocol/sdk cross-client data leak (HIGH) - Fix hono XSS, cache deception, IP spoofing vulnerabilities (MEDIUM) Remaining issues are in dev-only dependencies (esbuild, lodash, tmp) and don't affect the published CLI. * fix: remove allow-licenses from dependency-review config * fix: shorten CodeRabbit tone_instructions (max 250 chars) --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent a9a509a commit 7123d52

File tree

11 files changed

+826
-79
lines changed

11 files changed

+826
-79
lines changed

.coderabbit.yaml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# CodeRabbit Configuration
2+
# Documentation: https://docs.coderabbit.ai/configuration
3+
4+
language: en-US
5+
6+
# Review settings
7+
reviews:
8+
# Enable automatic reviews on PRs
9+
auto_review:
10+
enabled: true
11+
# Review drafts too
12+
drafts: false
13+
# Base branches to review
14+
base_branches:
15+
- main
16+
- develop
17+
18+
# Review profile - assertive for thorough reviews
19+
profile: assertive
20+
21+
# Request changes instead of just commenting when issues found
22+
request_changes_workflow: true
23+
24+
# High-level summary at the top of review
25+
high_level_summary: true
26+
27+
# Add poem to reviews (fun touch)
28+
poem: false
29+
30+
# Review scope
31+
path_filters:
32+
# Always review these
33+
- "src/**"
34+
- "docs/**"
35+
- ".github/**"
36+
# Ignore these
37+
- "!**/node_modules/**"
38+
- "!**/dist/**"
39+
- "!**/*.lock"
40+
- "!**/pnpm-lock.yaml"
41+
- "!**/package-lock.json"
42+
43+
# Collapse walkthrough for large PRs
44+
collapse_walkthrough: true
45+
46+
# Enable sequence diagrams for complex flows
47+
sequence_diagrams: true
48+
49+
# Chat settings for interacting with CodeRabbit
50+
chat:
51+
# Enable chat commands in PR comments
52+
auto_reply: true
53+
54+
# Early access features
55+
early_access: true
56+
57+
# Knowledge base for project context
58+
knowledge_base:
59+
# Learn from merged PRs
60+
learnings:
61+
scope: auto
62+
# Learn from repo issues
63+
issues:
64+
scope: auto
65+
66+
# Tone and style instructions (max 250 chars)
67+
tone_instructions: "Be constructive. Focus on security (OWASP), TypeScript best practices, performance, and test coverage. This is a CLI tool - check for credential handling, path traversal, proper exit codes."

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
33

44
# Default owner for everything
5-
* @rubenmarcus
5+
* @rubenmarcus @coderabbitai
66

77
# Core CLI source code
88
/src/ @rubenmarcus
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Dependency Review Configuration
2+
# https://github.com/actions/dependency-review-action#configuration-options
3+
4+
# Fail on high/critical vulnerabilities
5+
fail-on-severity: high
6+
7+
# Deny copyleft licenses that could cause licensing issues
8+
# (can't use both allow and deny, so we deny problematic ones)
9+
deny-licenses:
10+
- GPL-3.0
11+
- GPL-3.0-only
12+
- GPL-3.0-or-later
13+
- AGPL-3.0
14+
- AGPL-3.0-only
15+
- AGPL-3.0-or-later
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Updates CHANGELOG.md with a new release entry
4+
*
5+
* Usage: node update-changelog.js <title>
6+
* Environment variables:
7+
* - NEW_VERSION: The new version number
8+
* - TODAY: The release date (YYYY-MM-DD)
9+
* - CHANGE_TYPE: The type of change (Added, Fixed, Changed)
10+
* - SOURCE_PR: The PR number
11+
*/
12+
13+
const fs = require('fs');
14+
const path = require('path');
15+
16+
const version = process.env.NEW_VERSION;
17+
const date = process.env.TODAY;
18+
const changeType = process.env.CHANGE_TYPE;
19+
const pr = process.env.SOURCE_PR;
20+
const title = process.argv[2];
21+
22+
if (!version || !date || !changeType || !pr || !title) {
23+
console.error('Missing required environment variables or arguments');
24+
console.error('Required env: NEW_VERSION, TODAY, CHANGE_TYPE, SOURCE_PR');
25+
console.error('Required arg: title');
26+
process.exit(1);
27+
}
28+
29+
const changelogPath = path.join(process.cwd(), 'CHANGELOG.md');
30+
const entry = `## [${version}] - ${date}\n\n### ${changeType}\n- ${title} (#${pr})\n\n`;
31+
32+
let changelog = fs.readFileSync(changelogPath, 'utf8');
33+
const lines = changelog.split('\n');
34+
35+
// Find insertion point dynamically
36+
// First try to find a sentinel marker
37+
let insertIdx = lines.findIndex(l => l.trim().startsWith('<!-- CHANGELOG_ENTRY -->'));
38+
39+
// If no marker, find the first version heading
40+
if (insertIdx === -1) {
41+
insertIdx = lines.findIndex(l => l.trim().match(/^## \[\d/));
42+
}
43+
44+
// If still not found, default to after header (line 6)
45+
if (insertIdx === -1) {
46+
insertIdx = 6;
47+
}
48+
49+
// Build the new changelog
50+
const header = lines.slice(0, insertIdx).join('\n');
51+
const rest = lines.slice(insertIdx).join('\n');
52+
53+
changelog = header + '\n\n' + entry + rest;
54+
fs.writeFileSync(changelogPath, changelog);
55+
56+
console.log(`Updated CHANGELOG.md with entry for v${version}`);

.github/workflows/auto-label.yml

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
name: Auto Label & Assign
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
7+
permissions:
8+
contents: read
9+
pull-requests: write
10+
11+
jobs:
12+
auto-assign-and-label:
13+
name: Auto Assign & Smart Label
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v6
18+
19+
- name: Get changed files
20+
id: changed-files
21+
uses: tj-actions/changed-files@v47
22+
with:
23+
files_yaml: |
24+
src:
25+
- 'src/**'
26+
docs:
27+
- 'docs/**'
28+
- '**/*.md'
29+
- '!CHANGELOG.md'
30+
ci:
31+
- '.github/workflows/**'
32+
- '.github/actions/**'
33+
security:
34+
- '.github/workflows/security.yml'
35+
- '.coderabbit.yaml'
36+
- 'SECURITY.md'
37+
- '.gitleaks.toml'
38+
config:
39+
- 'package.json'
40+
- 'tsconfig.json'
41+
- '.eslintrc*'
42+
- '.prettierrc*'
43+
tests:
44+
- '**/*.test.ts'
45+
- '**/*.spec.ts'
46+
- 'vitest.config.*'
47+
- 'jest.config.*'
48+
49+
- name: Auto assign and label
50+
uses: actions/github-script@v8
51+
with:
52+
script: |
53+
const { owner, repo } = context.repo;
54+
const pr = context.payload.pull_request;
55+
const prNumber = pr.number;
56+
const prAuthor = pr.user.login;
57+
const prTitle = pr.title.toLowerCase();
58+
59+
// Auto-assign if author is rubenmarcus
60+
if (prAuthor === 'rubenmarcus') {
61+
await github.rest.issues.addAssignees({
62+
owner, repo,
63+
issue_number: prNumber,
64+
assignees: ['rubenmarcus']
65+
});
66+
console.log('Auto-assigned rubenmarcus');
67+
}
68+
69+
// Collect labels to add
70+
const labelsToAdd = new Set();
71+
72+
// Labels based on changed files
73+
const srcChanged = '${{ steps.changed-files.outputs.src_any_changed }}' === 'true';
74+
const docsChanged = '${{ steps.changed-files.outputs.docs_any_changed }}' === 'true';
75+
const ciChanged = '${{ steps.changed-files.outputs.ci_any_changed }}' === 'true';
76+
const securityChanged = '${{ steps.changed-files.outputs.security_any_changed }}' === 'true';
77+
const configChanged = '${{ steps.changed-files.outputs.config_any_changed }}' === 'true';
78+
const testsChanged = '${{ steps.changed-files.outputs.tests_any_changed }}' === 'true';
79+
80+
if (srcChanged) labelsToAdd.add('core');
81+
if (docsChanged) labelsToAdd.add('documentation');
82+
if (ciChanged) labelsToAdd.add('ci/cd');
83+
if (securityChanged) labelsToAdd.add('security');
84+
if (configChanged) labelsToAdd.add('config');
85+
if (testsChanged) labelsToAdd.add('tests');
86+
87+
// Labels based on PR title (conventional commits)
88+
if (prTitle.startsWith('feat')) labelsToAdd.add('enhancement');
89+
if (prTitle.startsWith('fix')) labelsToAdd.add('bug');
90+
if (prTitle.startsWith('docs')) labelsToAdd.add('documentation');
91+
if (prTitle.startsWith('chore')) labelsToAdd.add('chore');
92+
if (prTitle.startsWith('refactor')) labelsToAdd.add('refactor');
93+
if (prTitle.startsWith('perf')) labelsToAdd.add('performance');
94+
if (prTitle.startsWith('test')) labelsToAdd.add('tests');
95+
if (prTitle.startsWith('ci')) labelsToAdd.add('ci/cd');
96+
97+
// Special keywords in title
98+
if (prTitle.includes('security') || prTitle.includes('vulnerability')) labelsToAdd.add('security');
99+
if (prTitle.includes('breaking')) labelsToAdd.add('breaking-change');
100+
if (prTitle.includes('devops') || prTitle.includes('automation')) labelsToAdd.add('devops');
101+
if (prTitle.includes('dependabot') || prTitle.includes('deps')) labelsToAdd.add('dependencies');
102+
103+
// Only add candidate-release if src files changed (actual code changes)
104+
if (srcChanged && !prTitle.startsWith('chore') && !prTitle.startsWith('docs')) {
105+
labelsToAdd.add('candidate-release');
106+
}
107+
108+
// Convert to array and filter out empty
109+
const labels = Array.from(labelsToAdd).filter(Boolean);
110+
111+
if (labels.length > 0) {
112+
// Ensure labels exist
113+
for (const label of labels) {
114+
try {
115+
await github.rest.issues.getLabel({ owner, repo, name: label });
116+
} catch (e) {
117+
// Create label if it doesn't exist
118+
const colors = {
119+
'core': '0052CC',
120+
'documentation': '0075CA',
121+
'ci/cd': '7057FF',
122+
'security': 'B60205',
123+
'config': 'FBCA04',
124+
'tests': '1D76DB',
125+
'enhancement': 'A2EEEF',
126+
'bug': 'D73A4A',
127+
'chore': 'FEF2C0',
128+
'refactor': 'D4C5F9',
129+
'performance': '0E8A16',
130+
'breaking-change': 'B60205',
131+
'devops': '5319E7',
132+
'dependencies': '0366D6',
133+
'candidate-release': 'EDEDED'
134+
};
135+
await github.rest.issues.createLabel({
136+
owner, repo,
137+
name: label,
138+
color: colors[label] || 'EDEDED'
139+
});
140+
}
141+
}
142+
143+
// Add labels to PR
144+
await github.rest.issues.addLabels({
145+
owner, repo,
146+
issue_number: prNumber,
147+
labels
148+
});
149+
console.log(`Added labels: ${labels.join(', ')}`);
150+
}

0 commit comments

Comments
 (0)