Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,41 @@ jobs:
- name: package
env:
SEMVER: ${{ needs.tag.outputs.semver }}
run: bunx electron-builder ${{ matrix.args }} -c.extraMetadata.version="$SEMVER" --publish never
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
WIN_CSC_LINK: ${{ secrets.WIN_CSC_LINK }}
WIN_CSC_KEY_PASSWORD: ${{ secrets.WIN_CSC_KEY_PASSWORD }}
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
set -euo pipefail
case "$RUNNER_OS" in
macOS)
unset WIN_CSC_LINK WIN_CSC_KEY_PASSWORD
;;
Windows)
unset CSC_LINK CSC_KEY_PASSWORD APPLE_API_KEY APPLE_API_KEY_ID APPLE_API_ISSUER APPLE_TEAM_ID
;;
*)
unset CSC_LINK CSC_KEY_PASSWORD WIN_CSC_LINK WIN_CSC_KEY_PASSWORD
unset APPLE_API_KEY APPLE_API_KEY_ID APPLE_API_ISSUER APPLE_TEAM_ID
;;
esac
for name in CSC_LINK CSC_KEY_PASSWORD WIN_CSC_LINK WIN_CSC_KEY_PASSWORD APPLE_API_KEY APPLE_API_KEY_ID APPLE_API_ISSUER APPLE_TEAM_ID; do
if [ -z "${!name-}" ]; then
unset "$name"
fi
done
if [ "$RUNNER_OS" = "macOS" ] && [ -n "${CSC_LINK-}" ] && [ -n "${APPLE_API_KEY-}" ]; then
echo "signing and notarizing the macOS build"
elif [ "$RUNNER_OS" = "Windows" ] && [ -n "${WIN_CSC_LINK-}" ]; then
echo "signing the Windows build"
else
echo "no signing secrets for $RUNNER_OS; publishing unsigned artefacts"
fi
bunx electron-builder ${{ matrix.args }} -c.extraMetadata.version="$SEMVER" --publish never
- name: upload installers
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion Casks/pidex.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
desc "Desktop workbench for the Pi coding agent"
homepage "https://github.com/echohello-dev/pidex"

depends_on macos: :sonoma
depends_on macos: :monterey

app "pidex.app"

Expand Down
9 changes: 5 additions & 4 deletions docs/adr/0010-distribution-channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
- electron-builder wants semver; CalVer tags with leading zeros (`2026.08.09-2`) are mapped to `2026.8.9-2` for the packager and `2026.8.9.2` for Winget.
- Builds are unsigned. macOS Gatekeeper and Windows SmartScreen will warn until Developer ID / Authenticode certs are added via `CSC_*` secrets.
- Docker is a Linux/X11 fallback, not the daily-driver install. The app reads `~/.pi/agent/sessions` and expects a local Pi CLI.
- Official Homebrew and Winget directory listings remain a follow-up (manual PR plus, for Winget, a `WINGET_TOKEN`). The org tap is the supported install path until then.
- Snap, Flathub, Chocolatey, and the Mac / Microsoft stores are out of scope until there is signing and a store account.
- Official Homebrew and Winget directory listings are manual pull requests against the published installers. The org tap stays the install path until those land.
- Signing and notarization run in the release workflow when Developer ID and Authenticode secrets are set. Without them the artefacts stay unsigned.
- A Flatpak manifest lives in `packaging/flatpak/`. Flathub submission is a human pull request. Snap, Chocolatey, and the Mac / Microsoft stores stay out of scope.

- **Follow-ups**:
- Apple Developer ID + notarization; Authenticode for NSIS.
- Add `CSC_LINK`, `APPLE_API_*`, and `WIN_CSC_LINK` secrets. An Apple Development certificate cannot notarize.
- `electron-updater` once macOS builds are signed (Squirrel.Mac refuses unsigned updates).
- PR the cask into `homebrew/homebrew-cask` and the singleton into `microsoft/winget-pkgs`.
- After the first `echoHello.Pidex` Winget manifest is merged, update PRs can use `WINGET_TOKEN`.
36 changes: 29 additions & 7 deletions docs/distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

