-
Notifications
You must be signed in to change notification settings - Fork 2
misc: artifact size metrics actions #150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
638ffd1
ea8bc0a
9cb1f3a
4fb170b
2b94767
808ea09
7dafe57
38f2890
bd7e141
771898c
bbf999a
0907192
af71947
7c77b82
46ce318
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
name: Calculate Artifact Size | ||
description: Calculates size for JVM artifacts | ||
|
||
inputs: | ||
upload: | ||
description: Whether the metrics should be uploaded to S3/Cloudwatch | ||
type: boolean | ||
release_metrics: | ||
description: Whether the metrics are coming from a release build | ||
type: boolean | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: Calculate and upload artifact sizes | ||
shell: bash | ||
env: | ||
GITHUB_REPOSITORY: ${{ github.repository }} | ||
IDENTIFIER: ${{ github.ref_name }} | ||
UPLOAD: ${{ inputs.upload }} | ||
RELEASE_METRICS: ${{ inputs.release_metrics }} | ||
run: | | ||
chmod +x ../utils/calculate-and-upload/main.sh | ||
../utils/calculate-and-upload/main.sh |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
name: Process artifact size metrics | ||
description: Compares artifact size metrics, leaves a comment, and fails if a size increase of ≥5% is detected. | ||
|
||
inputs: | ||
download: | ||
description: Whether the artifact size metrics should be downloaded from S3 | ||
type: boolean | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: Download and process artifact size metrics | ||
description: Compares artifact size metrics and sets LARGE_DIFF to true if a size increase of ≥5% is detected. | ||
shell: bash | ||
env: | ||
DOWNLOAD: ${{ inputs.download }} | ||
GITHUB_REPOSITORY: ${{ github.repository }} | ||
IDENTIFIER: ${{ github.ref_name }} | ||
run: | | ||
chmod +x ../utils/download-and-process/main.sh | ||
../utils/download-and-process/main.sh | ||
|
||
- name: Comment artifact size metrics comparison | ||
if: github.event_name == 'pull_request' | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const fs = require('node:fs') | ||
|
||
// Read the artifact size metrics comparison | ||
const comparison = fs.readFileSync('build/reports/metrics/artifact-analysis.md', 'utf8') | ||
|
||
// Get PR ID | ||
const { data: pullRequest } = await github.rest.pulls.get({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
pull_number: context.issue.number | ||
}) | ||
const pullRequestId = pullRequest.node_id | ||
|
||
// Add the comment | ||
const addCommentResponse = await github.graphql(` | ||
mutation { | ||
addComment(input: {body: """${comparison}""", subjectId: "${pullRequestId}"}) { | ||
commentEdge { node { id } } | ||
} | ||
} | ||
`) | ||
|
||
const commentId = addCommentResponse.addComment.commentEdge.node.id | ||
|
||
// Minimize the comment | ||
await github.graphql(` | ||
mutation { | ||
minimizeComment(input: {subjectId: "${commentId}", classifier: RESOLVED}) { } | ||
} | ||
`) | ||
|
||
- name: Large size increase? | ||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'acknowledge-artifact-size-increase') }} | ||
shell: bash | ||
run: | | ||
if [ "$LARGE_DIFF" == "true" ]; then | ||
echo "An artifact has increased in size by more than 5%. | ||
If this is expected, please add the acknowledge-artifact-size-increase label to this pull request." | ||
exit 1 | ||
fi |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Gets artifact size metrics from staging dir | ||
calculateArtifactSizes() { | ||
# Artifact staging dir | ||
input_dir="build/m2" | ||
|
||
# Create output_file | ||
output_file="$1" | ||
mkdir -p "$(dirname "$output_file")" | ||
touch "$output_file" | ||
|
||
# Write CSV header | ||
echo "Artifact, Size (Bytes)" > "$output_file" | ||
|
||
# Find all JARs (exclude sources and javadoc) | ||
# TODO: Calculate KN artifacts sizes | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we have an internal task for this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have an older task for it: SDK-KT-771 |
||
find "$input_dir" -type f -name "*.jar" ! -name "*-sources.jar" ! -name "*-javadoc.jar" | while read -r jar; do | ||
size=$(stat -c%s "$jar") | ||
|
||
# remove dir path, version, optional timestamp, and .jar | ||
artifact=$(basename "$jar") | ||
artifact=$(echo "$artifact" | sed -E 's/-[0-9].*\.jar$//') | ||
|
||
# Add artifact size to CSV | ||
echo "$artifact, $size" >> "$output_file" | ||
done | ||
|
||
# Print results for debugging | ||
cat "$output_file" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Upload the artifact size metrics to cloudwatch | ||
uploadToCloudwatch() { | ||
metrics_file="$1" | ||
metrics=() | ||
|
||
# Read CSV | ||
while IFS=',' read -r artifactName artifactSize; do | ||
# Skip header | ||
[[ "$artifactName" == "Artifact" ]] && continue | ||
|
||
# Trim spaces | ||
artifactName=$(echo "$artifactName" | xargs) | ||
artifactSize=$(echo "$artifactSize" | xargs) | ||
|
||
# Build metric JSON | ||
metrics+=$(jq -n \ | ||
--arg name "$GITHUB_REPOSITORY-$artifactName" \ | ||
--arg value "$artifactSize" \ | ||
--arg project "$GITHUB_REPOSITORY" \ | ||
'{ | ||
MetricName: $name, | ||
Timestamp: (now | todate), | ||
Unit: "Bytes", | ||
Value: ($value | tonumber), | ||
Dimensions: [ | ||
{ Name: "Project", Value: $project } | ||
] | ||
}' | ||
) | ||
done < "$metrics_file" | ||
|
||
namespace="Artifact Size Metrics" | ||
chunk_size=1000 | ||
|
||
# Send metrics in chunks | ||
for ((i=0; i<${#metrics[@]}; i+=chunk_size)); do | ||
chunk=("${metrics[@]:i:chunk_size}") | ||
aws cloudwatch put-metric-data \ | ||
--namespace "$namespace" \ | ||
--metric-data "$(printf '%s\n' "${chunk[@]}" | jq -s '.')" | ||
done | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#!/bin/bash | ||
|
||
# Bash script to calculate, and upload artifact size metrics | ||
|
||
source "$(dirname "$0")/calculate_metrics.sh" | ||
source "$(dirname "$0")/cloudwatch.sh" | ||
source "$(dirname "$0")/../s3.sh" | ||
source "$(dirname "$0")/../constants.sh" | ||
source "$(dirname "$0")/../setup.sh" | ||
|
||
setup | ||
|
||
# Calculate size for artifacts in staging dir (build/m2) and save them to metrics_file | ||
calculateArtifactSizes "$metrics_file" # see: constants.sh | ||
|
||
# Upload metrics to S3/cloudwatch if required | ||
if [ "$UPLOAD" == "true" ]; then | ||
if [ "$RELEASE_METRICS" == "true" ]; then | ||
# For record-keeping | ||
uploadToMetricsBucket "$metrics_file" "$GITHUB_REPOSITORY"-v"$IDENTIFIER".csv | ||
uploadToMetricsBucket "$metrics_file" "$GITHUB_REPOSITORY"-latest.csv | ||
|
||
# For display in our OPS dashboard | ||
uploadToCloudwatch "$metrics_file" "$GITHUB_REPOSITORY" | ||
else | ||
# For downstream consumption in pull requests | ||
uploadToMetricsBucket "$metrics_file" [TEMP]"$GITHUB_REPOSITORY"-pull-request-"$IDENTIFIER".csv | ||
fi | ||
fi |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/bin/bash | ||
|
||
# Where current metrics are stored | ||
metrics_file="build/reports/metrics/artifact-size-metrics.csv" | ||
|
||
# Where metrics from latest release are stored | ||
latest_release_metrics_file="build/reports/metrics/latest-release-artifact-size-metrics.csv" | ||
|
||
# Where the metrics comparison results are stored | ||
metrics_comparison_file="build/reports/metrics/comparison.md" |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,50 @@ | ||||||||||
# Compares artifact size metrics to ones from the latest available release, | ||||||||||
# stores comparison as a markdown table, | ||||||||||
# and returns "true" if a large diff was found (over 5%) | ||||||||||
compareMetrics() { | ||||||||||
local metrics_file="$1" | ||||||||||
local latest_release_metrics_file="$2" | ||||||||||
local metrics_comparison_file="$3" | ||||||||||
|
||||||||||
# Title and table headers | ||||||||||
{ | ||||||||||
echo "Affected Artifacts" | ||||||||||
echo "=" | ||||||||||
echo "| Artifact | Pull Request (bytes) | Latest Release (bytes) | Delta (bytes) | Delta (percentage) |" | ||||||||||
echo "|----------|----------------------|------------------------|---------------|--------------------|" | ||||||||||
} > "$metrics_comparison_file" | ||||||||||
|
||||||||||
large_diff=false | ||||||||||
|
||||||||||
# Read CSV | ||||||||||
while IFS=',' read -r artifact size; do | ||||||||||
# Skip header | ||||||||||
[ "$artifact" = "Artifact" ] && continue | ||||||||||
|
||||||||||
# Trim spaces | ||||||||||
artifact=$(echo "$artifact" | xargs) | ||||||||||
size=$(echo "$size" | xargs) | ||||||||||
|
||||||||||
# Find corresponding artifact size in release file or skip | ||||||||||
latest_release_size=$(awk -F',' -v art="$artifact" 'NR>1 && $1==art {gsub(/ /,"",$2); print $2}' "$latest_release_metrics_file") | ||||||||||
[ -z "$latest_release_size" ] && continue | ||||||||||
|
||||||||||
# Find delta | ||||||||||
delta=$((size - latest_release_size)) | ||||||||||
abs_delta=${delta#-} | ||||||||||
percent=$((100 * abs_delta / latest_release_size)) | ||||||||||
|
||||||||||
# Add to file | ||||||||||
echo "| $artifact | $size | $latest_release_size | $delta | ${percent}% |" >> "$metrics_comparison_file" | ||||||||||
|
||||||||||
# Check for large diff | ||||||||||
if [ "$percent" -gt 5 ]; then | ||||||||||
large_diff=true | ||||||||||
fi | ||||||||||
Comment on lines
+40
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we no longer using the Lines 103 to 106 in 56de883
Let's delete it there if it's no longer being used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, forgot to delete all that. We never really changed the value from 5% so it doesn't seem necessary. |
||||||||||
done < "$metrics_file" | ||||||||||
|
||||||||||
# Print results for debugging | ||||||||||
cat "$metrics_comparison_file" | ||||||||||
|
||||||||||
$large_diff && echo "true" | ||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#!/bin/bash | ||
|
||
# Bash script to download, and compare artifact size metrics | ||
|
||
source "$(dirname "$0")/compare.sh" | ||
source "$(dirname "$0")/../s3.sh" | ||
source "$(dirname "$0")/../constants.sh" | ||
source "$(dirname "$0")/../setup.sh" | ||
|
||
setup | ||
|
||
if [ "$DOWNLOAD" == "true" ]; then | ||
# Get metrics calculated in codebuild - otherwise metrics will already be here | ||
downloadFromMetricsBucket [TEMP]"$GITHUB_REPOSITORY"-pull-request-"$IDENTIFIER".csv "$metrics_file" # see: constants.sh | ||
fi | ||
|
||
# Metrics from the latest release are never calculated here so we need to download them | ||
downloadFromMetricsBucket "$GITHUB_REPOSITORY"-latest.csv "$latest_release_metrics_file" # see: constants.sh | ||
|
||
# Compare metrics | ||
export LARGE_DIFF=$(compareMetrics "$metrics_file" "$latest_release_metrics_file" "$metrics_comparison_file") # see: constants.sh | ||
|
||
if [ "$LARGE_DIFF" == "true" ]; then | ||
echo "Large diff found!" | ||
fi |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Owned by: aws-kotlin-sdk+ci | ||
S3_ARTIFACT_SIZE_METRICS_BUCKET="artifact-size-metrics" | ||
|
||
# Uploads metrics to the metrics bucket under the specified file name | ||
uploadToMetricsBucket() { | ||
aws s3 cp "$1" s3://"$S3_ARTIFACT_SIZE_METRICS_BUCKET"/"$2" | ||
} | ||
|
||
# Downloads metrics from the metrics bucket to the specified local file | ||
downloadFromMetricsBucket() { | ||
aws s3 cp s3://"$S3_ARTIFACT_SIZE_METRICS_BUCKET"/"$1" "$2" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Exit if non zero exit code or if env var is missing, and enable command tracing | ||
setup() { | ||
set -u | ||
set -e | ||
set -x | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we always minimizing the comment now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we rarely have to actually look at the metrics. If we do, it's really easy to just un-minimize a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't the artifact sizes logged in the CI output? Maybe we don't need the comment at all