fix(ci): publish desktop installers via Gitea Release, not upload-artifact
actions/upload-artifact@v4's backend fails on the Gitea runner (Upload installers
step errored). Mirror release.yml's proven path instead: curl + the built-in token
to the Releases API, into a ROLLING per-branch prerelease (tag desktop-<branch>,
deleted+recreated each push). Installers renamed space-free
(parking-desktop-<branch>-<sha>.{deb,AppImage}). Signed v* releases unchanged.
Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
@@ -81,17 +81,54 @@ jobs:
|
|||||||
|
|
||||||
- name: Collect installers
|
- name: Collect installers
|
||||||
id: collect
|
id: collect
|
||||||
|
# Copy out the two installers under SPACE-FREE names (tauri names them
|
||||||
|
# "Parking System_0.0.0_amd64.deb" — spaces break asset URLs). Short SHA in the
|
||||||
|
# name so a downloaded file is traceable to its commit.
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
BUNDLE=apps/desktop/src-tauri/target/release/bundle
|
BUNDLE=apps/desktop/src-tauri/target/release/bundle
|
||||||
|
SHA="$(echo "${GITHUB_SHA}" | cut -c1-7)"
|
||||||
mkdir -p dist
|
mkdir -p dist
|
||||||
find "$BUNDLE" \( -name '*.AppImage' -o -name '*.deb' \) -exec cp {} dist/ \;
|
deb=$(find "$BUNDLE/deb" -name '*.deb' | head -1)
|
||||||
|
app=$(find "$BUNDLE/appimage" -name '*.AppImage' | head -1)
|
||||||
|
cp "$deb" "dist/parking-desktop-${GITHUB_REF_NAME}-${SHA}.deb"
|
||||||
|
cp "$app" "dist/parking-desktop-${GITHUB_REF_NAME}-${SHA}.AppImage"
|
||||||
echo "Artifacts:"; ls -la dist/
|
echo "Artifacts:"; ls -la dist/
|
||||||
|
|
||||||
- name: Upload installers
|
- name: Publish to a rolling per-branch pre-release
|
||||||
uses: actions/upload-artifact@v4
|
# actions/upload-artifact's backend isn't reliable on this Gitea runner, so we
|
||||||
with:
|
# publish to a Gitea RELEASE via the API instead (the proven pattern from
|
||||||
name: desktop-${{ github.ref_name }}-${{ github.sha }}
|
# release.yml — built-in token, plain curl). One ROLLING pre-release per branch
|
||||||
path: dist/*
|
# (tag desktop-<branch>): delete + recreate each push so it always holds the
|
||||||
if-no-files-found: error
|
# latest dev/main installer. This is NOT the signed updater release (release.yml,
|
||||||
retention-days: 14
|
# tag v*) — it's a prerelease, unsigned, with no latest.json.
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
API: ${{ github.api_url }}
|
||||||
|
REPO: ${{ github.repository }}
|
||||||
|
TAG: desktop-${{ github.ref_name }}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
auth="Authorization: token ${TOKEN}"
|
||||||
|
# Drop any existing rolling release for this branch (ignore if absent) so its
|
||||||
|
# tag + stale assets don't pile up; recreate it fresh below.
|
||||||
|
OLD=$(curl -sS -H "$auth" "${API}/repos/${REPO}/releases/tags/${TAG}" \
|
||||||
|
| grep -o '"id":[0-9]*' | head -1 | cut -d: -f2 || true)
|
||||||
|
if [ -n "$OLD" ]; then
|
||||||
|
curl -sS -X DELETE -H "$auth" "${API}/repos/${REPO}/releases/${OLD}" || true
|
||||||
|
# Also delete the tag itself so the recreate points at this commit.
|
||||||
|
curl -sS -X DELETE -H "$auth" "${API}/repos/${REPO}/git/refs/tags/${TAG}" || true
|
||||||
|
fi
|
||||||
|
REL=$(curl -sS -X POST -H "$auth" -H "Content-Type: application/json" \
|
||||||
|
-d "{\"tag_name\":\"${TAG}\",\"target_commitish\":\"${GITHUB_SHA}\",\"name\":\"Desktop build (${GITHUB_REF_NAME})\",\"body\":\"Unsigned per-commit desktop installers from ${GITHUB_REF_NAME} @ ${GITHUB_SHA}. Rolling — overwritten each push. Not an updater release.\",\"draft\":false,\"prerelease\":true}" \
|
||||||
|
"${API}/repos/${REPO}/releases")
|
||||||
|
REL_ID=$(printf '%s' "$REL" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
|
||||||
|
echo "release id: ${REL_ID}"
|
||||||
|
for f in dist/*; do
|
||||||
|
name=$(basename "$f")
|
||||||
|
echo "uploading ${name}"
|
||||||
|
curl -sS -X POST -H "$auth" -H "Content-Type: application/octet-stream" \
|
||||||
|
--data-binary @"${f}" \
|
||||||
|
"${API}/repos/${REPO}/releases/${REL_ID}/assets?name=${name}" >/dev/null
|
||||||
|
done
|
||||||
|
echo "done"
|
||||||
|
|||||||
@@ -177,12 +177,20 @@ The desktop bundle now runs in CI under **two distinct workflows** — keep the
|
|||||||
and publishes a Gitea Release. This is what the auto-updater consumes. Unchanged.
|
and publishes a Gitea Release. This is what the auto-updater consumes. Unchanged.
|
||||||
- **`.gitea/workflows/build-desktop.yml`** (push to `dev`/`main`) — a **per-commit test build**:
|
- **`.gitea/workflows/build-desktop.yml`** (push to `dev`/`main`) — a **per-commit test build**:
|
||||||
compiles `.deb` + `.AppImage` only (`pnpm --filter @parking/desktop bundle --bundles deb,appimage`)
|
compiles `.deb` + `.AppImage` only (`pnpm --filter @parking/desktop bundle --bundles deb,appimage`)
|
||||||
and uploads them as **workflow artifacts** (14-day retention). **Unsigned** — no `TAURI_SIGNING_*`,
|
and publishes them to a **rolling per-branch pre-release** (tag `desktop-<branch>`). **Unsigned** —
|
||||||
no Release, no `latest.json` — so it must NEVER be wired to the updater (an unsigned artifact would
|
no `TAURI_SIGNING_*`, no `latest.json` — so it must NEVER be wired to the updater (an unsigned
|
||||||
be rejected anyway). It exists so each branch push yields a downloadable installer for manual
|
artifact would be rejected anyway). It exists so each branch push yields a downloadable installer
|
||||||
testing of the native shell, and catches a broken Tauri/Rust build early. Same system-deps + cargo
|
for manual testing of the native shell, and catches a broken Tauri/Rust build early. Same
|
||||||
cache as `release.yml`. The container images (`build-images.yml`) and the desktop installers are
|
system-deps + cargo cache as `release.yml`. The container images (`build-images.yml`) and the
|
||||||
deliberately separate pipelines — the desktop app is **not** containerized ([[container-deployment]]).
|
desktop installers are deliberately separate pipelines — the desktop app is **not** containerized
|
||||||
|
([[container-deployment]]).
|
||||||
|
- **Delivery: a rolling pre-release, NOT `actions/upload-artifact`.** That action's artifact
|
||||||
|
backend isn't reliable on the Gitea runner (the *Upload installers* step failed). Instead the
|
||||||
|
workflow mirrors `release.yml`'s proven path — plain `curl` + the built-in `GITHUB_TOKEN` to the
|
||||||
|
**Releases API**. It DELETEs any existing `desktop-<branch>` release + tag, recreates it against
|
||||||
|
the new commit as a **prerelease**, and uploads the two installers (renamed space-free,
|
||||||
|
`parking-desktop-<branch>-<sha>.{deb,AppImage}`). So `desktop-dev` always holds the newest dev
|
||||||
|
build; `v*` tags remain the only *signed* releases.
|
||||||
- **Gotcha (the unsigned build still demands the key).** `tauri.conf.json` sets
|
- **Gotcha (the unsigned build still demands the key).** `tauri.conf.json` sets
|
||||||
`bundle.createUpdaterArtifacts: true` (so `release.yml` produces the `.sig` updater signatures).
|
`bundle.createUpdaterArtifacts: true` (so `release.yml` produces the `.sig` updater signatures).
|
||||||
With that on, `tauri build` **fails** if `TAURI_SIGNING_PRIVATE_KEY` is absent — *"A public key
|
With that on, `tauri build` **fails** if `TAURI_SIGNING_PRIVATE_KEY` is absent — *"A public key
|
||||||
|
|||||||
Reference in New Issue
Block a user