Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/validate-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,8 @@ jobs:
exit 1
fi
echo "Versions consistent: $VERSION"

- name: Validate README has no plugin version
env:
PLUGIN_MANIFEST: plugins/jfrog/.cursor-plugin/plugin.json
run: node scripts/validate-readme-no-version.mjs
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Before installing, make sure you have:
- **JFrog host URL and access token** — Your JFrog platform URL and a valid access token.
- **Cursor** — Installed with AI features enabled.
- **Node.js** (≥ 18) — with `npx` on your `PATH`.
- **Skill runtime requirements** — `jf` CLI, `jq`, and `curl` on `PATH`, plus a configured JFrog instance. For the minimum versions, see the upstream skills [`Requirements`](https://github.com/jfrog/jfrog-skills/blob/v0.11.0/README.md#requirements). Configure the CLI with `jf config add` — see [Authentication](#authentication).
- **Skill runtime requirements** — `jf` CLI, `jq`, and `curl` on `PATH`, plus a configured JFrog instance. For the minimum versions, see the upstream skills [`Requirements`](https://github.com/jfrog/jfrog-skills/blob/main/README.md#requirements). Configure the CLI with `jf config add` — see [Authentication](#authentication).
- **JFrog Platform access** (optional) — If you want to use the Agent Guard feature, your JFrog subscription needs to include the AI Catalog entitlement. Contact your JFrog account team if you're unsure whether it's enabled.
- **JFrog CLI ≥ 2.105.0** (optional) — If you want the Agent Guard to auto-resolve credentials/server ID from the JFrog CLI instead of `JFROG_PLATFORM_URL`/`JFROG_ACCESS_TOKEN` env vars. Older CLIs don't support the `--format` flag used by `jf config show`/`jf config export` for this.
- **JFrog project** (optional) — If you want to use the Agent Guard feature.
Expand Down Expand Up @@ -139,7 +139,7 @@ See the [JFrog MCP Registry troubleshooting guide](https://docs.jfrog.com/ai-ml/

The `skills/` tree is vendored from [`jfrog/jfrog-skills`](https://github.com/jfrog/jfrog-skills) at the version pinned in [`.github/scripts/sync-skills-vendor.json`](.github/scripts/sync-skills-vendor.json). To pull a newer upstream release into this repo:

1. Bump `pin` in `.github/scripts/sync-skills-vendor.json` to the new tag (e.g. `v0.12.0`).
1. Bump `pin` in `.github/scripts/sync-skills-vendor.json` to the new upstream tag.
2. Run the sync script from the repo root:

```bash
Expand All @@ -148,8 +148,7 @@ The `skills/` tree is vendored from [`jfrog/jfrog-skills`](https://github.com/jf

It downloads the pinned tarball from `codeload.github.com`, extracts it, and replaces the directories listed in `paths` (today: `skills/`) under `plugins/jfrog/`.
3. Bump `version` in [`plugins/jfrog/.cursor-plugin/plugin.json`](plugins/jfrog/.cursor-plugin/plugin.json) so users actually receive the update — Cursor skips installs whose resolved version hasn't changed.
4. Update the pinned-version link in the [Prerequisites](#prerequisites) section so the skill runtime requirements point at the new tag.
5. Commit the pin bump, the regenerated `plugins/jfrog/skills/` tree, the version bump, and the README link bump together, and open a PR.
4. Commit the pin bump, the regenerated `plugins/jfrog/skills/` tree, and the version bump together, and open a PR.

See [`VENDOR.md`](VENDOR.md) for the full picture.

Expand Down
78 changes: 78 additions & 0 deletions scripts/validate-readme-no-version.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env node

// Copyright (c) JFrog Ltd. 2026
// Licensed under the Apache License, Version 2.0
// https://www.apache.org/licenses/LICENSE-2.0

import { readFileSync, existsSync } from "node:fs";
import process from "node:process";

const docPaths = (process.env.DOCS || process.env.README_PATH || "README.md")
.split(/\s+/)
.filter(Boolean);

const errors = [];

for (const docPath of docPaths) {
const content = readFileSync(docPath, "utf8");
validateDoc(docPath, content, errors);
}

function validateDoc(docPath, content, errors) {

const bannedPatterns = [
{
re: /current version/i,
msg: 'README must not include a "Current version" callout — use GitHub Releases/tags.',
},
{
re: /^## Versioning\s*$/m,
msg: 'README must not include a "## Versioning" section — versions live in the manifest and GitHub Releases.',
},
{
re: /then tag \(for example `v/i,
msg: "README must not include example release tags.",
},
{
re: /github\.com\/jfrog\/jfrog-skills\/blob\/v\d+\.\d+\.\d+/i,
msg: "README must not pin jfrog-skills doc links to a release tag — use main README or sync-skills-vendor.json.",
},
{
re: /codeload\.github\.com\/jfrog\/jfrog-skills\/(tar\.gz|zip)\/v\d+\.\d+\.\d+/i,
msg: "README must not embed jfrog-skills release tags in download URLs.",
},
];

for (const { re, msg } of bannedPatterns) {
if (re.test(content)) {
errors.push(`${docPath}: ${msg}`);
}
}

const manifestPath = process.env.PLUGIN_MANIFEST;
if (docPath.endsWith("README.md") && manifestPath && existsSync(manifestPath)) {
let version;
if (manifestPath.endsWith(".json")) {
version = JSON.parse(readFileSync(manifestPath, "utf8")).version;
} else if (manifestPath.endsWith("gradle.properties")) {
const match = readFileSync(manifestPath, "utf8").match(/^version\s*=\s*(.+)$/m);
version = match?.[1]?.trim();
}

if (version && content.includes(version)) {
errors.push(
`${docPath}: contains plugin version "${version}" — authoritative source is ${manifestPath}.`
);
}
}
}

if (errors.length > 0) {
console.error("README version validation failed:");
for (const error of errors) {
console.error(`- ${error}`);
}
process.exit(1);
}

console.log("README version validation passed.");
Loading