Skip to content

Commit a4b819f

Browse files
committed
fix(ci): Fix development build appcast updates
**Problem:** - nightly-dev.yml workflow created dev releases but never updated appcast-dev.xml - appcast-dev.xml had stale/placeholder entries with no signatures - SAM users with dev updates enabled couldn't detect new dev builds - Workflow didn't commit appcast changes back to repo **Solution:** 1. Created update_dev_appcast.sh script - Signs dev release ZIP files with Sparkle EdDSA key - Updates appcast-dev-items.xml with proper signature - Includes sparkle:channel="development" tag 2. Updated nightly-dev.yml workflow - Added appcast update step (mirrors release.yml pattern) - Commits appcast-dev-items.xml and appcast-dev.xml back to repo - Uses SPARKLE_PRIVATE_KEY secret for signing 3. Enhanced generate-dev-appcast.sh - Properly skips XML comments when extracting items - Handles empty dev items gracefully - Validates generated XML with xmllint 4. Cleaned appcast-dev-items.xml - Removed placeholder example from active content - Ready for workflow to populate with real releases **T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**T**h works correctly ✅ XML: appcast-dev.xml validates successfully ✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅w ✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅âse ✅✅â� appca✅✅â� appca✅✅â� appca✅✅â� ata✅✅â� appca✅✅â� appca✅✅â� appca✅✅â� atabuilds
1 parent 313094b commit a4b819f

5 files changed

Lines changed: 221 additions & 33 deletions

File tree

.github/workflows/nightly-dev.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,36 @@ jobs:
110110
echo "Distribution files ready:"
111111
ls -lh dist/SAM-${DEV_VERSION}.*
112112
113+
- name: Update development appcast
114+
env:
115+
SPARKLE_PRIVATE_KEY: ${{ secrets.SPARKLE_PRIVATE_KEY }}
116+
run: |
117+
# Create temporary file for private key
118+
TEMP_KEY_FILE=$(mktemp)
119+
echo "$SPARKLE_PRIVATE_KEY" > "$TEMP_KEY_FILE"
120+
chmod 600 "$TEMP_KEY_FILE"
121+
122+
# Update appcast-dev-items.xml with new development release
123+
./scripts/update_dev_appcast.sh "${DEV_VERSION}" "dist/SAM-${DEV_VERSION}.zip" "$TEMP_KEY_FILE"
124+
125+
# Generate appcast-dev.xml from items + stable releases
126+
./scripts/generate-dev-appcast.sh
127+
128+
# Clean up temporary key file
129+
rm -f "$TEMP_KEY_FILE"
130+
131+
- name: Commit and push appcast changes
132+
run: |
133+
git config user.name "GitHub Actions"
134+
git config user.email "actions@github.com"
135+
git add appcast-dev-items.xml appcast-dev.xml
136+
if git diff --staged --quiet; then
137+
echo "No changes to development appcast files"
138+
else
139+
git commit -m "chore(dev-release): update appcast-dev.xml for v${DEV_VERSION}"
140+
git push origin HEAD:main
141+
fi
142+
113143
- name: Create GitHub pre-release
114144
uses: softprops/action-gh-release@v1
115145
with:

appcast-dev-items.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,3 @@
3535
-->
3636

3737
<!-- Development items will be added below this line -->
38-
39-

appcast-dev.xml

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,48 @@
77
<language>en</language>
88

