1- name : release -reproducible
1+ name : docker -reproducible
22
33on :
44 push :
5+ branches :
6+ - unstable
7+ - stable
58 tags :
69 - v*
7- workflow_dispatch :
8- inputs :
9- dry_run :
10- description : >-
11- Enable dry run mode (builds images but skips push to registry)
12- type : boolean
13- default : false
10+ workflow_dispatch : # allows manual triggering for testing purposes and skips publishing an image
1411
1512env :
1613 DOCKER_REPRODUCIBLE_IMAGE_NAME : >-
2118jobs :
2219 extract-version :
2320 name : extract version
24- runs-on : ubuntu-latest
21+ runs-on : ubuntu-22.04
2522 steps :
2623 - name : Extract version
27- run : >-
28- echo "VERSION=$(echo ${GITHUB_REF#refs/tags/})" >> $GITHUB_OUTPUT
24+ run : |
25+ if [[ "${{ github.ref }}" == refs/tags/* ]]; then
26+ # It's a tag (e.g., v1.2.3)
27+ VERSION="${GITHUB_REF#refs/tags/}"
28+ elif [[ "${{ github.ref }}" == refs/heads/stable ]]; then
29+ # stable branch -> latest
30+ VERSION="latest"
31+ elif [[ "${{ github.ref }}" == refs/heads/unstable ]]; then
32+ # unstable branch -> latest-unstable
33+ VERSION="latest-unstable"
34+ else
35+ # For manual triggers from other branches and will not publish any image
36+ VERSION="test-build"
37+ fi
38+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
2939 id : extract_version
3040 outputs :
3141 VERSION : ${{ steps.extract_version.outputs.VERSION }}
@@ -40,11 +50,11 @@ jobs:
4050 - arch : amd64
4151 rust_target : x86_64-unknown-linux-gnu
4252 platform : linux/amd64
43- runner : ubuntu-latest
53+ runner : ubuntu-22.04
4454 - arch : arm64
4555 rust_target : aarch64-unknown-linux-gnu
4656 platform : linux/arm64
47- runner : ubuntu-24 .04-arm
57+ runner : ubuntu-22 .04-arm
4858 runs-on : ${{ matrix.runner }}
4959 steps :
5060 - uses : actions/checkout@v4
5666
5767 - name : Verify reproducible builds (${{ matrix.arch }})
5868 run : |
59- echo "🔄 Verifying reproducible builds for ${{ matrix.arch }}..."
69+ echo "Verifying reproducible builds for ${{ matrix.arch }}..."
6070
6171 # Build first image
6272 echo "=== Building first verification image ==="
@@ -92,10 +102,10 @@ jobs:
92102 echo "Build 2 SHA256: $(sha256sum lighthouse-2-${{ matrix.arch }})"
93103
94104 if cmp lighthouse-1-${{ matrix.arch }} lighthouse-2-${{ matrix.arch }}; then
95- echo "✅ Reproducible build verified for ${{ matrix.arch }}"
105+ echo "Reproducible build verified for ${{ matrix.arch }}"
96106 else
97- echo "❌ Reproducible build FAILED for ${{ matrix.arch }}"
98- echo "🚨 BLOCKING RELEASE: Builds are not reproducible!"
107+ echo "Reproducible build FAILED for ${{ matrix.arch }}"
108+ echo "BLOCKING RELEASE: Builds are not reproducible!"
99109 echo "First 10 differences:"
100110 cmp -l lighthouse-1-${{ matrix.arch }} lighthouse-2-${{ matrix.arch }} | head -10
101111 exit 1
@@ -110,24 +120,24 @@ jobs:
110120 FINAL_TAG="${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}:${VERSION}-${{ matrix.arch }}"
111121 docker tag lighthouse-verify-2-${{ matrix.arch }} "$FINAL_TAG"
112122
113- echo "✅ Image ready for publishing: $FINAL_TAG"
123+ echo "Image ready for publishing: $FINAL_TAG"
114124
115125 - name : Log in to Docker Hub
116- if : ${{ github.event.inputs.dry_run != 'true ' }}
126+ if : ${{ github.event_name != 'workflow_dispatch ' }}
117127 uses : docker/login-action@v3
118128 with :
119129 username : ${{ env.DOCKER_USERNAME }}
120130 password : ${{ env.DOCKER_PASSWORD }}
121131
122132 - name : Push verified image (${{ matrix.arch }})
123- if : ${{ github.event.inputs.dry_run != 'true ' }}
133+ if : ${{ github.event_name != 'workflow_dispatch ' }}
124134 run : |
125135 VERSION=${{ needs.extract-version.outputs.VERSION }}
126136 IMAGE_TAG="${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}:${VERSION}-${{ matrix.arch }}"
127137
128- echo "📤 Pushing verified reproducible image: $IMAGE_TAG"
138+ echo "Pushing verified reproducible image: $IMAGE_TAG"
129139 docker push "$IMAGE_TAG"
130- echo "✅ Successfully pushed $IMAGE_TAG"
140+ echo "Successfully pushed $IMAGE_TAG"
131141
132142 - name : Clean up local images
133143 run : |
@@ -145,9 +155,9 @@ jobs:
145155
146156 create-manifest :
147157 name : create multi-arch manifest
148- runs-on : ubuntu-latest
158+ runs-on : ubuntu-22.04
149159 needs : [extract-version, verify-and-build]
150- if : ${{ github.event.inputs.dry_run != 'true ' }}
160+ if : ${{ github.event_name != 'workflow_dispatch ' }}
151161 steps :
152162 - name : Log in to Docker Hub
153163 uses : docker/login-action@v3
@@ -160,88 +170,14 @@ jobs:
160170 IMAGE_NAME=${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}
161171 VERSION=${{ needs.extract-version.outputs.VERSION }}
162172
163- echo "🔗 Creating multi-arch manifest for $IMAGE_NAME:$VERSION"
173+ echo "Creating multi-arch manifest for $IMAGE_NAME:$VERSION"
164174
165- # Create manifest for version tag
175+ # Create manifest for the version tag
166176 docker manifest create \
167177 ${IMAGE_NAME}:${VERSION} \
168178 ${IMAGE_NAME}:${VERSION}-amd64 \
169179 ${IMAGE_NAME}:${VERSION}-arm64
170180
171181 docker manifest push ${IMAGE_NAME}:${VERSION}
172182
173- # Create manifest for latest tag
174- docker manifest create \
175- ${IMAGE_NAME}:latest \
176- ${IMAGE_NAME}:${VERSION}-amd64 \
177- ${IMAGE_NAME}:${VERSION}-arm64
178-
179- docker manifest push ${IMAGE_NAME}:latest
180-
181- echo "✅ Multi-arch manifests published:"
182- echo " - ${IMAGE_NAME}:${VERSION}"
183- echo " - ${IMAGE_NAME}:latest"
184-
185- release-summary :
186- name : release summary
187- runs-on : ubuntu-latest
188- needs : [extract-version, verify-and-build, create-manifest]
189- if : always()
190- steps :
191- - name : Report release results
192- run : |
193- VERSION=${{ needs.extract-version.outputs.VERSION }}
194- IMAGE_NAME=${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}
195-
196- echo "## 🚀 Reproducible Release Summary for ${VERSION}"
197- echo ""
198-
199- if [[ "${{ needs.verify-and-build.result }}" == "success" ]]; then
200- echo "✅ **Reproducibility Verification & Build**: SUCCESS"
201- echo "- All architectures produce identical binaries"
202- echo "- Images built and ready for publishing"
203- else
204- echo "❌ **Reproducibility Verification & Build**: FAILED"
205- echo "- Builds are not reproducible OR build failed"
206- echo "- Release was blocked"
207- fi
208-
209- echo ""
210- if [[ "${{ github.event.inputs.dry_run }}" == "true" ]]; then
211- echo "🧪 **Mode**: DRY RUN"
212- echo "- Images were built and verified but NOT pushed"
213- echo "- Ready for real release"
214- elif [[ "${{ needs.create-manifest.result }}" == "success" ]]; then
215- echo "✅ **Publication**: SUCCESS"
216- echo "- Images published to Docker Hub"
217- echo "- Multi-arch manifests created"
218- echo ""
219- echo "### 📦 Published Images"
220- echo "- \`${IMAGE_NAME}:${VERSION}\`"
221- echo "- \`${IMAGE_NAME}:latest\`"
222- echo ""
223- echo "### 🏗️ Architectures"
224- echo "- linux/amd64 (\`${IMAGE_NAME}:${VERSION}-amd64\`)"
225- echo "- linux/arm64 (\`${IMAGE_NAME}:${VERSION}-arm64\`)"
226- else
227- echo "❌ **Publication**: FAILED"
228- echo "- Images were verified but failed to publish"
229- fi
230-
231- echo ""
232- if [[ "${{ needs.verify-and-build.result }}" == "success" ]] && [[ "${{ needs.create-manifest.result }}" == "success" ]] && [[ "${{ github.event.inputs.dry_run }}" != "true" ]]; then
233- echo "🎉 **Overall**: Secure release completed successfully!"
234- echo ""
235- echo "### 🔒 Security Guarantees"
236- echo "- ✅ Reproducible builds verified"
237- echo "- ✅ Identical binaries across architectures"
238- echo "- ✅ No build artifacts tampering"
239- echo "- ✅ Deterministic build process"
240- elif [[ "${{ github.event.inputs.dry_run }}" == "true" ]]; then
241- echo "🧪 **Overall**: Dry run completed successfully!"
242- echo "- Reproducibility verified ✅"
243- echo "- Ready for real release ✅"
244- else
245- echo "🚨 **Overall**: Release failed or incomplete"
246- echo "- Check logs above for details"
247- fi
183+ echo "Published: ${IMAGE_NAME}:${VERSION}"
0 commit comments