name: Build and Push Minecraft Docker Images on Debian-base update on: push: branches: - master paths: - '.github/workflows/**' - '**/Dockerfile' - '**/*.sh' - '!**/CHANGES.md' - '!**/build-info.json' workflow_dispatch: {} schedule: - cron: '30 */6 * * *' env: IMAGE_REGISTRY: gitea.fithwum.tech IMAGE_ORG: ${{ secrets.GIT_USERNAME }} IMAGE_REPO_DEBIAN: debian-base IMAGE_REPO_MINECRAFT: minecraft IMAGE_TAG_DEBIAN: bookworm DIGEST_FILE: .cache/debian-base.digest jobs: poll-debian-base-and-detect-changes: runs-on: docker-build outputs: digest_changed: ${{ steps.compare_digest.outputs.changed }} versions_changed: ${{ steps.check_changed_versions.outputs.versions_changed }} steps: - name: Checkout repo uses: actions/checkout@v3 with: fetch-depth: 0 - name: Ensure .cache exists run: mkdir -p .cache && touch .cache/.gitkeep - name: Log in to Gitea Registry run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login ${{ env.IMAGE_REGISTRY }} -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - name: Get current digest of debian-base image id: get_digest run: | IMAGE="${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.IMAGE_REPO_DEBIAN }}:${{ env.IMAGE_TAG_DEBIAN }}" docker pull "$IMAGE" > /dev/null DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE") echo "digest=$DIGEST" >> $GITHUB_OUTPUT echo "$DIGEST" > .cache/debian-base.digest.new - name: Compare with stored digest id: compare_digest run: | CURRENT_DIGEST="${{ steps.get_digest.outputs.digest }}" LAST_DIGEST="$(cat ${{ env.DIGEST_FILE }} 2>/dev/null || echo '')" if [ "$CURRENT_DIGEST" = "$LAST_DIGEST" ]; then echo "changed=false" >> $GITHUB_OUTPUT else echo "$CURRENT_DIGEST" > ${{ env.DIGEST_FILE }} git config user.name "${{ secrets.GIT_USERNAME }}" git config user.email "${{ secrets.GIT_EMAIL }}" git add ${{ env.DIGEST_FILE }} git commit -m "Update base digest to $CURRENT_DIGEST" || true git push echo "changed=true" >> $GITHUB_OUTPUT fi - name: Detect changed Minecraft versions id: check_changed_versions run: | BEFORE_COMMIT="${{ github.event.before }}" if [ -z "$BEFORE_COMMIT" ] || ! git cat-file -e "$BEFORE_COMMIT^{commit}" 2>/dev/null; then BEFORE_COMMIT=$(git rev-parse HEAD~1) fi CHANGED=$(git diff --name-only "$BEFORE_COMMIT" HEAD || true) CHANGED_VERSIONS="" for version in vanilla testing fabric; do echo "$CHANGED" | grep -q "^$version/.*\.\(sh\|Dockerfile\)$" && CHANGED_VERSIONS="$CHANGED_VERSIONS $version" done CHANGED_VERSIONS=$(echo "$CHANGED_VERSIONS" | xargs) # trim whitespace echo "versions_changed=$CHANGED_VERSIONS" >> $GITHUB_OUTPUT build-minecraft-images: runs-on: docker-build needs: poll-debian-base-and-detect-changes if: needs.poll-debian-base-and-detect-changes.outputs.digest_changed == 'true' || needs.poll-debian-base-and-detect-changes.outputs.versions_changed != '' strategy: matrix: version: [vanilla, testing, fabric] name: Build and Push ${{ matrix.version }} steps: - name: Checkout repo uses: actions/checkout@v3 - name: Log in to Gitea Registry run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login ${{ env.IMAGE_REGISTRY }} -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - name: Build and push image run: | IMAGE="$IMAGE_REGISTRY/$IMAGE_ORG/$IMAGE_REPO_MINECRAFT:${{ matrix.version }}" docker buildx build --platform linux/amd64 --push -t "$IMAGE" "./${{ matrix.version }}" generate-changelogs: needs: build-minecraft-images runs-on: docker-build strategy: matrix: version: [vanilla, testing, fabric] steps: - name: Checkout source uses: actions/checkout@v3 - name: Clone Minecraft repo run: git clone https://${{ secrets.GIT_USERNAME }}:${{ secrets.GIT_TOKEN }}@gitea.fithwum.tech/fithwum/minecraft.git upload-repo - name: Update changelog run: | cd upload-repo changelog="${{ matrix.version }}/CHANGES.md" mkdir -p "$(dirname "$changelog")" touch "$changelog" infofile="${{ matrix.version }}/build-info.json" last_commit="" if [ -f "$infofile" ]; then last_commit=$(jq -r '.commit' "$infofile") fi echo -e "\n## $(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> "$changelog" if [ -n "$last_commit" ]; then git log "${last_commit}..HEAD" --pretty=format:"- %s (%an)" | head -n 10 >> "$changelog" else git log -n 10 --pretty=format:"- %s (%an)" >> "$changelog" fi - name: Commit and push changelog run: | cd upload-repo git config user.name "${{ secrets.GIT_USERNAME }}" git config user.email "${{ secrets.GIT_EMAIL }}" git add "${{ matrix.version }}/CHANGES.md" git commit -m "Update changelog for ${{ matrix.version }}" || true git push generate-build-info: needs: generate-changelogs runs-on: docker-build strategy: matrix: version: [vanilla, testing, fabric] steps: - name: Checkout source uses: actions/checkout@v3 - name: Clone Minecraft repo run: git clone https://${{ secrets.GIT_USERNAME }}:${{ secrets.GIT_TOKEN }}@gitea.fithwum.tech/fithwum/minecraft.git upload-repo - name: Generate build-info.json run: | human_size() { local b=$1 d='' s=0 S=(B KB MB GB TB) while ((b >= 1024 && s < ${#S[@]}-1)); do d=$((b % 1024)); b=$((b / 1024)); s=$((s + 1)); done printf "%s%s\n" "$b" "${S[$s]}" } cd upload-repo mkdir -p "${{ matrix.version }}" infofile="${{ matrix.version }}/build-info.json" image="${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.IMAGE_REPO_MINECRAFT }}:${{ matrix.version }}" digest=$(docker inspect --format='{{index .RepoDigests 0}}' "$image" 2>/dev/null || echo "unknown") size_bytes=$(docker image inspect "$image" --format='{{.Size}}' 2>/dev/null || echo "0") size_human=$(human_size "$size_bytes") jq -n \ --arg version "${{ matrix.version }}" \ --arg commit "$(git rev-parse HEAD)" \ --arg build_time "$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \ --arg image_tag "$image" \ --arg digest "$digest" \ --arg image_size "$size_human" \ --argjson image_size_bytes "$size_bytes" \ '{ version: $version, commit: $commit, build_time: $build_time, image_tag: $image_tag, digest: $digest, image_size: $image_size, image_size_bytes: $image_size_bytes }' > "$infofile" - name: Commit and push build-info run: | cd upload-repo git config user.name "${{ secrets.GIT_USERNAME }}" git config user.email "${{ secrets.GIT_EMAIL }}" git add "${{ matrix.version }}/build-info.json" git # name: Build and Push Minecraft Docker Images on Debian-base update # on: # push: # branches: # - master # paths: # - '**/Dockerfile' # - '**/*.sh' # - '.github/workflows/**' # - '!**/CHANGES.md' # - '!**/build-info.json' # schedule: # - cron: '30 */6 * * *' # Every 6 hours # env: # IMAGE_REGISTRY: gitea.fithwum.tech # IMAGE_ORG: ${{ secrets.GIT_USERNAME }} # IMAGE_REPO_DEBIAN: debian-base # IMAGE_REPO_MINECRAFT: minecraft # IMAGE_TAG_DEBIAN: bookworm # DIGEST_FILE: .cache/debian-base.digest # jobs: # poll-debian-base-and-build: # runs-on: docker-build # steps: # - name: Checkout repo # uses: actions/checkout@v3 # with: # fetch-depth: 0 # - name: Ensure .cache exists with .gitkeep # run: | # mkdir -p .cache # touch .cache/.gitkeep # - name: Log in to Gitea Registry # run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login ${{ env.IMAGE_REGISTRY }} -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin # - name: Get current digest of debian-base image # id: get_digest # run: | # IMAGE="${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.IMAGE_REPO_DEBIAN }}:${{ env.IMAGE_TAG_DEBIAN }}" # echo "Checking image: $IMAGE" # docker pull "$IMAGE" > /dev/null # DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE" 2>/dev/null || echo "") # if [ -z "$DIGEST" ]; then # echo "Failed to get digest for $IMAGE" # exit 1 # fi # echo "digest=$DIGEST" >> $GITHUB_OUTPUT # echo "$DIGEST" > .cache/debian-base.digest.new # - name: Compare with stored digest # id: compare_digest # run: | # CURRENT_DIGEST="${{ steps.get_digest.outputs.digest }}" # LAST_DIGEST="" # if [ -f "${{ env.DIGEST_FILE }}" ]; then # LAST_DIGEST=$(cat "${{ env.DIGEST_FILE }}") # fi # echo "Current digest: $CURRENT_DIGEST" # echo "Last digest: $LAST_DIGEST" # if [ "$CURRENT_DIGEST" = "$LAST_DIGEST" ]; then # echo "Digest unchanged. Skipping build." # echo "changed=false" >> $GITHUB_OUTPUT # else # echo "Digest changed or first run." # echo "$CURRENT_DIGEST" > "${{ env.DIGEST_FILE }}" # git config user.name "${{ secrets.GIT_USERNAME }}" # git config user.email "${{ secrets.GIT_EMAIL }}" # git add "${{ env.DIGEST_FILE }}" # git commit -m "Update debian-base image digest to $CURRENT_DIGEST" || echo "No changes to commit" # git push # echo "changed=true" >> $GITHUB_OUTPUT # fi # - name: Check which Minecraft versions changed # id: check_changed_versions # run: | # set -e # BEFORE_COMMIT="${{ github.event.before }}" # if [ -z "$BEFORE_COMMIT" ] || ! git cat-file -e "$BEFORE_COMMIT^{commit}" 2>/dev/null; then # echo "[WARN] 'before' commit missing or invalid, using HEAD~1" # BEFORE_COMMIT=$(git rev-parse HEAD~1) # fi # echo "[INFO] Diffing against $BEFORE_COMMIT" # CHANGED_FILES=$(git diff --name-only "$BEFORE_COMMIT" HEAD || true) # echo "[INFO] Changed files:" # echo "$CHANGED_FILES" # VERSIONS_CHANGED="" # for version in vanilla testing fabric; do # if echo "$CHANGED_FILES" | grep -q "^$version/.*\.\(sh\|Dockerfile\)$"; then # echo "[INFO] Detected changes in $version" # VERSIONS_CHANGED="$VERSIONS_CHANGED $version" # fi # done # # Store output # echo "versions_changed=$VERSIONS_CHANGED" >> $GITHUB_OUTPUT # outputs: # digest_changed: ${{ steps.compare_digest.outputs.changed }} # versions_changed: ${{ steps.check_changed_versions.outputs.versions_changed }} # build-minecraft-images: # runs-on: docker-build # needs: poll-debian-base-and-build # if: needs.poll-debian-base-and-build.outputs.digest_changed == 'true' || needs.poll-debian-base-and-build.outputs.versions_changed != '' # strategy: # matrix: # version: [vanilla, testing, fabric] # name: Build ${{ matrix.version }} image # steps: # - name: Checkout repo # uses: actions/checkout@v3 # - name: Log in to Gitea Registry # run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login ${{ env.IMAGE_REGISTRY }} -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin # - name: Build and Push Minecraft Image # run: | # IMAGE="$IMAGE_REGISTRY/$IMAGE_ORG/$IMAGE_REPO_MINECRAFT:${{ matrix.version }}" # echo "[INFO] Building and pushing $IMAGE" # docker buildx build --platform linux/amd64 --push -t "$IMAGE" "./${{ matrix.version }}" # generate-changelogs: # needs: build-minecraft-images # runs-on: docker-build # steps: # - name: Checkout source # uses: actions/checkout@v3 # - name: Clone Minecraft repo # run: | # git clone https://${{ secrets.GIT_USERNAME }}:${{ secrets.GIT_TOKEN }}@gitea.fithwum.tech/fithwum/minecraft.git upload-repo # - name: Generate per-version changelogs # run: | # cd upload-repo # for version in vanilla testing fabric; do # echo "[INFO] Updating changelog for $version" # changelog="$version/CHANGES.md" # mkdir -p "$(dirname "$changelog")" # touch "$changelog" # infofile="$version/build-info.json" # last_commit="" # if [ -f "$infofile" ]; then # last_commit=$(jq -r '.commit' "$infofile") # fi # echo -e "\n## $(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> "$changelog" # if [ -n "$last_commit" ]; then # git log "${last_commit}..HEAD" --pretty=format:"- %s (%an)" | head -n 10 >> "$changelog" # else # git log -n 10 --pretty=format:"- %s (%an)" >> "$changelog" # fi # done # - name: Commit and push changelogs if changed # run: | # cd upload-repo # git config user.name "${{ secrets.GIT_USERNAME }}" # git config user.email "${{ secrets.GIT_EMAIL }}" # if git status --porcelain | grep .; then # git add */CHANGES.md # git commit -m "Update changelogs on $(date -u +'%Y-%m-%dT%H:%M:%SZ') [skip ci]" --no-verify # git push # else # echo "[INFO] No changelog changes to commit." # fi # generate-build-info: # needs: generate-changelogs # runs-on: docker-build # steps: # - name: Checkout source # uses: actions/checkout@v3 # - name: Clone Minecraft repo # run: | # git clone https://${{ secrets.GIT_USERNAME }}:${{ secrets.GIT_TOKEN }}@gitea.fithwum.tech/fithwum/minecraft.git upload-repo # - name: Generate build-info.json per version # run: | # human_size() { # local b=$1 # local d='' # local s=0 # local S=(B KB MB GB TB) # while ((b >= 1024 && s < ${#S[@]}-1)); do # d=$((b % 1024)) # b=$((b / 1024)) # s=$((s + 1)) # done # printf "%s%s\n" "$b" "${S[$s]}" # } # cd upload-repo # for version in vanilla testing fabric; do # echo "[INFO] Generating build-info.json for $version" # mkdir -p "$version" # infofile="$version/build-info.json" # image="${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.IMAGE_REPO_MINECRAFT }}:$version" # digest=$(docker inspect --format='{{if .RepoDigests}}{{index .RepoDigests 0}}{{else}}unknown{{end}}' "$image" 2>/dev/null || echo "unknown") # size_bytes=$(docker image inspect "$image" --format='{{.Size}}' 2>/dev/null || echo "0") # size_bytes=${size_bytes//[^0-9]/} # if [[ -z "$size_bytes" ]]; then size_bytes=0; fi # size_human=$(human_size "$size_bytes") # jq -n \ # --arg version "$version" \ # --arg commit "$(git rev-parse HEAD)" \ # --arg build_time "$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \ # --arg image_tag "$image" \ # --arg digest "$digest" \ # --arg image_size "$size_human" \ # --argjson image_size_bytes "$size_bytes" \ # '{ # version: $version, # commit: $commit, # build_time: $build_time, # image_tag: $image_tag, # digest: $digest, # image_size: $image_size, # image_size_bytes: $image_size_bytes # }' > "$infofile" # done # - name: Commit and push build-info if changed # run: | # cd upload-repo # git config user.name "${{ secrets.GIT_USERNAME }}" # git config user.email "${{ secrets.GIT_EMAIL }}" # if git status --porcelain | grep .; then # git add */build-info.json # git commit -m "Update build-info on $(date -u +'%Y-%m-%dT%H:%M:%SZ') [skip ci]" # git push # for version in vanilla testing fabric; do # TAG="build-$version" # git tag -d "$TAG" 2>/dev/null || true # git tag "$TAG" # git push origin "$TAG" --force # done # else # echo "[INFO] No build-info changes to commit." # fi