|
11 | 11 | GO_VERSION: '1.26' |
12 | 12 |
|
13 | 13 | jobs: |
14 | | - # ── Quality gates (run on every push and PR) ─────────────────────────────── |
15 | | - |
16 | 14 | lint: |
17 | 15 | name: Lint |
18 | 16 | runs-on: ubuntu-latest |
@@ -79,114 +77,123 @@ jobs: |
79 | 77 | go install golang.org/x/vuln/cmd/govulncheck@latest |
80 | 78 | govulncheck ./... |
81 | 79 |
|
82 | | - # ── Release (v* tags only) ───────────────────────────────────────────────── |
83 | | - # |
84 | | - # Responsibilities are split between GoReleaser and a post-release step: |
85 | | - # |
86 | | - # GoReleaser: |
87 | | - # - Cross-compiles all 5 platform binaries (linux/amd64, linux/arm64, |
88 | | - # darwin/amd64, darwin/arm64, windows/amd64) |
89 | | - # - Packages each binary into a helm-oci-<os>-<arch>.tgz archive whose |
90 | | - # directory layout (helm-oci/bin/, helm-oci/plugin.yaml, …) is exactly |
91 | | - # what install-binary.sh expects |
92 | | - # - Generates a sha256 checksum file |
93 | | - # - GPG-signs the checksum file (--detach-sign --armor → .asc) |
94 | | - # - Creates the GitHub Release and uploads all artifacts |
95 | | - # |
96 | | - # Post-GoReleaser step: |
97 | | - # - Uses `helm plugin package` to produce a Helm provenance file (.prov) |
98 | | - # so users can run `helm verify` against the plugin package |
99 | | - # - Exports the public signing key as helm-oci-signing-key.asc |
100 | | - # - Uploads both files to the release created by GoReleaser |
101 | | - |
102 | | - release: |
103 | | - name: Release |
| 80 | + build: |
| 81 | + name: Build (${{ matrix.os }}_${{ matrix.arch }}) |
104 | 82 | runs-on: ubuntu-latest |
105 | | - needs: [lint, test, security-scan] |
106 | | - if: startsWith(github.ref, 'refs/tags/v') |
107 | | - permissions: |
108 | | - contents: write # create GitHub releases and upload assets |
109 | | - |
| 83 | + needs: [lint, security-scan, test] |
| 84 | + strategy: |
| 85 | + matrix: |
| 86 | + include: |
| 87 | + - os: linux |
| 88 | + arch: amd64 |
| 89 | + - os: linux |
| 90 | + arch: arm64 |
| 91 | + - os: darwin |
| 92 | + arch: amd64 |
| 93 | + - os: darwin |
| 94 | + arch: arm64 |
| 95 | + - os: windows |
| 96 | + arch: amd64 |
110 | 97 | steps: |
111 | 98 | - name: Checkout code |
112 | 99 | uses: actions/checkout@v4 |
113 | | - with: |
114 | | - fetch-depth: 0 # GoReleaser needs full history for changelog |
115 | 100 |
|
116 | 101 | - name: Set up Go |
117 | 102 | uses: actions/setup-go@v5 |
118 | 103 | with: |
119 | 104 | go-version: ${{ env.GO_VERSION }} |
120 | 105 |
|
121 | | - # Import the GPG key before GoReleaser runs so the `signs:` block can |
122 | | - # invoke gpg with the key already present in the agent's keyring. |
123 | | - - name: Import GPG key |
| 106 | + - name: Build binary |
124 | 107 | env: |
125 | | - GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} |
126 | | - GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} |
| 108 | + GOOS: ${{ matrix.os }} |
| 109 | + GOARCH: ${{ matrix.arch }} |
| 110 | + CGO_ENABLED: '0' |
127 | 111 | run: | |
128 | | - echo "$GPG_PRIVATE_KEY" | gpg --batch --import |
129 | | - # Export the secret key to a temporary keyring so helm can use it |
130 | | - # in the plugin-package step below (helm requires a legacy keyring). |
131 | | - gpg --batch --pinentry-mode loopback \ |
132 | | - --passphrase "$GPG_PASSPHRASE" \ |
133 | | - --export-secret-keys "${{ secrets.GPG_KEY_ID }}" \ |
134 | | - > /tmp/secring.gpg |
135 | | -
|
136 | | - - name: Run GoReleaser |
137 | | - uses: goreleaser/goreleaser-action@v6 |
138 | | - with: |
139 | | - distribution: goreleaser |
140 | | - version: "~> v2" |
141 | | - args: release --clean |
| 112 | + EXT="" |
| 113 | + if [ "$GOOS" = "windows" ]; then EXT=".exe"; fi |
| 114 | + mkdir -p dist |
| 115 | + go build -trimpath -ldflags="-X main.version=$(sed -n 's/version:.*"\(.*\)"/\1/p' plugin.yaml)" \ |
| 116 | + -o "dist/helm-oci${EXT}" . |
| 117 | +
|
| 118 | + - name: Package archive |
142 | 119 | env: |
143 | | - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
144 | | - GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} |
145 | | - GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} |
| 120 | + MATRIX_OS: ${{ matrix.os }} |
| 121 | + MATRIX_ARCH: ${{ matrix.arch }} |
| 122 | + run: | |
| 123 | + mkdir -p release/helm-oci/bin |
| 124 | + cp plugin.yaml install-binary.sh release/helm-oci/ |
| 125 | + EXT="" |
| 126 | + if [ "$MATRIX_OS" = "windows" ]; then EXT=".exe"; fi |
| 127 | + cp "dist/helm-oci${EXT}" release/helm-oci/bin/ |
| 128 | + tar -C release -zcvf "helm-oci-${MATRIX_OS}-${MATRIX_ARCH}.tgz" helm-oci/ |
| 129 | +
|
| 130 | + - name: Upload artifact |
| 131 | + uses: actions/upload-artifact@v4 |
| 132 | + with: |
| 133 | + name: helm-oci-${{ matrix.os }}-${{ matrix.arch }} |
| 134 | + path: helm-oci-${{ matrix.os }}-${{ matrix.arch }}.tgz |
| 135 | + |
| 136 | + release: |
| 137 | + name: Release |
| 138 | + runs-on: ubuntu-latest |
| 139 | + needs: [build] |
| 140 | + if: startsWith(github.ref, 'refs/tags/v') |
| 141 | + permissions: |
| 142 | + contents: write |
| 143 | + steps: |
| 144 | + - name: Checkout code |
| 145 | + uses: actions/checkout@v4 |
| 146 | + |
| 147 | + - name: Download all build artifacts |
| 148 | + uses: actions/download-artifact@v4 |
| 149 | + with: |
| 150 | + path: dist |
| 151 | + pattern: helm-oci-* |
| 152 | + merge-multiple: true |
146 | 153 |
|
147 | | - # Produce the Helm plugin provenance file so users can run: |
148 | | - # helm verify helm-oci-<version>.tgz |
149 | | - # This step uses the same GPG key that GoReleaser used for the checksum |
150 | | - # signature above, so a single key covers all release artifacts. |
151 | 154 | - name: Install Helm |
152 | 155 | uses: azure/setup-helm@v4 |
153 | 156 | with: |
154 | 157 | version: 'latest' |
155 | 158 |
|
156 | | - - name: Build Helm plugin provenance (.prov) |
| 159 | + - name: Package and sign plugin |
157 | 160 | env: |
| 161 | + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} |
158 | 162 | GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} |
159 | 163 | GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} |
160 | | - TAG: ${{ github.ref_name }} |
161 | 164 | run: | |
162 | | - # Assemble a minimal plugin source directory that `helm plugin package` |
163 | | - # understands (it only needs plugin.yaml and install-binary.sh). |
164 | | - mkdir -p staging/helm-oci |
165 | | - cp plugin.yaml install-binary.sh staging/helm-oci/ |
| 165 | + echo "$GPG_PRIVATE_KEY" | gpg --batch --import |
| 166 | + gpg --batch --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" \ |
| 167 | + --export-secret-keys "$GPG_KEY_ID" > /tmp/secring.gpg |
| 168 | +
|
| 169 | + mkdir -p staging/oci |
| 170 | + cp plugin.yaml install-binary.sh staging/oci/ |
166 | 171 |
|
167 | 172 | echo "$GPG_PASSPHRASE" | helm plugin package \ |
168 | | - staging/helm-oci/ \ |
| 173 | + staging/oci/ \ |
169 | 174 | --destination dist/ \ |
170 | 175 | --key "$GPG_KEY_ID" \ |
171 | 176 | --keyring /tmp/secring.gpg \ |
172 | 177 | --passphrase-file - |
173 | 178 |
|
174 | | - # Export the public key so release consumers can import it easily. |
175 | | - gpg --batch --yes --armor \ |
176 | | - --export "$GPG_KEY_ID" \ |
177 | | - > dist/helm-oci-signing-key.asc |
| 179 | + gpg --batch --yes --armor --export "$GPG_KEY_ID" > dist/helm-oci-signing-key.asc |
178 | 180 |
|
179 | | - # Scrub the secret keyring from disk. |
180 | 181 | rm -f /tmp/secring.gpg |
181 | 182 |
|
182 | | - # Attach the provenance file and public key to the GitHub Release that |
183 | | - # GoReleaser already created in the previous step. |
184 | | - - name: Upload Helm provenance to release |
| 183 | + - name: Get version |
| 184 | + id: version |
| 185 | + run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT |
| 186 | + |
| 187 | + - name: Create release |
185 | 188 | env: |
186 | 189 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
187 | | - TAG: ${{ github.ref_name }} |
| 190 | + TAG: ${{ steps.version.outputs.VERSION }} |
188 | 191 | run: | |
189 | | - gh release upload "$TAG" \ |
190 | | - dist/helm-oci-*.tgz.prov \ |
191 | | - dist/helm-oci-signing-key.asc \ |
192 | | - --clobber |
| 192 | + TITLE=$(git tag -l --format='%(contents:subject)' "$TAG") |
| 193 | + gh release create "$TAG" \ |
| 194 | + --title "${TITLE:-Release $TAG}" \ |
| 195 | + --generate-notes \ |
| 196 | + dist/helm-oci-*.tgz \ |
| 197 | + dist/oci-*.tgz \ |
| 198 | + dist/oci-*.tgz.prov \ |
| 199 | + dist/helm-oci-signing-key.asc |
0 commit comments