@@ -27,6 +27,14 @@ inputs:
2727 description : ' Platform architecture to compare (amd64 or arm64)'
2828 required : false
2929 default : ' amd64'
30+ size-thresholds :
31+ description : ' Optional JSON: per-image trigger thresholds. Only comment when an image increase exceeds its threshold. Example: {"rocketchat":{"mb":50,"percent":5},"omnichannel":{"mb":10,"percent":2}}'
32+ required : false
33+ default : ' '
34+ fail-thresholds :
35+ description : ' Optional JSON: per-image fail thresholds. Task fails when an image increase exceeds its threshold (mb and/or percent). Example: {"rocketchat":{"mb":100,"percent":15}}'
36+ required : false
37+ default : ' '
3038
3139outputs :
3240 total-size :
@@ -38,6 +46,12 @@ outputs:
3846 size-diff-percent :
3947 description : ' Size difference percentage'
4048 value : ${{ steps.compare.outputs.size-diff-percent }}
49+ comment-triggered :
50+ description : ' Whether to post PR comment (only when size is bigger and thresholds met)'
51+ value : ${{ steps.compare.outputs.comment-triggered }}
52+ failed :
53+ description : ' True if image size exceeded fail-thresholds'
54+ value : ${{ steps.compare.outputs.failed }}
4155
4256runs :
4357 using : ' composite'
5266 - name : Measure image sizes from artifacts
5367 id : measure
5468 shell : bash
69+ env :
70+ PLATFORM : ${{ inputs.platform }}
71+ TAG : ${{ inputs.tag }}
5572 run : |
56- PLATFORM="${{ inputs.platform }}"
5773 echo "Reading image sizes from build artifacts for platform: $PLATFORM"
5874
5975 declare -A sizes
94110 # Save to JSON
95111 echo "{" > current-sizes.json
96112 echo " \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"," >> current-sizes.json
97- echo " \"tag\": \"${{ inputs.tag }} \"," >> current-sizes.json
113+ echo " \"tag\": \"$TAG \"," >> current-sizes.json
98114 echo " \"total\": $total," >> current-sizes.json
99115 echo " \"services\": {" >> current-sizes.json
100116
@@ -121,12 +137,12 @@ runs:
121137 id : baseline
122138 shell : bash
123139 continue-on-error : true
140+ env :
141+ REGISTRY : ${{ inputs.registry }}
142+ ORG : ${{ inputs.repository }}
143+ TAG : ${{ inputs.baseline-tag }}
144+ PLATFORM : ${{ inputs.platform }}
124145 run : |
125- REGISTRY="${{ inputs.registry }}"
126- ORG="${{ inputs.repository }}"
127- TAG="${{ inputs.baseline-tag }}"
128- PLATFORM="${{ inputs.platform }}"
129-
130146 echo "Measuring baseline: $REGISTRY/$ORG/*:$TAG (platform: $PLATFORM)"
131147
132148 declare -A sizes
@@ -251,6 +267,8 @@ runs:
251267 - name : Save current measurement to history
252268 if : github.ref == 'refs/heads/develop'
253269 shell : bash
270+ env :
271+ CI_PAT : ${{ inputs.ci-pat }}
254272 run : |
255273 timestamp=$(date -u +%Y%m%d-%H%M%S)
256274 commit_sha="${{ github.sha }}"
@@ -263,7 +281,7 @@ runs:
263281 git commit -m "Add measurement for ${timestamp} (${commit_sha:0:7})"
264282 git config --global user.email "ci@rocket.chat"
265283 git config --global user.name "rocketchat-ci[bot]"
266- git config --global url.https://${{ inputs.ci-pat }} @github.com/.insteadOf https://github.com/
284+ git config --global url.https://$CI_PAT @github.com/.insteadOf https://github.com/
267285 git push origin image-size-history
268286 cd -
269287
@@ -272,13 +290,19 @@ runs:
272290 - name : Compare and generate report
273291 id : compare
274292 shell : bash
293+ env :
294+ SIZE_THRESHOLDS : ${{ inputs.size-thresholds }}
295+ FAIL_THRESHOLDS : ${{ inputs.fail-thresholds }}
296+ TAG : ${{ inputs.tag }}
297+ BASELINE_TAG : ${{ inputs.baseline-tag }}
275298 run : |
276299 current_total=$(jq -r '.total' current-sizes.json)
277300
278301 if [[ ! -f baseline-sizes.json ]]; then
279302 echo "No baseline available"
280303 echo "size-diff=0" >> $GITHUB_OUTPUT
281304 echo "size-diff-percent=0" >> $GITHUB_OUTPUT
305+ echo "comment-triggered=false" >> $GITHUB_OUTPUT
282306
283307 cat > report.md << 'EOF'
284308 # 📦 Docker Image Size Report
@@ -302,6 +326,17 @@ runs:
302326 echo "size-diff=$diff" >> $GITHUB_OUTPUT
303327 echo "size-diff-percent=$percent" >> $GITHUB_OUTPUT
304328
329+ # Only comment when size is bigger than baseline; optionally require per-image thresholds
330+ THRESHOLDS="$SIZE_THRESHOLDS"
331+ FAIL_THRESHOLDS="$FAIL_THRESHOLDS"
332+ comment_triggered=false
333+ fail_triggered=false
334+ if [[ $diff -gt 0 ]]; then
335+ if [[ -z "$THRESHOLDS" ]] || [[ "$THRESHOLDS" == "{}" ]]; then
336+ comment_triggered=true
337+ fi
338+ fi
339+
305340 color="gray"
306341 if (( $(awk "BEGIN {print ($percent > 0.01)}") )); then
307342 color="red"
@@ -346,6 +381,38 @@ runs:
346381 service_percent=0
347382 fi
348383
384+ # Check per-image thresholds for comment trigger (only when size increased)
385+ if [[ $diff -gt 0 ]] && [[ -n "$THRESHOLDS" ]] && [[ "$THRESHOLDS" != "{}" ]]; then
386+ threshold_mb=$(echo "$THRESHOLDS" | jq -r ".\"$service\".mb // empty")
387+ threshold_pct=$(echo "$THRESHOLDS" | jq -r ".\"$service\".percent // empty")
388+ if [[ -n "$threshold_mb" ]] || [[ -n "$threshold_pct" ]]; then
389+ exceeded=false
390+ if [[ -n "$threshold_mb" ]] && [[ $service_diff -ge $(awk "BEGIN {printf \"%.0f\", $threshold_mb * 1048576}") ]]; then
391+ exceeded=true
392+ fi
393+ if [[ -n "$threshold_pct" ]] && [[ $service_percent != "0.00" ]] && (( $(awk "BEGIN {print ($service_percent >= $threshold_pct)}") )); then
394+ exceeded=true
395+ fi
396+ [[ "$exceeded" == "true" ]] && comment_triggered=true
397+ fi
398+ fi
399+
400+ # Check per-image fail thresholds (task fails when exceeded)
401+ if [[ $diff -gt 0 ]] && [[ -n "$FAIL_THRESHOLDS" ]] && [[ "$FAIL_THRESHOLDS" != "{}" ]]; then
402+ fail_mb=$(echo "$FAIL_THRESHOLDS" | jq -r ".\"$service\".mb // empty")
403+ fail_pct=$(echo "$FAIL_THRESHOLDS" | jq -r ".\"$service\".percent // empty")
404+ if [[ -n "$fail_mb" ]] || [[ -n "$fail_pct" ]]; then
405+ exceeded=false
406+ if [[ -n "$fail_mb" ]] && [[ $service_diff -ge $(awk "BEGIN {printf \"%.0f\", $fail_mb * 1048576}") ]]; then
407+ exceeded=true
408+ fi
409+ if [[ -n "$fail_pct" ]] && [[ $service_percent != "0.00" ]] && (( $(awk "BEGIN {print ($service_percent >= $fail_pct)}") )); then
410+ exceeded=true
411+ fi
412+ [[ "$exceeded" == "true" ]] && fail_triggered=true
413+ fi
414+ fi
415+
349416 color="gray"
350417 if (( $(awk "BEGIN {print ($service_percent > 0.01)}") )); then
351418 color="red"
@@ -474,62 +541,31 @@ runs:
474541 <details>
475542 <summary>ℹ️ About this report</summary>
476543
477- This report compares Docker image sizes from this build against the \`${{ inputs.baseline-tag }} \` baseline.
544+ This report compares Docker image sizes from this build against the \`$BASELINE_TAG \` baseline.
478545
479- - **Tag:** \`${{ inputs.tag }} \`
480- - **Baseline:** \`${{ inputs.baseline-tag }} \`
546+ - **Tag:** \`$TAG \`
547+ - **Baseline:** \`$BASELINE_TAG \`
481548 - **Timestamp:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")
482549 - **Historical data points:** $history_count
483550
484551 </details>
485552 EOF
486553
487- - name : Comment on PR
488- if : github.event_name == 'pull_request'
489- uses : actions/github-script@v7
490- with :
491- github-token : ${{ inputs.github-token }}
492- script : |
493- const fs = require('fs');
494-
495- if (!fs.existsSync('report.md')) {
496- console.log('No report found, skipping comment');
497- return;
498- }
499-
500- const report = fs.readFileSync('report.md', 'utf8');
501-
502- // Find existing comment
503- const comments = await github.rest.issues.listComments({
504- owner: context.repo.owner,
505- repo: context.repo.repo,
506- issue_number: context.issue.number
507- });
508-
509- const botComment = comments.data.find(comment =>
510- comment.user.type === 'Bot' &&
511- comment.body.includes('📦 Docker Image Size Report')
512- );
513-
514- const commentBody = report + '\n\n---\n*Updated: ' + new Date().toUTCString() + '*';
515-
516- if (botComment) {
517- await github.rest.issues.updateComment({
518- owner: context.repo.owner,
519- repo: context.repo.repo,
520- comment_id: botComment.id,
521- body: commentBody
522- });
523- console.log('Updated existing comment');
524- } else {
525- await github.rest.issues.createComment({
526- owner: context.repo.owner,
527- repo: context.repo.repo,
528- issue_number: context.issue.number,
529- body: commentBody
530- });
531- console.log('Created new comment');
532- }
554+ echo "comment-triggered=$comment_triggered" >> $GITHUB_OUTPUT
555+ echo "failed=$fail_triggered" >> $GITHUB_OUTPUT
556+
557+ if [[ "$fail_triggered" == "true" ]]; then
558+ echo "::error::Docker image size exceeded fail-thresholds (mb/percent). Check the report for details."
559+ exit 1
560+ fi
561+
562+ - name : Add report to Job Summary
563+ if : always()
564+ shell : bash
565+ run : |
566+ if [[ -f report.md ]]; then
567+ cat report.md >> $GITHUB_STEP_SUMMARY
568+ fi
533569
534570 - name : Cleanup worktree
535571 if : always()
0 commit comments