99
<!-- Development releases (from appcast-dev-items.xml) -->
10-
<item>
11-
<title>SAM 20260112.1-dev.1</title>
12-
<description><![CDATA[
13-
<h2>SAM 20260112.1-dev.1 (Pre-Release)</h2>
14-
<p><strong>⚠️ This is a DEVELOPMENT release for testing purposes.</strong></p>
15-
<h3>What's New:</h3>
16-
<ul>
17-
<li>Feature description here</li>
18-
</ul>
19-
<h3>Known Issues:</h3>
20-
<ul>
21-
<li>Issue description here</li>
22-
</ul>
23-
]]></description>
24-
<pubDate>Sun, 12 Jan 2026 14:00:00 +0000</pubDate>
25-
<sparkle:releaseNotesLink>https://github.com/SyntheticAutonomicMind/SAM/releases/tag/20260112.1-dev.1</sparkle:releaseNotesLink>
26-
<sparkle:channel>development</sparkle:channel>
27-
<enclosure
28-
url="https://github.com/SyntheticAutonomicMind/SAM/releases/download/20260112.1-dev.1/SAM-20260112.1-dev.1.zip"
29-
sparkle:version="20260112.1-dev.1"
30-
sparkle:shortVersionString="20260112.1-dev.1"
31-
sparkle:edSignature="[SIGNATURE_HERE]"
32-
length="[FILE_SIZE]"
33-
type="application/octet-stream"
34-
/>
35-
<sparkle:minimumSystemVersion>14.0</sparkle:minimumSystemVersion>
36-
</item>
3710

