From dea2903ce259683b5ab55fe62537d4b9559d71a3 Mon Sep 17 00:00:00 2001 From: clsferguson <48876201+clsferguson@users.noreply.github.com> Date: Tue, 30 Sep 2025 13:03:03 -0600 Subject: [PATCH] ci: free disk on GH runner, prune Docker cache, and reliable self-hosted fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add “Free Disk Space (Ubuntu)” and Docker prune steps before/after the GitHub-hosted build to recover tens of GB and avoid “no space left on device” failures on ubuntu-latest. - Remove continue-on-error and gate the self-hosted job with `always() && needs.build-gh.result != 'success'` so it runs only if the GH build fails, while publish proceeds if either path succeeds. - Enable buildx GHA cache (cache-from/cache-to) to minimize runner disk pressure and rebuild times without loading images locally. --- .github/workflows/build-release.yml | 50 +++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index d2e122bcb..5bd0918de 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -20,6 +20,7 @@ jobs: with: fetch-depth: 0 fetch-tags: true + - name: Install prerequisites (jq, curl) run: | set -e @@ -27,6 +28,7 @@ jobs: sudo apt-get update -y sudo apt-get install -y jq curl fi + - name: Determine current tag (release, then git fallback) id: resolve shell: bash @@ -47,14 +49,34 @@ jobs: name: Build on GitHub Runner (primary) needs: check-tag runs-on: ubuntu-latest - outputs: - build_succeeded: ${{ steps.set_out.outputs.succeeded }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true + - name: Show disk usage (pre) + run: df -h | sed 's/\s\+/ /g' + + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@main + with: + tool-cache: false + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: true + + - name: Prune Docker caches (pre) + run: | + docker builder prune -af || true + docker system prune -af --volumes || true + + - name: Show disk usage (post-clean) + run: df -h | sed 's/\s\+/ /g' + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 with: @@ -89,7 +111,6 @@ jobs: - name: Build and Push (GH runner) id: build uses: docker/build-push-action@v6 - continue-on-error: true with: context: . file: ./Dockerfile @@ -97,19 +118,22 @@ jobs: push: true provenance: false sbom: false + cache-from: type=gha,scope=gh + cache-to: type=gha,mode=max,scope=gh tags: | ${{ env.IMAGE_NAME }}:${{ needs.check-tag.outputs.current_tag }} ${{ env.IMAGE_NAME }}:latest - - name: Set outcome flag - id: set_out + - name: Prune Docker caches (post) + if: always() run: | - echo "succeeded=${{ steps.build.outcome == 'success' }}" >> "$GITHUB_OUTPUT" + docker builder prune -af || true + docker system prune -af --volumes || true build-self: name: Build on Self-Hosted (fallback) needs: [check-tag, build-gh] - if: needs.build-gh.outputs.build_succeeded != 'true' + if: ${{ always() && needs.build-gh.result != 'success' }} runs-on: [self-hosted, linux, x64, homelab] steps: - uses: actions/checkout@v4 @@ -157,14 +181,22 @@ jobs: push: true provenance: false sbom: false + cache-from: type=gha,scope=gh + cache-to: type=gha,mode=max,scope=gh tags: | ${{ env.IMAGE_NAME }}:${{ needs.check-tag.outputs.current_tag }} ${{ env.IMAGE_NAME }}:latest + - name: Prune Docker caches (post) + if: always() + run: | + docker builder prune -af || true + docker system prune -af --volumes || true + publish: name: Update Release needs: [check-tag, build-gh, build-self] - if: always() && (needs.build-gh.outputs.build_succeeded == 'true' || needs.build-self.result == 'success') + if: ${{ always() && (needs.build-gh.result == 'success' || needs.build-self.result == 'success') }} runs-on: ubuntu-latest steps: - name: Update GitHub Release (same tag) @@ -188,7 +220,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Fail if both build paths failed - if: ${{ !(needs.build-gh.outputs.build_succeeded == 'true' || needs.build-self.result == 'success') }} + if: ${{ !(needs.build-gh.result == 'success' || needs.build-self.result == 'success') }} run: | echo "Manual rebuild failed on both GitHub-hosted and self-hosted paths." exit 1