@@ -101,7 +101,7 @@ jobs:
101101 shell : bash
102102 run : ./restore.sh
103103
104- - name : Build ApiChief and compute baseline deltas
104+ - name : Build ApiChief and compute review diffs
105105 if : steps.detect.outputs.has_baselines == 'true'
106106 id : delta
107107 shell : bash
@@ -157,25 +157,36 @@ jobs:
157157 return False
158158 raise
159159
160- def truncate(text: str, limit: int = 20000) -> str:
161- if len(text) <= limit:
162- return text
163- return text[:limit] + '\n... (truncated)\n'
160+ max_comment_length = 60000
161+ comment_bodies: list[str] = []
162+ current_body = ''
164163
165- sections: list[str] = []
164+ def append_section(section: str) -> None:
165+ nonlocal current_body
166+
167+ if not current_body:
168+ current_body = section
169+ return
170+
171+ candidate = current_body + '\n\n' + section
172+ if len(candidate) > max_comment_length:
173+ comment_bodies.append(current_body)
174+ current_body = section
175+ else:
176+ current_body = candidate
166177
167178 for index, file in enumerate(files):
168179 filename = file['filename']
169180 old_path = workdir / f'{index}.old.baseline.json'
170181 new_path = workdir / f'{index}.new.baseline.json'
171- delta_path = workdir / f'{index}.delta.json '
182+ review_dir = workdir / f'{index}.review '
172183
173184 old_exists = download_file(base_sha, filename, old_path)
174185 new_exists = download_file(target_sha, filename, new_path)
175186
176187 if old_exists and new_exists:
177188 result = subprocess.run(
178- [dotnet, apichief, str(new_path), 'emit', 'delta', str(old_path), '-o', str(delta_path )],
189+ [dotnet, apichief, str(new_path), 'emit', 'delta', str(old_path), '--diff', '- o', str(review_dir )],
179190 capture_output=True,
180191 text=True,
181192 check=False)
@@ -185,54 +196,77 @@ jobs:
185196
186197 if result.returncode != 0:
187198 raise RuntimeError(
188- f'ApiChief delta failed for {filename} with exit code {result.returncode}:\n'
199+ f'ApiChief delta diff failed for {filename} with exit code {result.returncode}:\n'
189200 f'{result.stdout}\n{result.stderr}')
190201
191- delta_text = truncate(delta_path.read_text(encoding='utf-8'))
192- sections.append(
193- f"### `{filename}`\n\n"
194- f"<details>\n<summary>Show delta</summary>\n\n```json\n{delta_text}\n```\n</details>")
202+ review_files = sorted(review_dir.rglob('*.md'))
203+ if not review_files:
204+ continue
205+
206+ section = (
207+ f"## API review baseline changes for `{filename}`\n\n"
208+ 'The diff below was generated by `ApiChief` between the base and selected PR versions.\n\n')
209+
210+ for review_file in review_files:
211+ section += (
212+ f"{review_file.read_text(encoding='utf-8').rstrip()}\n\n")
213+
214+ append_section(section.rstrip())
195215 elif new_exists:
196- sections.append(f"### `{filename}`\n\nThis baseline file was **added** in the selected PR.")
216+ append_section(
217+ f"## API review baseline changes for `{filename}`\n\n"
218+ 'This baseline file was **added** in the selected PR.')
197219 elif old_exists:
198- sections.append(f"### `{filename}`\n\nThis baseline file was **removed** in the selected PR.")
220+ append_section(
221+ f"## API review baseline changes for `{filename}`\n\n"
222+ 'This baseline file was **removed** in the selected PR.')
199223
200- if not sections:
201- sections.append('No API deltas were produced for the modified baseline files.')
224+ if not current_body:
225+ append_section(
226+ '## API review baseline changes\n\n'
227+ 'No API deltas were produced for the modified baseline files.')
202228
203- body = (
204- '## API review baseline changes\n\n'
205- 'This PR modified one or more `*.baseline.json` files. '
206- 'The deltas below were generated by `ApiChief` between the base and selected PR versions.\n\n'
207- + '\n\n'.join(sections)
208- )
229+ if current_body:
230+ comment_bodies.append(current_body)
209231
210- comment_path = workdir / 'comment.md'
211- comment_path.write_text(body[:65000], encoding='utf-8')
232+ comments_dir = workdir / 'comments'
233+ comments_dir.mkdir(parents=True, exist_ok=True)
234+
235+ for index, body in enumerate(comment_bodies, start=1):
236+ comment_path = comments_dir / f'{index:03}.md'
237+ comment_path.write_text(body.rstrip() + '\n', encoding='utf-8')
212238
213239 with open(os.environ['GITHUB_OUTPUT'], 'a', encoding='utf-8') as output:
214- output.write(f'comment_path={comment_path }\n')
240+ output.write(f'comments_dir={comments_dir }\n')
215241 PY
216242
217- - name : Create PR comment with delta
243+ - name : Create PR comment with diffs
218244 if : steps.detect.outputs.has_baselines == 'true'
219245 uses : actions/github-script@v9
220246 env :
221- COMMENT_PATH : ${{ steps.delta.outputs.comment_path }}
247+ COMMENTS_DIR : ${{ steps.delta.outputs.comments_dir }}
222248 PR_NUMBER : ${{ steps.detect.outputs.pr_number }}
223249 with :
224250 script : |
225251 const fs = require('fs');
252+ const path = require('path');
226253 const owner = context.repo.owner;
227254 const repo = context.repo.repo;
228255 const issue_number = Number(process.env.PR_NUMBER);
229- const body = fs.readFileSync(process.env.COMMENT_PATH, 'utf8');
230-
231- await github.rest.issues.createComment({
232- owner,
233- repo,
234- issue_number,
235- body
236- });
256+ const commentsDir = process.env.COMMENTS_DIR;
257+
258+ const commentFiles = fs.readdirSync(commentsDir)
259+ .filter(file => file.endsWith('.md'))
260+ .sort((a, b) => a.localeCompare(b));
261+
262+ for (const file of commentFiles) {
263+ const body = fs.readFileSync(path.join(commentsDir, file), 'utf8');
264+ await github.rest.issues.createComment({
265+ owner,
266+ repo,
267+ issue_number,
268+ body
269+ });
270+ }
237271
238- console.log(`Created new API review comment for PR #${issue_number}.`);
272+ console.log(`Created ${commentFiles.length} API review comment(s) for PR #${issue_number}.`);
0 commit comments