pidex ships from GitHub Releases on every push to `main`. Tags stay CalVer (`YYYY.0M.0D`, see [ADR 0009](adr/0009-calver-releases.md)). The packager matrix and public channels are [ADR 0010](adr/0010-distribution-channels.md).

Builds are unsigned. First launch on macOS needs right-click → Open. Windows SmartScreen may ask you to keep the file.
Builds are unsigned until Developer ID and Authenticode secrets are set on the repository. Until then, first launch on macOS needs right-click → Open, and Windows SmartScreen may ask you to keep the file.

## GitHub Releases

Expand Down Expand Up @@ -63,13 +63,35 @@ $ mise run package

`mise run package` builds installers for the platform you are on. CI builds all three.

## Signing (not wired yet)
## Signing

The release workflow signs when these repository secrets exist. Empty secrets stay unset, and that platform is published unsigned.

| Secret | Value |
|---|---|
| `CSC_LINK` | Base64 of the Developer ID Application `.p12` |
| `CSC_KEY_PASSWORD` | Password for that `.p12` |
| `APPLE_API_KEY` | Base64 of the App Store Connect API `.p8` |
| `APPLE_API_KEY_ID` | Key ID |
| `APPLE_API_ISSUER` | Issuer ID |
| `APPLE_TEAM_ID` | 10-character Team ID |
| `WIN_CSC_LINK` | Base64 of the Authenticode `.pfx` |
| `WIN_CSC_KEY_PASSWORD` | Password for that `.pfx` |

An Apple Development certificate cannot notarize a public DMG. It has to be a Developer ID Application certificate from the Apple Developer Program. With the four `APPLE_*` secrets set as well, electron-builder notarizes and staples the macOS build. Windows uses `WIN_CSC_*` only, so a Mac `.p12` is not sent to the Windows runner.

```bash
$ base64 -i Certificates.p12 | pbcopy # store as CSC_LINK
$ base64 -i AuthKey_XXXX.p8 | pbcopy # store as APPLE_API_KEY
```

| Secret | Effect |
|---|---|
| `CSC_LINK` + `CSC_KEY_PASSWORD` | electron-builder signs macOS / Windows when present |
| Apple notarization keys | Required before Gatekeeper stops warning |
| `WINGET_TOKEN` | Would let CI open the `winget-pkgs` PR |
| `TAP_TOKEN` | PAT with `repo` on `echohello-dev/homebrew-tap`; pidex dispatches `pidex-release` so the tap syncs immediately instead of waiting for the hourly cron |
| `WINGET_TOKEN` | Classic PAT (`public_repo`) so a later workflow can open `winget-pkgs` update PRs. The first listing is a manual PR. |
| `TAP_TOKEN` | PAT with `repo` on `echohello-dev/homebrew-tap`. pidex dispatches `pidex-release` so the tap syncs immediately instead of waiting for the hourly cron. |

## Flathub

`packaging/flatpak/` is a Flatpak manifest for `dev.echohello.Pidex`. It wraps the published AppImage and grants `filesystem=home` so `~/.pi` and home-directory workspaces are visible.

Leave them unset and the workflow publishes unsigned artefacts on purpose.
Flathub does not accept agent-opened submission pull requests. A person opens that PR against `flathub/flathub` branch `new-pr`. Reviewers also treat host-dependent developer tools as a special case, because pidex shells out to the Pi CLI on the host. The manifest is here so that submission can be made by hand. The AppImage and `.deb` remain the Linux install.
1 change: 0 additions & 1 deletion electron-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ mac:
arch: [arm64, x64]
hardenedRuntime: true
gatekeeperAssess: false
identity: null
entitlements: build/entitlements.mac.plist
entitlementsInherit: build/entitlements.mac.plist

