diff --git a/.gitea/workflows/base-build.yml b/.gitea/workflows/base-build.yml index b5ba3cf..c3f0ac9 100644 --- a/.gitea/workflows/base-build.yml +++ b/.gitea/workflows/base-build.yml @@ -11,7 +11,7 @@ on: - '!**/CHANGES.md' - '!**/build-info.json' schedule: - - cron: '30 */6 * * *' # Every 6 hours + - cron: '30 */6 * * *' env: IMAGE_REGISTRY: gitea.fithwum.tech @@ -22,8 +22,11 @@ env: DIGEST_FILE: .cache/debian-base.digest jobs: - poll-debian-base-and-build: + 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 @@ -31,10 +34,8 @@ jobs: with: fetch-depth: 0 - - name: Ensure .cache exists with .gitkeep - run: | - mkdir -p .cache - touch .cache/.gitkeep + - 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 @@ -43,13 +44,8 @@ jobs: 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 + DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE") echo "digest=$DIGEST" >> $GITHUB_OUTPUT echo "$DIGEST" > .cache/debian-base.digest.new @@ -57,198 +53,432 @@ jobs: 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" - + LAST_DIGEST="$(cat ${{ env.DIGEST_FILE }} 2>/dev/null || echo '')" 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 }}" + 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 add ${{ env.DIGEST_FILE }} + git commit -m "Update base digest to $CURRENT_DIGEST" || true git push echo "changed=true" >> $GITHUB_OUTPUT fi - - name: Check for Dockerfile or .sh changes - id: check_files_changed + - name: Detect changed Minecraft versions + id: check_changed_versions run: | - set -e - - # Try to get the base commit for diff 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=$(git diff --name-only "$BEFORE_COMMIT" HEAD | grep -E '\.sh$|Dockerfile' || true) - - if [ -n "$CHANGED" ]; then - echo "[INFO] Found changed files:" - echo "$CHANGED" - echo "files_changed=true" >> $GITHUB_OUTPUT - else - echo "[INFO] No relevant files changed." - echo "files_changed=false" >> $GITHUB_OUTPUT - fi - - - name: Build and Push Minecraft Docker Images - if: steps.compare_digest.outputs.changed == 'true' || steps.check_files_changed.outputs.files_changed == 'true' - env: - IMAGE_TAG_VANILLA: vanilla - IMAGE_TAG_TESTING: testing - IMAGE_TAG_FABRIC: fabric - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - run: | - echo "${DOCKER_PASSWORD}" | docker login $IMAGE_REGISTRY -u "${DOCKER_USERNAME}" --password-stdin - - for TAG in $IMAGE_TAG_VANILLA $IMAGE_TAG_TESTING $IMAGE_TAG_FABRIC; do - IMAGE="$IMAGE_REGISTRY/$IMAGE_ORG/$IMAGE_REPO_MINECRAFT:$TAG" - echo "[INFO] Building and pushing $IMAGE" - docker buildx build --platform linux/amd64 --push -t "$IMAGE" "./$TAG" + 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 + run: git clone https://${{ secrets.GIT_USERNAME }}:${{ secrets.GIT_TOKEN }}@gitea.fithwum.tech/fithwum/minecraft.git upload-repo - - name: Generate per-version changelogs + - name: Update changelog 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" + changelog="${{ matrix.version }}/CHANGES.md" + mkdir -p "$(dirname "$changelog")" + touch "$changelog" + infofile="${{ matrix.version }}/build-info.json" + last_commit="" + [ -f "$infofile" ] && last_commit=$(jq -r '.commit' "$infofile") + 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" - 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 + - name: Commit and push changelog 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 + 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 + 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 + - name: Generate build-info.json 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 + 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 - 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" + 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") - 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") + 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" - 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 + - 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 - 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 + + + + + + + + + + + + + + + + + + +# 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