Skip to content

Commit d3095cb

Browse files
committed
CI: Simplify release pipeline, fix publish job
Build job: remove 3 steps (rename updater artifacts, save/upload signature artifacts) — tauri-action already uploads arch-named files to the release. Publish job: download sigs directly from the release via `gh release download` instead of the broken artifact-passing mechanism. Generate `latest.json` with `jq` instead of fragile heredoc. Replace tauri-action's incomplete `latest.json` on the release. Update release body with real changelog from CHANGELOG.md. Also: validate all 3 sigs exist before proceeding, use `printf` over `echo` for changelog extraction, `git pull --rebase` before push to handle concurrent pushes to main, strip leading blank lines from changelog notes.
1 parent 5b82cd0 commit d3095cb

1 file changed

Lines changed: 57 additions & 97 deletions

File tree

.github/workflows/release.yml

Lines changed: 57 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -125,57 +125,6 @@ jobs:
125125
echo "Both build attempts failed"
126126
exit 1
127127
128-
- name: Rename and upload updater artifacts
129-
env:
130-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
131-
run: |
132-
TAG="${{ github.ref_name }}"
133-
BUNDLE_DIR="apps/desktop/src-tauri/target/${{ matrix.target }}/release/bundle"
134-
135-
# tauri-action uploads DMG automatically. We just need to rename
136-
# updater artifacts to include arch (Tauri names them all Cmdr.app.tar.gz)
137-
UPDATER=$(find "$BUNDLE_DIR" -name "*.app.tar.gz" | head -1)
138-
SIG_FILE="${UPDATER}.sig"
139-
140-
if [ -z "$UPDATER" ] || [ ! -f "$SIG_FILE" ]; then
141-
echo "Updater artifacts not found, tauri-action may have uploaded them already"
142-
exit 0
143-
fi
144-
145-
UPDATER_RENAMED="/tmp/Cmdr_${{ matrix.arch }}.app.tar.gz"
146-
SIG_RENAMED="/tmp/Cmdr_${{ matrix.arch }}.app.tar.gz.sig"
147-
cp "$UPDATER" "$UPDATER_RENAMED"
148-
cp "$SIG_FILE" "$SIG_RENAMED"
149-
150-
gh release upload "$TAG" "$UPDATER_RENAMED" "$SIG_RENAMED" --clobber
151-
152-
- name: Save signature as artifact
153-
run: |
154-
BUNDLE_DIR="apps/desktop/src-tauri/target/${{ matrix.target }}/release/bundle"
155-
SIG_FILE=$(find "$BUNDLE_DIR" -name "*.app.tar.gz.sig" | head -1)
156-
mkdir -p /tmp/sig-artifacts
157-
158-
if [ -n "$SIG_FILE" ] && [ -f "$SIG_FILE" ]; then
159-
cp "$SIG_FILE" "/tmp/sig-artifacts/signature-${{ matrix.arch }}.txt"
160-
else
161-
echo "Signature file not found in bundle dir, checking tauri-action output"
162-
# Fall back: download from release
163-
TAG="${{ github.ref_name }}"
164-
# tauri-action uploads as Cmdr.app.tar.gz.sig
165-
gh release download "$TAG" -p "Cmdr.app.tar.gz.sig" -D /tmp/sig-artifacts --clobber || true
166-
if [ -f "/tmp/sig-artifacts/Cmdr.app.tar.gz.sig" ]; then
167-
mv "/tmp/sig-artifacts/Cmdr.app.tar.gz.sig" "/tmp/sig-artifacts/signature-${{ matrix.arch }}.txt"
168-
fi
169-
fi
170-
env:
171-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
172-
173-
- name: Upload signature artifact
174-
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
175-
with:
176-
name: signature-${{ matrix.arch }}
177-
path: /tmp/sig-artifacts/signature-${{ matrix.arch }}.txt
178-
179128
- name: Clean up keychain
180129
if: always()
181130
run: security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
@@ -189,23 +138,28 @@ jobs:
189138
- name: Checkout code
190139
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
191140

