-
Notifications
You must be signed in to change notification settings - Fork 14
175 lines (149 loc) · 7.3 KB
/
plugin-version-check.yml
File metadata and controls
175 lines (149 loc) · 7.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
name: Plugin Version Check
on:
pull_request:
paths:
- 'plugins/**'
- '.claude-plugin/marketplace.json'
jobs:
check-version-bump:
name: Verify plugin version bump
runs-on: ubuntu-latest
steps:
- name: Checkout PR branch
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect changed plugins
id: detect
run: |
BASE_BRANCH="${{ github.base_ref }}"
CHANGED_PLUGINS=""
MARKETPLACE_JSON=".claude-plugin/marketplace.json"
BASE_MARKETPLACE_JSON=$(git show "origin/${BASE_BRANCH}:${MARKETPLACE_JSON}" 2>/dev/null || echo '{"plugins":[]}')
# Check which plugins have changes in their directory
for plugin_dir in plugins/*/; do
plugin_name=$(basename "$plugin_dir")
if git diff --name-only "origin/${BASE_BRANCH}...HEAD" | grep -q "^plugins/${plugin_name}/"; then
CHANGED_PLUGINS="${CHANGED_PLUGINS} ${plugin_name}"
fi
done
# Also include plugins whose marketplace version changed (catches marketplace-only changes)
if [ -f "$MARKETPLACE_JSON" ]; then
CURRENT_PLUGINS=$(jq -r '.plugins[].name' "$MARKETPLACE_JSON" 2>/dev/null || echo "")
BASE_PLUGINS=$(echo "$BASE_MARKETPLACE_JSON" | jq -r '.plugins[].name' 2>/dev/null || echo "")
ALL_PLUGIN_NAMES=$(echo -e "${CURRENT_PLUGINS}\n${BASE_PLUGINS}" | sort -u)
for plugin_name in $ALL_PLUGIN_NAMES; do
[ -z "$plugin_name" ] && continue
# Skip if already in changed list
echo "$CHANGED_PLUGINS" | grep -qw "$plugin_name" && continue
CURRENT_VER=$(jq -r --arg name "$plugin_name" '.plugins[] | select(.name == $name) | .version // "null"' "$MARKETPLACE_JSON" 2>/dev/null || echo "null")
BASE_VER=$(echo "$BASE_MARKETPLACE_JSON" | jq -r --arg name "$plugin_name" '.plugins[] | select(.name == $name) | .version // "null"' 2>/dev/null || echo "null")
if [ "$CURRENT_VER" != "$BASE_VER" ]; then
echo "Detected marketplace version change for $plugin_name: $BASE_VER → $CURRENT_VER"
CHANGED_PLUGINS="${CHANGED_PLUGINS} ${plugin_name}"
fi
done
fi
echo "Changed plugins:${CHANGED_PLUGINS}"
echo "plugins=${CHANGED_PLUGINS}" >> $GITHUB_OUTPUT
- name: Check for version bump
run: |
MARKETPLACE_JSON=".claude-plugin/marketplace.json"
BASE_BRANCH="${{ github.base_ref }}"
CHANGED_PLUGINS="${{ steps.detect.outputs.plugins }}"
# Version comparison function (returns 0 if v1 > v2)
version_greater() {
local v1=$1 v2=$2
if [ "$v1" == "$v2" ]; then
return 1
fi
local IFS=.
local i v1_parts=($v1) v2_parts=($v2)
for ((i=0; i<${#v1_parts[@]} || i<${#v2_parts[@]}; i++)); do
local n1=${v1_parts[i]:-0}
local n2=${v2_parts[i]:-0}
if ((n1 > n2)); then
return 0
elif ((n1 < n2)); then
return 1
fi
done
return 1
}
# Function to get marketplace version for a plugin
get_marketplace_version() {
local plugin_name=$1
local file=$2
jq -r --arg name "$plugin_name" '.plugins[] | select(.name == $name) | .version // "null"' "$file"
}
ALL_PASSED=true
for plugin_name in $CHANGED_PLUGINS; do
echo ""
echo "=== Checking $plugin_name ==="
# Check both Claude (.claude-plugin) and Codex (.codex-plugin) manifest paths
PLUGIN_JSON="plugins/${plugin_name}/.claude-plugin/plugin.json"
if [ ! -f "$PLUGIN_JSON" ]; then
PLUGIN_JSON="plugins/${plugin_name}/.codex-plugin/plugin.json"
fi
if [ ! -f "$PLUGIN_JSON" ]; then
echo "❌ ERROR: No plugin.json found for $plugin_name!"
echo "Checked: plugins/${plugin_name}/.claude-plugin/plugin.json and plugins/${plugin_name}/.codex-plugin/plugin.json"
ALL_PASSED=false
continue
fi
# Get versions from PR branch
PR_PLUGIN_VERSION=$(jq -r '.version' "$PLUGIN_JSON")
PR_MARKETPLACE_VERSION=$(get_marketplace_version "$plugin_name" "$MARKETPLACE_JSON")
# Get versions from base branch
BASE_PLUGIN_VERSION=$(git show "origin/${BASE_BRANCH}:${PLUGIN_JSON}" 2>/dev/null | jq -r '.version' 2>/dev/null || echo "null")
BASE_MARKETPLACE_VERSION=$(git show "origin/${BASE_BRANCH}:${MARKETPLACE_JSON}" 2>/dev/null | jq -r --arg name "$plugin_name" '.plugins[] | select(.name == $name) | .version // "null"' 2>/dev/null || echo "null")
echo "plugin.json: ${BASE_PLUGIN_VERSION:-new} → $PR_PLUGIN_VERSION"
echo "marketplace.json: ${BASE_MARKETPLACE_VERSION:-new} → $PR_MARKETPLACE_VERSION"
# Check if plugin exists in Claude marketplace
# Codex plugins use .agents/plugins/marketplace.json (no version field) and are exempt
if [ "$PR_MARKETPLACE_VERSION" == "null" ] || [ -z "$PR_MARKETPLACE_VERSION" ]; then
echo "ℹ️ Plugin $plugin_name not in Claude marketplace ($MARKETPLACE_JSON)"
echo " Checking if it has its own manifest..."
if [ -f "$PLUGIN_JSON" ]; then
echo "✅ $plugin_name has manifest at $PLUGIN_JSON (version: $PR_PLUGIN_VERSION)"
continue
fi
echo "❌ ERROR: Plugin $plugin_name not found in any marketplace!"
ALL_PASSED=false
continue
fi
# Check if versions match between plugin.json and marketplace.json
if [ "$PR_PLUGIN_VERSION" != "$PR_MARKETPLACE_VERSION" ]; then
echo "❌ ERROR: Version mismatch for $plugin_name!"
echo "plugin.json version: $PR_PLUGIN_VERSION"
echo "marketplace.json version: $PR_MARKETPLACE_VERSION"
ALL_PASSED=false
continue
fi
# Check if this is a new plugin (no base versions)
if [ -z "$BASE_PLUGIN_VERSION" ] || [ "$BASE_PLUGIN_VERSION" == "null" ]; then
echo "✅ New plugin. Version: $PR_PLUGIN_VERSION"
continue
fi
# Check plugin.json version bump
if [ "$PR_PLUGIN_VERSION" == "$BASE_PLUGIN_VERSION" ]; then
echo "❌ ERROR: $plugin_name files changed but version not bumped!"
echo "Current version: $BASE_PLUGIN_VERSION"
ALL_PASSED=false
continue
fi
if ! version_greater "$PR_PLUGIN_VERSION" "$BASE_PLUGIN_VERSION"; then
echo "❌ ERROR: $plugin_name version downgraded!"
echo "Base: $BASE_PLUGIN_VERSION → PR: $PR_PLUGIN_VERSION"
ALL_PASSED=false
continue
fi
echo "✅ $plugin_name version check passed"
done
echo ""
if [ "$ALL_PASSED" = true ]; then
echo "✅ All version checks passed!"
else
echo "❌ Some version checks failed"
exit 1
fi