-
Notifications
You must be signed in to change notification settings - Fork 0
165 lines (136 loc) · 5.08 KB
/
build-dockerfile.yaml
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
158
159
160
161
162
163
164
165
name: build-julia-notebook-jp
on:
push:
branches:
- main
schedule:
# Run every day at 24:00 JST
- cron: '0 9 * * *'
workflow_dispatch:
permissions:
contents: read
packages: write
env:
IMAGE_NAME: ${{ github.repository }}
#set tagname
TAG_NAME: latest
#set targetdir
TARGET_DIR: ./
jobs:
upstream-digest-check:
runs-on: ubuntu-latest
outputs:
update: ${{ steps.set-update.outputs.update }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Get base image digest
id: get-base-image-digest
run: |
mkdir -p ~/.base_image_digest
touch ~/.base_image_digest/digests.txt
# Dockerfile のパスを指定
DOCKERFILE="Dockerfile"
# Dockerfile 内の FROM ステートメントの値を再帰的に取得する関数
function get_from_statements() {
local dockerfile=$1
local from_statements=()
declare -A args=() # 連想配列を宣言
# Dockerfile を行ごとに読み込み、FROM ステートメントを探す
while IFS= read -r line; do
if [[ $line =~ ^ARG[[:space:]]+(.*)$ ]]; then
local arg=("${BASH_REMATCH[1]//[\"\']}")
local arg_name=${arg%%=*}
local arg_value=${arg#*=}
args[$arg_name]=$arg_value
elif [[ $line =~ ^FROM[[:space:]]+(.*):(.*)$ ]]; then
local from_statement=${BASH_REMATCH[1]}:${BASH_REMATCH[2]}
# ASが後にあったらAS以降を消して上書き
if [[ $from_statement == *" AS"* ]]; then
from_statement=${from_statement%% AS*}
fi
# 環境変数を置換
for arg_name in "${!args[@]}"; do
from_statement=${from_statement//\$\{$arg_name\}/${args[${arg_name}]}}
done
from_statements+=("$from_statement")
fi
done < "$dockerfile"
echo "${from_statements[@]}"
}
# イメージの digest を取得する関数
function get_image_digest() {
local image=$1
local digest=$(docker manifest inspect "$from_statement" -v | jq -r '.[0].Descriptor.digest' 2>/dev/null)
if [ -n "$digest" ]; then
echo "$digest"
else
echo "イメージ '$image' の digest を取得できませんでした。"
fi
}
from_statements=($(get_from_statements "$DOCKERFILE"))
if [ ${#from_statements[@]} -eq 0 ]; then
echo "Dockerfile 内で FROM ステートメントが見つかりませんでした。"
else
digest_list=()
for from_statement in "${from_statements[@]}"; do
# イメージの digest を取得
digest=$(get_image_digest "$from_statement")
digest_list+=("$digest")
done
for digest in "${digest_list[@]}"; do
echo "$digest" > ~/.base_image_digest/digests.txt
done
fi
echo digest-list=$(md5sum ~/.base_image_digest/digests.txt) >> $GITHUB_OUTPUT
- uses: actions/cache@v4
id: cache
with:
path: ~/.base_image_digest
key: ${{ runner.os }}-${{ hashFiles('**/Dockerfile') }}-${{ steps.get-base-image-digest.outputs.digest-list }}
- name: set update flag
id: set-update
if: steps.cache.outputs.cache-hit != 'true'
run: |
echo "update=true" >> "$GITHUB_OUTPUT"
# Push image to GitHub Packages.
# See also https://docs.docker.com/docker-hub/builds/
push-image:
needs: upstream-digest-check
# Ensure test job passes before pushing image.
if: ${{ needs.upstream-digest-check.outputs.update == 'true' }}
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.ACTOR }}
password: ${{ github.TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64/v8
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
driver-opts: network=host
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: ${{ env.TAG_NAME }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: ${{ env.TARGET_DIR }}
platforms: linux/amd64,linux/arm64/v8
push: true
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max