192-
- name: Download all signature artifacts
193-
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
194-
with:
195-
path: /tmp/signatures
196-
pattern: signature-*
141+
- name: Download signatures from release
142+
env:
143+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
144+
run: |
145+
TAG="${{ github.ref_name }}"
146+
mkdir -p /tmp/signatures
147+
gh release download "$TAG" -p "Cmdr_*.app.tar.gz.sig" -D /tmp/signatures
148+
149+
# Verify all 3 arch sigs were downloaded
150+
for arch in aarch64 x64 universal; do
151+
[ -f "/tmp/signatures/Cmdr_${arch}.app.tar.gz.sig" ] || { echo "Missing sig for $arch"; exit 1; }
152+
done
197153
198154
- name: Extract changelog for this version
199-
id: changelog
200155
run: |
201156
VERSION="${{ github.ref_name }}"
202157
VERSION="${VERSION#v}"
203158
204159
# Extract section for this version from CHANGELOG.md
205-
NOTES=$(sed -n "/## \[$VERSION\]/,/## \[/p" CHANGELOG.md | sed '1d;$d')
160+
NOTES=$(sed -n "/## \[$VERSION\]/,/## \[/p" CHANGELOG.md | sed '1d;$d' | sed '/./,$!d')
206161
207-
# Write to file to preserve newlines
208-
echo "$NOTES" > /tmp/notes.txt
162+
printf '%s\n' "$NOTES" > /tmp/notes.txt
209163
210164
- name: Generate latest.json
211165
env:
@@ -215,47 +169,52 @@ jobs:
215169
VERSION="${VERSION#v}"
216170
TAG="${{ github.ref_name }}"
217171
218-
# Read signatures from downloaded artifacts
219-
SIG_AARCH64=$(cat /tmp/signatures/signature-aarch64/signature-aarch64.txt)
220-
SIG_X86_64=$(cat /tmp/signatures/signature-x86_64/signature-x86_64.txt)
221-
SIG_UNIVERSAL=$(cat /tmp/signatures/signature-universal/signature-universal.txt)
172+
# Read signatures downloaded from the release
173+
SIG_AARCH64=$(cat /tmp/signatures/Cmdr_aarch64.app.tar.gz.sig)
174+
SIG_X86_64=$(cat /tmp/signatures/Cmdr_x64.app.tar.gz.sig)
175+
SIG_UNIVERSAL=$(cat /tmp/signatures/Cmdr_universal.app.tar.gz.sig)
222176
223-
# Query DMG sizes from the release assets
224-
SIZE_AARCH64=$(gh api "repos/vdavid/cmdr/releases/tags/$TAG" --jq ".assets[] | select(.name | endswith(\"_aarch64.dmg\")) | .size" || echo 0)
225-
SIZE_X86_64=$(gh api "repos/vdavid/cmdr/releases/tags/$TAG" --jq ".assets[] | select(.name | endswith(\"_x86_64.dmg\")) | .size" || echo 0)
226-
SIZE_UNIVERSAL=$(gh api "repos/vdavid/cmdr/releases/tags/$TAG" --jq ".assets[] | select(.name | endswith(\"_universal.dmg\")) | .size" || echo 0)
177+
# Query DMG sizes from the release assets (tauri-action uses "x64" in DMG names)
178+
RELEASE_JSON=$(gh api "repos/${{ github.repository }}/releases/tags/$TAG")
179+
SIZE_AARCH64=$(echo "$RELEASE_JSON" | jq '[.assets[] | select(.name | endswith("_aarch64.dmg"))][0].size // 0')
180+
SIZE_X86_64=$(echo "$RELEASE_JSON" | jq '[.assets[] | select(.name | endswith("_x64.dmg"))][0].size // 0')
181+
SIZE_UNIVERSAL=$(echo "$RELEASE_JSON" | jq '[.assets[] | select(.name | endswith("_universal.dmg"))][0].size // 0')
227182
228183
# Read notes from file, escape for JSON
229-
NOTES=$(cat /tmp/notes.txt | jq -Rs .)
230-
231-
BASE_URL="https://github.com/vdavid/cmdr/releases/download/$TAG"
232-
233-
cat > /tmp/latest.json << EOF
234-
{
235-
"version": "$VERSION",
236-
"dmgSizes": {
237-
"aarch64": ${SIZE_AARCH64:-0},
238-
"x86_64": ${SIZE_X86_64:-0},
239-
"universal": ${SIZE_UNIVERSAL:-0}
240-
},
241-
"notes": $NOTES,
242-
"pub_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
243-
"platforms": {
244-
"darwin-universal": {
245-
"signature": "$SIG_UNIVERSAL",
246-
"url": "$BASE_URL/Cmdr_universal.app.tar.gz"
247-
},
248-
"darwin-aarch64": {
249-
"signature": "$SIG_AARCH64",
250-
"url": "$BASE_URL/Cmdr_aarch64.app.tar.gz"
251-
},
252-
"darwin-x86_64": {
253-
"signature": "$SIG_X86_64",
254-
"url": "$BASE_URL/Cmdr_x86_64.app.tar.gz"
255-
}
184+
NOTES=$(jq -Rs . < /tmp/notes.txt)
185+
186+
BASE_URL="https://github.com/${{ github.repository }}/releases/download/$TAG"
187+
188+
jq -n --indent 4 \
189+
--arg version "$VERSION" \
190+
--argjson size_aarch64 "$SIZE_AARCH64" \
191+
--argjson size_x86_64 "$SIZE_X86_64" \
192+
--argjson size_universal "$SIZE_UNIVERSAL" \
193+
--argjson notes "$NOTES" \
194+
--arg pub_date "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
195+
--arg sig_universal "$SIG_UNIVERSAL" \
196+
--arg sig_aarch64 "$SIG_AARCH64" \
197+
--arg sig_x86_64 "$SIG_X86_64" \
198+
--arg base_url "$BASE_URL" \
199+
'{
200+
version: $version,
201+
dmgSizes: { aarch64: $size_aarch64, x86_64: $size_x86_64, universal: $size_universal },
202+
notes: $notes,
203+
pub_date: $pub_date,
204+
platforms: {
205+
"darwin-universal": { signature: $sig_universal, url: "\($base_url)/Cmdr_universal.app.tar.gz" },
206+
"darwin-aarch64": { signature: $sig_aarch64, url: "\($base_url)/Cmdr_aarch64.app.tar.gz" },
207+
"darwin-x86_64": { signature: $sig_x86_64, url: "\($base_url)/Cmdr_x64.app.tar.gz" }
256208
}
257-
}
258-
EOF
209+
}' > /tmp/latest.json
210+
211+
- name: Replace tauri-action's latest.json on the release
212+
env:
213+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
214+
run: |
215+
TAG="${{ github.ref_name }}"
216+
gh release delete-asset "$TAG" latest.json --yes || true
217+
gh release upload "$TAG" /tmp/latest.json
259218
260219
- name: Update release body with changelog
261220
env:
@@ -277,6 +236,7 @@ jobs:
277236
cp /tmp/latest.json apps/website/public/latest.json
278237
git add apps/website/public/latest.json
279238
git commit -m "chore(release): update latest.json for ${{ github.ref_name }} [skip ci]"
239+
git pull --rebase origin main
280240
git push origin main
281241
282242
- name: Trigger website deploy

0 commit comments

Comments
 (0)