-
Notifications
You must be signed in to change notification settings - Fork 4
91 lines (82 loc) · 3.4 KB
/
Copy pathpromote-release.yml
File metadata and controls
91 lines (82 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
name: Promote Release
on:
workflow_dispatch:
inputs:
tag:
description: 'Release tag to promote (e.g. v1.2.3)'
required: true
type: string
permissions:
contents: write
jobs:
promote:
runs-on: ubuntu-latest
environment:
name: release-promote
env:
PROMOTE_TAG: ${{ inputs.tag }}
GH_REPO: ${{ github.repository }}
steps:
- uses: actions/checkout@v4
- name: Verify prerelease and binary assets
id: verify
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
RELEASE_INFO=$(gh release view "$PROMOTE_TAG" --json body,isPrerelease,tagName)
IS_PRERELEASE=$(echo "$RELEASE_INFO" | jq -r '.isPrerelease')
if [ "$IS_PRERELEASE" != "true" ]; then
echo "::error::Release ${PROMOTE_TAG} is not a prerelease. Nothing to promote."
exit 1
fi
BODY=$(echo "$RELEASE_INFO" | jq -r '.body // ""')
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
# Collect "<asset> <sha256>" pairs recorded in the release body. Newer
# releases record one line per asset:
# Binary asset sha256 (threat-detect-linux-amd64): sha256:<hash>
# Legacy releases record a single amd64-only line:
# Binary asset sha256: sha256:<hash>
pairs_file="$tmp/pairs.txt"
: > "$pairs_file"
while IFS= read -r line; do
case "$line" in
"Binary asset sha256 ("*"): sha256:"*)
asset="${line#Binary asset sha256 (}"
asset="${asset%%): sha256:*}"
sha="${line##*): sha256:}"
echo "${asset} ${sha}" >> "$pairs_file"
;;
"Binary asset sha256: sha256:"*)
sha="${line#Binary asset sha256: sha256:}"
echo "threat-detect-linux-amd64 ${sha}" >> "$pairs_file"
;;
esac
done < <(printf '%s\n' "$BODY")
if [ ! -s "$pairs_file" ]; then
echo "::error::Release ${PROMOTE_TAG} does not record any binary asset sha256. Nothing to promote."
exit 1
fi
# Download each recorded asset and confirm it matches the recorded digest,
# so promotion can never mark a tampered or missing binary as Latest.
while read -r asset sha; do
if ! echo "$sha" | grep -Eq '^[0-9a-f]{64}$'; then
echo "::error::Release ${PROMOTE_TAG} records ${asset} with an invalid sha256 format. Nothing to promote."
exit 1
fi
gh release download "$PROMOTE_TAG" --pattern "$asset" --dir "$tmp"
actual="$(sha256sum "$tmp/$asset" | awk '{print $1}')"
if [ "$actual" != "$sha" ]; then
echo "::error::Release ${PROMOTE_TAG} asset ${asset} sha256 ${actual} does not match recorded ${sha}. Nothing to promote."
exit 1
fi
echo "✅ Verified ${asset} sha256:${sha}"
done < "$pairs_file"
echo "✅ ${PROMOTE_TAG} is a prerelease with all recorded binary assets verified — proceeding with promotion."
- name: Promote release to stable
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release edit "$PROMOTE_TAG" --prerelease=false --latest
echo "✅ Release ${PROMOTE_TAG} promoted to stable and marked as Latest."