|
1 | 1 | #!/usr/bin/env bash |
2 | 2 | set -euo pipefail |
3 | | - |
4 | | -ROOT=$(cd "$(dirname "$0")/.." && pwd) |
5 | | -ZIP=${1:? |
6 | | -"Usage: $0 CodexBar-macos-<arch>-<ver>.zip"} |
7 | | -FEED_URL=${2:-"https://raw.githubusercontent.com/steipete/CodexBar/main/appcast.xml"} |
8 | | -PRIVATE_KEY_FILE=${SPARKLE_PRIVATE_KEY_FILE:-} |
9 | | -SPARKLE_CHANNEL=${SPARKLE_CHANNEL:-} |
10 | | -if [[ -z "$PRIVATE_KEY_FILE" ]]; then |
11 | | - echo "Set SPARKLE_PRIVATE_KEY_FILE to your ed25519 private key (Sparkle)." >&2 |
12 | | - exit 1 |
13 | | -fi |
14 | | -if [[ ! -f "$ZIP" ]]; then |
15 | | - echo "Zip not found: $ZIP" >&2 |
16 | | - exit 1 |
17 | | -fi |
18 | | - |
19 | | -ZIP_DIR=$(cd "$(dirname "$ZIP")" && pwd) |
20 | | -ZIP_NAME=$(basename "$ZIP") |
21 | | -ZIP_BASE="${ZIP_NAME%.zip}" |
22 | | -VERSION=${SPARKLE_RELEASE_VERSION:-} |
23 | | -if [[ -z "$VERSION" ]]; then |
24 | | - if [[ "$ZIP_NAME" =~ ^CodexBar-(macos-[A-Za-z0-9_+-]+-)?([0-9]+(\.[0-9]+){1,2}([-.][^.]*)?)\.zip$ ]]; then |
25 | | - VERSION="${BASH_REMATCH[2]}" |
26 | | - else |
27 | | - echo "Could not infer version from $ZIP_NAME; set SPARKLE_RELEASE_VERSION." >&2 |
28 | | - exit 1 |
29 | | - fi |
30 | | -fi |
31 | | - |
32 | | -NOTES_HTML="${ZIP_DIR}/${ZIP_BASE}.html" |
33 | | -KEEP_NOTES=${KEEP_SPARKLE_NOTES:-0} |
34 | | -if [[ -x "$ROOT/Scripts/changelog-to-html.sh" ]]; then |
35 | | - "$ROOT/Scripts/changelog-to-html.sh" "$VERSION" >"$NOTES_HTML" |
36 | | -else |
37 | | - echo "Missing Scripts/changelog-to-html.sh; cannot generate HTML release notes." >&2 |
38 | | - exit 1 |
39 | | -fi |
40 | | -cleanup() { |
41 | | - if [[ -n "${WORK_DIR:-}" ]]; then |
42 | | - rm -rf "$WORK_DIR" |
43 | | - fi |
44 | | - if [[ "$KEEP_NOTES" != "1" ]]; then |
45 | | - rm -f "$NOTES_HTML" |
46 | | - fi |
47 | | -} |
48 | | -trap cleanup EXIT |
49 | | - |
50 | | -DOWNLOAD_URL_PREFIX=${SPARKLE_DOWNLOAD_URL_PREFIX:-"https://github.com/steipete/CodexBar/releases/download/v${VERSION}/"} |
51 | | - |
52 | | -# Sparkle provides generate_appcast; ensure it's on PATH (via SwiftPM build of Sparkle's bin) or Xcode dmg |
53 | | -if ! command -v generate_appcast >/dev/null; then |
54 | | - echo "generate_appcast not found in PATH. Install Sparkle tools (see Sparkle docs)." >&2 |
55 | | - exit 1 |
56 | | -fi |
57 | | - |
58 | | -WORK_DIR=$(mktemp -d /tmp/codexbar-appcast.XXXXXX) |
59 | | - |
60 | | -cp "$ROOT/appcast.xml" "$WORK_DIR/appcast.xml" |
61 | | -cp "$ZIP" "$WORK_DIR/$ZIP_NAME" |
62 | | -cp "$NOTES_HTML" "$WORK_DIR/$ZIP_BASE.html" |
63 | | - |
64 | | -pushd "$WORK_DIR" >/dev/null |
65 | | -generate_appcast \ |
66 | | - --ed-key-file "$PRIVATE_KEY_FILE" \ |
67 | | - --download-url-prefix "$DOWNLOAD_URL_PREFIX" \ |
68 | | - --embed-release-notes \ |
69 | | - --link "$FEED_URL" \ |
70 | | - "$WORK_DIR" |
71 | | -popd >/dev/null |
72 | | - |
73 | | -if [[ -n "$SPARKLE_CHANNEL" ]]; then |
74 | | - python3 - "$WORK_DIR/appcast.xml" "$VERSION" "$SPARKLE_CHANNEL" <<'PY' |
75 | | -import re |
76 | | -import sys |
77 | | -
|
78 | | -path, version, channel = sys.argv[1], sys.argv[2], sys.argv[3] |
79 | | -with open(path, "r", encoding="utf-8") as handle: |
80 | | - lines = handle.read().splitlines() |
81 | | -
|
82 | | -target = f"<sparkle:shortVersionString>{version}</sparkle:shortVersionString>" |
83 | | -try: |
84 | | - index = next(i for i, line in enumerate(lines) if target in line) |
85 | | -except StopIteration as exc: |
86 | | - raise SystemExit(f"Could not find {target} in {path}") from exc |
87 | | -
|
88 | | -for j in range(index, -1, -1): |
89 | | - if "<item" in lines[j]: |
90 | | - line = lines[j] |
91 | | - if "sparkle:channel" in line: |
92 | | - line = re.sub(r'sparkle:channel="[^"]*"', f'sparkle:channel="{channel}"', line) |
93 | | - else: |
94 | | - line = line.replace("<item", f'<item sparkle:channel="{channel}"', 1) |
95 | | - lines[j] = line |
96 | | - break |
97 | | -else: |
98 | | - raise SystemExit(f"Could not find <item> for version {version} in {path}") |
99 | | -
|
100 | | -with open(path, "w", encoding="utf-8") as handle: |
101 | | - handle.write("\n".join(lines) + "\n") |
102 | | -PY |
103 | | - echo "Tagged ${VERSION} with sparkle:channel=\"${SPARKLE_CHANNEL}\"" |
104 | | -fi |
105 | | - |
106 | | -cp "$WORK_DIR/appcast.xml" "$ROOT/appcast.xml" |
107 | | - |
108 | | -echo "Appcast generated (appcast.xml). Upload alongside $ZIP at $FEED_URL" |
| 3 | +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) |
| 4 | +exec "$SCRIPT_DIR/mac-release" make-appcast "$@" |
0 commit comments