From 620e28e4346e21c14a9e7d140caebd57c30e1ed6 Mon Sep 17 00:00:00 2001 From: fithwum Date: Thu, 16 Jul 2026 15:13:54 -0700 Subject: [PATCH] added seperate version builds --- ...t-build.yml => minecraft-build-bukkit.yml} | 14 +- .gitea/workflows/minecraft-build-fabric.yml | 331 ++++++++++++++++++ .gitea/workflows/minecraft-build-forge.yml | 331 ++++++++++++++++++ .../workflows/minecraft-build-neoforged.yml | 331 ++++++++++++++++++ .gitea/workflows/minecraft-build-quilt.yml | 331 ++++++++++++++++++ .gitea/workflows/minecraft-build-testing.yml | 331 ++++++++++++++++++ .gitea/workflows/minecraft-build-vanilla.yml | 331 ++++++++++++++++++ 7 files changed, 1993 insertions(+), 7 deletions(-) rename .gitea/workflows/{minecraft-build.yml => minecraft-build-bukkit.yml} (97%) create mode 100644 .gitea/workflows/minecraft-build-fabric.yml create mode 100644 .gitea/workflows/minecraft-build-forge.yml create mode 100644 .gitea/workflows/minecraft-build-neoforged.yml create mode 100644 .gitea/workflows/minecraft-build-quilt.yml create mode 100644 .gitea/workflows/minecraft-build-testing.yml create mode 100644 .gitea/workflows/minecraft-build-vanilla.yml diff --git a/.gitea/workflows/minecraft-build.yml b/.gitea/workflows/minecraft-build-bukkit.yml similarity index 97% rename from .gitea/workflows/minecraft-build.yml rename to .gitea/workflows/minecraft-build-bukkit.yml index 23656c4..b5bb36f 100644 --- a/.gitea/workflows/minecraft-build.yml +++ b/.gitea/workflows/minecraft-build-bukkit.yml @@ -5,12 +5,12 @@ on: branches: - master paths: - - '.gitea/workflows/*.yml' - - '**/Dockerfile' - - '**/*.sh' + - '.gitea/workflows/minecraft-build-bukkit.yml' + - 'bukkit/Dockerfile' + - 'bukkit/*.sh' - '!.cache/*' - - '!**/CHANGES.md' - - '!**/build-info.json' + - '!bukkit/CHANGES.md' + - '!bukkit/build-info.json' schedule: - cron: '30 21 * * 0' @@ -21,7 +21,7 @@ env: IMAGE_REPO_MINECRAFT: minecraft IMAGE_TAG_DEBIAN: bookworm DIGEST_FILE: .cache/debian-base.digest - VERSIONS: testing vanilla fabric neoforged forge bukkit quilt + VERSIONS: bukkit jobs: docker-prune: @@ -145,7 +145,7 @@ jobs: needs.poll-debian-base-and-detect-changes.outputs.new_versions != '' strategy: matrix: - version: [testing, vanilla, fabric, neoforged, forge, bukkit, quilt] + version: [bukkit] name: Build and Push ${{ matrix.version }} steps: - name: Checkout repo diff --git a/.gitea/workflows/minecraft-build-fabric.yml b/.gitea/workflows/minecraft-build-fabric.yml new file mode 100644 index 0000000..d453042 --- /dev/null +++ b/.gitea/workflows/minecraft-build-fabric.yml @@ -0,0 +1,331 @@ +name: Build and Push Minecraft Docker Images on Debian-base update + +on: + push: + branches: + - master + paths: + - '.gitea/workflows/minecraft-build-fabric.yml' + - 'fabric/Dockerfile' + - 'fabric/*.sh' + - '!.cache/*' + - '!fabric/CHANGES.md' + - '!fabric/build-info.json' + schedule: + - cron: '30 21 * * 0' + +env: + IMAGE_REGISTRY: gitea.fithwum.tech + IMAGE_ORG: fithwum + IMAGE_REPO_DEBIAN: debian-base + IMAGE_REPO_MINECRAFT: minecraft + IMAGE_TAG_DEBIAN: bookworm + DIGEST_FILE: .cache/debian-base.digest + VERSIONS: fabric + +jobs: + docker-prune: + name: Docker prune (${{ matrix.runner }}) + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + runner: + - vm-docker-build2 + - vm-docker-build2 + steps: + - name: Prune unused Docker images + run: | + echo "[INFO] Pruning Docker images on ${{ matrix.runner }}..." + docker image prune -a -f || true + + poll-debian-base-and-detect-changes: + runs-on: vm-docker-build2 + needs: docker-prune + outputs: + digest_changed: ${{ steps.compare_digest.outputs.changed }} + versions_changed: ${{ steps.check_changed_versions.outputs.versions_changed }} + new_versions: ${{ steps.check_new_versions.outputs.new_versions }} + 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 gitea.fithwum.tech -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 "[INFO] Digest unchanged" + echo "changed=false" >> $GITHUB_OUTPUT + exit 0 + fi + + echo "[INFO] Digest changed → updating cache" + 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 + + # --- Safe rebase with auto conflict resolution --- + git fetch origin master + if ! git rebase --strategy-option=theirs origin/master; then + echo "[WARN] Rebase conflict, auto-resolving by preferring local digest" + git rebase --abort + git fetch origin master + git reset --hard origin/master + echo "$CURRENT_DIGEST" > ${{ env.DIGEST_FILE }} + git add ${{ env.DIGEST_FILE }} + git commit -m "Force-update base digest to $CURRENT_DIGEST (auto-resolved)" + fi + + git push origin HEAD:master + echo "changed=true" >> $GITHUB_OUTPUT + + - 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 $VERSIONS; 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 + + - name: Detect Minecraft versions without build-info + id: check_new_versions + run: | + NEW_VERSIONS="" + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + for version in $VERSIONS; do + if [ ! -f "upload-repo/$version/build-info.json" ]; then + echo "[INFO] No build-info.json for $version → treating as new" + NEW_VERSIONS="$NEW_VERSIONS $version" + fi + done + + echo "new_versions=$NEW_VERSIONS" >> $GITHUB_OUTPUT + + build-minecraft-images: + runs-on: vm-docker-build2 + needs: + - docker-prune + - 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 != '' || + needs.poll-debian-base-and-detect-changes.outputs.new_versions != '' + strategy: + matrix: + version: [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 gitea.fithwum.tech -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin + + - name: Clone Minecraft repo (with retries) + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + for i in {1..5}; do + git clone "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo && break + echo "[WARN] Clone attempt $i failed. Retrying in 10s..." + sleep 10 + done + if [ ! -d upload-repo ]; then + echo "[ERROR] Failed to clone Minecraft repo after retries." + exit 1 + fi + + - 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: vm-docker-build2 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Create temporary changelog workspace + run: mkdir -p changelogs + + - name: Clone Minecraft repo + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=3 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + - name: Generate changelogs + run: | + for version in $VERSIONS; do + echo "[INFO] Generating changelog for $version" + changelog="changelogs/$version/CHANGES.md" + mkdir -p "$(dirname "$changelog")" + touch "$changelog" + + cd upload-repo + infofile="$version/build-info.json" + last_commit="" + if [ -f "$infofile" ]; then + last_commit=$(jq -r '.commit' "$infofile") + fi + + echo -e "## $(date -u +'%Y-%m-%dT%H:%M:%SZ')\n" > "../$changelog" + if [ -n "$last_commit" ]; then + COMMITS=$(git log "${last_commit}..HEAD" --pretty=format:"- %s (%an)" || true) + fi + if [ -z "$COMMITS" ]; then + echo "[INFO] No new commits since last build. Showing latest 5 instead." + COMMITS=$(git log -n 5 --pretty=format:"- %s (%an)" || true) + fi + echo "$COMMITS" >> "../$changelog" + cd .. + done + + - name: Copy changelogs into repo + run: | + for version in $VERSIONS; do + mkdir -p upload-repo/$version + cp changelogs/$version/CHANGES.md upload-repo/$version/ + done + + - name: Commit and push changelogs + 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')" --no-verify + git push + else + echo "[INFO] No changelog changes to commit." + fi + + generate-build-info: + needs: generate-changelogs + runs-on: vm-docker-build2 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Prepare temporary build-info workspace + run: mkdir -p buildinfo + + - name: Clone Minecraft repo + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + - name: Generate build-info files + 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]}" + } + + for version in $VERSIONS; do + echo "[INFO] Generating build-info.json for $version" + image="${IMAGE_REGISTRY}/${IMAGE_ORG}/${IMAGE_REPO_MINECRAFT}:$version" + infofile="buildinfo/$version/build-info.json" + mkdir -p "$(dirname "$infofile")" + + if ! docker pull "$image"; then + echo "[WARN] Failed to pull $image — setting fields to unknown/0" + digest="unknown" + size_bytes=0 + else + 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 + fi + + size_human=$(human_size "$size_bytes") + + cd upload-repo + commit=$(git rev-parse HEAD) + cd .. + + jq -n \ + --arg version "$version" \ + --arg commit "$commit" \ + --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: Copy build-info.json into repo + run: | + for version in $VERSIONS; do + mkdir -p upload-repo/$version + cp "buildinfo/$version/build-info.json" "upload-repo/$version/" + done + + - name: Commit and push build-info + 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')" + git push + + for version in $VERSIONS; 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 diff --git a/.gitea/workflows/minecraft-build-forge.yml b/.gitea/workflows/minecraft-build-forge.yml new file mode 100644 index 0000000..d67ce82 --- /dev/null +++ b/.gitea/workflows/minecraft-build-forge.yml @@ -0,0 +1,331 @@ +name: Build and Push Minecraft Docker Images on Debian-base update + +on: + push: + branches: + - master + paths: + - '.gitea/workflows/minecraft-build-forge.yml' + - 'forge/Dockerfile' + - 'forge/*.sh' + - '!.cache/*' + - '!forge/CHANGES.md' + - '!forge/build-info.json' + schedule: + - cron: '30 21 * * 0' + +env: + IMAGE_REGISTRY: gitea.fithwum.tech + IMAGE_ORG: fithwum + IMAGE_REPO_DEBIAN: debian-base + IMAGE_REPO_MINECRAFT: minecraft + IMAGE_TAG_DEBIAN: bookworm + DIGEST_FILE: .cache/debian-base.digest + VERSIONS: forge + +jobs: + docker-prune: + name: Docker prune (${{ matrix.runner }}) + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + runner: + - vm-docker-build2 + - vm-docker-build2 + steps: + - name: Prune unused Docker images + run: | + echo "[INFO] Pruning Docker images on ${{ matrix.runner }}..." + docker image prune -a -f || true + + poll-debian-base-and-detect-changes: + runs-on: vm-docker-build2 + needs: docker-prune + outputs: + digest_changed: ${{ steps.compare_digest.outputs.changed }} + versions_changed: ${{ steps.check_changed_versions.outputs.versions_changed }} + new_versions: ${{ steps.check_new_versions.outputs.new_versions }} + 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 gitea.fithwum.tech -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 "[INFO] Digest unchanged" + echo "changed=false" >> $GITHUB_OUTPUT + exit 0 + fi + + echo "[INFO] Digest changed → updating cache" + 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 + + # --- Safe rebase with auto conflict resolution --- + git fetch origin master + if ! git rebase --strategy-option=theirs origin/master; then + echo "[WARN] Rebase conflict, auto-resolving by preferring local digest" + git rebase --abort + git fetch origin master + git reset --hard origin/master + echo "$CURRENT_DIGEST" > ${{ env.DIGEST_FILE }} + git add ${{ env.DIGEST_FILE }} + git commit -m "Force-update base digest to $CURRENT_DIGEST (auto-resolved)" + fi + + git push origin HEAD:master + echo "changed=true" >> $GITHUB_OUTPUT + + - 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 $VERSIONS; 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 + + - name: Detect Minecraft versions without build-info + id: check_new_versions + run: | + NEW_VERSIONS="" + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + for version in $VERSIONS; do + if [ ! -f "upload-repo/$version/build-info.json" ]; then + echo "[INFO] No build-info.json for $version → treating as new" + NEW_VERSIONS="$NEW_VERSIONS $version" + fi + done + + echo "new_versions=$NEW_VERSIONS" >> $GITHUB_OUTPUT + + build-minecraft-images: + runs-on: vm-docker-build2 + needs: + - docker-prune + - 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 != '' || + needs.poll-debian-base-and-detect-changes.outputs.new_versions != '' + strategy: + matrix: + version: [forge] + 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 gitea.fithwum.tech -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin + + - name: Clone Minecraft repo (with retries) + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + for i in {1..5}; do + git clone "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo && break + echo "[WARN] Clone attempt $i failed. Retrying in 10s..." + sleep 10 + done + if [ ! -d upload-repo ]; then + echo "[ERROR] Failed to clone Minecraft repo after retries." + exit 1 + fi + + - 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: vm-docker-build2 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Create temporary changelog workspace + run: mkdir -p changelogs + + - name: Clone Minecraft repo + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=3 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + - name: Generate changelogs + run: | + for version in $VERSIONS; do + echo "[INFO] Generating changelog for $version" + changelog="changelogs/$version/CHANGES.md" + mkdir -p "$(dirname "$changelog")" + touch "$changelog" + + cd upload-repo + infofile="$version/build-info.json" + last_commit="" + if [ -f "$infofile" ]; then + last_commit=$(jq -r '.commit' "$infofile") + fi + + echo -e "## $(date -u +'%Y-%m-%dT%H:%M:%SZ')\n" > "../$changelog" + if [ -n "$last_commit" ]; then + COMMITS=$(git log "${last_commit}..HEAD" --pretty=format:"- %s (%an)" || true) + fi + if [ -z "$COMMITS" ]; then + echo "[INFO] No new commits since last build. Showing latest 5 instead." + COMMITS=$(git log -n 5 --pretty=format:"- %s (%an)" || true) + fi + echo "$COMMITS" >> "../$changelog" + cd .. + done + + - name: Copy changelogs into repo + run: | + for version in $VERSIONS; do + mkdir -p upload-repo/$version + cp changelogs/$version/CHANGES.md upload-repo/$version/ + done + + - name: Commit and push changelogs + 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')" --no-verify + git push + else + echo "[INFO] No changelog changes to commit." + fi + + generate-build-info: + needs: generate-changelogs + runs-on: vm-docker-build2 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Prepare temporary build-info workspace + run: mkdir -p buildinfo + + - name: Clone Minecraft repo + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + - name: Generate build-info files + 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]}" + } + + for version in $VERSIONS; do + echo "[INFO] Generating build-info.json for $version" + image="${IMAGE_REGISTRY}/${IMAGE_ORG}/${IMAGE_REPO_MINECRAFT}:$version" + infofile="buildinfo/$version/build-info.json" + mkdir -p "$(dirname "$infofile")" + + if ! docker pull "$image"; then + echo "[WARN] Failed to pull $image — setting fields to unknown/0" + digest="unknown" + size_bytes=0 + else + 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 + fi + + size_human=$(human_size "$size_bytes") + + cd upload-repo + commit=$(git rev-parse HEAD) + cd .. + + jq -n \ + --arg version "$version" \ + --arg commit "$commit" \ + --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: Copy build-info.json into repo + run: | + for version in $VERSIONS; do + mkdir -p upload-repo/$version + cp "buildinfo/$version/build-info.json" "upload-repo/$version/" + done + + - name: Commit and push build-info + 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')" + git push + + for version in $VERSIONS; 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 diff --git a/.gitea/workflows/minecraft-build-neoforged.yml b/.gitea/workflows/minecraft-build-neoforged.yml new file mode 100644 index 0000000..78865b4 --- /dev/null +++ b/.gitea/workflows/minecraft-build-neoforged.yml @@ -0,0 +1,331 @@ +name: Build and Push Minecraft Docker Images on Debian-base update + +on: + push: + branches: + - master + paths: + - '.gitea/workflows/minecraft-build-neoforged.yml' + - 'neoforged/Dockerfile' + - 'neoforged/*.sh' + - '!.cache/*' + - '!neoforged/CHANGES.md' + - '!neoforged/build-info.json' + schedule: + - cron: '30 21 * * 0' + +env: + IMAGE_REGISTRY: gitea.fithwum.tech + IMAGE_ORG: fithwum + IMAGE_REPO_DEBIAN: debian-base + IMAGE_REPO_MINECRAFT: minecraft + IMAGE_TAG_DEBIAN: bookworm + DIGEST_FILE: .cache/debian-base.digest + VERSIONS: neoforged + +jobs: + docker-prune: + name: Docker prune (${{ matrix.runner }}) + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + runner: + - vm-docker-build2 + - vm-docker-build2 + steps: + - name: Prune unused Docker images + run: | + echo "[INFO] Pruning Docker images on ${{ matrix.runner }}..." + docker image prune -a -f || true + + poll-debian-base-and-detect-changes: + runs-on: vm-docker-build2 + needs: docker-prune + outputs: + digest_changed: ${{ steps.compare_digest.outputs.changed }} + versions_changed: ${{ steps.check_changed_versions.outputs.versions_changed }} + new_versions: ${{ steps.check_new_versions.outputs.new_versions }} + 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 gitea.fithwum.tech -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 "[INFO] Digest unchanged" + echo "changed=false" >> $GITHUB_OUTPUT + exit 0 + fi + + echo "[INFO] Digest changed → updating cache" + 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 + + # --- Safe rebase with auto conflict resolution --- + git fetch origin master + if ! git rebase --strategy-option=theirs origin/master; then + echo "[WARN] Rebase conflict, auto-resolving by preferring local digest" + git rebase --abort + git fetch origin master + git reset --hard origin/master + echo "$CURRENT_DIGEST" > ${{ env.DIGEST_FILE }} + git add ${{ env.DIGEST_FILE }} + git commit -m "Force-update base digest to $CURRENT_DIGEST (auto-resolved)" + fi + + git push origin HEAD:master + echo "changed=true" >> $GITHUB_OUTPUT + + - 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 $VERSIONS; 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 + + - name: Detect Minecraft versions without build-info + id: check_new_versions + run: | + NEW_VERSIONS="" + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + for version in $VERSIONS; do + if [ ! -f "upload-repo/$version/build-info.json" ]; then + echo "[INFO] No build-info.json for $version → treating as new" + NEW_VERSIONS="$NEW_VERSIONS $version" + fi + done + + echo "new_versions=$NEW_VERSIONS" >> $GITHUB_OUTPUT + + build-minecraft-images: + runs-on: vm-docker-build2 + needs: + - docker-prune + - 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 != '' || + needs.poll-debian-base-and-detect-changes.outputs.new_versions != '' + strategy: + matrix: + version: [neoforged] + 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 gitea.fithwum.tech -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin + + - name: Clone Minecraft repo (with retries) + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + for i in {1..5}; do + git clone "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo && break + echo "[WARN] Clone attempt $i failed. Retrying in 10s..." + sleep 10 + done + if [ ! -d upload-repo ]; then + echo "[ERROR] Failed to clone Minecraft repo after retries." + exit 1 + fi + + - 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: vm-docker-build2 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Create temporary changelog workspace + run: mkdir -p changelogs + + - name: Clone Minecraft repo + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=3 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + - name: Generate changelogs + run: | + for version in $VERSIONS; do + echo "[INFO] Generating changelog for $version" + changelog="changelogs/$version/CHANGES.md" + mkdir -p "$(dirname "$changelog")" + touch "$changelog" + + cd upload-repo + infofile="$version/build-info.json" + last_commit="" + if [ -f "$infofile" ]; then + last_commit=$(jq -r '.commit' "$infofile") + fi + + echo -e "## $(date -u +'%Y-%m-%dT%H:%M:%SZ')\n" > "../$changelog" + if [ -n "$last_commit" ]; then + COMMITS=$(git log "${last_commit}..HEAD" --pretty=format:"- %s (%an)" || true) + fi + if [ -z "$COMMITS" ]; then + echo "[INFO] No new commits since last build. Showing latest 5 instead." + COMMITS=$(git log -n 5 --pretty=format:"- %s (%an)" || true) + fi + echo "$COMMITS" >> "../$changelog" + cd .. + done + + - name: Copy changelogs into repo + run: | + for version in $VERSIONS; do + mkdir -p upload-repo/$version + cp changelogs/$version/CHANGES.md upload-repo/$version/ + done + + - name: Commit and push changelogs + 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')" --no-verify + git push + else + echo "[INFO] No changelog changes to commit." + fi + + generate-build-info: + needs: generate-changelogs + runs-on: vm-docker-build2 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Prepare temporary build-info workspace + run: mkdir -p buildinfo + + - name: Clone Minecraft repo + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + - name: Generate build-info files + 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]}" + } + + for version in $VERSIONS; do + echo "[INFO] Generating build-info.json for $version" + image="${IMAGE_REGISTRY}/${IMAGE_ORG}/${IMAGE_REPO_MINECRAFT}:$version" + infofile="buildinfo/$version/build-info.json" + mkdir -p "$(dirname "$infofile")" + + if ! docker pull "$image"; then + echo "[WARN] Failed to pull $image — setting fields to unknown/0" + digest="unknown" + size_bytes=0 + else + 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 + fi + + size_human=$(human_size "$size_bytes") + + cd upload-repo + commit=$(git rev-parse HEAD) + cd .. + + jq -n \ + --arg version "$version" \ + --arg commit "$commit" \ + --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: Copy build-info.json into repo + run: | + for version in $VERSIONS; do + mkdir -p upload-repo/$version + cp "buildinfo/$version/build-info.json" "upload-repo/$version/" + done + + - name: Commit and push build-info + 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')" + git push + + for version in $VERSIONS; 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 diff --git a/.gitea/workflows/minecraft-build-quilt.yml b/.gitea/workflows/minecraft-build-quilt.yml new file mode 100644 index 0000000..4f9ad2b --- /dev/null +++ b/.gitea/workflows/minecraft-build-quilt.yml @@ -0,0 +1,331 @@ +name: Build and Push Minecraft Docker Images on Debian-base update + +on: + push: + branches: + - master + paths: + - '.gitea/workflows/minecraft-build-quilt.yml' + - 'quilt/Dockerfile' + - 'quilt/*.sh' + - '!.cache/*' + - '!quilt/CHANGES.md' + - '!quilt/build-info.json' + schedule: + - cron: '30 21 * * 0' + +env: + IMAGE_REGISTRY: gitea.fithwum.tech + IMAGE_ORG: fithwum + IMAGE_REPO_DEBIAN: debian-base + IMAGE_REPO_MINECRAFT: minecraft + IMAGE_TAG_DEBIAN: bookworm + DIGEST_FILE: .cache/debian-base.digest + VERSIONS: quilt + +jobs: + docker-prune: + name: Docker prune (${{ matrix.runner }}) + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + runner: + - vm-docker-build2 + - vm-docker-build2 + steps: + - name: Prune unused Docker images + run: | + echo "[INFO] Pruning Docker images on ${{ matrix.runner }}..." + docker image prune -a -f || true + + poll-debian-base-and-detect-changes: + runs-on: vm-docker-build2 + needs: docker-prune + outputs: + digest_changed: ${{ steps.compare_digest.outputs.changed }} + versions_changed: ${{ steps.check_changed_versions.outputs.versions_changed }} + new_versions: ${{ steps.check_new_versions.outputs.new_versions }} + 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 gitea.fithwum.tech -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 "[INFO] Digest unchanged" + echo "changed=false" >> $GITHUB_OUTPUT + exit 0 + fi + + echo "[INFO] Digest changed → updating cache" + 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 + + # --- Safe rebase with auto conflict resolution --- + git fetch origin master + if ! git rebase --strategy-option=theirs origin/master; then + echo "[WARN] Rebase conflict, auto-resolving by preferring local digest" + git rebase --abort + git fetch origin master + git reset --hard origin/master + echo "$CURRENT_DIGEST" > ${{ env.DIGEST_FILE }} + git add ${{ env.DIGEST_FILE }} + git commit -m "Force-update base digest to $CURRENT_DIGEST (auto-resolved)" + fi + + git push origin HEAD:master + echo "changed=true" >> $GITHUB_OUTPUT + + - 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 $VERSIONS; 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 + + - name: Detect Minecraft versions without build-info + id: check_new_versions + run: | + NEW_VERSIONS="" + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + for version in $VERSIONS; do + if [ ! -f "upload-repo/$version/build-info.json" ]; then + echo "[INFO] No build-info.json for $version → treating as new" + NEW_VERSIONS="$NEW_VERSIONS $version" + fi + done + + echo "new_versions=$NEW_VERSIONS" >> $GITHUB_OUTPUT + + build-minecraft-images: + runs-on: vm-docker-build2 + needs: + - docker-prune + - 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 != '' || + needs.poll-debian-base-and-detect-changes.outputs.new_versions != '' + strategy: + matrix: + version: [quilt] + 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 gitea.fithwum.tech -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin + + - name: Clone Minecraft repo (with retries) + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + for i in {1..5}; do + git clone "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo && break + echo "[WARN] Clone attempt $i failed. Retrying in 10s..." + sleep 10 + done + if [ ! -d upload-repo ]; then + echo "[ERROR] Failed to clone Minecraft repo after retries." + exit 1 + fi + + - 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: vm-docker-build2 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Create temporary changelog workspace + run: mkdir -p changelogs + + - name: Clone Minecraft repo + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=3 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + - name: Generate changelogs + run: | + for version in $VERSIONS; do + echo "[INFO] Generating changelog for $version" + changelog="changelogs/$version/CHANGES.md" + mkdir -p "$(dirname "$changelog")" + touch "$changelog" + + cd upload-repo + infofile="$version/build-info.json" + last_commit="" + if [ -f "$infofile" ]; then + last_commit=$(jq -r '.commit' "$infofile") + fi + + echo -e "## $(date -u +'%Y-%m-%dT%H:%M:%SZ')\n" > "../$changelog" + if [ -n "$last_commit" ]; then + COMMITS=$(git log "${last_commit}..HEAD" --pretty=format:"- %s (%an)" || true) + fi + if [ -z "$COMMITS" ]; then + echo "[INFO] No new commits since last build. Showing latest 5 instead." + COMMITS=$(git log -n 5 --pretty=format:"- %s (%an)" || true) + fi + echo "$COMMITS" >> "../$changelog" + cd .. + done + + - name: Copy changelogs into repo + run: | + for version in $VERSIONS; do + mkdir -p upload-repo/$version + cp changelogs/$version/CHANGES.md upload-repo/$version/ + done + + - name: Commit and push changelogs + 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')" --no-verify + git push + else + echo "[INFO] No changelog changes to commit." + fi + + generate-build-info: + needs: generate-changelogs + runs-on: vm-docker-build2 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Prepare temporary build-info workspace + run: mkdir -p buildinfo + + - name: Clone Minecraft repo + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + - name: Generate build-info files + 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]}" + } + + for version in $VERSIONS; do + echo "[INFO] Generating build-info.json for $version" + image="${IMAGE_REGISTRY}/${IMAGE_ORG}/${IMAGE_REPO_MINECRAFT}:$version" + infofile="buildinfo/$version/build-info.json" + mkdir -p "$(dirname "$infofile")" + + if ! docker pull "$image"; then + echo "[WARN] Failed to pull $image — setting fields to unknown/0" + digest="unknown" + size_bytes=0 + else + 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 + fi + + size_human=$(human_size "$size_bytes") + + cd upload-repo + commit=$(git rev-parse HEAD) + cd .. + + jq -n \ + --arg version "$version" \ + --arg commit "$commit" \ + --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: Copy build-info.json into repo + run: | + for version in $VERSIONS; do + mkdir -p upload-repo/$version + cp "buildinfo/$version/build-info.json" "upload-repo/$version/" + done + + - name: Commit and push build-info + 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')" + git push + + for version in $VERSIONS; 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 diff --git a/.gitea/workflows/minecraft-build-testing.yml b/.gitea/workflows/minecraft-build-testing.yml new file mode 100644 index 0000000..c87d192 --- /dev/null +++ b/.gitea/workflows/minecraft-build-testing.yml @@ -0,0 +1,331 @@ +name: Build and Push Minecraft Docker Images on Debian-base update + +on: + push: + branches: + - master + paths: + - '.gitea/workflows/minecraft-build-testing.yml' + - 'testing/Dockerfile' + - 'testing/*.sh' + - '!.cache/*' + - '!testing/CHANGES.md' + - '!testing/build-info.json' + schedule: + - cron: '30 21 * * 0' + +env: + IMAGE_REGISTRY: gitea.fithwum.tech + IMAGE_ORG: fithwum + IMAGE_REPO_DEBIAN: debian-base + IMAGE_REPO_MINECRAFT: minecraft + IMAGE_TAG_DEBIAN: bookworm + DIGEST_FILE: .cache/debian-base.digest + VERSIONS: testing + +jobs: + docker-prune: + name: Docker prune (${{ matrix.runner }}) + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + runner: + - vm-docker-build2 + - vm-docker-build2 + steps: + - name: Prune unused Docker images + run: | + echo "[INFO] Pruning Docker images on ${{ matrix.runner }}..." + docker image prune -a -f || true + + poll-debian-base-and-detect-changes: + runs-on: vm-docker-build2 + needs: docker-prune + outputs: + digest_changed: ${{ steps.compare_digest.outputs.changed }} + versions_changed: ${{ steps.check_changed_versions.outputs.versions_changed }} + new_versions: ${{ steps.check_new_versions.outputs.new_versions }} + 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 gitea.fithwum.tech -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 "[INFO] Digest unchanged" + echo "changed=false" >> $GITHUB_OUTPUT + exit 0 + fi + + echo "[INFO] Digest changed → updating cache" + 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 + + # --- Safe rebase with auto conflict resolution --- + git fetch origin master + if ! git rebase --strategy-option=theirs origin/master; then + echo "[WARN] Rebase conflict, auto-resolving by preferring local digest" + git rebase --abort + git fetch origin master + git reset --hard origin/master + echo "$CURRENT_DIGEST" > ${{ env.DIGEST_FILE }} + git add ${{ env.DIGEST_FILE }} + git commit -m "Force-update base digest to $CURRENT_DIGEST (auto-resolved)" + fi + + git push origin HEAD:master + echo "changed=true" >> $GITHUB_OUTPUT + + - 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 $VERSIONS; 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 + + - name: Detect Minecraft versions without build-info + id: check_new_versions + run: | + NEW_VERSIONS="" + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + for version in $VERSIONS; do + if [ ! -f "upload-repo/$version/build-info.json" ]; then + echo "[INFO] No build-info.json for $version → treating as new" + NEW_VERSIONS="$NEW_VERSIONS $version" + fi + done + + echo "new_versions=$NEW_VERSIONS" >> $GITHUB_OUTPUT + + build-minecraft-images: + runs-on: vm-docker-build2 + needs: + - docker-prune + - 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 != '' || + needs.poll-debian-base-and-detect-changes.outputs.new_versions != '' + strategy: + matrix: + version: [testing] + 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 gitea.fithwum.tech -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin + + - name: Clone Minecraft repo (with retries) + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + for i in {1..5}; do + git clone "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo && break + echo "[WARN] Clone attempt $i failed. Retrying in 10s..." + sleep 10 + done + if [ ! -d upload-repo ]; then + echo "[ERROR] Failed to clone Minecraft repo after retries." + exit 1 + fi + + - 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: vm-docker-build2 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Create temporary changelog workspace + run: mkdir -p changelogs + + - name: Clone Minecraft repo + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=3 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + - name: Generate changelogs + run: | + for version in $VERSIONS; do + echo "[INFO] Generating changelog for $version" + changelog="changelogs/$version/CHANGES.md" + mkdir -p "$(dirname "$changelog")" + touch "$changelog" + + cd upload-repo + infofile="$version/build-info.json" + last_commit="" + if [ -f "$infofile" ]; then + last_commit=$(jq -r '.commit' "$infofile") + fi + + echo -e "## $(date -u +'%Y-%m-%dT%H:%M:%SZ')\n" > "../$changelog" + if [ -n "$last_commit" ]; then + COMMITS=$(git log "${last_commit}..HEAD" --pretty=format:"- %s (%an)" || true) + fi + if [ -z "$COMMITS" ]; then + echo "[INFO] No new commits since last build. Showing latest 5 instead." + COMMITS=$(git log -n 5 --pretty=format:"- %s (%an)" || true) + fi + echo "$COMMITS" >> "../$changelog" + cd .. + done + + - name: Copy changelogs into repo + run: | + for version in $VERSIONS; do + mkdir -p upload-repo/$version + cp changelogs/$version/CHANGES.md upload-repo/$version/ + done + + - name: Commit and push changelogs + 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')" --no-verify + git push + else + echo "[INFO] No changelog changes to commit." + fi + + generate-build-info: + needs: generate-changelogs + runs-on: vm-docker-build2 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Prepare temporary build-info workspace + run: mkdir -p buildinfo + + - name: Clone Minecraft repo + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + - name: Generate build-info files + 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]}" + } + + for version in $VERSIONS; do + echo "[INFO] Generating build-info.json for $version" + image="${IMAGE_REGISTRY}/${IMAGE_ORG}/${IMAGE_REPO_MINECRAFT}:$version" + infofile="buildinfo/$version/build-info.json" + mkdir -p "$(dirname "$infofile")" + + if ! docker pull "$image"; then + echo "[WARN] Failed to pull $image — setting fields to unknown/0" + digest="unknown" + size_bytes=0 + else + 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 + fi + + size_human=$(human_size "$size_bytes") + + cd upload-repo + commit=$(git rev-parse HEAD) + cd .. + + jq -n \ + --arg version "$version" \ + --arg commit "$commit" \ + --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: Copy build-info.json into repo + run: | + for version in $VERSIONS; do + mkdir -p upload-repo/$version + cp "buildinfo/$version/build-info.json" "upload-repo/$version/" + done + + - name: Commit and push build-info + 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')" + git push + + for version in $VERSIONS; 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 diff --git a/.gitea/workflows/minecraft-build-vanilla.yml b/.gitea/workflows/minecraft-build-vanilla.yml new file mode 100644 index 0000000..00d5ad3 --- /dev/null +++ b/.gitea/workflows/minecraft-build-vanilla.yml @@ -0,0 +1,331 @@ +name: Build and Push Minecraft Docker Images on Debian-base update + +on: + push: + branches: + - master + paths: + - '.gitea/workflows/minecraft-build-vanilla.yml' + - 'vanilla/Dockerfile' + - 'vanilla/*.sh' + - '!.cache/*' + - '!vanilla/CHANGES.md' + - '!vanilla/build-info.json' + schedule: + - cron: '30 21 * * 0' + +env: + IMAGE_REGISTRY: gitea.fithwum.tech + IMAGE_ORG: fithwum + IMAGE_REPO_DEBIAN: debian-base + IMAGE_REPO_MINECRAFT: minecraft + IMAGE_TAG_DEBIAN: bookworm + DIGEST_FILE: .cache/debian-base.digest + VERSIONS: vanilla + +jobs: + docker-prune: + name: Docker prune (${{ matrix.runner }}) + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + runner: + - vm-docker-build2 + - vm-docker-build2 + steps: + - name: Prune unused Docker images + run: | + echo "[INFO] Pruning Docker images on ${{ matrix.runner }}..." + docker image prune -a -f || true + + poll-debian-base-and-detect-changes: + runs-on: vm-docker-build2 + needs: docker-prune + outputs: + digest_changed: ${{ steps.compare_digest.outputs.changed }} + versions_changed: ${{ steps.check_changed_versions.outputs.versions_changed }} + new_versions: ${{ steps.check_new_versions.outputs.new_versions }} + 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 gitea.fithwum.tech -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 "[INFO] Digest unchanged" + echo "changed=false" >> $GITHUB_OUTPUT + exit 0 + fi + + echo "[INFO] Digest changed → updating cache" + 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 + + # --- Safe rebase with auto conflict resolution --- + git fetch origin master + if ! git rebase --strategy-option=theirs origin/master; then + echo "[WARN] Rebase conflict, auto-resolving by preferring local digest" + git rebase --abort + git fetch origin master + git reset --hard origin/master + echo "$CURRENT_DIGEST" > ${{ env.DIGEST_FILE }} + git add ${{ env.DIGEST_FILE }} + git commit -m "Force-update base digest to $CURRENT_DIGEST (auto-resolved)" + fi + + git push origin HEAD:master + echo "changed=true" >> $GITHUB_OUTPUT + + - 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 $VERSIONS; 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 + + - name: Detect Minecraft versions without build-info + id: check_new_versions + run: | + NEW_VERSIONS="" + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + for version in $VERSIONS; do + if [ ! -f "upload-repo/$version/build-info.json" ]; then + echo "[INFO] No build-info.json for $version → treating as new" + NEW_VERSIONS="$NEW_VERSIONS $version" + fi + done + + echo "new_versions=$NEW_VERSIONS" >> $GITHUB_OUTPUT + + build-minecraft-images: + runs-on: vm-docker-build2 + needs: + - docker-prune + - 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 != '' || + needs.poll-debian-base-and-detect-changes.outputs.new_versions != '' + strategy: + matrix: + version: [vanilla] + 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 gitea.fithwum.tech -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin + + - name: Clone Minecraft repo (with retries) + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + for i in {1..5}; do + git clone "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo && break + echo "[WARN] Clone attempt $i failed. Retrying in 10s..." + sleep 10 + done + if [ ! -d upload-repo ]; then + echo "[ERROR] Failed to clone Minecraft repo after retries." + exit 1 + fi + + - 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: vm-docker-build2 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Create temporary changelog workspace + run: mkdir -p changelogs + + - name: Clone Minecraft repo + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=3 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + - name: Generate changelogs + run: | + for version in $VERSIONS; do + echo "[INFO] Generating changelog for $version" + changelog="changelogs/$version/CHANGES.md" + mkdir -p "$(dirname "$changelog")" + touch "$changelog" + + cd upload-repo + infofile="$version/build-info.json" + last_commit="" + if [ -f "$infofile" ]; then + last_commit=$(jq -r '.commit' "$infofile") + fi + + echo -e "## $(date -u +'%Y-%m-%dT%H:%M:%SZ')\n" > "../$changelog" + if [ -n "$last_commit" ]; then + COMMITS=$(git log "${last_commit}..HEAD" --pretty=format:"- %s (%an)" || true) + fi + if [ -z "$COMMITS" ]; then + echo "[INFO] No new commits since last build. Showing latest 5 instead." + COMMITS=$(git log -n 5 --pretty=format:"- %s (%an)" || true) + fi + echo "$COMMITS" >> "../$changelog" + cd .. + done + + - name: Copy changelogs into repo + run: | + for version in $VERSIONS; do + mkdir -p upload-repo/$version + cp changelogs/$version/CHANGES.md upload-repo/$version/ + done + + - name: Commit and push changelogs + 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')" --no-verify + git push + else + echo "[INFO] No changelog changes to commit." + fi + + generate-build-info: + needs: generate-changelogs + runs-on: vm-docker-build2 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Prepare temporary build-info workspace + run: mkdir -p buildinfo + + - name: Clone Minecraft repo + run: | + GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/minecraft.git" upload-repo + + - name: Generate build-info files + 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]}" + } + + for version in $VERSIONS; do + echo "[INFO] Generating build-info.json for $version" + image="${IMAGE_REGISTRY}/${IMAGE_ORG}/${IMAGE_REPO_MINECRAFT}:$version" + infofile="buildinfo/$version/build-info.json" + mkdir -p "$(dirname "$infofile")" + + if ! docker pull "$image"; then + echo "[WARN] Failed to pull $image — setting fields to unknown/0" + digest="unknown" + size_bytes=0 + else + 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 + fi + + size_human=$(human_size "$size_bytes") + + cd upload-repo + commit=$(git rev-parse HEAD) + cd .. + + jq -n \ + --arg version "$version" \ + --arg commit "$commit" \ + --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: Copy build-info.json into repo + run: | + for version in $VERSIONS; do + mkdir -p upload-repo/$version + cp "buildinfo/$version/build-info.json" "upload-repo/$version/" + done + + - name: Commit and push build-info + 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')" + git push + + for version in $VERSIONS; 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