Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 63 additions & 12 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ jobs:
permissions:
contents: read
id-token: write
env:
WINDOWS_GORELEASER_DIST: ${{ runner.temp }}/go-win-dist
outputs:
windows_manifest: ${{ steps.generate-windows-manifest.outputs.windows_manifest }}
steps:
Expand Down Expand Up @@ -561,6 +563,8 @@ jobs:
RELEASE_TAG: ${{ inputs.tag }}
run: |
export BUILD_STARTED_ON=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
export WINDOWS_GORELEASER_DIST="${WINDOWS_GORELEASER_DIST//\\//}"
mkdir -p "$WINDOWS_GORELEASER_DIST"

# Generate GoReleaser config
envsubst < templates/.goreleaser-windows-template.yaml.tmpl | tee "_generated/.goreleaser.windows.yaml"
Expand All @@ -579,18 +583,65 @@ jobs:
GITHUB_TOKEN: ${{ secrets.RELENG_GITHUB_TOKEN }}
GORELEASER_KEY: ${{ secrets.GORELEASER_PRO_KEY }}

- name: Flatten MSI directory structure
- name: Stage Windows dist assets
shell: pwsh
env:
REPO_NAME: ${{ github.event.repository.name }}
RELEASE_TAG: ${{ inputs.tag }}
run: |
if (Test-Path "_caller/dist") {
Remove-Item "_caller/dist" -Recurse -Force
}
New-Item -ItemType Directory -Force -Path "_caller/dist"

$zipName = "${env:REPO_NAME}-${env:RELEASE_TAG}-windows-amd64.zip"
$msiName = "${env:REPO_NAME}_${env:RELEASE_TAG}_windows_amd64.msi"
$artifacts = @(
$zipName,
"$zipName.sig",
"$zipName.cert",
$msiName,
"$msiName.sig",
"$msiName.cert"
)

$artifacts | ForEach-Object {
$artifact = $_
$found = Get-ChildItem -Path $env:WINDOWS_GORELEASER_DIST -Recurse -File | Where-Object { $_.Name -eq $artifact }
if ($found.Count -ne 1) {
Write-Error "Expected exactly one Windows dist output named $artifact, found $($found.Count)"
exit 1
}
Write-Host "Copying $artifact to dist root"
Copy-Item $found[0].FullName "_caller/dist/$artifact"
}

- name: Generate Windows dist SBOMs
shell: pwsh
env:
REPO_NAME: ${{ github.event.repository.name }}
RELEASE_TAG: ${{ inputs.tag }}
run: |
# GoReleaser Pro puts MSI files in dist/msi/<name>/ subdirectory
# Copy all files to dist root to match binaries job pattern
$msiDir = "_caller/dist/msi"
if (Test-Path $msiDir) {
Get-ChildItem $msiDir -Recurse -File | ForEach-Object {
Write-Host "Copying $($_.Name) to dist root"
Copy-Item $_.FullName -Destination "_caller/dist/"
$artifacts = @(
"${env:REPO_NAME}-${env:RELEASE_TAG}-windows-amd64.zip",
"${env:REPO_NAME}_${env:RELEASE_TAG}_windows_amd64.msi"
)
Push-Location "_caller/dist"
try {
$artifacts | ForEach-Object {
$artifact = $_
if (!(Test-Path $artifact)) {
Write-Error "Expected Windows dist artifact was not generated: $artifact"
exit 1
}
$sbomPath = "$artifact.sbom.json"
syft "file:$artifact" -o "spdx-json=$sbomPath"
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
}
Write-Host "✅ Flattened MSI directory structure"
} finally {
Pop-Location
}

- name: Generate SLSA provenance for Windows artifacts
Expand All @@ -604,7 +655,7 @@ jobs:
PROVENANCE_COUNT=0

# Find all downloadable archives (zip and msi files)
# MSI files are flattened to dist root by previous step
# MSI files are staged to dist root by the previous step
for artifact in "${CALLER_DIST}"/*.zip "${CALLER_DIST}"/*.msi; do
[ -f "$artifact" ] || continue
[[ "$artifact" == *checksums* ]] && continue
Expand Down Expand Up @@ -639,7 +690,7 @@ jobs:
SIGNED_COUNT=0

# Require every Windows release artifact to have an SPDX SBOM.
# MSI files are flattened to dist root by the previous step.
# MSI files are staged to dist root by the previous step.
for artifact in "${CALLER_DIST}"/*.zip "${CALLER_DIST}"/*.msi; do
[ -f "$artifact" ] || continue
[[ "$artifact" == *checksums* ]] && continue
Expand Down Expand Up @@ -698,7 +749,7 @@ jobs:
--content-type "application/zip"
}

# Upload MSI files (flattened to dist root by earlier step)
# Upload MSI files staged to dist root by the earlier step
$msiFiles = Get-ChildItem "_caller/dist/*.msi" -ErrorAction SilentlyContinue
foreach ($msi in $msiFiles) {
Write-Host "Uploading $($msi.Name) to S3..."
Expand Down
4 changes: 2 additions & 2 deletions cmd/generate-windows-manifest/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func main() {
fmt.Fprintf(os.Stderr, "✅ Added zip asset: windows-amd64 -> %s\n", filename)
}

// Find and process MSI files (flattened to dist root by workflow)
// Find and process MSI files staged to dist root by workflow
msiFiles, err := filepath.Glob(filepath.Join(distDir, "*.msi"))
if err != nil {
fmt.Fprintf(os.Stderr, "generate-windows-manifest: error finding MSI files: %v\n", err)
Expand Down Expand Up @@ -141,7 +141,7 @@ func buildAsset(filePath, filename, mediaType, baseURL, distDir string) (*pb.Ass
sizeBytes := info.Size()
href := fmt.Sprintf("%s/%s", baseURL, filename)

// Check for signature and certificate files (all in dist root after flatten step)
// Check for signature and certificate files (all in dist root after staging)
var signatureHref, certificateHref *string
sigPath := filepath.Join(distDir, filename+".sig")
if _, err := os.Stat(sigPath); err == nil {
Expand Down
10 changes: 1 addition & 9 deletions templates/.goreleaser-windows-template.yaml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
## This runs on Windows runner with Wix Toolset
version: 2
project_name: "${REPO_NAME}"
dist: '${WINDOWS_GORELEASER_DIST}'
builds:
- binary: "${REPO_NAME}"
env:
Expand Down Expand Up @@ -31,15 +32,6 @@ release:
disable: true
checksum:
disable: true
sboms:
- id: sbom-archive
artifacts: archive
ids:
- windows-archive
- id: sbom-msi
artifacts: installer
ids:
- windows-msi
signs:
- id: cosign-archives
output: true
Expand Down