Skip to content

Commit 209dcc2

Browse files
committed
AX-1651 - Change script to update the version + change to version 5
1 parent ff1fa02 commit 209dcc2

3 files changed

Lines changed: 96 additions & 44 deletions

File tree

.github/plugins.json

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
11
{
22
"plugins": [
3-
{ "name": "claude-plugin", "dest_prefix": "" },
4-
{ "name": "cursor-plugin", "dest_prefix": "plugins/jfrog" },
5-
{ "name": "vscode-plugin", "dest_prefix": "plugin" }
3+
{
4+
"name": "claude-plugin",
5+
"dest_prefix": "",
6+
"version_bumps": [
7+
{ "file": ".claude-plugin/plugin.json", "path": "version" }
8+
]
9+
},
10+
{
11+
"name": "cursor-plugin",
12+
"dest_prefix": "plugins/jfrog",
13+
"version_bumps": [
14+
{ "file": ".cursor-plugin/marketplace.json", "path": "metadata.version" },
15+
{ "file": "plugins/jfrog/.cursor-plugin/plugin.json", "path": "version" }
16+
]
17+
},
18+
{
19+
"name": "vscode-plugin",
20+
"dest_prefix": "plugin",
21+
"version_bumps": [
22+
{ "file": "marketplace.json", "path": "plugins.0.version" }
23+
]
24+
}
625
]
726
}

.github/scripts/jfrog-sync-plugins.py

Lines changed: 69 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111
import json
1212
import os
1313
import shutil
14+
import subprocess
1415
import sys
1516
from pathlib import Path
1617

17-
PLUGINS_FILE = Path(".github/plugins.json")
18-
SOURCE = "skills" # the directory under jfrog-skills we vendor into each plugin
19-
UPSTREAM_DIR = Path("upstream") # sibling checkout of jfrog-skills@version (set by the workflow)
20-
PLUGIN_DIR = Path("plugin") # sibling checkout of the target plugin repo (set by the workflow)
21-
USAGE = "usage: jfrog-sync-plugins.py matrix|copy"
18+
PLUGINS_FILE: Path = Path(".github/plugins.json")
19+
SOURCE: str = "skills" # directory under jfrog-skills we vendor into each plugin
20+
UPSTREAM_DIR: Path = Path("upstream") # sibling checkout of jfrog-skills@version (set by the workflow)
21+
PLUGIN_DIR: Path = Path("plugin") # sibling checkout of the target plugin repo (set by the workflow)
22+
USAGE: str = "usage: jfrog-sync-plugins.py matrix|copy"
2223

2324

2425
def fail(msg: str) -> None:
@@ -29,25 +30,18 @@ def fail(msg: str) -> None:
2930
def create_matrix() -> None:
3031
"""Emit a GitHub Actions matrix from .github/plugins.json.
3132
32-
Writes `matrix=<compact-json>` to $GITHUB_OUTPUT (the per-step output
33-
file the runner provides automatically) and prints the matrix to
34-
stdout for the run log.
33+
Writes `matrix=<compact-json>` to $GITHUB_OUTPUT and prints it to stdout.
3534
3635
Example input (.github/plugins.json):
37-
{
38-
"plugins": [
39-
{ "name": "claude-plugin", "dest_prefix": "" },
40-
{ "name": "cursor-plugin", "dest_prefix": "plugins/jfrog" }
41-
]
42-
}
36+
{ "plugins": [{ "name": "claude-plugin", "dest_prefix": "" }] }
4337
4438
Example output (appended to $GITHUB_OUTPUT):
45-
matrix={"include":[{"name":"claude-plugin","dest_prefix":""},{"name":"cursor-plugin","dest_prefix":"plugins/jfrog"}]}
39+
matrix={"include":[{"name":"claude-plugin","dest_prefix":""}]}
4640
"""
47-
data = json.loads(PLUGINS_FILE.read_text())
48-
matrix = {"include": data["plugins"]}
41+
data: dict = json.loads(PLUGINS_FILE.read_text())
42+
matrix: dict = {"include": data["plugins"]}
4943

50-
output_file = os.environ.get("GITHUB_OUTPUT")
44+
output_file: str | None = os.environ.get("GITHUB_OUTPUT")
5145
if output_file:
5246
with open(output_file, "a", encoding="utf-8") as f:
5347
f.write(f"matrix={json.dumps(matrix, separators=(',', ':'))}\n")
@@ -56,39 +50,77 @@ def create_matrix() -> None:
5650

5751

