diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 85022ba..6dc3f4f 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -351,6 +351,52 @@ jobs: -H "Content-Type: application/octet-stream" \ --data-binary @"$PKG" + # [cinny-desktop #36] The .deb / .pkg.tar.zst aren't signed packages, and + # the in-app update prompt has users install them by hand. Publish a + # SHA256SUMS.txt for the Linux downloads, signed with the updater's minisign + # key, so the install command can verify before installing. + checksums: + needs: [prepare, build-linux, build-arch] + runs-on: ubuntu-latest + steps: + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Hash, sign and upload SHA256SUMS.txt + env: + TOKEN: ${{ secrets.RELEASE_TOKEN }} + RELEASE_ID: ${{ needs.prepare.outputs.release_id }} + TAURI_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_PRIVATE_KEY_PASSWORD: '' + run: | + set -euo pipefail + BASE="$GITEA_URL/LotusGuild/cinny-desktop/releases/download/latest" + mkdir -p sums && cd sums + for f in LotusChat-x86_64.deb LotusChat-x86_64.pkg.tar.zst LotusChat-x86_64.AppImage; do + curl -sfL -o "$f" "$BASE/$f" + done + sha256sum LotusChat-x86_64.deb LotusChat-x86_64.pkg.tar.zst LotusChat-x86_64.AppImage > SHA256SUMS.txt + cat SHA256SUMS.txt + # The Tauri signer writes .sig (base64 of a minisign signature) + # and needs a file extension. Publish the decoded .minisig so users + # can run `minisign -Vm` directly. + npx --yes @tauri-apps/cli@2.7.1 signer sign SHA256SUMS.txt + base64 -d SHA256SUMS.txt.sig > SHA256SUMS.txt.minisig + for NAME in SHA256SUMS.txt SHA256SUMS.txt.minisig; do + OLD=$(curl -sf "$GITEA_URL/api/v1/repos/$REPO/releases/$RELEASE_ID/assets" \ + -H "Authorization: token $TOKEN" \ + | python3 -c "import sys,json; print(next((str(a['id']) for a in json.load(sys.stdin) if a['name']=='$NAME'), ''))" 2>/dev/null || true) + [ -n "$OLD" ] && curl -sf -X DELETE \ + "$GITEA_URL/api/v1/repos/$REPO/releases/$RELEASE_ID/assets/$OLD" \ + -H "Authorization: token $TOKEN" || true + curl -sf -X POST \ + "$GITEA_URL/api/v1/repos/$REPO/releases/$RELEASE_ID/assets?name=$NAME" \ + -H "Authorization: token $TOKEN" \ + -H "Content-Type: application/octet-stream" \ + --data-binary @"$NAME" + done + update-manifest: needs: [prepare, build-windows, build-linux] runs-on: ubuntu-latest diff --git a/README.md b/README.md index a91da1a..0befde3 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,22 @@ Builds are published on this repo's releases page: There is no macOS build at the moment. +### Verify a Linux download + +Each release has a `SHA256SUMS.txt`, signed with the same key as the updater +(below). Check the signature, then the file, then install, e.g. for Arch: + +```sh +B=https://code.lotusguild.org/LotusGuild/cinny-desktop/releases/download/latest +curl -LO $B/LotusChat-x86_64.pkg.tar.zst -LO $B/SHA256SUMS.txt -LO $B/SHA256SUMS.txt.minisig +minisign -Vm SHA256SUMS.txt -P RWRZZdyii05/NUcz337A5SAbiZK+NPVDWuiL2mM5Jk1p/LfRmNfiZ/6l \ + && sha256sum -c --ignore-missing SHA256SUMS.txt \ + && sudo pacman -U ./LotusChat-x86_64.pkg.tar.zst +``` + +For Debian / Ubuntu use `LotusChat-x86_64.deb` and `sudo apt install ./LotusChat-x86_64.deb`. +`minisign` is in both distributions' repositories. + ### Updates and signatures The app updates itself from