5555 - name : Tidy go.mod files
5656 run : go mod tidy
5757
58- - name : Verify build
58+ - name : Cache sources
59+ id : cache-sources
60+ uses : actions/cache@v4
61+ with :
62+ path : distributions/${{ inputs.distribution }}/_build
63+ key : " sources-${{ hashFiles('distributions/${{ inputs.distribution }}/manifest.yaml', 'Makefile') }}"
64+
65+ - name : Generate sources
66+ if : steps.cache-sources.outputs.cache-hit != 'true'
5967 run : make ci DISTRIBUTIONS=${{ inputs.distribution }}
6068
69+ - name : Skip source generation (cached)
70+ if : steps.cache-sources.outputs.cache-hit == 'true'
71+ run : echo "✅ Source generation skipped - no source changes detected"
72+
6173 - name : Login to Docker
6274 uses : docker/login-action@v3
6375 if : ${{ env.ACT }}
@@ -92,14 +104,36 @@ jobs:
92104 run : |
93105 if [ ${{ inputs.nightly }} = "true" ]; then
94106 echo "goreleaser_args=--snapshot --clean --skip=publish,validate --timeout 2h --config .goreleaser-nightly.yaml" >> $GITHUB_ENV
95- elif [ ${{github.event.pull_request.user.login == 'dependabot[bot]' }} ]; then
96- echo "goreleaser_args=--snapshot --clean --skip=publish,validate,sign --timeout 2h" >> $GITHUB_ENV
97107 else
98- echo "goreleaser_args=--snapshot --clean --skip=publish,validate --timeout 2h " >> $GITHUB_ENV
108+ echo "goreleaser_args=build --single-target --snapshot --clean " >> $GITHUB_ENV
99109 fi
110+
111+ - name : Generate docker cache key
112+ id : build-cache-keys
113+ run : |
114+ # Hash files that affect binary generation
115+ BINARY_HASH="${{ hashFiles('distributions/${{ inputs.distribution }}/.goreleaser*.yaml', 'distributions/${{ inputs.distribution }}/_build/*') }}"
116+ echo "binary_key=${{ inputs.distribution }}-${{ github.ref_name }}-${BINARY_HASH}" >> $GITHUB_OUTPUT
117+ # Extended hash for Docker build (includes generated sources)
118+ DOCKER_HASH="${{ hashFiles('distributions/${{ inputs.distribution }}/Dockerfile', 'distributions/${{ inputs.distribution }}/config*.yaml') }}"
119+ echo "docker_key=${{ inputs.distribution }}-${{ github.ref_name }}-${DOCKER_HASH}-${BINARY_HASH}" >> $GITHUB_OUTPUT
120+
121+ - name : Cache GoReleaser build
122+ id : cache-goreleaser
123+ if : ${{ !inputs.nightly }}
124+ uses : actions/cache@v4
125+ with :
126+ path : |
127+ distributions/${{ inputs.distribution }}/dist
128+ ~/.cache/go-build
129+ ~/go/pkg/mod
130+ key : ${{ steps.build-cache-keys.outputs.binary_key }}
131+ restore-keys : |
132+ goreleaser-build-${{ inputs.distribution }}-
100133
101134 - name : Build binaries & packages with GoReleaser
102135 id : goreleaser
136+ if : steps.cache-goreleaser.outputs.cache-hit != 'true'
103137 uses : goreleaser/goreleaser-action@v6
104138 env :
105139 NFPM_PASSPHRASE : ${{ secrets.gpg_passphrase }}
@@ -111,10 +145,29 @@ jobs:
111145 version : ' ~> v2'
112146 args : ${{ env.goreleaser_args }}
113147 workdir : distributions/${{ inputs.distribution }}
148+
149+ - name : Skip GoReleaser build (cached)
150+ if : steps.cache-goreleaser.outputs.cache-hit == 'true'
151+ run : echo "✅ GoReleaser build skipped - using cached binaries"
114152
115- - name : Extract relevant metadata
153+ - name : Extract relevant metadata from GoReleaser output
116154 run : |
117- VERSION=$(echo '${{ steps.goreleaser.outputs.metadata }}' | jq -r '.version')
155+ if [ "${{ steps.cache-goreleaser.outputs.cache-hit }}" = "true" ]; then
156+ # Try to find version from dist folder structure or metadata file
157+ if [ -f "distributions/${{ inputs.distribution }}/dist/metadata.json" ]; then
158+ VERSION=$(jq -r '.version' distributions/${{ inputs.distribution }}/dist/metadata.json)
159+ else
160+ # Fallback version
161+ VERSION="cached-$(date +%Y%m%d-%H%M)"
162+ echo "⚠️ Warning: No metadata found, using fallback version: $VERSION"
163+ fi
164+
165+ echo "Using cached version: $VERSION"
166+ else
167+ # Extract from fresh GoReleaser build
168+ VERSION=$(echo '${{ steps.goreleaser.outputs.metadata }}' | jq -r '.version')
169+ echo "Using fresh build version: $VERSION"
170+ fi
118171 ARCH=$(echo '${{ runner.arch }}' | sed 's/X/amd/g')
119172 ARCH=${ARCH@L}
120173 echo "version=$VERSION" >> $GITHUB_ENV
@@ -125,6 +178,38 @@ jobs:
125178 echo "image_tag=$VERSION-$ARCH" >> $GITHUB_ENV
126179 fi
127180
181+ - name : Copy GoReleaser binary to Docker context
182+ if : ${{ !inputs.nightly }}
183+ run : |
184+ cd distributions/${{ inputs.distribution }}
185+ BINARY_PATH="$(find dist -name "${{ inputs.distribution }}_linux_amd64*" -type d)/${{ inputs.distribution }}"
186+ if [ ! -f "$BINARY_PATH" ]; then
187+ echo "❌ Error: Binary not found at $BINARY_PATH"
188+ find dist -name "*${{ inputs.distribution }}*" -type f
189+ exit 1
190+ fi
191+ cp "$BINARY_PATH" ./${{ inputs.distribution }}
192+ echo "✅ Binary copied: $(ls -la ./${{ inputs.distribution }})"
193+
194+
195+ - name : Build and load Docker image
196+ uses : docker/build-push-action@v5
197+ if : ${{ !inputs.nightly }}
198+ with :
199+ context : distributions/${{ inputs.distribution }}
200+ platforms : linux/amd64
201+ push : false
202+ load : true
203+ tags : |
204+ ${{ secrets.registry }}/${{ inputs.distribution }}:${{ env.image_tag }}
205+ cache-from : |
206+ type=gha,scope=${{ steps.build-cache-keys.outputs.docker_key }}
207+ type=gha,scope=${{ inputs.distribution }}-${{ github.ref_name }}
208+ type=gha,scope=${{ inputs.distribution }}-main
209+ cache-to : |
210+ type=gha,mode=max,scope=${{ steps.build-cache-keys.outputs.docker_key }}
211+ ${{ github.ref_name == 'main' && format('type=gha,mode=max,scope={0}-main', inputs.distribution) || format('type=gha,mode=max,scope={0}-{1}', inputs.distribution, github.ref_name) }}
212+
128213 - name : Setup local kind cluster
129214 uses : helm/kind-action@v1
130215 with :
0 commit comments