5852
def copy_skills_folder() -> None:
59-
"""Copy this repo's `skills/` into a plugin checkout at DEST_PREFIX.
60-
61-
Removes any existing destination first so the result matches upstream
62-
exactly (no stale files left behind).
53+
"""Copy skills/ into the plugin at DEST_PREFIX, then bump each configured
54+
version file in lock-step — but only if the copy actually produced changes.
6355
6456
Required env:
65-
DEST_PREFIX Prefix inside the plugin, may be empty.
66-
67-
Example (cursor-plugin layout, DEST_PREFIX=plugins/jfrog):
68-
copies upstream/skills -> plugin/plugins/jfrog/skills
57+
DEST_PREFIX Prefix inside the plugin, may be empty.
58+
e.g. "plugins/jfrog" -> skills/ lands at plugins/jfrog/skills/.
6959
70-
Example (claude-plugin layout, DEST_PREFIX=""):
71-
copies upstream/skills -> plugin/skills
60+
Optional env:
61+
VERSION_BUMPS JSON array of {file, path} entries.
62+
Each entry points to a JSON file inside the plugin and a
63+
dotted path to the semver field to patch-bump.
7264
"""
73-
# strip("/") tolerates "plugins/jfrog", "/plugins/jfrog/", and "" identically.
74-
dest_prefix = os.environ.get("DEST_PREFIX", "").strip("/")
65+
dest_prefix: str = os.environ.get("DEST_PREFIX", "").strip("/")
66+
bumps: list[dict] = json.loads(os.environ.get("VERSION_BUMPS", "[]") or "[]")
7567

76-
src_path = UPSTREAM_DIR / SOURCE
77-
if not src_path.exists():
78-
fail(f"upstream missing {SOURCE}/ at {src_path}")
68+
src: Path = UPSTREAM_DIR / SOURCE
69+
if not src.exists():
70+
fail(f"upstream missing {SOURCE}/ at {src}")
7971

80-
dest = PLUGIN_DIR / dest_prefix / SOURCE if dest_prefix else PLUGIN_DIR / SOURCE
72+
dest: Path = PLUGIN_DIR / dest_prefix / SOURCE if dest_prefix else PLUGIN_DIR / SOURCE
8173
if dest.exists():
8274
shutil.rmtree(dest)
8375
dest.parent.mkdir(parents=True, exist_ok=True)
84-
shutil.copytree(src_path, dest)
85-
print(f"Copied {src_path} -> {dest.relative_to(PLUGIN_DIR)}")
76+
shutil.copytree(src, dest)
77+
print(f"Copied {src} -> {dest.relative_to(PLUGIN_DIR)}")
78+
79+
if not bumps:
80+
return
81+
if not has_changes(PLUGIN_DIR):
82+
print("No skill changes detected — skipping version bumps.")
83+
return
84+
for bump in bumps:
85+
bump_patch_version(PLUGIN_DIR / bump["file"], bump["path"])
86+
87+
88+
def has_changes(repo_dir: Path) -> bool:
89+
"""Return True if `git status --porcelain` reports any working-tree changes."""
90+
result = subprocess.run(
91+
["git", "status", "--porcelain"],
92+
cwd=repo_dir,
93+
capture_output=True,
94+
text=True,
95+
check=True,
96+
)
97+
return bool(result.stdout.strip())
98+
99+
100+
def bump_patch_version(file_path: Path, dotted_path: str) -> None:
101+
data: dict = json.loads(file_path.read_text())
102+
103+
# Convert numeric parts to int indices up front, e.g.
104+
# "plugins.0.version" -> ["plugins", 0, "version"].
105+
keys: list = [int(p) if p.isdigit() else p for p in dotted_path.split(".")]
106+
parent = data
107+
for key in keys[:-1]:
108+
parent = parent[key]
109+
leaf_key = keys[-1]
110+
111+
current: str = parent[leaf_key]
112+
major, minor, patch = current.split(".")
113+
new_version: str = f"{major}.{minor}.{int(patch) + 1}"
114+
parent[leaf_key] = new_version
115+
116+
file_path.write_text(json.dumps(data, indent=2) + "\n")
117+
print(f"Bumped {file_path.relative_to(PLUGIN_DIR)} {dotted_path}: {current} -> {new_version}")
86118

87119

88120
def main() -> None:
89121
# sys.argv[0] is the script path; sys.argv[1] is the first real argument.
90122
# We expect exactly one argument: either "matrix" or "copy".
91-
command = sys.argv[1] if len(sys.argv) == 2 else ""
123+
command: str = sys.argv[1] if len(sys.argv) == 2 else ""
92124

93125
if command == "matrix":
94126
create_matrix()

.github/workflows/sync-plugins.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ on:
2222
permissions:
2323
contents: read
2424

25-
# TEMP: hardcoded to v0.10.0 for pre-merge testing — plugins are currently at v0.11.0,
26-
# so syncing v0.10.0 will produce a visible diff in the PRs. Revert to the line below
27-
# before merging:
25+
# TEMP: hardcoded to v0.5.0 for pre-merge testing — plugins are currently at v0.11.0,
26+
# so syncing v0.5.0 exercises additions, modifications, AND deletions (~12 files,
27+
# +434/-355) plus the patch-version bump. Revert to the line below before merging:
2828
# VERSION: ${{ github.event.inputs.version || github.ref_name }}
2929
env:
30-
VERSION: v0.10.0
30+
VERSION: v0.5.0
3131

3232
jobs:
3333
prepare:
@@ -64,6 +64,7 @@ jobs:
6464
- name: Copy skills into plugin
6565
env:
6666
DEST_PREFIX: ${{ matrix.dest_prefix }}
67+
VERSION_BUMPS: ${{ toJson(matrix.version_bumps) }}
6768
run: python3 .github/scripts/jfrog-sync-plugins.py copy
6869

6970
- uses: peter-evans/create-pull-request@v7

0 commit comments

Comments
 (0)