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
4 changes: 4 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ jobs:
run: node --test scripts/validate.test.mjs
- name: Validate manifests + skills
run: node scripts/validate.mjs
- name: Validate README has no plugin version
env:
PLUGIN_MANIFEST: .codex-plugin/plugin.json
run: node scripts/validate-readme-no-version.mjs
- name: Version consistency (plugin.json == package.json)
run: |
PJ=$(jq -r .version .codex-plugin/plugin.json)
Expand Down
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Before installing, make sure you have:
- **JFrog host URL and access token** — Your JFrog platform URL and a valid access token.
- **OpenAI Codex** — Installed, with plugin support (`codex plugin` CLI commands available).
- **Node.js** (≥ 18) — with `npx` on your `PATH` (used by the Agent Guard).
- **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.22.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 AI Catalog** (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 the credentials/server ID from the JFrog CLI configuration.
- **JFrog project** (optional) — If you want to use the Agent Guard feature.
Expand Down Expand Up @@ -148,7 +148,7 @@ The `skills/` tree is vendored from
pinned in [`scripts/sync-skills-vendor.json`](scripts/sync-skills-vendor.json).
To pull a newer upstream release into this repo:

1. Bump `pin` in `scripts/sync-skills-vendor.json` to the new tag (e.g. `v0.23.0`).
1. Bump `pin` in `scripts/sync-skills-vendor.json` to the new upstream tag.
2. Re-sync and commit the refreshed tree:

```bash
Expand All @@ -160,10 +160,7 @@ To pull a newer upstream release into this repo:
3. Bump `version` in both [`.codex-plugin/plugin.json`](.codex-plugin/plugin.json)
and [`package.json`](package.json) (they must match — CI enforces this) so the
published plugin reflects the new skills bundle.
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 `skills/` tree, the version bump, and the
README link bump together, and open a PR whose merge commit subject carries a
4. Commit the pin bump, the regenerated `skills/` tree, and the version bump together, and open a PR whose merge commit subject carries a
`[patch]` / `[minor]` / `[major]` marker (see [Releasing](#releasing)).

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