Chat component enhancements v2 #1278
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Package Report | |
on: | |
pull_request: | |
branches: | |
- develop | |
env: | |
COMMENT_TITLE: "## Packages Report" | |
UPDATING_MESSAGE: "Generating... ⚠️" | |
jobs: | |
post-status-comment: | |
if: github.actor != 'dependabot[bot]' | |
name: Post Status Comment | |
runs-on: ubuntu-latest | |
steps: | |
- name: Post status PR comment | |
uses: actions/github-script@v6 | |
with: | |
script: | | |
const { data: comments } = await github.rest.issues.listComments({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.payload.pull_request.number, | |
}); | |
const botComment = comments.find(comment => | |
comment.user.login === 'github-actions[bot]' && | |
comment.body.startsWith(process.env.COMMENT_TITLE) | |
); | |
if (botComment) { | |
await github.rest.issues.updateComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
comment_id: botComment.id, | |
body: `${process.env.COMMENT_TITLE}\n\n${process.env.UPDATING_MESSAGE}`, | |
}); | |
} else { | |
await github.rest.issues.createComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.payload.pull_request.number, | |
body: `${process.env.COMMENT_TITLE}\n\n${process.env.UPDATING_MESSAGE}`, | |
}); | |
} | |
extract-pr-data: | |
name: Extract PR Data | |
runs-on: ubuntu-latest | |
needs: post-status-comment | |
strategy: | |
matrix: | |
package: [core, default, classic, bootstrap, material, fluent, utils, html] | |
steps: | |
- name: Checkout branch | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Setup node | |
id: setup-node | |
uses: actions/setup-node@v4 | |
with: | |
node-version: 22.x | |
- name: Use cache for root node_modules | |
id: cache-root-node_modules | |
uses: actions/cache@v4 | |
with: | |
path: node_modules | |
key: root-node_modules-${{ steps.setup-node.outputs.node-version }}-${{ hashFiles('package-lock.json') }} | |
- name: Install PR dependencies | |
run: | | |
npm ci --no-audit --no-fund | |
- name: Measure time and size | |
run: | | |
# Run 5 times to get median with decimal precision | |
times=() | |
for i in {1..5}; do | |
start_time=$(date +%s.%N) | |
if [ "${{ matrix.package }}" = "html" ]; then | |
npm run build --prefix packages/${{ matrix.package }} | |
else | |
npm run sass:compile:all --prefix packages/${{ matrix.package }} | |
fi | |
end_time=$(date +%s.%N) | |
elapsed=$(awk "BEGIN {printf \"%.1f\", $end_time - $start_time}") | |
times+=($elapsed) | |
done | |
# Sort times and get median (middle value) | |
IFS=$'\n' sorted_times=($(sort -n <<<"${times[*]}")) | |
build_time=${sorted_times[2]} | |
if [ "${{ matrix.package }}" = "html" ]; then | |
size=$(du -sb packages/${{ matrix.package }}/dist | awk '{printf "%.2f", $1/(1024*1024)}') | |
tar -czf packages/${{ matrix.package }}/dist.tar.gz -C packages/${{ matrix.package }} dist | |
gzip_size=$(du -b packages/${{ matrix.package }}/dist.tar.gz | awk '{printf "%.2f", $1/(1024*1024)}') | |
rm packages/${{ matrix.package }}/dist.tar.gz | |
else | |
size=$(du -b packages/${{ matrix.package }}/dist/all.css | awk '{printf "%.2f", $1/1024}') | |
gzip_size=$(gzip -c packages/${{ matrix.package }}/dist/all.css | wc -c | awk '{printf "%.2f", $1/1024}') | |
fi | |
echo "${{ matrix.package }}:$size:$gzip_size:$build_time" >> data.txt | |
- name: Upload PR data | |
uses: actions/upload-artifact@v4 | |
with: | |
name: pr-data-${{ matrix.package }} | |
path: data.txt | |
extract-develop-data: | |
name: Extract Develop Data | |
runs-on: ubuntu-latest | |
needs: post-status-comment | |
strategy: | |
matrix: | |
package: [core, default, classic, bootstrap, material, fluent, utils, html] | |
steps: | |
- name: Checkout branch | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Checkout develop branch | |
run: | | |
git fetch origin develop | |
git checkout origin/develop | |
- name: Setup node | |
id: setup-node | |
uses: actions/setup-node@v4 | |
with: | |
node-version: 22.x | |
- name: Use cache for develop node_modules | |
id: cache-develop-node_modules | |
uses: actions/cache@v4 | |
with: | |
path: node_modules | |
key: develop-node_modules-${{ steps.setup-node.outputs.node-version }}-${{ hashFiles('package-lock.json') }} | |
- name: Install develop dependencies | |
if: steps.cache-develop-node_modules.outputs.cache-hit != 'true' | |
run: | | |
npm ci --no-audit --no-fund | |
- name: Measure time and size | |
run: | | |
# Run 5 times to get median with decimal precision | |
times=() | |
for i in {1..5}; do | |
start_time=$(date +%s.%N) | |
if [ "${{ matrix.package }}" = "html" ]; then | |
npm run build --prefix packages/${{ matrix.package }} | |
else | |
npm run sass:compile:all --prefix packages/${{ matrix.package }} | |
fi | |
end_time=$(date +%s.%N) | |
elapsed=$(awk "BEGIN {printf \"%.1f\", $end_time - $start_time}") | |
times+=($elapsed) | |
done | |
# Sort times and get median (middle value) | |
IFS=$'\n' sorted_times=($(sort -n <<<"${times[*]}")) | |
build_time=${sorted_times[2]} | |
if [ "${{ matrix.package }}" = "html" ]; then | |
size=$(du -sb packages/${{ matrix.package }}/dist | awk '{printf "%.2f", $1/(1024*1024)}') | |
tar -czf packages/${{ matrix.package }}/dist.tar.gz -C packages/${{ matrix.package }} dist | |
gzip_size=$(du -b packages/${{ matrix.package }}/dist.tar.gz | awk '{printf "%.2f", $1/(1024*1024)}') | |
rm packages/${{ matrix.package }}/dist.tar.gz | |
else | |
size=$(du -b packages/${{ matrix.package }}/dist/all.css | awk '{printf "%.2f", $1/1024}') | |
gzip_size=$(gzip -c packages/${{ matrix.package }}/dist/all.css | wc -c | awk '{printf "%.2f", $1/1024}') | |
fi | |
echo "${{ matrix.package }}:$size:$gzip_size:$build_time" >> data.txt | |
- name: Upload Develop data | |
uses: actions/upload-artifact@v4 | |
with: | |
name: develop-data-${{ matrix.package }} | |
path: data.txt | |
generate-report: | |
name: Generate Report | |
runs-on: ubuntu-latest | |
needs: | |
- extract-pr-data | |
- extract-develop-data | |
steps: | |
- name: Download Artifacts | |
uses: actions/download-artifact@v4 | |
- name: Generate Comparison Table | |
run: | | |
echo "| | core | default | classic | bootstrap | material | fluent | utils | html |" >> size-comparison.md | |
echo "|----------------|---------------|--------------------|-----------------------|----------------------|---------------------|-----------------|-------------------|-------------------|" >> size-comparison.md | |
size_row="| **Size** " | |
gzip_row="| **Gzip Size** " | |
time_row="| **Compile Time** " | |
for package in core default classic bootstrap material fluent utils html; do | |
pr_file="pr-data-$package/data.txt" | |
develop_file="develop-data-$package/data.txt" | |
if [[ ! -f "$pr_file" || ! -f "$develop_file" ]]; then | |
size_row+="| N/A " | |
gzip_row+="| N/A " | |
time_row+="| N/A " | |
continue | |
fi | |
pr_data=$(cat "$pr_file") | |
develop_data=$(cat "$develop_file") | |
pr_size=$(echo "$pr_data" | cut -d':' -f2) | |
pr_gzip_size=$(echo "$pr_data" | cut -d':' -f3) | |
pr_time=$(echo "$pr_data" | cut -d':' -f4) | |
develop_size=$(echo "$develop_data" | cut -d':' -f2) | |
develop_gzip_size=$(echo "$develop_data" | cut -d':' -f3) | |
develop_time=$(echo "$develop_data" | cut -d':' -f4) | |
size_diff=$(awk "BEGIN {print $pr_size - $develop_size}") | |
size_diff_percent=$(awk "BEGIN {if ($develop_size > 0) print sprintf(\"%.1f\", (($pr_size - $develop_size) / $develop_size) * 100); else print 0}") | |
gzip_diff=$(awk "BEGIN {print $pr_gzip_size - $develop_gzip_size}") | |
gzip_diff_percent=$(awk "BEGIN {if ($develop_gzip_size > 0) print sprintf(\"%.1f\", (($pr_gzip_size - $develop_gzip_size) / $develop_gzip_size) * 100); else print 0}") | |
time_diff=$(awk "BEGIN {print $pr_time - $develop_time}") | |
time_diff_abs=$(awk "BEGIN {x = $time_diff; print (x < 0 ? -x : x)}") | |
time_diff_percent=$(awk "BEGIN {if ($develop_time > 0) print sprintf(\"%.1f\", ($time_diff / $develop_time) * 100); else print 0}") | |
time_diff_percent_abs=$(awk "BEGIN {x = $time_diff_percent; print (x < 0 ? -x : x)}") | |
# Hybrid tolerance: Hide indicator if BOTH conditions are met: | |
# 1. Absolute difference < 1 second (filters small timing noise) | |
# 2. Percentage difference < 15% (filters variance relative to baseline) | |
if (( $(awk "BEGIN {print ($time_diff_abs < 1 && $time_diff_percent_abs < 15)}") )); then | |
time_diff_percent="0.0" | |
fi | |
size_arrow=$(awk "BEGIN {if ($size_diff > 0) print \"🔼\"; else if ($size_diff < 0) print \"🔽\"; else print \"\"}") | |
gzip_arrow=$(awk "BEGIN {if ($gzip_diff > 0) print \"🔼\"; else if ($gzip_diff < 0) print \"🔽\"; else print \"\"}") | |
time_arrow=$(awk "BEGIN {if ($time_diff_percent > 0) print \"🔼\"; else if ($time_diff_percent < 0) print \"🔽\"; else print \"\"}") | |
if [ "$package" = "html" ]; then | |
size_row+="| $pr_size MB (${size_diff_percent}%$size_arrow)" | |
gzip_row+="| $pr_gzip_size MB (${gzip_diff_percent}%$gzip_arrow)" | |
else | |
size_row+="| $pr_size KB (${size_diff_percent}%$size_arrow)" | |
gzip_row+="| $pr_gzip_size KB (${gzip_diff_percent}%$gzip_arrow)" | |
fi | |
time_row+="| $(awk "BEGIN {printf \"%.1f\", $pr_time}") s (${time_diff_percent}%$time_arrow)" | |
done | |
echo "$size_row|" >> size-comparison.md | |
echo "$gzip_row|" >> size-comparison.md | |
echo "$time_row|" >> size-comparison.md | |
- name: Update PR comment | |
uses: actions/github-script@v6 | |
with: | |
script: | | |
const fs = require('fs'); | |
const table = fs.readFileSync('size-comparison.md', 'utf8'); | |
const { data: comments } = await github.rest.issues.listComments({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.payload.pull_request.number, | |
}); | |
const botComment = comments.find(comment => | |
comment.user.login === 'github-actions[bot]' && | |
comment.body.startsWith(process.env.COMMENT_TITLE) | |
); | |
await github.rest.issues.updateComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
comment_id: botComment.id, | |
body: `${process.env.COMMENT_TITLE}\n\n${table}`, | |
}); |