@@ -173,6 +173,9 @@ jobs:
173173 (needs.benchmark.result != 'failure')
174174 runs-on : ubuntu-latest
175175 steps :
176+ # ---------------------------
177+ # Checkout repository
178+ # ---------------------------
176179 - name : Checkout with latest changes
177180 uses : actions/checkout@v5
178181 with :
@@ -186,12 +189,36 @@ jobs:
186189 git pull origin ${{ github.head_ref || github.ref_name }}
187190 echo "✅ Latest changes pulled"
188191
192+ # ---------------------------
193+ # Setup Julia
194+ # ---------------------------
189195 - uses : julia-actions/setup-julia@latest
196+
197+ # ---------------------------
198+ # Cache Julia packages and compiled artifacts
199+ # ---------------------------
200+ - name : Cache Julia packages for docs
201+ uses : actions/cache@v4
202+ with :
203+ path : |
204+ ~/.julia/packages
205+ ~/.julia/compiled
206+ key : julia-docs-${{ hashFiles('docs/Project.toml') }}
207+ restore-keys : julia-docs-
208+
209+ # ---------------------------
210+ # Build Julia package for docs
211+ # ---------------------------
190212 - uses : julia-actions/julia-buildpkg@latest
213+ with :
214+ ignore-no-cache : true
191215
192- - name : Install dependencies
216+ - name : Install dependencies for docs
193217 run : julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
194218
219+ # ---------------------------
220+ # Build and deploy documentation
221+ # ---------------------------
195222 - name : Build and deploy
196223 env :
197224 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
@@ -212,58 +239,74 @@ jobs:
212239 DOCS_RESULT : ${{ needs.docs.result }}
213240 with :
214241 script : |
215- console.log('🚨 Workflow failure detected - posting notification...');
216-
242+ console.log('🚨 Workflow failure detected - posting/updating comment...');
243+
244+ const marker = '<!-- ctbenchmarks-failure-comment -->';
217245 const prNumber = context.payload.pull_request.number;
218246 const failedJobs = [];
219-
220- console.log('📊 Analyzing job results...');
221-
247+
222248 // Check benchmark job
223249 if (process.env.BENCHMARK_RESULT === 'failure') {
224- console.log('❌ Benchmark job failed');
225250 failedJobs.push('Benchmarks');
226251 }
227-
252+
228253 // Check docs job
229254 if (process.env.DOCS_RESULT === 'failure') {
230- console.log('❌ Documentation job failed');
231255 failedJobs.push('Documentation');
232256 }
233-
234- console.log(`📝 Failed jobs: ${failedJobs.join(', ')}`);
235257
236- const comment = `
258+ const runUrl = `${context.payload.repository.html_url}/actions/runs/${context.runId}`;
259+
260+ const comment = `${marker}
237261 ## ❌ Workflow Failed
238-
262+
239263 The benchmark and documentation workflow encountered failures:
240-
264+
241265 ### Failed Jobs
242266 ${failedJobs.map(job => `- ❌ ${job}`).join('\n')}
243-
267+
244268 ### 🔍 Troubleshooting
245- - Check the [workflow run](${context.payload.repository.html_url}/actions/runs/${context.runId }) for detailed logs
269+ - Check the [workflow run](${runUrl }) for detailed logs
246270 - Verify that all required dependencies are available
247271 - Ensure the benchmark code is functioning correctly
248-
272+
249273 ### 🔄 Next Steps
250274 - Fix any issues identified in the logs
251275 - Push new commits to retry, or
252276 - Remove and re-add the benchmark label to restart
253-
277+
254278 ---
255- *🤖 This notification was automatically generated*
256- `;
279+ *🤖 This notification was automatically generated*`;
257280
258- console.log('💬 Posting failure comment to PR...');
259- await github.rest.issues.createComment ({
281+ // Find existing failure comment
282+ const { data: comments } = await github.rest.issues.listComments ({
260283 owner: context.repo.owner,
261284 repo: context.repo.repo,
262285 issue_number: prNumber,
263- body: comment
286+ per_page: 100
264287 });
265-
266- console.log('✅ Failure notification posted successfully');
288+
289+ const existing = comments.find(c => c.body && c.body.includes(marker));
290+
291+ if (existing) {
292+ console.log(`✏️ Updating existing comment ${existing.id}`);
293+ await github.rest.issues.updateComment({
294+ owner: context.repo.owner,
295+ repo: context.repo.repo,
296+ comment_id: existing.id,
297+ body: comment
298+ });
299+ } else {
300+ console.log('💬 Posting new comment to PR...');
301+ await github.rest.issues.createComment({
302+ owner: context.repo.owner,
303+ repo: context.repo.repo,
304+ issue_number: prNumber,
305+ body: comment
306+ });
307+ }
308+
309+ console.log('✅ Failure comment posted/updated successfully');
267310
268311 notify-success :
269312 needs : [guard, benchmark, docs]
@@ -281,45 +324,21 @@ jobs:
281324 BENCHMARKS_SUMMARY : ${{ needs.guard.outputs.benchmarks_summary }}
282325 with :
283326 script : |
284- console.log('🎉 Workflow success detected - posting notification ...');
327+ console.log('🎉 Workflow success detected - posting/updating comment ...');
285328
329+ const marker = '<!-- ctbenchmarks-success-comment -->';
286330 const prNumber = context.payload.pull_request.number;
287331 const previewUrl = `https://control-toolbox.org/CTBenchmarks.jl/previews/PR${prNumber}/index.html`;
288332 const benchmarksSummary = process.env.BENCHMARKS_SUMMARY;
333+ const runUrl = `${context.payload.repository.html_url}/actions/runs/${context.runId}`;
334+ const branchName = context.payload.pull_request.head.ref;
289335
290- console.log(`🔍 Checking documentation preview at: ${previewUrl}`);
291-
292- // Wait up to 30s for the preview page to exist
293- async function checkPreview(url, attempts=6, delayMs=5000) {
294- for (let i = 0; i < attempts; i++) {
295- try {
296- const response = await fetch(url, { method: 'HEAD' });
297- if (response.ok) return true;
298- } catch {}
299- console.log(`⏳ Preview not ready yet (attempt ${i+1}/${attempts})`);
300- await new Promise(r => setTimeout(r, delayMs));
301- }
302- return false;
303- }
304-
305- const previewReady = await checkPreview(previewUrl);
306-
307- let previewSection = '';
308- if (previewReady) {
309- console.log('✅ Documentation preview is available');
310- previewSection = `
336+ const previewSection = `
311337 ### 📖 Documentation Preview
312338 - 🌐 **[📚 View Documentation Preview](${previewUrl})** ← Click to see your changes!
313- `;
314- } else {
315- console.log('⚠️ Documentation preview still not available');
316- previewSection = `
317- ### 📖 Documentation Preview
318- - ⏳ Documentation preview will be available shortly at: [Preview Link](${previewUrl})
319- `;
320- }
339+ `;
321340
322- let comment = `
341+ const comment = `${marker}
323342 ## ✅ Benchmark and Documentation Complete
324343
325344 The automated workflow has completed successfully! 🎉
@@ -329,27 +348,47 @@ jobs:
329348 - 📚 **Documentation**: Documentation updated successfully
330349 - 🔄 **Integration**: All changes integrated properly
331350 ${previewSection}
351+
332352 ### 📋 Results
333353 - 🎯 Benchmark results have been committed to your feature branch
334354 - 📚 Documentation has been regenerated with the latest benchmark data
335355
336356 ### 🔗 Links
337- - 📊 [View workflow run](${context.payload.repository.html_url}/actions/runs/${context.runId })
338- - 🌿 [View your feature branch](${context.payload.repository.html_url}/tree/${context.payload.pull_request.head.ref })
357+ - 📊 [View workflow run](${runUrl })
358+ - 🌿 [View your feature branch](${context.payload.repository.html_url}/tree/${branchName })
339359
340360 ---
341- *🤖 This notification was automatically generated*
342- `;
361+ *🤖 This notification was automatically generated*`;
343362
344- console.log('💬 Posting success comment to PR...');
345- await github.rest.issues.createComment ({
363+ // Find existing success comment
364+ const { data: comments } = await github.rest.issues.listComments ({
346365 owner: context.repo.owner,
347366 repo: context.repo.repo,
348367 issue_number: prNumber,
349- body: comment
368+ per_page: 100
350369 });
351370
352- console.log('✅ Success notification posted successfully');
371+ const existing = comments.find(c => c.body && c.body.includes(marker));
372+
373+ if (existing) {
374+ console.log(`✏️ Updating existing comment ${existing.id}`);
375+ await github.rest.issues.updateComment({
376+ owner: context.repo.owner,
377+ repo: context.repo.repo,
378+ comment_id: existing.id,
379+ body: comment
380+ });
381+ } else {
382+ console.log('💬 Posting new comment to PR...');
383+ await github.rest.issues.createComment({
384+ owner: context.repo.owner,
385+ repo: context.repo.repo,
386+ issue_number: prNumber,
387+ body: comment
388+ });
389+ }
390+
391+ console.log('✅ Success comment posted/updated successfully');
353392
354393 workflow-summary :
355394 needs : [guard, benchmark, docs]
0 commit comments