forked from angular/angular
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpayload-size.sh
157 lines (129 loc) · 4.55 KB
/
payload-size.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env bash
set -eu -o pipefail
# statc makes `stat -c` work on both Linux & OSX
function statc () {
case $(uname) in
Darwin*) format='-f%z' ;;
*) format='-c%s' ;;
esac
stat ${format} $@
}
# sedr makes `sed -r` work on both Linux & OSX
function sedr () {
case $(uname) in
Darwin*) flag='-E' ;;
*) flag='-r' ;;
esac
sed ${flag} "$@"
}
readonly PROJECT_NAME="angular-payload-size"
NODE_MODULES_BIN=$PROJECT_ROOT/node_modules/.bin/
# Get the gzip size of a file with the specified compression level.
# $1: string - The file path.
# $2: number - The level of compression.
getGzipSize() {
local filePath=$1
local compLevel=$2
local compPath="$(mktemp).gz"
local size=-1
gzip -c -$compLevel "$filePath" >> "$compPath"
size=$(statc "$compPath")
rm "$compPath"
echo $size
}
# Calculate the size of target file uncompressed size, gzip7 size, gzip9 size
# Write to global variable $payloadData, $filename
calculateSize() {
label=$(echo "$filename" | sed "s/.*\///" | sed "s/\..*//")
rawSize=$(statc $filename)
gzip7Size=$(getGzipSize "$filename" 7)
gzip9Size=$(getGzipSize "$filename" 9)
# Log the sizes (for information/debugging purposes).
printf "Size: %6d (gzip7: %6d, gzip9: %6d) %s\n" $rawSize $gzip7Size $gzip9Size $label
payloadData="$payloadData\"uncompressed/$label\": $rawSize, "
payloadData="$payloadData\"gzip7/$label\": $gzip7Size, "
payloadData="$payloadData\"gzip9/$label\": $gzip9Size, "
}
# Check whether the file size is under limit.
# Exit with an error if limit is exceeded.
# $1: string - The name in database.
# $2: string - The payload size limit file.
checkSize() {
name="$1"
limitFile="$2"
# PRs and non-PR pushes will always test against the size-limits of the current revision.
node ${PROJECT_ROOT}/scripts/ci/payload-size.js $limitFile $name ${CI_COMMIT:-}
}
# Write timestamp to global variable `$payloadData`.
addTimestamp() {
# Add Timestamp
timestamp=$(date +%s)
payloadData="$payloadData\"timestamp\": $timestamp, "
}
# Write the current CI build URL to global variable `$payloadData`.
# This allows mapping the data stored in the database to the CI build job that generated it, which
# might contain more info/context.
# $1: string - The CI build URL.
addBuildUrl() {
buildUrl="$1"
payloadData="$payloadData\"buildUrl\": \"$buildUrl\", "
}
# Write the commit message for the specified CI commit to global variable `$payloadData`.
# $1: string - The commit SHA for this build (in `<SHA-1>` format).
addMessage() {
message="${1}"
message=$(echo $message | sed 's/\r//g' | sed 's/\\/\\\\/g' | sed 's/"/\\"/g')
payloadData="$payloadData\"message\": \"$message\", "
}
# Convert the current `payloadData` value to a JSON string.
# (Basically remove trailing `,` and wrap in `{...}`.)
payloadToJson() {
echo "{$(sedr 's|, *$||' <<< $payloadData)}"
}
# Upload data to firebase database if it's commit, print out data for pull requests.
# $1: string - The name in database.
uploadData() {
name="$1"
readonly safeBranchName=$(echo $CI_BRANCH | sed -e 's/\./_/g')
readonly dbPath=/payload/$name/$safeBranchName/$CI_COMMIT
readonly jsonPayload=$(payloadToJson)
# WARNING: CI_SECRET_PAYLOAD_FIREBASE_TOKEN should NOT be printed.
set +x
$NODE_MODULES_BIN/firebase database:update --data "$jsonPayload" --project $PROJECT_NAME --force --token "$CI_SECRET_PAYLOAD_FIREBASE_TOKEN" $dbPath
}
# Track payload size.
# $1: string - The name in database.
# $2: string - The file path.
# $3: true | false - Whether to check the payload size and fail the test if it exceeds limit.
# $4: [string] - The payload size limit file. Only necessary if `$3` is `true`.
trackPayloadSize() {
name="$1"
path="$2"
checkSize="$3"
limitFile="${4:-}"
payloadData=""
# Calculate the file sizes.
echo "Calculating sizes for files in '$path'..."
for filename in $path; do
calculateSize
done
# Save the file sizes to be retrieved from `payload-size.js`.
echo "$(payloadToJson)" > /tmp/current.log
# If this is a non-PR build, upload the data to firebase.
if [[ "${CI_PULL_REQUEST:-}" == "false" ]]; then
echo "Uploading data for '$name'..."
addTimestamp
addBuildUrl $CI_BUILD_URL
addMessage $CI_COMMIT
uploadData $name
else
echo "Skipped uploading data for '$name', because this is a pull request."
fi
# Check the file sizes against the specified limits.
if [[ $checkSize = true ]]; then
echo "Verifying sizes against '$limitFile'..."
checkSize $name $limitFile
else
echo "Skipped verifying sizes (checkSize: false)."
fi
}