|
6 | 6 | from github import Auth, Repository |
7 | 7 | from github import Github |
8 | 8 | from typing import Dict, List |
| 9 | +import json as json_lib |
9 | 10 |
|
10 | 11 | MAX_FILENAME_LENGTH = 60 |
11 | 12 |
|
@@ -120,53 +121,66 @@ def render_msg_header(state: AppState) -> str: |
120 | 121 |
|
121 | 122 |
|
122 | 123 | def print_for_slack(occurrences: List[Occurrence], state: AppState): |
123 | | - json = """ |
124 | | - { |
125 | | - "channel": "@CHANNEL@", |
| 124 | + occurrences_by_ann_path: Dict[str, List[Occurrence]] = {} |
| 125 | + for o in occurrences: |
| 126 | + occurrences_by_ann_path.setdefault(o.annotation_path, []).append(o) |
| 127 | + items = [i for i in occurrences_by_ann_path.items()] |
| 128 | + items.sort(key=lambda i: len(i[1]), reverse=True) # sort by number of occurrences, highest first |
| 129 | + |
| 130 | + limit = 12 |
| 131 | + items = items[:limit] |
| 132 | + |
| 133 | + # Chunk results so that individual message blocks do not exceed the 3000 character limit from Slack API |
| 134 | + chunk_size=5 |
| 135 | + chunks = [items[i:i+chunk_size] for i in range(0, len(items), chunk_size)] |
| 136 | + |
| 137 | + content_blocks = [] |
| 138 | + |
| 139 | + for chunk in chunks: |
| 140 | + content = "" |
| 141 | + for ann_path, occrs in chunk: |
| 142 | + nice_path = truncate_left(ann_path, MAX_FILENAME_LENGTH) |
| 143 | + count = len(occrs) |
| 144 | + content += f"{count}x `{nice_path}` " |
| 145 | + occrs.sort(key=lambda o: o.commit.timestamp, reverse=True) |
| 146 | + recent_occrs = occrs[:5] |
| 147 | + content += " ".join([f"<{occr.check_url}|{i+1}> " for i, occr in enumerate(recent_occrs)]) |
| 148 | + content += '\n' |
| 149 | + |
| 150 | + content_blocks += [ |
| 151 | + { |
| 152 | + "type": "section", |
| 153 | + "text": { |
| 154 | + "type": "mrkdwn", |
| 155 | + "text": content, |
| 156 | + } |
| 157 | + } |
| 158 | + ] |
| 159 | + |
| 160 | + |
| 161 | + data = { |
| 162 | + "channel": state.slack_channel, |
126 | 163 | "text": "Flaky Tests Summary", |
127 | 164 | "blocks": [ |
128 | 165 | { |
129 | 166 | "type": "section", |
130 | 167 | "text": { |
131 | 168 | "type": "mrkdwn", |
132 | | - "text": "@HEADER@" |
| 169 | + "text": render_msg_header(state), |
133 | 170 | } |
134 | 171 | }, |
135 | 172 | { |
136 | 173 | "type": "section", |
137 | 174 | "text": { |
138 | 175 | "type": "mrkdwn", |
139 | | - "text": "Top failed runs (limit=@LIMIT@):\\n@CONTENT@" |
| 176 | + "text": f"Top {len(items)} failed runs (limit={limit})", |
140 | 177 | } |
141 | 178 | } |
142 | | - ] |
| 179 | + ] + content_blocks |
143 | 180 | } |
144 | | - """ |
145 | | - |
146 | | - occurrences_by_ann_path: Dict[str, List[Occurrence]] = {} |
147 | | - for o in occurrences: |
148 | | - occurrences_by_ann_path.setdefault(o.annotation_path, []).append(o) |
149 | | - items = [i for i in occurrences_by_ann_path.items()] |
150 | | - items.sort(key=lambda i: len(i[1]), reverse=True) # sort by number of occurrences, highest first |
151 | 181 |
|
152 | | - limit = 12 # limit to 12 items, to avoid running into issues with Slack API (limit 3000 chars) |
153 | | - items = items[:limit] |
| 182 | + json = json_lib.dumps(data, indent=4) |
154 | 183 |
|
155 | | - content = "" |
156 | | - for ann_path, occrs in items: |
157 | | - nice_path = truncate_left(ann_path, MAX_FILENAME_LENGTH) |
158 | | - count = len(occrs) |
159 | | - content += f"{count}x `{nice_path}`" |
160 | | - occrs.sort(key=lambda o: o.commit.timestamp, reverse=True) |
161 | | - recent_occrs = occrs[:10] |
162 | | - content += " ".join([f"<{occr.check_url}|{i+1}> " for i, occr in enumerate(recent_occrs)]) |
163 | | - content += '\\n' |
164 | | - |
165 | | - header = render_msg_header(state) |
166 | | - json = json.replace("@HEADER@", header) |
167 | | - json = json.replace("@LIMIT@", str(limit)) |
168 | | - json = json.replace("@CHANNEL@", state.slack_channel) |
169 | | - json = json.replace("@CONTENT@", content) |
170 | 184 | print(json) |
171 | 185 |
|
172 | 186 |
|
@@ -218,10 +232,10 @@ def main(): |
218 | 232 | state: AppState = parse_args() |
219 | 233 | r = access_repo(state) |
220 | 234 | occurrences = list_occurrences(state, r) |
221 | | - if state.slack_channel: |
222 | | - print_for_slack(occurrences, state) |
223 | | - else: |
224 | | - print_for_humans(occurrences) |
| 235 | + #if state.slack_channel: |
| 236 | + print_for_slack(occurrences, state) |
| 237 | + #else: |
| 238 | + # print_for_humans(occurrences) |
225 | 239 |
|
226 | 240 |
|
227 | 241 | if __name__ == '__main__': |
|
0 commit comments