From f480004dda34d0bf8945684c2e7c6380d023c4c4 Mon Sep 17 00:00:00 2001 From: Yoni Melki Date: Tue, 23 Jun 2026 21:59:54 +0300 Subject: [PATCH 1/6] [minor] Add tag/release mechanism and drift-prevention check (AX-1735) Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/release.yml | 83 ++++++++++++++++++++++++++ .github/workflows/validate-version.yml | 31 ++++++++++ VERSION | 1 + 3 files changed, 115 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/validate-version.yml create mode 100644 VERSION diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..38e3654 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,83 @@ +name: Release + +on: + push: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Detect release tag in commit message + id: detect + run: | + MSG="${{ github.event.head_commit.message }}" + if echo "$MSG" | grep -qE '\[(major|minor|patch)\]'; then + TAG=$(echo "$MSG" | grep -oE '\[(major|minor|patch)\]' | head -1 | tr -d '[]') + echo "tag=$TAG" >> "$GITHUB_OUTPUT" + echo "triggered=true" >> "$GITHUB_OUTPUT" + else + echo "triggered=false" >> "$GITHUB_OUTPUT" + fi + + - name: Compute next version + if: steps.detect.outputs.triggered == 'true' + id: version + run: | + VERSION=$(cat VERSION) + MAJOR=$(echo "$VERSION" | cut -d. -f1) + MINOR=$(echo "$VERSION" | cut -d. -f2) + PATCH=$(echo "$VERSION" | cut -d. -f3) + case "${{ steps.detect.outputs.tag }}" in + major) NEXT="$((MAJOR + 1)).0.0" ;; + minor) NEXT="${MAJOR}.$((MINOR + 1)).0" ;; + patch) NEXT="${MAJOR}.${MINOR}.$((PATCH + 1))" ;; + esac + echo "version=$NEXT" >> "$GITHUB_OUTPUT" + + - name: Update VERSION and JSON files + if: steps.detect.outputs.triggered == 'true' + run: | + VERSION="${{ steps.version.outputs.version }}" + echo "$VERSION" > VERSION + jq --arg v "$VERSION" '.version = $v' plugins/jfrog/.cursor-plugin/plugin.json > /tmp/plugin.json + mv /tmp/plugin.json plugins/jfrog/.cursor-plugin/plugin.json + jq --arg v "$VERSION" '.metadata.version = $v' .cursor-plugin/marketplace.json > /tmp/marketplace.json + mv /tmp/marketplace.json .cursor-plugin/marketplace.json + + - name: Commit, tag, and push + if: steps.detect.outputs.triggered == 'true' + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add VERSION plugins/jfrog/.cursor-plugin/plugin.json .cursor-plugin/marketplace.json + git commit -m "Release v${{ steps.version.outputs.version }}" + git push origin main + git tag "v${{ steps.version.outputs.version }}" + git push origin "v${{ steps.version.outputs.version }}" + + - name: Package release artifact + if: steps.detect.outputs.triggered == 'true' + run: zip -r release.zip . --exclude ".git/*" --exclude ".github/*" + + - name: Create GitHub Release + if: steps.detect.outputs.triggered == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create "v${{ steps.version.outputs.version }}" \ + release.zip \ + --title "Release v${{ steps.version.outputs.version }}" \ + --generate-notes diff --git a/.github/workflows/validate-version.yml b/.github/workflows/validate-version.yml new file mode 100644 index 0000000..883e037 --- /dev/null +++ b/.github/workflows/validate-version.yml @@ -0,0 +1,31 @@ +name: Validate version + +on: + pull_request: + branches: [main] + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Check version consistency + run: | + VERSION=$(cat VERSION) + FAILED=0 + + PLUGIN_VERSION=$(jq -r '.version' plugins/jfrog/.cursor-plugin/plugin.json) + if [ "$VERSION" != "$PLUGIN_VERSION" ]; then + echo "::error::Version mismatch: VERSION=$VERSION but plugins/jfrog/.cursor-plugin/plugin.json.version=$PLUGIN_VERSION" + FAILED=1 + fi + + MARKET_VERSION=$(jq -r '.metadata.version' .cursor-plugin/marketplace.json) + if [ "$VERSION" != "$MARKET_VERSION" ]; then + echo "::error::Version mismatch: VERSION=$VERSION but .cursor-plugin/marketplace.json.metadata.version=$MARKET_VERSION" + FAILED=1 + fi + + [ "$FAILED" -eq 0 ] && echo "All versions consistent: $VERSION" + exit $FAILED diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..7d85683 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.5.4 From a5874980fa587d18b1bfd7483f0b0b0ec2b3cc6a Mon Sep 17 00:00:00 2001 From: Yoni Melki <58732001+YoniMelki@users.noreply.github.com> Date: Mon, 29 Jun 2026 10:34:17 +0300 Subject: [PATCH 2/6] docs: add Releasing section to CONTRIBUTING.md --- CONTRIBUTING.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1b11640..a041c82 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,6 +36,22 @@ The `skills/` tree is vendored from [`jfrog/jfrog-skills`](https://github.com/jf See [`VENDOR.md`](VENDOR.md) for the full picture. +## Releasing + +Releases are automated by `.github/workflows/release.yml`. To cut a release, push (or merge) a commit to `main` whose message contains `[major]`, `[minor]`, or `[patch]`: + +- `[patch]` — bug fixes; bumps `X.Y.Z` → `X.Y.Z+1` +- `[minor]` — new features; bumps `X.Y.Z` → `X.Y+1.0` +- `[major]` — breaking changes; bumps `X.Y.Z` → `X+1.0.0` + +The workflow: +1. Bumps `VERSION` and syncs the version in `plugins/jfrog/.cursor-plugin/plugin.json` and `.cursor-plugin/marketplace.json` +2. Commits and pushes the bump to `main` +3. Creates a `vX.Y.Z` git tag +4. Publishes a GitHub Release with a repo zip attached + +**Prerequisite:** `github-actions[bot]` must be allowed to push to `main`. In the repository's branch protection (or ruleset) settings, add `github-actions[bot]` to the bypass list. + ## Reporting Issues Open a [GitHub issue](https://github.com/jfrog/cursor-plugin/issues) with: From 610e159008122e6b45f7397225982f552beb7398 Mon Sep 17 00:00:00 2001 From: Yoni Melki <58732001+YoniMelki@users.noreply.github.com> Date: Mon, 29 Jun 2026 13:32:43 +0300 Subject: [PATCH 3/6] fix: remove push-to-main from release workflow, read VERSION as-is --- .github/workflows/release.yml | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 38e3654..468c804 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,6 @@ jobs: steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Detect release tag in commit message @@ -25,46 +24,19 @@ jobs: run: | MSG="${{ github.event.head_commit.message }}" if echo "$MSG" | grep -qE '\[(major|minor|patch)\]'; then - TAG=$(echo "$MSG" | grep -oE '\[(major|minor|patch)\]' | head -1 | tr -d '[]') - echo "tag=$TAG" >> "$GITHUB_OUTPUT" echo "triggered=true" >> "$GITHUB_OUTPUT" else echo "triggered=false" >> "$GITHUB_OUTPUT" fi - - name: Compute next version + - name: Read version if: steps.detect.outputs.triggered == 'true' id: version - run: | - VERSION=$(cat VERSION) - MAJOR=$(echo "$VERSION" | cut -d. -f1) - MINOR=$(echo "$VERSION" | cut -d. -f2) - PATCH=$(echo "$VERSION" | cut -d. -f3) - case "${{ steps.detect.outputs.tag }}" in - major) NEXT="$((MAJOR + 1)).0.0" ;; - minor) NEXT="${MAJOR}.$((MINOR + 1)).0" ;; - patch) NEXT="${MAJOR}.${MINOR}.$((PATCH + 1))" ;; - esac - echo "version=$NEXT" >> "$GITHUB_OUTPUT" - - - name: Update VERSION and JSON files - if: steps.detect.outputs.triggered == 'true' - run: | - VERSION="${{ steps.version.outputs.version }}" - echo "$VERSION" > VERSION - jq --arg v "$VERSION" '.version = $v' plugins/jfrog/.cursor-plugin/plugin.json > /tmp/plugin.json - mv /tmp/plugin.json plugins/jfrog/.cursor-plugin/plugin.json - jq --arg v "$VERSION" '.metadata.version = $v' .cursor-plugin/marketplace.json > /tmp/marketplace.json - mv /tmp/marketplace.json .cursor-plugin/marketplace.json + run: echo "version=$(cat VERSION)" >> "$GITHUB_OUTPUT" - - name: Commit, tag, and push + - name: Create and push tag if: steps.detect.outputs.triggered == 'true' run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add VERSION plugins/jfrog/.cursor-plugin/plugin.json .cursor-plugin/marketplace.json - git commit -m "Release v${{ steps.version.outputs.version }}" - git push origin main git tag "v${{ steps.version.outputs.version }}" git push origin "v${{ steps.version.outputs.version }}" From 5dece5777f5ac752b1a9e3e1c80050b0008fab0b Mon Sep 17 00:00:00 2001 From: Yoni Melki <58732001+YoniMelki@users.noreply.github.com> Date: Mon, 29 Jun 2026 13:33:35 +0300 Subject: [PATCH 4/6] docs: update Releasing section to reflect new developer-driven version bump flow --- CONTRIBUTING.md | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a041c82..c040477 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,19 +38,12 @@ See [`VENDOR.md`](VENDOR.md) for the full picture. ## Releasing -Releases are automated by `.github/workflows/release.yml`. To cut a release, push (or merge) a commit to `main` whose message contains `[major]`, `[minor]`, or `[patch]`: +To cut a release: -- `[patch]` — bug fixes; bumps `X.Y.Z` → `X.Y.Z+1` -- `[minor]` — new features; bumps `X.Y.Z` → `X.Y+1.0` -- `[major]` — breaking changes; bumps `X.Y.Z` → `X+1.0.0` +1. In your PR, bump `VERSION` and sync both `plugins/jfrog/.cursor-plugin/plugin.json` `.version` and `.cursor-plugin/marketplace.json` `.metadata.version` to match. The `validate-version` PR check enforces this. +2. Merge to `main` with `[major]`, `[minor]`, or `[patch]` anywhere in the commit message. -The workflow: -1. Bumps `VERSION` and syncs the version in `plugins/jfrog/.cursor-plugin/plugin.json` and `.cursor-plugin/marketplace.json` -2. Commits and pushes the bump to `main` -3. Creates a `vX.Y.Z` git tag -4. Publishes a GitHub Release with a repo zip attached - -**Prerequisite:** `github-actions[bot]` must be allowed to push to `main`. In the repository's branch protection (or ruleset) settings, add `github-actions[bot]` to the bypass list. +The release workflow reads `VERSION`, creates a `vX.Y.Z` git tag, and publishes a GitHub Release with a repo zip attached. No bot push to `main` — the version bump is part of the PR itself. ## Reporting Issues From 1e44508dd9938c4c39f25d32854300bd28c8c5de Mon Sep 17 00:00:00 2001 From: Yoni Melki Date: Thu, 16 Jul 2026 12:48:45 +0300 Subject: [PATCH 5/6] AX-1735 - Apply PR review feedback: copyright headers, checkout@v5, step comments Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/release.yml | 9 ++++++++- .github/workflows/validate-version.yml | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 468c804..9a08dd1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,4 @@ +# Copyright (c) JFrog Ltd. 2026 name: Release on: @@ -15,10 +16,12 @@ jobs: release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + # Check out the repository with a token so the workflow can push tags + - uses: actions/checkout@v5 with: token: ${{ secrets.GITHUB_TOKEN }} + # Parse the commit message for a [major], [minor], or [patch] tag - name: Detect release tag in commit message id: detect run: | @@ -29,21 +32,25 @@ jobs: echo "triggered=false" >> "$GITHUB_OUTPUT" fi + # Read the current version from the VERSION file - name: Read version if: steps.detect.outputs.triggered == 'true' id: version run: echo "version=$(cat VERSION)" >> "$GITHUB_OUTPUT" + # Create a git tag for the version and push it to origin - name: Create and push tag if: steps.detect.outputs.triggered == 'true' run: | git tag "v${{ steps.version.outputs.version }}" git push origin "v${{ steps.version.outputs.version }}" + # Bundle the plugin directory into a zip file for the GitHub Release - name: Package release artifact if: steps.detect.outputs.triggered == 'true' run: zip -r release.zip . --exclude ".git/*" --exclude ".github/*" + # Publish the GitHub Release with the zip artifact and auto-generated notes - name: Create GitHub Release if: steps.detect.outputs.triggered == 'true' env: diff --git a/.github/workflows/validate-version.yml b/.github/workflows/validate-version.yml index 883e037..bab3303 100644 --- a/.github/workflows/validate-version.yml +++ b/.github/workflows/validate-version.yml @@ -1,3 +1,4 @@ +# Copyright (c) JFrog Ltd. 2026 name: Validate version on: @@ -8,7 +9,7 @@ jobs: validate: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Check version consistency run: | From 54cf93712b6b3d26909f22c0b9dbf2ab466950d9 Mon Sep 17 00:00:00 2001 From: Yoni Melki Date: Thu, 16 Jul 2026 17:26:43 +0300 Subject: [PATCH 6/6] AX-1735 - Sync VERSION and plugin manifests to current main (0.5.6) Releases landed on main after this branch was cut, bumping plugin.json and marketplace.json to 0.5.6. The validate-version CI check runs against the merge commit and fails when VERSION (0.5.4) doesn't match the JSON files (0.5.6). Bring VERSION and both manifests in line with current main so the merge commit is fully consistent. Co-Authored-By: Claude Sonnet 4.6 --- .cursor-plugin/marketplace.json | 2 +- VERSION | 2 +- plugins/jfrog/.cursor-plugin/plugin.json | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json index 58fd978..e30f8ae 100644 --- a/.cursor-plugin/marketplace.json +++ b/.cursor-plugin/marketplace.json @@ -6,7 +6,7 @@ }, "metadata": { "description": "JFrog Platform plugins for Cursor", - "version": "0.5.4", + "version": "0.5.6", "pluginRoot": "plugins" }, "plugins": [ diff --git a/VERSION b/VERSION index 7d85683..b49b253 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.4 +0.5.6 diff --git a/plugins/jfrog/.cursor-plugin/plugin.json b/plugins/jfrog/.cursor-plugin/plugin.json index e24c846..3aa316a 100644 --- a/plugins/jfrog/.cursor-plugin/plugin.json +++ b/plugins/jfrog/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "jfrog", "displayName": "JFrog Platform", - "version": "0.5.4", + "version": "0.5.6", "description": "JFrog Platform integration with MCP, security skills, supply-chain best practices, and JFrog Agent Guard governance for adding, removing, and listing MCP servers.", "author": { "name": "JFrog", @@ -23,6 +23,7 @@ "logo": "assets/logo.svg", "skills": [ "skills/jfrog/SKILL.md", + "skills/jfrog-ai-catalog-skills/SKILL.md", "skills/jfrog-package-safety-and-download/SKILL.md" ], "hooks": "hooks/hooks.json"