diff --git a/.gitea/workflows/base-build.yml b/.gitea/workflows/base-build.yml index 7a506ca..55d0f12 100644 --- a/.gitea/workflows/base-build.yml +++ b/.gitea/workflows/base-build.yml @@ -26,168 +26,173 @@ env: OUTPUT_DIR: ./output jobs: - build-and-push-rootfs-archives: - runs-on: vm-docker-build2 - outputs: - archives_changed: ${{ steps.commit_archives.outputs.archives_changed }} - steps: - - name: Checkout source - uses: actions/checkout@v3 - - - name: Create output directory - run: mkdir -p ./output - - - name: Build all Debian rootfs versions into volumes and extract - run: | - versions=($VERSIONS) - for version in "${versions[@]}"; do - echo "[INFO] Building $version..." - volume_name="build_output_$version" - docker volume create "$volume_name" - - docker build --build-arg VERSION=$version -t fithwum/debian-$version-base . - - docker run --rm --privileged \ - -v "$volume_name:/output" \ - -e VERSION="$version" \ - fithwum/debian-$version-base \ - bash -c "/scripts/bootstrap-rootfs.sh \"$version\"" - - # Extract the output file from the volume - container_id=$(docker create -v "$volume_name:/output" debian) - mkdir -p ./output/$version - docker cp "$container_id:/output/$version/debian-$version.tar.bz2" ./output/$version/ - docker rm "$container_id" - done - - - name: Validate that archives exist for each version - run: | - IFS=' ' read -r -a versions <<< "$VERSIONS" - for version in "${versions[@]}"; do - path="./output/$version/debian-$version.tar.bz2" - if [[ ! -f "$path" ]]; then - echo "[ERROR] Missing archive: $path" - exit 1 - else - echo "[OK] Found: $path" - fi - done - - - name: Clone upload repo - run: | - GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" - git clone --depth=1 "https://${{ env.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/debian-base.git" upload-repo - - - name: Clean old archives in upload-repo - run: rm -rfv upload-repo/*/*.tar.bz2 - - - name: Copy new archives to upload-repo - run: | - for filepath in ./output/*/debian-*.tar.bz2; do - version_dir=$(basename "$(dirname "$filepath")") - mkdir -p "upload-repo/$version_dir" - cp "$filepath" "upload-repo/$version_dir/" - done - - - name: Calculate and store sha256sums in upload-repo - run: | - cd upload-repo - rm -f sha256sums.txt - for tarball in */debian-*.tar.bz2; do - echo "[INFO] Processing: $tarball" - checksum=$(sha256sum "$tarball" | awk '{print $1}') - echo "$checksum $tarball" >> sha256sums.txt - done - echo "[INFO] SHA256 contents:" - cat sha256sums.txt - - - name: Commit and push files if changed - id: commit_archives - run: | - cd upload-repo - git config --global user.name "${{ env.GIT_USERNAME }}" - git config --global user.email "${{ env.GIT_EMAIL }}" - - if git status --porcelain | grep .; then - git add **/*.tar.bz2 sha256sums.txt || true - git commit -m "Update base images and checksum on $(date -u +'%Y-%m-%dT%H:%M:%SZ') [skip ci]" - git push - echo "archives_changed=true" >> $GITHUB_OUTPUT - else - echo "[INFO] No changes to commit." - echo "archives_changed=false" >> $GITHUB_OUTPUT - fi - - # build-rootfs: - # name: Build rootfs (${{ matrix.version }}) + # build-and-push-rootfs-archives: # runs-on: vm-docker-build2 - - # strategy: - # fail-fast: false - # matrix: - # version: [bullseye, bookworm, trixie] - + # outputs: + # archives_changed: ${{ steps.commit_archives.outputs.archives_changed }} # steps: - # - uses: actions/checkout@v3 + # - name: Checkout source + # uses: actions/checkout@v3 - # - name: Ensure output directory exists - # run: mkdir -p ${{ env.OUTPUT_DIR }}/${{ matrix.version }} + # - name: Create output directory + # run: mkdir -p ./output - # - name: Build rootfs tarball + # - name: Build all Debian rootfs versions into volumes and extract # run: | - # VERSION=${{ matrix.version }} - # OUT_DIR=${{ env.OUTPUT_DIR }}/$VERSION + # versions=($VERSIONS) + # for version in "${versions[@]}"; do + # echo "[INFO] Building $version..." + # volume_name="build_output_$version" + # docker volume create "$volume_name" - # docker build \ - # --build-arg VERSION="$VERSION" \ - # -t rootfs-$VERSION . + # docker build --build-arg VERSION=$version -t fithwum/debian-$version-base . - # docker run --rm \ - # -v "$(pwd)/$OUT_DIR:/output" \ - # rootfs-$VERSION \ - # bash -c "/scripts/bootstrap-rootfs.sh $VERSION /output" + # docker run --rm --privileged \ + # -v "$volume_name:/output" \ + # -e VERSION="$version" \ + # fithwum/debian-$version-base \ + # bash -c "/scripts/bootstrap-rootfs.sh \"$version\"" - # if [[ ! -f "$OUT_DIR/debian-$VERSION.tar.bz2" ]]; then - # echo "[ERROR] Rootfs tarball not found at $OUT_DIR/debian-$VERSION.tar.bz2" - # exit 1 - # else - # echo "[OK] Rootfs tarball created at $OUT_DIR/debian-$VERSION.tar.bz2" - # fi + # # Extract the output file from the volume + # container_id=$(docker create -v "$volume_name:/output" debian) + # mkdir -p ./output/$version + # docker cp "$container_id:/output/$version/debian-$version.tar.bz2" ./output/$version/ + # docker rm "$container_id" + # done + + # - name: Validate that archives exist for each version + # run: | + # IFS=' ' read -r -a versions <<< "$VERSIONS" + # for version in "${versions[@]}"; do + # path="./output/$version/debian-$version.tar.bz2" + # if [[ ! -f "$path" ]]; then + # echo "[ERROR] Missing archive: $path" + # exit 1 + # else + # echo "[OK] Found: $path" + # fi + # done # - name: Clone upload repo # run: | - # git clone --depth=1 \ - # https://${GIT_USERNAME}:${GIT_TOKEN}@gitea.fithwum.tech/fithwum/debian-base.git upload + # GIT_CREDENTIAL="${{ secrets.GIT_TOKEN || secrets.GIT_PASSWORD }}" + # git clone --depth=1 "https://${{ env.GIT_USERNAME }}:${GIT_CREDENTIAL}@gitea.fithwum.tech/fithwum/debian-base.git" upload-repo - # - name: Update archive + sha256 + # - name: Clean old archives in upload-repo + # run: rm -rfv upload-repo/*/*.tar.bz2 + + # - name: Copy new archives to upload-repo # run: | - # VERSION=${{ matrix.version }} - # OUT_DIR=${{ env.OUTPUT_DIR }}/$VERSION + # for filepath in ./output/*/debian-*.tar.bz2; do + # version_dir=$(basename "$(dirname "$filepath")") + # mkdir -p "upload-repo/$version_dir" + # cp "$filepath" "upload-repo/$version_dir/" + # done - # mkdir -p upload/$VERSION - # cp "$OUT_DIR/debian-$VERSION.tar.bz2" "upload/$VERSION/" - - # cd upload - # # Remove previous sha256 entry for this version - # sed -i "/debian-$VERSION.tar.bz2/d" sha256sums.txt 2>/dev/null || true - # sha256sum "$VERSION/debian-$VERSION.tar.bz2" >> sha256sums.txt - - # - name: Commit if changed + # - name: Calculate and store sha256sums in upload-repo # run: | - # VERSION=${{ matrix.version }} + # cd upload-repo + # rm -f sha256sums.txt + # for tarball in */debian-*.tar.bz2; do + # echo "[INFO] Processing: $tarball" + # checksum=$(sha256sum "$tarball" | awk '{print $1}') + # echo "$checksum $tarball" >> sha256sums.txt + # done + # echo "[INFO] SHA256 contents:" + # cat sha256sums.txt - # cd upload - # git config user.name "$GIT_USERNAME" - # git config user.email "$GIT_EMAIL" + # - name: Commit and push files if changed + # id: commit_archives + # run: | + # cd upload-repo + # git config --global user.name "${{ env.GIT_USERNAME }}" + # git config --global user.email "${{ env.GIT_EMAIL }}" # if git status --porcelain | grep .; then - # git add "$VERSION/debian-$VERSION.tar.bz2" sha256sums.txt - # git commit -m "Update rootfs for $VERSION [skip ci]" + # git add **/*.tar.bz2 sha256sums.txt || true + # git commit -m "Update base images and checksum on $(date -u +'%Y-%m-%dT%H:%M:%SZ') [skip ci]" # git push + # echo "archives_changed=true" >> $GITHUB_OUTPUT # else - # echo "[INFO] No changes for $VERSION" + # echo "[INFO] No changes to commit." + # echo "archives_changed=false" >> $GITHUB_OUTPUT # fi + build-rootfs: + name: Build rootfs (${{ matrix.version }}) + runs-on: vm-docker-build2 + + strategy: + fail-fast: false + matrix: + version: [bullseye, bookworm, trixie] + + steps: + - uses: actions/checkout@v3 + + - name: Create output directory + run: mkdir -p ${{ env.OUTPUT_DIR }}/${{ matrix.version }} + + - name: Build rootfs Docker image + run: | + VERSION=${{ matrix.version }} + docker build \ + --build-arg VERSION="$VERSION" \ + -t rootfs-$VERSION . + + - name: Run rootfs bootstrap + run: | + VERSION=${{ matrix.version }} + OUTPUT_DIR=${{ env.OUTPUT_DIR }}/$VERSION + + docker run --rm \ + -v "$PWD/$OUTPUT_DIR:/output" \ + rootfs-$VERSION \ + bash -c "/scripts/bootstrap-rootfs.sh $VERSION /output" + + # Verify tarball exists + TAR="$OUTPUT_DIR/debian-$VERSION.tar.bz2" + if [[ ! -f "$TAR" ]]; then + echo "[ERROR] Rootfs tarball missing: $TAR" + exit 1 + else + echo "[OK] Created $TAR" + fi + + - name: Clone upload repo + run: | + git clone --depth=1 \ + https://${GIT_USERNAME}:${GIT_TOKEN}@gitea.fithwum.tech/fithwum/debian-base.git upload + + - name: Update archive + sha256 + run: | + VERSION=${{ matrix.version }} + OUTPUT_DIR=${{ env.OUTPUT_DIR }}/$VERSION + + mkdir -p upload/$VERSION + cp "$OUTPUT_DIR/debian-$VERSION.tar.bz2" upload/$VERSION/ + + cd upload + # Remove old checksum for this version + sed -i "/debian-$VERSION.tar.bz2/d" sha256sums.txt 2>/dev/null || true + # Add new checksum + sha256sum "$VERSION/debian-$VERSION.tar.bz2" >> sha256sums.txt + + - name: Commit if changed + run: | + VERSION=${{ matrix.version }} + + cd upload + git config user.name "$GIT_USERNAME" + git config user.email "$GIT_EMAIL" + + if git status --porcelain | grep .; then + git add "$VERSION/debian-$VERSION.tar.bz2" sha256sums.txt + git commit -m "Update rootfs for $VERSION [skip ci]" + git push + else + echo "[INFO] No changes for $VERSION" + # build-and-push-docker-images: # needs: build-and-push-rootfs-archives # if: always() @@ -284,67 +289,38 @@ jobs: # done build-and-push-docker-images: - needs: build-and-push-rootfs-archives - if: always() + name: Build & Push Docker Images (${{ matrix.version }}) + needs: build-rootfs runs-on: vm-docker-build2 strategy: + fail-fast: false matrix: - version: [bullseye, bookworm, trixie] # replace with your $VERSIONS + version: [bullseye, bookworm, trixie] + steps: - name: Checkout source uses: actions/checkout@v3 - - name: Wait for archives to appear in upload repo + - name: Prepare Docker context run: | - echo "[INFO] Waiting for archive for ${{ matrix.version }}..." - mkdir -p temp-check && cd temp-check + VERSION=${{ matrix.version }} + OUTPUT_DIR=${{ env.OUTPUT_DIR }}/$VERSION + mkdir -p "$VERSION" + cp "$OUTPUT_DIR/debian-$VERSION.tar.bz2" "$VERSION/" - for i in {1..10}; do - echo "[INFO] Attempt $i: Cloning upload-repo..." - if git clone --depth=1 "https://${{ secrets.GIT_USERNAME }}:${{ secrets.GIT_TOKEN }}@gitea.fithwum.tech/fithwum/debian-base.git"; then - break - fi - echo "[WARN] Clone failed. Retrying in 10s..." - sleep 10 - done - - if [ ! -d "debian-base" ]; then - echo "[ERROR] Failed to clone upload-repo after retries." - exit 1 - fi - - cd debian-base - - # Wait for this version's archive - for i in {1..30}; do - if [[ -f "${{ matrix.version }}/debian-${{ matrix.version }}.tar.bz2" ]]; then - echo "[OK] Found archive for ${{ matrix.version }}" - break - else - echo "[WAIT] ${{ matrix.version }} not ready yet, sleeping 10s..." - sleep 10 - fi - done - - if [[ ! -f "${{ matrix.version }}/debian-${{ matrix.version }}.tar.bz2" ]]; then - echo "[ERROR] Missing archive for ${{ matrix.version }}" - exit 1 - fi - - - name: Generate Dockerfile for ${{ matrix.version }} + - name: Generate Dockerfile run: | - mkdir -p "${{ matrix.version }}" - DOCKERFILE_PATH="${{ matrix.version }}/Dockerfile" - - if [[ ! -f "$DOCKERFILE_PATH" ]]; then + VERSION=${{ matrix.version }} + DOCKERFILE="$VERSION/Dockerfile" + if [[ ! -f "$DOCKERFILE" ]]; then printf '%s\n' \ "FROM scratch" \ "LABEL maintainer=\"fithwum\"" \ - "ADD debian-${{ matrix.version }}.tar.bz2 /" \ - "CMD [\"/bin/bash\"]" > "$DOCKERFILE_PATH" - echo "[INFO] Created $DOCKERFILE_PATH" + "ADD debian-$VERSION.tar.bz2 /" \ + "CMD [\"/bin/bash\"]" > "$DOCKERFILE" + echo "[INFO] Created $DOCKERFILE" else - echo "[INFO] Dockerfile already exists for ${{ matrix.version }}" + echo "[INFO] Dockerfile exists for $VERSION" fi - name: Set up Docker Buildx @@ -353,14 +329,26 @@ jobs: - name: Log in to Gitea Registry run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login gitea.fithwum.tech -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - - name: Build and push Docker image for ${{ matrix.version }} + - name: Build & Push Docker Image run: | + VERSION=${{ matrix.version }} IMAGE_REGISTRY=gitea.fithwum.tech IMAGE_ORG=fithwum IMAGE_REPO=debian-base - FULL_IMAGE="${IMAGE_REGISTRY}/${IMAGE_ORG}/${IMAGE_REPO}:${{ matrix.version }}" - echo "[INFO] Building and pushing $FULL_IMAGE" - docker buildx build --platform linux/amd64 --push -t "$FULL_IMAGE" "./${{ matrix.version }}" + FULL_IMAGE="$IMAGE_REGISTRY/$IMAGE_ORG/$IMAGE_REPO:$VERSION" + + # Skip build if image already exists with same digest + if docker pull "$FULL_IMAGE" >/dev/null 2>&1; then + EXISTING_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$FULL_IMAGE") + NEW_DIGEST=$(sha256sum "${VERSION}/debian-$VERSION.tar.bz2" | awk '{print $1}') + if [[ "$EXISTING_DIGEST" == *"$NEW_DIGEST"* ]]; then + echo "[INFO] Docker image for $VERSION is up-to-date, skipping build." + exit 0 + fi + fi + + echo "[INFO] Building and pushing Docker image: $FULL_IMAGE" + docker buildx build --platform linux/amd64 --push -t "$FULL_IMAGE" "./$VERSION" generate-changelogs: needs: build-and-push-rootfs-archives