3811
<!-- Stable releases (fallback from appcast.xml) -->
12+
<item>
13+
<title>SAM 20260110.1</title>
14+
<description><![CDATA[
15+
<h2>What's New in SAM 20260110.1</h2>
16+
<ul>
17+
<li>See <a href="https://github.com/SyntheticAutonomicMind/SAM/releases/tag/20260110.1">GitHub Releases</a> for details</li>
18+
</ul>
19+
]]></description>
20+
<pubDate>Sat, 10 Jan 2026 14:51:02 +0000</pubDate>
21+
<sparkle:releaseNotesLink>https://github.com/SyntheticAutonomicMind/SAM/releases/tag/20260110.1</sparkle:releaseNotesLink>
22+
<enclosure
23+
url="https://github.com/SyntheticAutonomicMind/SAM/releases/download/20260110.1/SAM-20260110.1.zip"
24+
sparkle:version="20260110.1"
25+
sparkle:shortVersionString="20260110.1"
26+
sparkle:edSignature="2qKyPt5QTDUItvckBOrwQ/l/WMZoVHi2xjYLgxXDBTGi9fZkZhSagOo2mkmNvGwV3Oq55juDFeOhFu0nhFC+DA=="
27+
length="770923496"
28+
type="application/octet-stream"
29+
/>
30+
<sparkle:minimumSystemVersion>14.0</sparkle:minimumSystemVersion>
31+
</item>
32+
<item>
33+
<title>SAM 20260108.1</title>
34+
<description><![CDATA[
35+
<h2>What's New in SAM 20260108.1</h2>
36+
<ul>
37+
<li>See <a href="https://github.com/SyntheticAutonomicMind/SAM/releases/tag/20260108.1">GitHub Releases</a> for details</li>
38+
</ul>
39+
]]></description>
40+
<pubDate>Thu, 08 Jan 2026 23:47:03 +0000</pubDate>
41+
<sparkle:releaseNotesLink>https://github.com/SyntheticAutonomicMind/SAM/releases/tag/20260108.1</sparkle:releaseNotesLink>
42+
<enclosure
43+
url="https://github.com/SyntheticAutonomicMind/SAM/releases/download/20260108.1/SAM-20260108.1.zip"
44+
sparkle:version="20260108.1"
45+
sparkle:shortVersionString="20260108.1"
46+
sparkle:edSignature="DUJsESu3Orfsnp2HwD4zE9J21w2cWkBsyov5knl17/NTAPW1kUafqyDoEnFnpenFg8tTqnyGAzLbMmklhWpADw=="
47+
length="770854850"
48+
type="application/octet-stream"
49+
/>
50+
<sparkle:minimumSystemVersion>14.0</sparkle:minimumSystemVersion>
51+
</item>
3952
<item>
4053
<title>SAM 20260107.1</title>
4154
<description><![CDATA[

scripts/generate-dev-appcast.sh

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,19 @@ cat > "$DEV_APPCAST" <<'EOF'
3535
EOF
3636

3737
# Extract and add development items (skip XML comments and empty lines)
38-
# Look for actual <item> tags, not comments
39-
if grep -q '<item>' "$DEV_ITEMS" 2>/dev/null; then
38+
# Use awk to properly handle multi-line comments
39+
DEV_ITEMS_CONTENT=$(awk '
40+
BEGIN { in_comment = 0; in_item = 0 }
41+
/<!--/ { in_comment = 1; next }
42+
/-->/ { in_comment = 0; next }
43+
!in_comment && /<item>/ { in_item = 1 }
44+
!in_comment && in_item { print }
45+
!in_comment && /<\/item>/ { in_item = 0 }
46+
' "$DEV_ITEMS")
47+
48+
if [ -n "$DEV_ITEMS_CONTENT" ]; then
4049
echo "Adding development items from $DEV_ITEMS"
41-
# Extract everything between first <item> and last </item>
42-
sed -n '/<item>/,/<\/item>/p' "$DEV_ITEMS" >> "$DEV_APPCAST"
50+
echo "$DEV_ITEMS_CONTENT" >> "$DEV_APPCAST"
4351
else
4452
echo "No development items found in $DEV_ITEMS (this is OK for initial setup)"
4553
fi

scripts/update_dev_appcast.sh

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: GPL-3.0-only
3+
# SPDX-FileCopyrightText: Copyright (c) 2025 Andrew Wyatt (Fewtarius)
4+
5+
# Script to update appcast-dev-items.xml with new development release entry
6+
# Usage: ./scripts/update_dev_appcast.sh <version> <zip_path> [private_key_path]
7+
8+
set -e
9+
10+
VERSION="$1"
11+
ZIP_PATH="$2"
12+
PRIVATE_KEY_PATH="${3:-$HOME/.sam-sparkle-keys/private_key.txt}"
13+
14+
if [ -z "$VERSION" ] || [ -z "$ZIP_PATH" ]; then
15+
echo "Usage: $0 <version> <zip_path> [private_key_path]"
16+
echo "Example: $0 20260111.1-dev.1 dist/SAM-20260111.1-dev.1.zip"
17+
echo " $0 20260111.1-dev.1 dist/SAM-20260111.1-dev.1.zip /tmp/sparkle_key.txt"
18+
exit 1
19+
fi
20+
21+
if [ ! -f "$ZIP_PATH" ]; then
22+
echo "Error: ZIP file not found: $ZIP_PATH"
23+
exit 1
24+
fi
25+
26+
if [ ! -f "$PRIVATE_KEY_PATH" ]; then
27+
echo "Error: Sparkle private key not found: $PRIVATE_KEY_PATH"
28+
echo "Please run scripts/setup_sparkle.sh to generate keys"
29+
exit 1
30+
fi
31+
32+
DEV_ITEMS_FILE="appcast-dev-items.xml"
33+
if [ ! -f "$DEV_ITEMS_FILE" ]; then
34+
echo "Error: $DEV_ITEMS_FILE not found in current directory"
35+
exit 1
36+
fi
37+
38+
# Get file size
39+
FILE_SIZE=$(stat -f%z "$ZIP_PATH")
40+
41+
# Get current date in RFC 822 format
42+
PUB_DATE=$(date -u +"%a, %d %b %Y %H:%M:%S %z")
43+
44+
# Find sign_update binary
45+
SIGN_UPDATE_BINARY=""
46+
if [ -f ".build/artifacts/sparkle/Sparkle/bin/sign_update" ]; then
47+
SIGN_UPDATE_BINARY=".build/artifacts/sparkle/Sparkle/bin/sign_update"
48+
elif [ -f ".build/SourcePackages/artifacts/sparkle/Sparkle/bin/sign_update" ]; then
49+
SIGN_UPDATE_BINARY=".build/SourcePackages/artifacts/sparkle/Sparkle/bin/sign_update"
50+
elif [ -f ".build/checkouts/Sparkle/sign_update" ]; then
51+
SIGN_UPDATE_BINARY=".build/checkouts/Sparkle/sign_update"
52+
fi
53+
54+
if [ -z "$SIGN_UPDATE_BINARY" ]; then
55+
echo "Error: sign_update binary not found"
56+
echo "Please run 'make build-debug' or 'make build-release' first"
57+
exit 1
58+
fi
59+
60+
# Sign the ZIP file to get EdDSA signature
61+
echo "Signing ZIP file with EdDSA key..."
62+
SIGNATURE_OUTPUT=$("$SIGN_UPDATE_BINARY" "$ZIP_PATH" -f "$PRIVATE_KEY_PATH")
63+
64+
if [ -z "$SIGNATURE_OUTPUT" ]; then
65+
echo "Error: Failed to generate signature"
66+
exit 1
67+
fi
68+
69+
# Extract just the signature value from: sparkle:edSignature="VALUE" length="..."
70+
SIGNATURE=$(echo "$SIGNATURE_OUTPUT" | sed -n 's/.*sparkle:edSignature="\([^"]*\)".*/\1/p')
71+
72+
if [ -z "$SIGNATURE" ]; then
73+
echo "Error: Failed to extract signature from output: $SIGNATURE_OUTPUT"
74+
exit 1
75+
fi
76+
77+
echo " Signature: $SIGNATURE"
78+
79+
echo "Updating $DEV_ITEMS_FILE for version $VERSION"
80+
echo " ZIP: $ZIP_PATH"
81+
echo " Size: $FILE_SIZE bytes"
82+
echo " Date: $PUB_DATE"
83+
echo " EdDSA Signature: ${SIGNATURE:0:40}..."
84+
echo ""
85+
86+
# Create new development item entry
87+
read -r -d '' NEW_ITEM << EOF || true
88+
<item>
89+
<title>SAM $VERSION</title>
90+
<description><![CDATA[
91+
<h2>SAM $VERSION (Development Build)</h2>
92+
<p><strong>⚠️ This is a DEVELOPMENT release for testing purposes.</strong></p>
93+
<h3>What's New:</h3>
94+
<ul>
95+
<li>See <a href="https://github.com/SyntheticAutonomicMind/SAM/releases/tag/$VERSION">GitHub Releases</a> for details</li>
96+
</ul>
97+
<h3>Known Issues:</h3>
98+
<ul>
99+
<li>Development builds may contain bugs and incomplete features</li>
100+
</ul>
101+
]]></description>
102+
<pubDate>$PUB_DATE</pubDate>
103+
<sparkle:releaseNotesLink>https://github.com/SyntheticAutonomicMind/SAM/releases/tag/$VERSION</sparkle:releaseNotesLink>
104+
<sparkle:channel>development</sparkle:channel>
105+
<enclosure
106+
url="https://github.com/SyntheticAutonomicMind/SAM/releases/download/$VERSION/SAM-$VERSION.zip"
107+
sparkle:version="$VERSION"
108+
sparkle:shortVersionString="$VERSION"
109+
sparkle:edSignature="$SIGNATURE"
110+
length="$FILE_SIZE"
111+
type="application/octet-stream"
112+
/>
113+
<sparkle:minimumSystemVersion>14.0</sparkle:minimumSystemVersion>
114+
</item>
115+
116+
EOF
117+
118+
# Create a temporary file
119+
TEMP_FILE=$(mktemp)
120+
121+
# Read through the file and insert new item after the "Development items will be added below this line" comment
122+
INSERTED=0
123+
while IFS= read -r line; do
124+
echo "$line" >> "$TEMP_FILE"
125+
if [[ "$line" == *"Development items will be added below this line"* ]] && [ $INSERTED -eq 0 ]; then
126+
echo "" >> "$TEMP_FILE"
127+
echo "$NEW_ITEM" >> "$TEMP_FILE"
128+
INSERTED=1
129+
fi
130+
done < "$DEV_ITEMS_FILE"
131+
132+
# Move the temp file to replace the original
133+
mv "$TEMP_FILE" "$DEV_ITEMS_FILE"
134+
135+
echo "✅ Updated $DEV_ITEMS_FILE with version $VERSION"
136+
echo ""
137+
echo "Next steps:"
138+
echo "1. Run: ./scripts/generate-dev-appcast.sh"
139+
echo "2. Commit both appcast-dev-items.xml and appcast-dev.xml"

0 commit comments

Comments
 (0)