-
Notifications
You must be signed in to change notification settings - Fork 1.4k
121 lines (110 loc) · 4.18 KB
/
weekly-chromatic.yml
File metadata and controls
121 lines (110 loc) · 4.18 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
name: Weekly Chromatic
on:
schedule:
- cron: '0 17 * * 1' # Monday 9am PST / 10am PDT (GH Actions cron is UTC)
workflow_dispatch: # manual trigger for testing
permissions:
contents: read
jobs:
chromatic:
runs-on: ubuntu-latest
outputs:
build_url: ${{ steps.chromatic.outputs.buildUrl }}
code: ${{ steps.chromatic.outputs.code }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # chromatic needs full history for baseline comparison
- uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'yarn'
- run: yarn --immutable
- name: Run Chromatic
id: chromatic
uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
buildScriptName: build:chromatic
exitZeroOnChanges: true
env:
NODE_ENV: production
CHROMATIC: '1'
chromatic-fc:
runs-on: ubuntu-latest
outputs:
build_url: ${{ steps.chromatic.outputs.buildUrl }}
code: ${{ steps.chromatic.outputs.code }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # chromatic needs full history for baseline comparison
- uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'yarn'
- run: yarn --immutable
- name: Run Chromatic FC
id: chromatic
uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_FC_PROJECT_TOKEN }}
buildScriptName: build:chromatic-fc
exitZeroOnChanges: true
env:
NODE_ENV: production
CHROMATIC: '1'
notify:
runs-on: ubuntu-latest
needs: [chromatic, chromatic-fc]
if: always()
env:
SLACK_TSDIFF_CHROMATIC_BOT_TOKEN: ${{ secrets.SLACK_TSDIFF_CHROMATIC_BOT_TOKEN }}
SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }}
CHROMATIC_URL: ${{ needs.chromatic.outputs.build_url }}
CHROMATIC_CODE: ${{ needs.chromatic.outputs.code }}
CHROMATIC_FC_URL: ${{ needs.chromatic-fc.outputs.build_url }}
CHROMATIC_FC_CODE: ${{ needs.chromatic-fc.outputs.code }}
steps:
- name: Post to Slack
run: |
python3 << 'PYEOF'
import json, os, urllib.request
from datetime import date
required = ['SLACK_TSDIFF_CHROMATIC_BOT_TOKEN', 'SLACK_CHANNEL_ID']
missing = [k for k in required if not os.environ.get(k)]
if missing:
raise SystemExit(f"Missing required environment variables: {', '.join(missing)}")
today = date.today().isoformat()
channel = os.environ['SLACK_CHANNEL_ID']
slack_token = os.environ['SLACK_TSDIFF_CHROMATIC_BOT_TOKEN']
def fmt(code, url):
if not url:
return "❌ failed"
if code == 'BUILD_PASSED':
return f"✅ | {url}"
return f"⚠️ changes pending review | {url}"
body = "\n".join([
f"Chromatic: {fmt(os.environ['CHROMATIC_CODE'], os.environ['CHROMATIC_URL'])}",
f"Forced Colors: {fmt(os.environ['CHROMATIC_FC_CODE'], os.environ['CHROMATIC_FC_URL'])}",
])
def post(text, thread_ts=None):
payload = {"channel": channel, "text": text, "unfurl_links": False, "unfurl_media": False}
if thread_ts:
payload["thread_ts"] = thread_ts
req = urllib.request.Request(
'https://slack.com/api/chat.postMessage',
data=json.dumps(payload).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')}")
return resp['message']['ts']
ts = post(f"📸 Weekly Chromatic — {today}")
post(f"📸 Weekly Chromatic — {today}\n\n{body}", thread_ts=ts)
PYEOF