diff --git a/.github/workflows/require-version-label.yml b/.github/workflows/require-version-label.yml new file mode 100644 index 0000000..ae8b784 --- /dev/null +++ b/.github/workflows/require-version-label.yml @@ -0,0 +1,67 @@ +name: Require Version Bump Label + +on: + pull_request: + types: [opened, labeled, unlabeled, synchronize] + +jobs: + check-plugin-changes: + name: Check for Plugin Changes + runs-on: ubuntu-latest + outputs: + has_plugin_changes: ${{ steps.check.outputs.has_changes }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check if plugin files changed + id: check + env: + BASE_REF: ${{ github.base_ref }} + run: | + # Get list of changed files + CHANGED_FILES=$(git diff --name-only origin/"$BASE_REF"...HEAD) + + # Define plugin file patterns (adjust based on repo structure) + # For Claude: plugin/, For Cursor: hooks/, mcp.json, skills/, scripts/ + PLUGIN_PATTERNS="plugin/|hooks/|mcp\.json|\.mcp\.json|skills/|scripts/|commands/|semgrep-version" + + if echo "$CHANGED_FILES" | grep -qE "$PLUGIN_PATTERNS"; then + echo "has_changes=true" >> $GITHUB_OUTPUT + echo "Plugin files changed:" + echo "$CHANGED_FILES" | grep -E "$PLUGIN_PATTERNS" || true + else + echo "has_changes=false" >> $GITHUB_OUTPUT + echo "No plugin files changed" + fi + + check-version-label: + name: Check Version Bump Label + needs: check-plugin-changes + if: needs.check-plugin-changes.outputs.has_plugin_changes == 'true' + runs-on: ubuntu-latest + env: + PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} + steps: + - name: Check for version bump label + run: | + if echo "$PR_LABELS" | grep -q '"bump:patch"'; then + echo "✓ Found label: bump:patch" + exit 0 + elif echo "$PR_LABELS" | grep -q '"bump:minor"'; then + echo "✓ Found label: bump:minor" + exit 0 + elif echo "$PR_LABELS" | grep -q '"bump:major"'; then + echo "✓ Found label: bump:major" + exit 0 + else + echo "✗ Missing version bump label!" + echo "" + echo "This PR modifies plugin files and requires a version bump." + echo "Please add one of the following labels:" + echo " - bump:patch (bug fixes: 0.4.1 → 0.4.2)" + echo " - bump:minor (new features: 0.4.1 → 0.5.0)" + echo " - bump:major (breaking changes: 0.4.1 → 1.0.0)" + exit 1 + fi diff --git a/.github/workflows/version-bump.yml b/.github/workflows/version-bump.yml new file mode 100644 index 0000000..04a37dd --- /dev/null +++ b/.github/workflows/version-bump.yml @@ -0,0 +1,116 @@ +name: Version Bump on Label + +on: + pull_request: + types: [labeled] + +jobs: + bump-version: + name: Bump Version + if: startsWith(github.event.label.name, 'bump:') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ref: ${{ github.head_ref }} + + - name: Determine bump type + id: bump_type + env: + LABEL: ${{ github.event.label.name }} + run: | + BUMP_TYPE="${LABEL#bump:}" + echo "type=$BUMP_TYPE" >> $GITHUB_OUTPUT + + - name: Find plugin.json + id: find_plugin + run: | + # Look for plugin.json in different locations + if [ -f "plugin/.claude-plugin/plugin.json" ]; then + echo "path=plugin/.claude-plugin/plugin.json" >> $GITHUB_OUTPUT + elif [ -f ".claude-plugin/plugin.json" ]; then + echo "path=.claude-plugin/plugin.json" >> $GITHUB_OUTPUT + elif [ -f ".cursor-plugin/plugin.json" ]; then + echo "path=.cursor-plugin/plugin.json" >> $GITHUB_OUTPUT + else + echo "Could not find plugin.json" + exit 1 + fi + + - name: Read current version + id: current_version + run: | + PLUGIN_JSON="${{ steps.find_plugin.outputs.path }}" + VERSION=$(grep -o '"version": *"[^"]*"' "$PLUGIN_JSON" | head -1 | grep -o '[0-9]*\.[0-9]*\.[0-9]*') + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Current version: $VERSION" + + - name: Calculate new version + id: new_version + run: | + VERSION="${{ steps.current_version.outputs.version }}" + BUMP_TYPE="${{ steps.bump_type.outputs.type }}" + + IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION" + + case "$BUMP_TYPE" in + major) + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + ;; + minor) + MINOR=$((MINOR + 1)) + PATCH=0 + ;; + patch) + PATCH=$((PATCH + 1)) + ;; + esac + + NEW_VERSION="$MAJOR.$MINOR.$PATCH" + echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT + echo "Bumping version: $VERSION → $NEW_VERSION ($BUMP_TYPE)" + + - name: Update version in plugin.json + run: | + PLUGIN_JSON="${{ steps.find_plugin.outputs.path }}" + OLD_VERSION="${{ steps.current_version.outputs.version }}" + NEW_VERSION="${{ steps.new_version.outputs.version }}" + + sed -i "s/\"version\": *\"$OLD_VERSION\"/\"version\": \"$NEW_VERSION\"/" "$PLUGIN_JSON" + + echo "Updated $PLUGIN_JSON:" + grep version "$PLUGIN_JSON" + + - name: Update CHANGELOG.md + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: | + # Strip the "[Template Sync] " prefix from the PR title to get the description + DESCRIPTION="${PR_TITLE#\[Template Sync\] }" + NEW_VERSION="${{ steps.new_version.outputs.version }}" + + if [ -f CHANGELOG.md ]; then + # Build new file: keep header, insert entry, append rest + { + head -1 CHANGELOG.md + printf '## %s\n%s\n' "$NEW_VERSION" "$DESCRIPTION" + tail -n +2 CHANGELOG.md + } > CHANGELOG.tmp + mv CHANGELOG.tmp CHANGELOG.md + else + printf '# Change Log\n\n## %s\n%s\n' "$NEW_VERSION" "$DESCRIPTION" > CHANGELOG.md + fi + + echo "Updated CHANGELOG.md:" + head -10 CHANGELOG.md + + - name: Commit version bump + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add . + git commit -m "chore: bump version to ${{ steps.new_version.outputs.version }}" + git push diff --git a/README.md b/README.md index 798cc2e..a7a9258 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,14 @@ To use the Semgrep plugin: ``` /plugin install semgrep-plugin@semgrep ``` -1. If it is installed, see if you can run the `/semgrep-plugin:setup_semgrep_plugin` command. If you cannot run the command, try restarting your claude instance by exiting out of the current session and re-running: - ``` - claude - ``` +1. If it is installed, see if you can run the `/semgrep-plugin:setup-semgrep-plugin` command. If you cannot run the command, try restarting your claude instance by exiting out of the current session and re-running: + ``` + claude + ``` 1. If it still doesn't work, try enabling the plugin: ``` /plugin enable semgrep-plugin@semgrep - ``` + +## Contributing + +This plugin is managed by the [mcp-marketplace-template](https://github.com/semgrep/mcp-marketplace-template) repository. Changes should be made there and synced via automated PRs. diff --git a/plugin/.mcp.json b/plugin/.mcp.json index bc767a9..e05488a 100644 --- a/plugin/.mcp.json +++ b/plugin/.mcp.json @@ -1,8 +1,10 @@ { - "mcpServers": { - "semgrep": { - "command": "semgrep", - "args": ["mcp"] - } + "mcpServers": { + "semgrep": { + "command": "semgrep", + "args": [ + "mcp" + ] } -} \ No newline at end of file + } +} diff --git a/plugin/commands/setup-semgrep-plugin.md b/plugin/commands/setup-semgrep-plugin.md new file mode 100644 index 0000000..e2fad92 --- /dev/null +++ b/plugin/commands/setup-semgrep-plugin.md @@ -0,0 +1,52 @@ +--- +name: setup-semgrep-plugin +description: Set up the Semgrep plugin by installing Semgrep, authenticating, and verifying compatibility +--- +# Setup Semgrep Plugin + +Follow these steps to set up the Semgrep plugin: + +## 1. Install Semgrep + +Check if Semgrep is installed, and install it if not: + +```bash +which semgrep || brew install semgrep +``` + +## 2. Authenticate with Semgrep + +Log in to Semgrep (this will open a browser window): + +```bash +semgrep login --force +``` + +## 3. Install Semgrep Pro Engine + +Install the Pro engine for enhanced scanning capabilities: + +```bash +semgrep install-semgrep-pro || true +``` + +## 4. Verify Installation + +Confirm everything is working: + +```bash +semgrep --pro --version +``` + +## 5. Check Version Compatibility + +Verify your Semgrep version is >= 1.146.0: + +```bash +semgrep --version +``` + +If your version is older than 1.146.0, please update: +```bash +brew upgrade semgrep +``` diff --git a/plugin/hooks/hooks.json b/plugin/hooks/hooks.json index e69694a..152ee8a 100644 --- a/plugin/hooks/hooks.json +++ b/plugin/hooks/hooks.json @@ -11,17 +11,6 @@ ] } ], - "UserPromptSubmit": [ - { - "matcher": "", - "hooks": [ - { - "type": "command", - "command": "semgrep mcp -k inject-secure-defaults-short" - } - ] - } - ], "SessionStart": [ { "matcher": "startup", @@ -41,6 +30,17 @@ } ] } + ], + "UserPromptSubmit": [ + { + "matcher": "", + "hooks": [ + { + "type": "command", + "command": "semgrep mcp -k inject-secure-defaults-short" + } + ] + } ] } -} \ No newline at end of file +}