-
Notifications
You must be signed in to change notification settings - Fork 1.4k
137 lines (115 loc) · 5.6 KB
/
weekly-api-diff.yml
File metadata and controls
137 lines (115 loc) · 5.6 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
name: Weekly API Diff
on:
push:
branches: [tsdiff_script] # temporary: remove before merging to main
schedule:
- cron: '0 17 * * 1' # Monday 9am PST / 10am PDT (GH Actions cron is UTC)
workflow_dispatch: # manual trigger for testing
jobs:
weekly-api-diff:
runs-on: ubuntu-latest
env:
SNAPSHOTS_REPO: LFDanLu/react-spectrum-api-snapshots
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # required for build:api-published to find the last Publish commit
- uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'yarn'
- run: yarn --immutable
# Build current main API (~20 min, always fresh)
- name: Build current API snapshot
run: yarn build:api-branch
# Build release baseline using the last Publish commit (~20 min, always fresh)
- name: Build release baseline
run: yarn build:api-published
- name: Generate diff
run: yarn compare:apis --isCI > /tmp/diff-current.txt || true
# Check out snapshots repo so we can read the previous diff and commit the new one
- uses: actions/checkout@v4
with:
repository: ${{ env.SNAPSHOTS_REPO }}
path: snapshots
token: ${{ secrets.SNAPSHOTS_REPO_TOKEN }}
# Compute week-to-week delta and commit new diff
- name: Save diff and compute delta
run: |
TODAY=$(date +%Y-%m-%d)
echo "TODAY=$TODAY" >> $GITHUB_ENV
cp /tmp/diff-current.txt snapshots/diffs/$TODAY.txt
PREV=$(ls -t snapshots/diffs/*.txt 2>/dev/null | sed -n '2p')
if [ -n "$PREV" ]; then
diff "$PREV" snapshots/diffs/$TODAY.txt > /tmp/weekly-delta.txt || true
else
echo "(first run — no previous diff to compare against)" > /tmp/weekly-delta.txt
fi
if [ -s /tmp/diff-current.txt ]; then
cd snapshots
git config user.email "github-actions@github.com"
git config user.name "GitHub Actions"
git add diffs/$TODAY.txt
git diff --cached --quiet || (git commit -m "weekly api diff $TODAY" && git push)
fi
# Summarize with GitHub Models (free via GITHUB_TOKEN) and post to Slack
- name: Summarize and post to Slack
env:
SLACK_TSDIFF_CHROMATIC_BOT_TOKEN: ${{ secrets.SLACK_TSDIFF_CHROMATIC_BOT_TOKEN }}
SLACK_CHANNEL_ID: ${{ secrets.TEST_SLACK_ID }}
GITHUB_TOKEN: ${{ github.token }}
run: |
python3 << 'PYEOF'
import json, os, urllib.request, subprocess
required = ['SLACK_TSDIFF_CHROMATIC_BOT_TOKEN', 'SLACK_CHANNEL_ID', 'GITHUB_TOKEN', 'TODAY', 'SNAPSHOTS_REPO', 'GITHUB_WORKSPACE']
missing = [k for k in required if not os.environ.get(k)]
if missing:
raise SystemExit(f"Missing required environment variables: {', '.join(missing)}")
today = os.environ['TODAY']
channel = os.environ['SLACK_CHANNEL_ID']
snapshots_repo = os.environ['SNAPSHOTS_REPO']
slack_token = os.environ['SLACK_TSDIFF_CHROMATIC_BOT_TOKEN']
github_token = os.environ['GITHUB_TOKEN']
workspace = os.environ['GITHUB_WORKSPACE']
diff_url = f"https://github.com/{snapshots_repo}/blob/main/diffs/{today}.txt"
diff_size = os.path.getsize('/tmp/diff-current.txt')
if diff_size == 0:
message = f"📊 Weekly API Diff — {today}\n\nNo API changes vs release baseline this week — either nothing new has landed on main yet, or all pending changes were included in a release."
else:
delta = open('/tmp/weekly-delta.txt').read()[:4000]
# Extract classification rules from prompt.md (single source of truth)
prompt_md = open(f"{workspace}/scripts/weekly-api-diff/prompt.md").read()
rules_start = prompt_md.find("Apply these grouping and classification rules")
rules_end = prompt_md.find("\n## Step 9", rules_start)
rules = prompt_md[rules_start:rules_end].strip() if rules_start != -1 else ""
payload = {
"model": "gpt-4o-mini",
"max_tokens": 600,
"messages": [{
"role": "user",
"content": f"Summarize this week-to-week react-spectrum API diff in under 200 words using bullet points.\n\n{rules}\n\nDelta (changes from last week):\n{delta}"
}]
}
req = urllib.request.Request(
'https://models.inference.ai.azure.com/chat/completions',
data=json.dumps(payload).encode(),
headers={
'Authorization': f'Bearer {github_token}',
'Content-Type': 'application/json'
}
)
summary = json.loads(urllib.request.urlopen(req).read())['choices'][0]['message']['content']
message = f"📊 Weekly API Diff — {today}\n\n{summary}\n\nFull diff vs release: {diff_url}\n\nReact ✅ if changes look expected, or 🚨 if something looks wrong."
req = urllib.request.Request(
'https://slack.com/api/chat.postMessage',
data=json.dumps({"channel": channel, "text": message}).encode(),
headers={
'Authorization': f'Bearer {slack_token}',
'Content-Type': 'application/json'
}
)
resp = json.loads(urllib.request.urlopen(req).read())
print("Slack response:", resp.get('ok'), resp.get('error', ''))
if not resp.get('ok'):
raise SystemExit(f"Slack error: {resp.get('error')}")
PYEOF