77 template :
88 description : template yaml file
99 required : true
10+ detect-containerd :
11+ description : detect containerd usage from template by using limactl validate
12+ required : false
13+ default : ' true'
1014runs :
1115 using : " composite"
1216 steps :
@@ -27,10 +31,15 @@ runs:
2731 set -eux
2832 arch="${{ inputs.arch }}"
2933 template="${{ inputs.template }}"
34+ detect_containerd="${{ inputs.detect-containerd }}"
35+ if [[ $detect_containerd == "true" ]] && ! command -v limactl &>/dev/null; then
36+ echo "containerd detection is disabled because limactl is not found" >&2
37+ detect_containerd="false"
38+ fi
3039 case "$template" in
3140 https://*)
3241 tmp_yaml=$(mktemp -d)/template.yaml
33- curl -sSLf "$template" > $tmp_yaml || exit 1
42+ curl -sSLf "$template" > " $tmp_yaml" || exit 1
3443 template=$tmp_yaml
3544 ;;
3645 *)
@@ -47,27 +56,85 @@ runs:
4756 arm64) arch=aarch64 ;;
4857 esac
4958
50- # extract digest and location from template using arch
51- digest="$(yq ".images | map(select(.arch == \"$arch\")) | .[0].digest // \"\"" "$template") "
52- location="$(yq ".images | map(select(.arch == \"$arch\")) | .[0].location // \"\"" "$template")"
53- test -n "$location" || exit 1
54-
55- # path to cache
56- if command -v sha256sum > /dev/null; then
57- sha256="$(echo -n "$location" | sha256sum | cut -d' ' -f1) "
58- elif command -v shasum > /dev/null ; then
59- sha256="$(echo -n "$location" | shasum -a 256 | cut -d' ' -f1)"
59+ # extract digest, location and size by parsing template using arch
60+ readonly yq_filter= "
61+ [
62+ .images | map(select(.arch == \"${arch}\")) | [.[0,1].location, .[0,1].digest],
63+ .containerd|[.system or .user],
64+ .containerd.archives | map(select(.arch == \"${arch}\")) | [.[0].location, .[0].digest]
65+ ]|flatten|.[]
66+ "
67+ if [[ $detect_containerd == "true" ]] ; then
68+ parsed=$(LIMA_HOME=$(mktemp -d) limactl validate "$template" --fill 2>/dev/null | yq eval "${yq_filter}")
6069 else
61- echo "sha256sum or shasum not found" >&2
70+ parsed=$(yq eval "${yq_filter}" "$template")
71+ fi
72+ # macOS earlier than 15.0 uses bash 3.2.57, which does not support readarray -t
73+ # readarray -t arr <<<"$parsed"
74+ while IFS= read -r line; do arr+=("$line"); done <<<"${parsed}"
75+ readonly locations=("${arr[@]:0:2}") digests=("${arr[@]:2:2}")
76+ readonly containerd="${arr[4]}" containerd_location="${arr[5]}" containerd_digest="${arr[6]}"
77+ for ((i = 0; i < ${#locations[@]}; i++)); do
78+ [[ ${locations[i]} != "null" ]] || continue
79+ http_code=$(curl -sIL -w "%{http_code}" "${locations[i]}" -o /dev/null)
80+ if [[ ${http_code} -eq 200 ]]; then
81+ location=${locations[i]}
82+ digest=${digests[i]}
83+ break
84+ fi
85+ done
86+ if [[ -z ${location} ]]; then
87+ echo "Failed to get the image location for ${template}" >&2
6288 exit 1
6389 fi
64- echo "path=.download/by-url-sha256/$sha256" >> "$GITHUB_OUTPUT"
90+
91+ function location_to_sha256() {
92+ local location=$1
93+ if command -v sha256sum > /dev/null; then
94+ sha256="$(echo -n "$location" | sha256sum | cut -d' ' -f1)"
95+ elif command -v shasum > /dev/null; then
96+ sha256="$(echo -n "$location" | shasum -a 256 | cut -d' ' -f1)"
97+ else
98+ echo "sha256sum or shasum not found" >&2
99+ exit 1
100+ fi
101+ echo "$sha256"
102+ }
103+
104+ function location_to_cache_path() {
105+ local location=$1
106+ sha256=$(location_to_sha256 "$location") && echo ".download/by-url-sha256/$sha256"
107+ }
108+
109+ # path to cache
110+ image_cache_path=$(location_to_cache_path "$location")
111+ echo "path=$image_cache_path" >> "$GITHUB_OUTPUT"
65112
66113 # key for cache
67- key="${digest:+image-$digest}"
68- # fallback to os and hash of template file if digest not found
69- key="${key:-${{ runner.os }}-${{ hashFiles(inputs.template) }}}"
114+ image_basename=$(basename "$location")
115+ if [[ "$digest" != "null" ]]; then
116+ key="image:$image_basename-$digest"
117+ else
118+ # use sha256 of location as key if digest is not available
119+ key="image:$image_basename-url-sha256:$(location_to_sha256 "$location")"
120+ fi
70121 echo "key=$key" >> "$GITHUB_OUTPUT"
122+
123+ # containerd path and key for cache
124+ if [[ $containerd == "true" && "$containerd_location" != "null" ]]; then
125+ containerd_basename=$(basename "$containerd_location")
126+ if [[ ${containerd_digest} != "null" ]]; then
127+ containerd_key="containerd:$containerd_basename-$containerd_digest"
128+ else
129+ containerd_key="containerd:$containerd_basename-url-sha256:$(sha256 "$containerd_location")"
130+ fi
131+ echo "containerd-key=$containerd_key" >> "$GITHUB_OUTPUT"
132+ containerd_cache_path=$(location_to_cache_path "$containerd_location")
133+ echo "containerd-path=$containerd_cache_path" >> "$GITHUB_OUTPUT"
134+ else
135+ echo "containerd-key=" >> "$GITHUB_OUTPUT"
136+ echo "containerd-path=" >> "$GITHUB_OUTPUT"
137+ fi
71138 shell : bash
72139
73140 - name : " Cache ${{ steps.cache-params-from-template.outputs.path }}"
@@ -78,11 +145,19 @@ runs:
78145 key : ${{ steps.cache-params-from-template.outputs.key }}
79146 enableCrossOsArchive : true
80147
148+ - name : " Cache ${{ steps.cache-params-from-template.outputs.containerd-key }}"
149+ if : ${{ steps.cache-params-from-template.outputs.containerd-key != '' }}
150+ uses : actions/cache@v4
151+ with :
152+ path : ${{ steps.cache-params-from-template.outputs.containerd-path }}
153+ key : ${{ steps.cache-params-from-template.outputs.containerd-key }}
154+ enableCrossOsArchive : true
155+
81156 - name : " Create symbolic link named ${{ steps.detect-platform.outputs.download-dir }} pointing to .download"
82157 run : |
83158 set -eux
84159 [ -d .download ] || mkdir -p .download
85160 path_to_cache=${{ steps.detect-platform.outputs.download-dir }}
86- mkdir -p $(dirname $path_to_cache)
87- ln -sfn $PWD/.download $path_to_cache
161+ mkdir -p " $(dirname " $path_to_cache")"
162+ ln -sfn " $PWD/.download" " $path_to_cache"
88163 shell : bash
0 commit comments