-
Notifications
You must be signed in to change notification settings - Fork 0
116 lines (101 loc) · 4.33 KB
/
update-external-plugins.yml
File metadata and controls
116 lines (101 loc) · 4.33 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
name: Update External Plugins
# Auto-bump external-plugin pins (source.ref + mirrored version) when an
# upstream publishes a newer release. Opens a reviewable chore(...) PR;
# manifest-only chore commits do not trigger an agent-plugins release.
on:
schedule:
- cron: '17 6 * * *' # daily, 06:17 UTC
workflow_dispatch:
permissions:
contents: write
pull-requests: write
concurrency:
group: update-external-plugins
cancel-in-progress: false
jobs:
update:
name: Resolve and pin latest external releases
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Update external plugin pins
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: python3 .github/scripts/update_external_plugins.py
- name: Validate manifest sync
run: |
python3 << 'EOF'
import json, re, sys
claude = json.load(open('.claude-plugin/marketplace.json'))
agents = json.load(open('.agents/plugins/marketplace.json'))
a_by_name = {p.get('name'): p for p in agents.get('plugins', [])}
def norm(url):
m = re.match(r'^git@github\.com:(.+?)(?:\.git)?$', (url or '').strip())
if m:
return m.group(1).lower()
m = re.match(r'^https://github\.com/(.+?)(?:\.git)?$',
(url or '').strip())
return m.group(1).lower() if m else (url or '').strip().lower()
errors = []
for e in claude.get('plugins', []):
s = e.get('source')
if not isinstance(s, dict) or s.get('source') != 'github':
continue
name, repo = e.get('name'), s.get('repo', '')
ref, ver = s.get('ref', ''), e.get('version')
if ver is not None and ref != f"v{ver}":
errors.append(f"{name}: ref {ref!r} != v+version {ver!r}")
a = a_by_name.get(name)
if a is None:
errors.append(f"{name}: missing from .agents manifest")
continue
a_src = a.get('source', {})
if norm(a_src.get('url', '')) != repo.lower():
errors.append(f"{name}: .agents repo mismatch")
if a_src.get('ref', '') != ref:
errors.append(
f"{name}: ref mismatch claude {ref!r} vs "
f".agents {a_src.get('ref','')!r}")
if errors:
print("\n".join(f"❌ {x}" for x in errors))
sys.exit(1)
print("✅ external manifests in sync")
EOF
- name: Open PR
id: cpr
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
branch: automation/external-plugin-updates
base: master
commit-message: 'chore(external-plugins): update external plugin pins'
title: 'chore(external-plugins): update external plugin pins'
body: |
Automated external-plugin pin update.
Bumps `source.ref` in both manifests (and the mirrored
`version` in `.claude-plugin/marketplace.json`) to the latest
eligible upstream release. Manifest-only `chore:` change - no
agent-plugins release is triggered.
Review the diff against the upstream changelog before merging.
delete-branch: true
add-paths: |
.claude-plugin/marketplace.json
.agents/plugins/marketplace.json
- name: Auto-merge
# The inline "Validate manifest sync" step above is the gate: if it
# fails the workflow stops and no PR exists. Manifest-only chore PR
# -> no agent-plugins release. Squash-merge immediately.
if: >-
${{ steps.cpr.outputs.pull-request-number != '' &&
(steps.cpr.outputs.pull-request-operation == 'created' ||
steps.cpr.outputs.pull-request-operation == 'updated') }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR: ${{ steps.cpr.outputs.pull-request-number }}
run: |
gh pr merge "$PR" --squash --delete-branch \
--subject 'chore(external-plugins): update external plugin pins'