返回 CodeWhale
generate-winget-manifest.sh
根目录 / packaging / winget / generate-winget-manifest.sh
1 #!/usr/bin/env bash
2 set -euo pipefail
3 # Regenerate Hmbown.CodeWhale winget manifests for a given release version.
4 # Usage: ./packaging/winget/generate-winget-manifest.sh X.Y.Z [release-assets-dir]
5 # X.Y.Z — version without leading v (e.g. 0.9.5)
6 # release-assets-dir — directory containing codewhale-artifacts-sha256.txt and the four
7 # Windows assets (defaults to ./release-assets if present).
8 # The script rewrites both packaging/winget/Hmbown.CodeWhale.yaml and .winget/Hmbown.CodeWhale.yaml.
9
10 if [[ $# -lt 1 || $# -gt 2 ]]; then
11 echo "usage: $0 X.Y.Z [release-assets-dir]" >&2
12 exit 2
13 fi
14
15 version="$1"
16 assets_dir="${2:-release-assets}"
17
18 if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
19 echo "version must be X.Y.Z without leading v, got: $version" >&2
20 exit 2
21 fi
22
23 if [[ ! -f "$assets_dir/codewhale-artifacts-sha256.txt" ]]; then
24 echo "release assets dir must contain codewhale-artifacts-sha256.txt: $assets_dir" >&2
25 exit 1
26 fi
27
28 require_sha() {
29 local name="$1"
30 local sha
31 sha="$(grep -E " ${name}\$" "$assets_dir/codewhale-artifacts-sha256.txt" | awk '{print $1}' || true)"
32 if [[ -z "$sha" ]]; then
33 echo "SHA not found for $name in $assets_dir/codewhale-artifacts-sha256.txt" >&2
34 exit 1
35 fi
36 if [[ ! "$sha" =~ ^[0-9a-fA-F]{64}$ ]]; then
37 echo "invalid SHA for $name: $sha" >&2
38 exit 1
39 fi
40 printf '%s' "$sha" | tr 'A-F' 'a-f'
41 }
42
43 installer_sha="$(require_sha "CodeWhaleSetup.exe")"
44 x64_sha="$(require_sha "codewhale-windows-x64.zip")"
45 x64_portable_sha="$(require_sha "codewhale-windows-x64-portable.zip")"
46 arm64_sha="$(require_sha "codewhale-windows-arm64.zip")"
47 arm64_portable_sha="$(require_sha "codewhale-windows-arm64-portable.zip")"
48 today="$(date -u +%Y-%m-%d)"
49
50 repo_root="$(cd "$(dirname "$0")/../.." && pwd)"
51 winget_primary="$repo_root/packaging/winget/Hmbown.CodeWhale.yaml"
52 winget_mirror="$repo_root/.winget/Hmbown.CodeWhale.yaml"
53
54 bump_manifest() {
55 local file="$1"
56 if [[ ! -f "$file" ]]; then
57 echo "manifest not found: $file" >&2
58 exit 1
59 fi
60 # PackageVersion + ReleaseNotes
61 sed -i.bak -E "s/^PackageVersion:.*/PackageVersion: ${version}/" "$file"
62 sed -i.bak -E "s|ReleaseNotes:.*|ReleaseNotes: https://github.com/Hmbown/CodeWhale/releases/tag/v${version}|" "$file"
63 sed -i.bak -E "s|ReleaseNotesUrl:.*|ReleaseNotesUrl: https://github.com/Hmbown/CodeWhale/releases/tag/v${version}|" "$file"
64 # Installer URLs (all five)
65 sed -i.bak -E "s|https://github.com/Hmbown/CodeWhale/releases/download/v[0-9.]+/CodeWhaleSetup.exe|https://github.com/Hmbown/CodeWhale/releases/download/v${version}/CodeWhaleSetup.exe|g" "$file"
66 sed -i.bak -E "s|https://github.com/Hmbown/CodeWhale/releases/download/v[0-9.]+/codewhale-windows-x64\.zip|https://github.com/Hmbown/CodeWhale/releases/download/v${version}/codewhale-windows-x64.zip|g" "$file"
67 sed -i.bak -E "s|https://github.com/Hmbown/CodeWhale/releases/download/v[0-9.]+/codewhale-windows-x64-portable\.zip|https://github.com/Hmbown/CodeWhale/releases/download/v${version}/codewhale-windows-x64-portable.zip|g" "$file"
68 sed -i.bak -E "s|https://github.com/Hmbown/CodeWhale/releases/download/v[0-9.]+/codewhale-windows-arm64\.zip|https://github.com/Hmbown/CodeWhale/releases/download/v${version}/codewhale-windows-arm64.zip|g" "$file"
69 sed -i.bak -E "s|https://github.com/Hmbown/CodeWhale/releases/download/v[0-9.]+/codewhale-windows-arm64-portable\.zip|https://github.com/Hmbown/CodeWhale/releases/download/v${version}/codewhale-windows-arm64-portable.zip|g" "$file"
70 sed -i.bak -E "s/^ ReleaseDate:.*/ ReleaseDate: ${today}/g" "$file"
71 rm -f "$file.bak"
72
73 # Patch SHAs in order of appearance: CodeWhaleSetup.exe, x64 zip, x64 portable, arm64 zip, arm64 portable.
74 # Use awk for ordered replacement to avoid sed ambiguity with identical sha lengths.
75 local tmp
76 tmp="$(mktemp)"
77 awk -v a="$installer_sha" -v b="$x64_sha" -v c="$x64_portable_sha" -v d="$arm64_sha" -v e="$arm64_portable_sha" '
78 BEGIN { n=0 }
79 /InstallerSha256:/ {
80 n++
81 if (n==1) sub(/InstallerSha256:.*/, "InstallerSha256: " a)
82 else if (n==2) sub(/InstallerSha256:.*/, "InstallerSha256: " b)
83 else if (n==3) sub(/InstallerSha256:.*/, "InstallerSha256: " c)
84 else if (n==4) sub(/InstallerSha256:.*/, "InstallerSha256: " d)
85 else if (n==5) sub(/InstallerSha256:.*/, "InstallerSha256: " e)
86 }
87 { print }
88 ' "$file" > "$tmp"
89 mv "$tmp" "$file"
90 }
91
92 bump_manifest "$winget_primary"
93 # The README promises a verbatim structural mirror. Generate the canonical
94 # manifest once, then copy those exact bytes so comments and optional fields
95 # cannot drift while versions and hashes still look current.
96 cp "$winget_primary" "$winget_mirror"
97
98 echo "winget manifests bumped to v$version ($today)"
99 echo " CodeWhaleSetup.exe: $installer_sha"
100 echo " codewhale-windows-x64.zip: $x64_sha"
101 echo " codewhale-windows-x64-portable.zip: $x64_portable_sha"
102 echo " codewhale-windows-arm64.zip: $arm64_sha"
103 echo " codewhale-windows-arm64-portable.zip: $arm64_portable_sha"
104 echo "Validate: winget validate --manifest $winget_primary"
105
105 lines BASH