Skip to content

Commit f8101dc

Browse files
authored
misc: artifact size metrics actions (#150)
1 parent a4b8c95 commit f8101dc

File tree

18 files changed

+258
-726
lines changed

18 files changed

+258
-726
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Calculate Artifact Size
2+
description: Calculates size for JVM artifacts
3+
4+
inputs:
5+
upload:
6+
description: Whether the metrics should be uploaded to S3/Cloudwatch
7+
type: boolean
8+
release_metrics:
9+
description: Whether the metrics are coming from a release build
10+
type: boolean
11+
12+
runs:
13+
using: composite
14+
steps:
15+
- name: Calculate and upload artifact sizes
16+
shell: bash
17+
env:
18+
GITHUB_REPOSITORY: ${{ github.repository }}
19+
IDENTIFIER: ${{ github.ref_name }}
20+
UPLOAD: ${{ inputs.upload }}
21+
RELEASE_METRICS: ${{ inputs.release_metrics }}
22+
run: |
23+
chmod +x $GITHUB_ACTION_PATH/../utils/calculate-and-upload/main.sh
24+
$GITHUB_ACTION_PATH/../utils/calculate-and-upload/main.sh
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Process artifact size metrics
2+
description: Compares artifact size metrics, leaves a comment, and fails if a size increase of ≥5% is detected.
3+
4+
inputs:
5+
download:
6+
description: Whether the artifact size metrics should be downloaded from S3
7+
type: boolean
8+
9+
runs:
10+
using: composite
11+
steps:
12+
# Compares artifact size metrics and sets LARGE_DIFF to true if a size increase of ≥5% is detected.
13+
- name: Download and process artifact size metrics
14+
shell: bash
15+
env:
16+
DOWNLOAD: ${{ inputs.download }}
17+
GITHUB_REPOSITORY: ${{ github.repository }}
18+
IDENTIFIER: ${{ github.ref_name }}
19+
run: |
20+
chmod +x $GITHUB_ACTION_PATH/../utils/download-and-process/main.sh
21+
$GITHUB_ACTION_PATH/../utils/download-and-process/main.sh
22+
23+
- name: Large size increase?
24+
if: ${{ !contains(github.event.pull_request.labels.*.name, 'acknowledge-artifact-size-increase') }}
25+
shell: bash
26+
run: |
27+
if [ "$LARGE_DIFF" == "true" ]; then
28+
echo "An artifact has increased in size by more than 5%.
29+
If this is expected, please add the acknowledge-artifact-size-increase label to this pull request."
30+
exit 1
31+
fi

.github/actions/artifact-size-metrics/show-results/action.yml

Lines changed: 0 additions & 86 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Gets artifact size metrics from staging dir
2+
calculateArtifactSizes() {
3+
# Artifact staging dir
4+
input_dir="build/m2"
5+
6+
# Create output_file
7+
output_file="$1"
8+
mkdir -p "$(dirname "$output_file")"
9+
touch "$output_file"
10+
11+
# Write CSV header
12+
echo "Artifact, Size (Bytes)" > "$output_file"
13+
14+
# Find all JARs (exclude sources and javadoc)
15+
# TODO: Calculate KN artifacts sizes
16+
find "$input_dir" -type f -name "*.jar" ! -name "*-sources.jar" ! -name "*-javadoc.jar" | while read -r jar; do
17+
size=$(stat -c%s "$jar")
18+
19+
# remove dir path, version, optional timestamp, and .jar
20+
artifact=$(basename "$jar")
21+
artifact=$(echo "$artifact" | sed -E 's/-[0-9].*\.jar$//')
22+
23+
# Add artifact size to CSV
24+
echo "$artifact, $size" >> "$output_file"
25+
done
26+
27+
# Print results for debugging
28+
cat "$output_file"
29+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Upload the artifact size metrics to cloudwatch
2+
uploadToCloudwatch() {
3+
metrics_file="$1"
4+
metrics=()
5+
6+
# Read CSV
7+
while IFS=',' read -r artifactName artifactSize; do
8+
# Skip header
9+
[[ "$artifactName" == "Artifact" ]] && continue
10+
11+
# Trim spaces
12+
artifactName=$(echo "$artifactName" | xargs)
13+
artifactSize=$(echo "$artifactSize" | xargs)
14+
15+
# Build metric JSON
16+
metrics+=$(jq -n \
17+
--arg name "$GITHUB_REPOSITORY-$artifactName" \
18+
--arg value "$artifactSize" \
19+
--arg project "$GITHUB_REPOSITORY" \
20+
'{
21+
MetricName: $name,
22+
Timestamp: (now | todate),
23+
Unit: "Bytes",
24+
Value: ($value | tonumber),
25+
Dimensions: [
26+
{ Name: "Project", Value: $project }
27+
]
28+
}'
29+
)
30+
done < "$metrics_file"
31+
32+
namespace="Artifact Size Metrics"
33+
chunk_size=1000
34+
35+
# Send metrics in chunks
36+
for ((i=0; i<${#metrics[@]}; i+=chunk_size)); do
37+
chunk=("${metrics[@]:i:chunk_size}")
38+
aws cloudwatch put-metric-data \
39+
--namespace "$namespace" \
40+
--metric-data "$(printf '%s\n' "${chunk[@]}" | jq -s '.')"
41+
done
42+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/bin/bash
2+
3+
# Bash script to calculate, and upload artifact size metrics
4+
5+
source "$(dirname "$0")/calculate_metrics.sh"
6+
source "$(dirname "$0")/cloudwatch.sh"
7+
source "$(dirname "$0")/../s3.sh"
8+
source "$(dirname "$0")/../constants.sh"
9+
source "$(dirname "$0")/../setup.sh"
10+
11+
setup
12+
13+
# Calculate size for artifacts in staging dir (build/m2) and save them to metrics_file
14+
calculateArtifactSizes "$metrics_file" # see: constants.sh
15+
16+
# Upload metrics to S3/cloudwatch if required
17+
if [ "$UPLOAD" == "true" ]; then
18+
if [ "$RELEASE_METRICS" == "true" ]; then
19+
# For record-keeping
20+
uploadToMetricsBucket "$metrics_file" "$GITHUB_REPOSITORY"-v"$IDENTIFIER".csv
21+
uploadToMetricsBucket "$metrics_file" "$GITHUB_REPOSITORY"-latest.csv
22+
23+
# For display in our OPS dashboard
24+
uploadToCloudwatch "$metrics_file" "$GITHUB_REPOSITORY"
25+
else
26+
# For downstream consumption in pull requests
27+
uploadToMetricsBucket "$metrics_file" [TEMP]"$GITHUB_REPOSITORY"-pull-request-"$IDENTIFIER".csv
28+
fi
29+
fi
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/bash
2+
3+
# Where current metrics are stored
4+
metrics_file="build/reports/metrics/artifact-size-metrics.csv"
5+
6+
# Where metrics from latest release are stored
7+
latest_release_metrics_file="build/reports/metrics/latest-release-artifact-size-metrics.csv"
8+
9+
# Where the metrics comparison results are stored
10+
metrics_comparison_file="build/reports/metrics/comparison.md"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Compares artifact size metrics to ones from the latest available release,
2+
# stores comparison as a markdown table,
3+
# and returns "true" if a large diff was found (over 5%)
4+
compareMetrics() {
5+
local metrics_file="$1"
6+
local latest_release_metrics_file="$2"
7+
local metrics_comparison_file="$3"
8+
9+
# Title and table headers
10+
{
11+
echo "Affected Artifacts"
12+
echo "="
13+
echo "| Artifact | Pull Request (bytes) | Latest Release (bytes) | Delta (bytes) | Delta (percentage) |"
14+
echo "|----------|----------------------|------------------------|---------------|--------------------|"
15+
} > "$metrics_comparison_file"
16+
17+
large_diff=false
18+
19+
# Read CSV
20+
while IFS=',' read -r artifact size; do
21+
# Skip header
22+
[ "$artifact" = "Artifact" ] && continue
23+
24+
# Trim spaces
25+
artifact=$(echo "$artifact" | xargs)
26+
size=$(echo "$size" | xargs)
27+
28+
# Find corresponding artifact size in release file or skip
29+
latest_release_size=$(awk -F',' -v art="$artifact" 'NR>1 && $1==art {gsub(/ /,"",$2); print $2}' "$latest_release_metrics_file")
30+
[ -z "$latest_release_size" ] && continue
31+
32+
# Find delta
33+
delta=$((size - latest_release_size))
34+
abs_delta=${delta#-}
35+
percent=$((100 * abs_delta / latest_release_size))
36+
37+
# Add to file
38+
echo "| $artifact | $size | $latest_release_size | $delta | ${percent}% |" >> "$metrics_comparison_file"
39+
40+
# Check for large diff
41+
if [ "$percent" -gt 5 ]; then
42+
large_diff=true
43+
fi
44+
done < "$metrics_file"
45+
46+
# Print results for debugging
47+
cat "$metrics_comparison_file"
48+
49+
$large_diff && echo "true"
50+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/bash
2+
3+
# Bash script to download, and compare artifact size metrics
4+
5+
source "$(dirname "$0")/compare.sh"
6+
source "$(dirname "$0")/../s3.sh"
7+
source "$(dirname "$0")/../constants.sh"
8+
source "$(dirname "$0")/../setup.sh"
9+
10+
setup
11+
12+
if [ "$DOWNLOAD" == "true" ]; then
13+
# Get metrics calculated in codebuild - otherwise metrics will already be here
14+
downloadFromMetricsBucket [TEMP]"$GITHUB_REPOSITORY"-pull-request-"$IDENTIFIER".csv "$metrics_file" # see: constants.sh
15+
fi
16+
17+
# Metrics from the latest release are never calculated here so we need to download them
18+
downloadFromMetricsBucket "$GITHUB_REPOSITORY"-latest.csv "$latest_release_metrics_file" # see: constants.sh
19+
20+
# Compare metrics
21+
export LARGE_DIFF=$(compareMetrics "$metrics_file" "$latest_release_metrics_file" "$metrics_comparison_file") # see: constants.sh
22+
23+
if [ "$LARGE_DIFF" == "true" ]; then
24+
echo "Large diff found!"
25+
fi
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Owned by: aws-kotlin-sdk+ci
2+
S3_ARTIFACT_SIZE_METRICS_BUCKET="artifact-size-metrics"
3+
4+
# Uploads metrics to the metrics bucket under the specified file name
5+
uploadToMetricsBucket() {
6+
aws s3 cp "$1" s3://"$S3_ARTIFACT_SIZE_METRICS_BUCKET"/"$2"
7+
}
8+
9+
# Downloads metrics from the metrics bucket to the specified local file
10+
downloadFromMetricsBucket() {
11+
aws s3 cp s3://"$S3_ARTIFACT_SIZE_METRICS_BUCKET"/"$1" "$2"
12+
}

0 commit comments

Comments
 (0)