Refactor CI and release workflows for improved caching and versioning #62
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - 'v*.*.*' | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| GO_VERSION: '1.25.1' | |
| jobs: | |
| build-image: | |
| name: Build and Push Image | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| outputs: | |
| digest: ${{ steps.build.outputs.digest }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| version: ${{ steps.version.outputs.version }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Cache Go modules | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/go/pkg/mod | |
| ~/.cache/go-build | |
| key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} | |
| restore-keys: | | |
| ${{ runner.os }}-go- | |
| - name: Extract version | |
| id: version | |
| run: | | |
| if [[ "${{ github.ref_type }}" == "tag" ]]; then | |
| VERSION="${{ github.ref_name }}" | |
| VERSION="${VERSION#v}" | |
| else | |
| VERSION="0.0.0-dev" | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "Version: $VERSION" | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to GHCR | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=branch | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| type=sha,prefix=sha-,enable={{is_default_branch}} | |
| - name: Build and push Docker image | |
| id: build | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| platforms: ${{ github.ref_type == 'tag' && 'linux/amd64,linux/arm64' || 'linux/amd64' }} | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| provenance: false | |
| sbom: false | |
| build-args: | | |
| GO_VERSION=${{ env.GO_VERSION }} | |
| - name: Verify build success | |
| run: | | |
| if [[ -z "${{ steps.build.outputs.digest }}" ]]; then | |
| echo "❌ Docker build failed - no digest generated" | |
| exit 1 | |
| fi | |
| echo "✅ Docker build successful with digest: ${{ steps.build.outputs.digest }}" | |
| - name: Install cosign | |
| uses: sigstore/[email protected] | |
| - name: Sign container image | |
| env: | |
| DIGEST: ${{ steps.build.outputs.digest }} | |
| TAGS: ${{ steps.meta.outputs.tags }} | |
| run: | | |
| echo "$TAGS" | while IFS= read -r tag; do | |
| if [[ -n "$tag" ]]; then | |
| echo "Signing: $tag@${DIGEST}" | |
| cosign sign --yes "$tag@${DIGEST}" || echo "::warning::Failed to sign image $tag" | |
| fi | |
| done | |
| release-helm: | |
| name: Release Helm Chart | |
| runs-on: ubuntu-latest | |
| needs: build-image | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Helm | |
| uses: azure/setup-helm@v4 | |
| with: | |
| version: v3.17.0 | |
| - name: Log in to GHCR for Helm | |
| run: | | |
| echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ${{ env.REGISTRY }} --username ${{ github.actor }} --password-stdin | |
| - name: Update Helm chart with image digest | |
| if: github.ref_type == 'tag' | |
| run: | | |
| DIGEST="${{ needs.build-image.outputs.digest }}" | |
| VERSION="${{ needs.build-image.outputs.version }}" | |
| # Update values.yaml with digest | |
| sed -i "s|tag:.*|digest: \"$DIGEST\"|g" charts/homer-operator/values.yaml | |
| # Update Chart.yaml version | |
| sed -i "s|^version:.*|version: $VERSION|g" charts/homer-operator/Chart.yaml | |
| sed -i "s|^appVersion:.*|appVersion: $VERSION|g" charts/homer-operator/Chart.yaml | |
| - name: Package and push Helm chart | |
| run: | | |
| VERSION="${{ needs.build-image.outputs.version }}" | |
| # Package chart | |
| helm package charts/homer-operator --version "$VERSION" | |
| # Push to GHCR | |
| helm push homer-operator-${VERSION}.tgz oci://${{ env.REGISTRY }}/${{ github.repository }}/charts | |
| create-github-release: | |
| name: Create GitHub Release | |
| runs-on: ubuntu-latest | |
| if: github.ref_type == 'tag' | |
| needs: [build-image, release-helm] | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Generate release notes | |
| id: notes | |
| run: | | |
| VERSION="${{ needs.build-image.outputs.version }}" | |
| DIGEST="${{ needs.build-image.outputs.digest }}" | |
| cat > release-notes.md <<EOF | |
| ## Homer Operator $VERSION | |
| ### Container Image | |
| \`\`\` | |
| ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$VERSION | |
| ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@$DIGEST | |
| \`\`\` | |
| ### Helm Chart | |
| \`\`\`bash | |
| helm install homer-operator oci://${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/charts/homer-operator --version $VERSION | |
| \`\`\` | |
| ### Verification | |
| \`\`\`bash | |
| # Verify image signature | |
| cosign verify ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@$DIGEST | |
| \`\`\` | |
| EOF | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| body_path: release-notes.md | |
| draft: false | |
| prerelease: false | |
| generate_release_notes: true |