Expand Down
9 changes: 9 additions & 0 deletions packaging/flatpak/dev.echohello.Pidex.desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[Desktop Entry]
Name=pidex
Comment=Desktop workbench for the Pi coding agent
Exec=pidex
Icon=dev.echohello.Pidex
Terminal=false
Type=Application
Categories=Development;
StartupWMClass=pidex
23 changes: 23 additions & 0 deletions packaging/flatpak/dev.echohello.Pidex.metainfo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>dev.echohello.Pidex</id>
<name>pidex</name>
<summary>Desktop workbench for the Pi coding agent</summary>
<metadata_license>CC0-1.0</metadata_license>
<project_license>Apache-2.0</project_license>
<developer id="dev.echohello">
<name>echoHello</name>
</developer>
<url type="homepage">https://github.com/echohello-dev/pidex</url>
<description>
<p>
pidex is a workspace-first desktop workbench for the Pi coding agent.
It reads existing sessions from the Pi CLI on this computer.
</p>
</description>
<launchable type="desktop-id">dev.echohello.Pidex.desktop</launchable>
<content_rating type="oars-1.1"/>
<releases>
<release version="2026.09.28-2" date="2026-09-28"/>
</releases>
</component>
Binary file added packaging/flatpak/dev.echohello.Pidex.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 47 additions & 0 deletions packaging/flatpak/dev.echohello.Pidex.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
app-id: dev.echohello.Pidex
runtime: org.freedesktop.Platform
runtime-version: '25.08'
sdk: org.freedesktop.Sdk
base: org.electronjs.Electron2.BaseApp
base-version: '25.08'
command: pidex
separate-locales: false
finish-args:
- --share=ipc
- --share=network
- --socket=fallback-x11
- --socket=wayland
- --socket=pulseaudio
- --device=dri
- --filesystem=home
- --talk-name=org.freedesktop.Notifications
modules:
- name: pidex
buildsystem: simple
build-commands:
- install -Dm644 dev.echohello.Pidex.metainfo.xml /app/share/metainfo/dev.echohello.Pidex.metainfo.xml
- install -Dm644 dev.echohello.Pidex.desktop /app/share/applications/dev.echohello.Pidex.desktop
- install -Dm644 dev.echohello.Pidex.png /app/share/icons/hicolor/256x256/apps/dev.echohello.Pidex.png
- install -Dm755 pidex.sh /app/bin/pidex
sources:
- type: file
path: dev.echohello.Pidex.metainfo.xml
- type: file
path: dev.echohello.Pidex.desktop
- type: file
path: dev.echohello.Pidex.png
- type: file
path: pidex.sh
- type: extra-data
filename: pidex.AppImage
only-arches:
- x86_64
url: https://github.com/echohello-dev/pidex/releases/download/2026.09.28-2/pidex-linux-x86_64.AppImage
sha256: d619aa5afbc7c1cac7146135d41510ed97b7bc819e957b7aa009e2a454eaab6b
size: 126532577
- type: script
dest-filename: apply_extra
commands:
- chmod +x pidex.AppImage
- ./pidex.AppImage --appimage-extract
- mv squashfs-root pidex
3 changes: 3 additions & 0 deletions packaging/flatpak/flathub.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"only-arches": ["x86_64"]
}
2 changes: 2 additions & 0 deletions packaging/flatpak/pidex.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
exec zypak-wrapper /app/extra/pidex/pidex "$@"
4 changes: 2 additions & 2 deletions scripts/release-manifests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function homebrewCask(tag: string, checksums: ReleaseChecksums): string {
desc "Desktop workbench for the Pi coding agent"
homepage "${REPO}"

depends_on macos: :sonoma
depends_on macos: :monterey

app "pidex.app"

Expand Down Expand Up @@ -150,7 +150,7 @@ export function latestHomebrewCask(): string {
desc "Desktop workbench for the Pi coding agent"
homepage "${REPO}"

depends_on macos: :sonoma
depends_on macos: :monterey

app "pidex.app"

Expand Down
Loading