-
-
Notifications
You must be signed in to change notification settings - Fork 1
320 lines (277 loc) · 12.2 KB
/
upstream-monitor.yml
File metadata and controls
320 lines (277 loc) · 12.2 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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
name: Upstream Release Monitor
on:
schedule:
# Run once per week: Sunday at 12:00 UTC (mid-day)
- cron: '0 12 * * 0'
workflow_dispatch: # Allow manual trigger
permissions:
contents: write
issues: write
jobs:
check-upstream:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Update ref-proj/CyberChef from upstream
id: update_ref
run: |
# Ensure ref-proj directory exists
mkdir -p ref-proj
# Clone or update upstream reference
if [ -d "ref-proj/CyberChef/.git" ]; then
echo "Updating existing ref-proj/CyberChef"
cd ref-proj/CyberChef
git fetch origin --tags
BEFORE_SHA=$(git rev-parse HEAD)
git pull origin master
AFTER_SHA=$(git rev-parse HEAD)
echo "before_sha=$BEFORE_SHA" >> $GITHUB_OUTPUT
echo "after_sha=$AFTER_SHA" >> $GITHUB_OUTPUT
cd ../..
else
echo "Cloning upstream to ref-proj/CyberChef"
cd ref-proj
git clone https://github.com/gchq/CyberChef.git
cd CyberChef
AFTER_SHA=$(git rev-parse HEAD)
echo "before_sha=initial" >> $GITHUB_OUTPUT
echo "after_sha=$AFTER_SHA" >> $GITHUB_OUTPUT
cd ../..
fi
- name: Get upstream version info
id: upstream
run: |
cd ref-proj/CyberChef
# Get latest tag
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "unknown")
echo "latest=$LATEST_TAG" >> $GITHUB_OUTPUT
echo "Latest CyberChef release: $LATEST_TAG"
# Get version from package.json
UPSTREAM_VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo "unknown")
echo "version=$UPSTREAM_VERSION" >> $GITHUB_OUTPUT
echo "Upstream package.json version: $UPSTREAM_VERSION"
cd ../..
- name: Get current version
id: current
run: |
# Extract mcpVersion from package.json
CURRENT_VERSION=$(node -p "require('./package.json').mcpVersion")
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
echo "Current MCP version: $CURRENT_VERSION"
# Extract CyberChef version from package.json
CYBERCHEF_VERSION=$(node -p "require('./package.json').version")
echo "cyberchef_version=$CYBERCHEF_VERSION" >> $GITHUB_OUTPUT
echo "Current CyberChef version: $CYBERCHEF_VERSION"
- name: Compare operation files
id: compare_ops
run: |
# Count operations in both repos
MAIN_OPS=$(ls src/core/operations/*.mjs 2>/dev/null | wc -l)
REF_OPS=$(ls ref-proj/CyberChef/src/core/operations/*.mjs 2>/dev/null | wc -l)
echo "main_ops=$MAIN_OPS" >> $GITHUB_OUTPUT
echo "ref_ops=$REF_OPS" >> $GITHUB_OUTPUT
echo "Main operations: $MAIN_OPS"
echo "Ref operations: $REF_OPS"
# Find new operations (in ref but not in main)
NEW_OPS=$(comm -13 \
<(ls src/core/operations/*.mjs 2>/dev/null | xargs -n1 basename | sort) \
<(ls ref-proj/CyberChef/src/core/operations/*.mjs 2>/dev/null | xargs -n1 basename | sort) \
| wc -l)
echo "new_ops=$NEW_OPS" >> $GITHUB_OUTPUT
echo "New operations: $NEW_OPS"
# Find modified operations (different checksums)
MODIFIED_OPS=0
for op in src/core/operations/*.mjs; do
if [ -f "$op" ]; then
basename_op=$(basename "$op")
ref_op="ref-proj/CyberChef/src/core/operations/$basename_op"
if [ -f "$ref_op" ]; then
if ! cmp -s "$op" "$ref_op"; then
MODIFIED_OPS=$((MODIFIED_OPS + 1))
fi
fi
fi
done
echo "modified_ops=$MODIFIED_OPS" >> $GITHUB_OUTPUT
echo "Modified operations: $MODIFIED_OPS"
# Determine if update needed
if [ "$NEW_OPS" -gt 0 ] || [ "$MODIFIED_OPS" -gt 0 ]; then
echo "needs_update=true" >> $GITHUB_OUTPUT
else
echo "needs_update=false" >> $GITHUB_OUTPUT
fi
- name: Compare versions
id: compare
env:
LATEST: ${{ steps.upstream.outputs.latest }}
CYBERCHEF_VERSION: ${{ steps.current.outputs.cyberchef_version }}
run: |
CURRENT="v${CYBERCHEF_VERSION}"
echo "Comparing: $CURRENT vs $LATEST"
if [ "$LATEST" != "$CURRENT" ]; then
echo "new_version=true" >> $GITHUB_OUTPUT
echo "New version available: $LATEST (current: $CURRENT)"
else
echo "new_version=false" >> $GITHUB_OUTPUT
echo "Already up-to-date"
fi
- name: Check for existing issue
if: steps.compare.outputs.new_version == 'true' || steps.compare_ops.outputs.needs_update == 'true'
id: existing
env:
GH_TOKEN: ${{ github.token }}
LATEST: ${{ steps.upstream.outputs.latest }}
run: |
# Check if issue already exists for this version
ISSUE_COUNT=$(gh issue list \
--label "upstream-release" \
--state open \
--search "$LATEST" \
--json number \
--jq 'length')
echo "count=$ISSUE_COUNT" >> $GITHUB_OUTPUT
echo "Found $ISSUE_COUNT existing issues for this release"
- name: Generate operation change list
if: (steps.compare.outputs.new_version == 'true' || steps.compare_ops.outputs.needs_update == 'true') && steps.existing.outputs.count == '0'
id: op_changes
run: |
# List new operations
NEW_LIST=$(comm -13 \
<(ls src/core/operations/*.mjs 2>/dev/null | xargs -n1 basename | sort) \
<(ls ref-proj/CyberChef/src/core/operations/*.mjs 2>/dev/null | xargs -n1 basename | sort) \
| head -20)
# List modified operations
MODIFIED_LIST=""
COUNT=0
for op in src/core/operations/*.mjs; do
if [ -f "$op" ] && [ $COUNT -lt 20 ]; then
basename_op=$(basename "$op")
ref_op="ref-proj/CyberChef/src/core/operations/$basename_op"
if [ -f "$ref_op" ]; then
if ! cmp -s "$op" "$ref_op"; then
MODIFIED_LIST="$MODIFIED_LIST$basename_op"$'\n'
COUNT=$((COUNT + 1))
fi
fi
fi
done
# Save to file for multiline output
echo "$NEW_LIST" > /tmp/new_ops.txt
echo "$MODIFIED_LIST" > /tmp/modified_ops.txt
- name: Create issue for new release
if: (steps.compare.outputs.new_version == 'true' || steps.compare_ops.outputs.needs_update == 'true') && steps.existing.outputs.count == '0'
env:
GH_TOKEN: ${{ github.token }}
LATEST: ${{ steps.upstream.outputs.latest }}
CYBERCHEF_VERSION: ${{ steps.current.outputs.cyberchef_version }}
MAIN_OPS: ${{ steps.compare_ops.outputs.main_ops }}
REF_OPS: ${{ steps.compare_ops.outputs.ref_ops }}
NEW_OPS: ${{ steps.compare_ops.outputs.new_ops }}
MODIFIED_OPS: ${{ steps.compare_ops.outputs.modified_ops }}
run: |
TIMESTAMP=$(date -u +'%Y-%m-%d %H:%M:%S UTC')
# Read operation lists
NEW_OPS_LIST=$(cat /tmp/new_ops.txt)
MODIFIED_OPS_LIST=$(cat /tmp/modified_ops.txt)
ISSUE_BODY="## New Upstream Release Detected
**CyberChef Version**: $LATEST
**Current Version**: v$CYBERCHEF_VERSION
**Detected**: $TIMESTAMP
### Operation Changes
- **Current Operations**: $MAIN_OPS
- **Upstream Operations**: $REF_OPS
- **New Operations**: $NEW_OPS
- **Modified Operations**: $MODIFIED_OPS
#### New Operations (first 20)
\`\`\`
$NEW_OPS_LIST
\`\`\`
#### Modified Operations (first 20)
\`\`\`
$MODIFIED_OPS_LIST
\`\`\`
### Next Steps
1. Review the [upstream release notes](https://github.com/gchq/CyberChef/releases/tag/$LATEST)
2. Check the [upstream commit log](https://github.com/gchq/CyberChef/compare/v$CYBERCHEF_VERSION...$LATEST)
3. Review operation changes above for breaking changes
4. To trigger automatic sync, add the \`upstream-sync-approved\` label
5. For manual sync or complex changes, see instructions below
### Automatic Sync (Recommended)
The new selective sync workflow will:
- Only sync \`src/core/operations/\` files
- Preserve MCP-specific modifications
- Run comprehensive tests
- Create a PR for review
To trigger:
\`\`\`bash
gh issue edit <issue-number> --add-label upstream-sync-approved
\`\`\`
### Manual Sync (If Needed)
If automatic sync is not suitable:
\`\`\`bash
# Update ref-proj (already done by monitor workflow)
cd ref-proj/CyberChef
git pull origin master
cd ../..
# Use the upstream-sync workflow manually
gh workflow run upstream-sync.yml
\`\`\`
---
This issue was created automatically by the Upstream Release Monitor workflow."
gh issue create \
--title "New CyberChef release $LATEST available" \
--label "upstream-release,needs-review" \
--body "$ISSUE_BODY"
- name: Commit ref-proj updates
if: steps.compare_ops.outputs.needs_update == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -f ref-proj/CyberChef
git commit -m "chore(upstream): update ref-proj/CyberChef to latest upstream" || echo "No changes to commit"
git push origin master || echo "Nothing to push"
- name: Summary
if: always()
env:
LATEST: ${{ steps.upstream.outputs.latest }}
CYBERCHEF_VERSION: ${{ steps.current.outputs.cyberchef_version }}
MCP_VERSION: ${{ steps.current.outputs.version }}
NEW_VERSION: ${{ steps.compare.outputs.new_version }}
NEEDS_UPDATE: ${{ steps.compare_ops.outputs.needs_update }}
MAIN_OPS: ${{ steps.compare_ops.outputs.main_ops }}
REF_OPS: ${{ steps.compare_ops.outputs.ref_ops }}
NEW_OPS: ${{ steps.compare_ops.outputs.new_ops }}
MODIFIED_OPS: ${{ steps.compare_ops.outputs.modified_ops }}
EXISTING_COUNT: ${{ steps.existing.outputs.count }}
run: |
echo "### Upstream Monitor Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Latest CyberChef:** $LATEST" >> $GITHUB_STEP_SUMMARY
echo "- **Current Version:** v$CYBERCHEF_VERSION" >> $GITHUB_STEP_SUMMARY
echo "- **MCP Version:** $MCP_VERSION" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "#### Operation Comparison" >> $GITHUB_STEP_SUMMARY
echo "- **Main Operations:** $MAIN_OPS" >> $GITHUB_STEP_SUMMARY
echo "- **Ref Operations:** $REF_OPS" >> $GITHUB_STEP_SUMMARY
echo "- **New Operations:** $NEW_OPS" >> $GITHUB_STEP_SUMMARY
echo "- **Modified Operations:** $MODIFIED_OPS" >> $GITHUB_STEP_SUMMARY
if [ "$NEW_VERSION" == "true" ] || [ "$NEEDS_UPDATE" == "true" ]; then
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Status:** Updates available" >> $GITHUB_STEP_SUMMARY
if [ "${EXISTING_COUNT:-0}" == "0" ]; then
echo "- **Action:** Issue created" >> $GITHUB_STEP_SUMMARY
else
echo "- **Action:** Issue already exists" >> $GITHUB_STEP_SUMMARY
fi
else
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Status:** Up-to-date" >> $GITHUB_STEP_SUMMARY
echo "- **Action:** None" >> $GITHUB_STEP_SUMMARY
fi