Skip to content

Commit ec7132e

Browse files
authored
Add docker images size change check (opea-project#2133)
Signed-off-by: ZePan110 <[email protected]>
1 parent 68c90a3 commit ec7132e

File tree

1 file changed

+202
-0
lines changed

1 file changed

+202
-0
lines changed
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
name: Check Docker Image Size Change
4+
permissions:
5+
contents: read
6+
7+
on:
8+
pull_request:
9+
branches: [main]
10+
types: [opened, reopened, ready_for_review, synchronize]
11+
paths:
12+
- '**/Dockerfile'
13+
14+
# If there is a new commit, the previous jobs will be canceled
15+
concurrency:
16+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
17+
cancel-in-progress: true
18+
19+
jobs:
20+
get-check-list:
21+
runs-on: ubuntu-latest
22+
outputs:
23+
files: ${{ steps.changed-dockerfiles.outputs.files }}
24+
steps:
25+
- name: Checkout PR branch
26+
uses: actions/checkout@v4
27+
with:
28+
fetch-depth: 0
29+
30+
- name: Get changed Dockerfiles
31+
id: changed-dockerfiles
32+
run: |
33+
merged_commit=$(git log -1 --format='%H')
34+
files=$(git diff --name-status --diff-filter=ARM ${{ github.event.pull_request.base.sha }} ${merged_commit} | awk '{print $2}' | grep -E 'Dockerfile$' | jq -R . | jq -sc .)
35+
echo "files=$files"
36+
echo "files=$files" >> $GITHUB_OUTPUT
37+
38+
build-and-check:
39+
needs: get-check-list
40+
runs-on: ubuntu-latest
41+
permissions:
42+
contents: read
43+
pull-requests: write
44+
actions: write
45+
if: needs.get-check-list.outputs.files != ''
46+
strategy:
47+
matrix:
48+
dockerfile: ${{ fromJson(needs.get-check-list.outputs.files) }}
49+
fail-fast: false
50+
# outputs:
51+
# comments: ${{ steps.build-check.outputs.comment_message }}
52+
steps:
53+
- name: Checkout PR branch
54+
uses: actions/checkout@v4
55+
with:
56+
fetch-depth: 0
57+
58+
- name: Set up Docker Buildx
59+
uses: docker/setup-buildx-action@v3
60+
61+
- name: Build and check image sizes
62+
id: build-check
63+
env:
64+
dockerfile: ${{ matrix.dockerfile }}
65+
run: |
66+
merged_commit=$(git log -1 --format='%H')
67+
68+
[ -z "$dockerfile" ] && continue
69+
dir=$(dirname "$dockerfile")
70+
file=$(basename "$dockerfile")
71+
image_base="pr-image-size-base:$(echo $dir | tr '/' '-')"
72+
image_pr="pr-image-size-pr:$(echo $dir | tr '/' '-')"
73+
74+
slash_count=$(grep -o "/" <<< "$dockerfile" | wc -l)
75+
if [ "$slash_count" -eq 1 ]; then
76+
cd "${{github.workspace}}/$dir"
77+
elif [ "$slash_count" -gt 1 ]; then
78+
if [[ "$dockerfile" == *"ui/"* ]]; then
79+
dir=$(echo "$dir" | sed 's|\(.*\)/ui.*|\1/ui|')
80+
cd "${{github.workspace}}/$dir"
81+
file=docker/$file
82+
image_base="pr-image-size-base:$(echo $dir | tr '/' '-')"
83+
image_pr="pr-image-size-pr:$(echo $dir | tr '/' '-')"
84+
elif [[ "$dockerfile" == *"WorkflowExecAgent/tests"* ]]; then
85+
echo "Skipping $dockerfile"
86+
exit 0
87+
else
88+
echo "Error: Multiple '/' in dockerfile path but no 'ui/' found."
89+
exit 1
90+
fi
91+
fi
92+
93+
echo "Building base image for $dockerfile"
94+
git checkout ${{ github.event.pull_request.base.sha }}
95+
echo "::group::Build image_base"
96+
docker build -f $file -t "$image_base" --no-cache . || true
97+
echo "::endgroup::"
98+
size_base=$(docker image inspect "$image_base" | jq '.[0].Size / (1024 * 1024) | round')
99+
100+
echo "Building PR image for $dockerfile"
101+
git checkout $merged_commit
102+
echo "PR: $merged_commit"
103+
echo "::group::Build image_pr"
104+
docker build -f $file -t "$image_pr" --no-cache . || true
105+
echo "::endgroup::"
106+
size_pr=$(docker image inspect "$image_pr" | jq '.[0].Size / (1024 * 1024) | round')
107+
108+
diff=$((size_pr - size_base))
109+
# echo "::warning::Image size change: $size_base -> $size_pr MB' (diff: $diff MB)"
110+
echo "comment to ${{ github.event.pull_request.number }}"
111+
if [ "$diff" -gt 50 ]; then
112+
comment_message="⚠️ WARNING\nFile $dockerfile resulted in a change in the image size from $size_base -> $size_pr MB (diff: $diff MB)"
113+
else
114+
comment_message="ℹ️ INFO\nFile $dockerfile resulted in a change in the image size from $size_base -> $size_pr MB (diff: $diff MB)"
115+
fi
116+
117+
# echo "comment_message=$comment_message" >> $GITHUB_OUTPUT
118+
# echo "File $dockerfile resulted in a change in the image size from $size_base -> $size_pr MB" >> $GITHUB_STEP_SUMMARY
119+
docker rmi "$image_base" "$image_pr"
120+
121+
echo $comment_message >> $GITHUB_STEP_SUMMARY
122+
image_name=$(echo $dir | tr '/' '-')
123+
cp $GITHUB_STEP_SUMMARY ${{github.workspace}}/build-$image_name.md
124+
echo "summary_path=${{github.workspace}}/build-$image_name.md" >> $GITHUB_ENV
125+
126+
- name: Download origin artifact log
127+
uses: actions/download-artifact@v4
128+
with:
129+
name: build-comments
130+
path: merged-files
131+
continue-on-error: true
132+
133+
- name: Merge logs
134+
run: |
135+
mkdir -p merged-files
136+
ls merged-files/
137+
cp ${{ env.summary_path }} merged-files/
138+
139+
- name: Save Summary as Artifact
140+
uses: actions/upload-artifact@v4
141+
with:
142+
name: build-comments
143+
path: merged-files/
144+
overwrite: true
145+
146+
collect-comments:
147+
needs: build-and-check
148+
permissions:
149+
actions: read
150+
if: always()
151+
runs-on: ubuntu-latest
152+
outputs:
153+
all_comments: ${{ steps.summary.outputs.all_comments }}
154+
steps:
155+
- name: Download Summary
156+
uses: actions/download-artifact@v4
157+
with:
158+
name: build-comments
159+
path: downloaded-files
160+
161+
- name: Read Summary
162+
id: summary
163+
run: |
164+
all_comments=$(cat downloaded-files/*.md | jq -Rs .)
165+
echo "all_comments=$all_comments"
166+
echo "all_comments=$all_comments" >> $GITHUB_OUTPUT
167+
168+
Post-comment-on-PR:
169+
needs: collect-comments
170+
runs-on: ubuntu-latest
171+
permissions:
172+
contents: read
173+
pull-requests: write
174+
if: always() && needs.collect-comments.outputs.all_comments != ''
175+
steps:
176+
- name: Post comment on PR
177+
env:
178+
all_comments: ${{ needs.collect-comments.outputs.all_comments }}
179+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
180+
run: |
181+
all_comments=$(echo $all_comments | jq -r . | sed 's|\\n|\n|g')
182+
json_body=$(jq -n --arg msg "$all_comments" '{"body": $msg}')
183+
184+
comment_id=$(curl -s \
185+
-H "Authorization: token ${GITHUB_TOKEN}" \
186+
-H "Accept: application/vnd.github.v3+json" \
187+
"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" \
188+
| jq '.[] | select(.user.login=="github-actions[bot]") | .id' | tail -n1)
189+
190+
if [ -n "$comment_id" ]; then
191+
curl -X PATCH \
192+
-H "Authorization: token ${GITHUB_TOKEN}" \
193+
-H "Accept: application/vnd.github.v3+json" \
194+
"https://api.github.com/repos/${{ github.repository }}/issues/comments/$comment_id" \
195+
-d "$json_body"
196+
else
197+
curl -X POST \
198+
-H "Authorization: token ${GITHUB_TOKEN}" \
199+
-H "Accept: application/vnd.github.v3+json" \
200+
"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" \
201+
-d "$json_body"
202+
fi

0 commit comments

Comments
 (0)