Skip to content

build-julia-notebook-jp #101

build-julia-notebook-jp

build-julia-notebook-jp #101

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