From 7ec807548b31c47313202815ab080370c3ccc3de Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Thu, 18 Jun 2026 15:56:33 +0200 Subject: [PATCH 1/6] feat: release pipeline producing installers for all three platforms Tag-triggered (`v*`) GitHub Actions workflow that bundles the app with cargo-packager and attaches the artifacts to a GitHub Release: macOS universal .dmg (lipo of both arches), Linux AppImage + .deb, Windows .msi. `workflow_dispatch` builds artifacts without releasing, for dry-runs. Artifacts are unsigned for now; codesign/notarize (mac) + signtool (win) hooks are documented and env-gated so adding cert secrets later activates them with no other change. Includes a placeholder app icon (swap anytime) and bundle metadata in crates/app/Cargo.toml, plus README install notes (incl. the Gatekeeper/SmartScreen workaround for unsigned builds). --- .github/workflows/release.yml | 129 ++++++++++++++++++++++++++++++++++ .gitignore | 1 + README.md | 22 +++++- crates/app/Cargo.toml | 19 +++++ packaging/icons/icon.icns | Bin 0 -> 67894 bytes packaging/icons/icon.ico | Bin 0 -> 13043 bytes packaging/icons/icon.png | Bin 0 -> 9047 bytes 7 files changed, 168 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 packaging/icons/icon.icns create mode 100644 packaging/icons/icon.ico create mode 100644 packaging/icons/icon.png diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a8a13b0 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,129 @@ +name: Release + +# Builds installable artifacts (cargo-packager) for macOS / Linux / Windows and attaches them to a +# GitHub Release. Runs on a version tag `v*`; `workflow_dispatch` builds the artifacts without +# releasing (for dry-runs). Separate from ci.yml (which only tests). +on: + push: + tags: ["v*"] + workflow_dispatch: + +concurrency: + group: release-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + name: package · ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # macos-14 = Apple Silicon (we lipo a universal binary on it); ubuntu-22.04 has libfuse2 for + # AppImage; windows-latest builds the .msi (cargo-packager fetches WiX itself). + os: [macos-14, ubuntu-22.04, windows-latest] + steps: + - uses: actions/checkout@v4 + + - name: Show toolchain + run: rustup show + + # gpui links X11/Wayland/Vulkan/fontconfig (build) + libfuse2 (AppImage tooling needs FUSE2, + # absent on ubuntu-24.04 — hence pinning 22.04). + - name: Install Linux deps + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + build-essential pkg-config clang libfontconfig-dev \ + libwayland-dev libxkbcommon-x11-dev libx11-xcb-dev libvulkan1 \ + libfuse2 + + - uses: Swatinem/rust-cache@v2 + + - uses: cargo-bins/cargo-binstall@main + - name: Install cargo-packager + run: cargo binstall --no-confirm cargo-packager + + # macOS: build both arches, lipo into the default profile dir, then package WITHOUT the + # default build hook (empty beforePackagingCommand) so it bundles the universal binary as-is. + - name: Package (macOS — universal .app + .dmg) + if: runner.os == 'macOS' + run: | + rustup target add aarch64-apple-darwin x86_64-apple-darwin + cargo build --release --target aarch64-apple-darwin -p posel-app + cargo build --release --target x86_64-apple-darwin -p posel-app + mkdir -p target/release + lipo -create -output target/release/posel \ + target/aarch64-apple-darwin/release/posel \ + target/x86_64-apple-darwin/release/posel + lipo -info target/release/posel + cargo packager --formats app,dmg --manifest-path crates/app/Cargo.toml --out-dir "${{ github.workspace }}/dist" \ + --config '{"beforePackagingCommand": ""}' + # Guard: the binary inside the bundle must be universal. + lipo -info "$(find dist -path '*Posel.app/Contents/MacOS/posel')" + # Signing is intentionally OFF (unsigned). To enable later, set these from secrets and add a + # conditional `--config` injecting macos.signing-identity — no other change needed: + # env: + # APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + # APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + # APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} + # APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} + # APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} + # APPLE_API_KEY_PATH: ${{ secrets.APPLE_API_KEY_PATH }} + + - name: Package (Linux — AppImage + .deb) + if: runner.os == 'Linux' + run: | + cargo packager --release --formats appimage,deb \ + --manifest-path crates/app/Cargo.toml --out-dir "${{ github.workspace }}/dist" + + - name: Package (Windows — .msi) + if: runner.os == 'Windows' + run: | + cargo packager --release --formats wix ` + --manifest-path crates/app/Cargo.toml --out-dir "${{ github.workspace }}/dist" + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: posel-${{ matrix.os }} + # Bundle binaries/installers only — skip the loose unbundled exe/.app dirs. + path: | + dist/*.dmg + dist/*.AppImage + dist/*.deb + dist/*.msi + if-no-files-found: error + + release: + name: publish GitHub Release + needs: build + runs-on: ubuntu-latest + # Only publish on a real version tag; workflow_dispatch stops after `build` (artifacts only). + if: startsWith(github.ref, 'refs/tags/v') + steps: + - uses: actions/checkout@v4 + + # Fail loudly if the tag and the crate version disagree (tag v0.1.0 ⇔ version 0.1.0). + - name: Check tag matches crate version + run: | + TAG="${GITHUB_REF_NAME#v}" + VER=$(cargo metadata --no-deps --format-version 1 \ + | jq -r '.packages[] | select(.name=="posel-app") | .version') + echo "tag=$TAG crate=$VER" + [ "$TAG" = "$VER" ] || { echo "::error::tag $TAG != crate version $VER"; exit 1; } + + - uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Publish release + uses: softprops/action-gh-release@v2 + with: + files: artifacts/**/* + fail_on_unmatched_files: true + generate_release_notes: true diff --git a/.gitignore b/.gitignore index a8d165b..8dd454e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /target +/dist **/*.rs.bk *.pdb .DS_Store diff --git a/README.md b/README.md index cc4dab7..2398dfe 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ is the opposite corner of the design space: ## Status -Working, in active development. v1 targets **macOS**. +Working, in active development. Runs on **macOS, Linux, and Windows**. - **REST** — request editor (method, query/headers/body), streaming response panel, environments + variables, secrets in the OS keychain, request history. @@ -36,6 +36,21 @@ Working, in active development. v1 targets **macOS**. See [docs/PLAN.md](./docs/PLAN.md) for the phased roadmap and what's next. +## Install + +Grab the latest build for your platform from the +[Releases](https://github.com/starvy/posel/releases) page: + +- **macOS** — `.dmg` (universal: Apple Silicon + Intel) +- **Linux** — `.AppImage` (portable) or `.deb` (Debian/Ubuntu) +- **Windows** — `.msi` installer + +> **Unsigned builds.** Releases aren't code-signed yet, so the OS warns on first launch: +> - **macOS** — right-click the app → **Open**, or `xattr -dr com.apple.quarantine /Applications/Posel.app`. +> - **Windows** — SmartScreen → **More info** → **Run anyway**. +> +> This goes away once signing/notarization is set up. + ## Architecture The domain logic is headless and unit-tested; GPUI is confined to the edge (`ui`/`app` only). @@ -58,8 +73,9 @@ stays protocol-agnostic. See [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md). ## Build & run Requires a current stable Rust toolchain (GPUI uses recently-stabilized std features; run -`rustup update stable` if a build fails with `E0658`). macOS only for now — secret storage uses -the macOS keychain. +`rustup update stable` if a build fails with `E0658`). Builds on macOS, Linux, and Windows; +secrets use the platform keychain (macOS Keychain, Windows Credential Manager, Linux +Secret Service). ```bash cargo run -p posel-app # the desktop app (binary: posel) diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml index 9f266dc..b83a2b3 100644 --- a/crates/app/Cargo.toml +++ b/crates/app/Cargo.toml @@ -19,3 +19,22 @@ gpui-component.workspace = true gpui-component-assets.workspace = true anyhow.workspace = true tracing-subscriber.workspace = true + +# Installer/bundle config for `cargo packager` (see .github/workflows/release.yml). `version` is read +# from [workspace.package]. GUI assets are embedded in the binary (with_assets), so no `resources`. +# `icons` is a single placeholder PNG — cargo-packager derives the per-platform .icns/.ico from it. +# No `before-packaging-command`: the release binary is built explicitly by the workflow first (the +# macOS leg lipos a universal binary), then `cargo packager --release` bundles target/release/posel. +[package.metadata.packager] +product-name = "Posel" +identifier = "com.starvy.posel" +category = "DeveloperTool" +icons = [ + "../../packaging/icons/icon.icns", + "../../packaging/icons/icon.ico", + "../../packaging/icons/icon.png", +] + +[package.metadata.packager.macos] +minimum-system-version = "11.0" +# signing-identity intentionally unset → unsigned (no failure); CI injects it once certs exist. diff --git a/packaging/icons/icon.icns b/packaging/icons/icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..290513a5d9a8ffbca934e67702929889337946e7 GIT binary patch literal 67894 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 literal 0 HcmV?d00001 diff --git a/packaging/icons/icon.png b/packaging/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5323b5d5620329d13409f611beb6116ff5af32bd GIT binary patch literal 9047 zcmeHMO=w(I6h3eAnoMJwypTm(8QW$GzJIBVe*=uh$ zQM$i7m1=r{DE47K-+R*{r*UpB@h?%bc{1O-Y*E_jP7M|sC>fv3=SOxE?f2kti)hTs zW+#S-oCd$2Y(&5c0$LDovw_?l1KDeZCZatE__>Yfq?^xQ0>CKAJokHxmdqzsiCkwO z+d2%q81T?f+Q7qnI^LZ+zt8V;IL|KuZj5|*hFfkR>I2*=;MzS22b^SwdtwdfaUY%0 zW*IFuDP+pgmO(Z{l8mFd>sS&^ovwHzda#IG=$g3ma z1gpv{mjNQo6TD3#3Yup@M0hw>KRV=4iEZ`#tOSG;M6gp3TRArFkCqjzAUb%~_PK&O zkD?NV)WwrY3XMV>6^b&5tiU(Odi&8%x13USq8P0TdYwEo3*;;X#)M#3w@{sPak1;yjrIf;2t6^l4ia zAΞS4uK7MoFy73pY~i7%5OCS6F^wlSWziD>XSj2W~vcgDwit4Yq^dTi`Q6?P>0j zRj={FtEJMHbBc!;mU`u~+kvu5i>S?A$H{7!mN2}awR>?Y?IFk$J$$3%6tj&^yRLlR z+O?~6w0PXMah9=P@zIv$+1S4P;jufnOuV~AzAt$9w03V~yXY9`=0G`LH*Lx3!6SwB z#)*q)nJD)JuQ1%MakRBQhSYXUs>LcvP4eI~EQj!fM$xQ_Y_({XfufNg7Q9Wi?y~dD z9d&1`?p;cpJyn>-``e;I_dg4NcQ?)NJbOysTF=cbac_R7(cAtV(V5A`6RoR5=iuoT z4^i77oTq2rYm~EK_SyyuWpg!q;KFlD(-x!D>PdZOhH&@)? zO0}|=^3BYD`DY8igod7U&-daQATOjCZgmkXmk1w@FfDn%L`31cho8+v(a7t@tAQNG zL+w%tUwookNiH0fGxM+&!~HrciuN;6H1fLf0IpHA6~c3OH~X1m@Q!NX+Jz5C7#6PK zfgTSS52f5Yep(l!UY+CNseECrGl_M<;^3pL@Q%l}m7UAW7|k;Ad}MxR$TyNWZw1#s z2-*U+8mqKooLOcKYXk8%57R&^KE|e|hJISpI!e~7yywCe^1o8rWLLNFwVAJ^xR%Ll zyW9#Qxm#tdr%@#-HIe&i=?e@3R_T38e=y7 zwHFsyjiarg&P`c+w6($QTh>mFN}0vV_+yopuN%*rmiqPp-R?IYU3}Htje3=g-Kh6| zcwhdnYd^X<*F8;z54K?E@qeQDfgiT~*AuXR_(1ft&a0P4(>(BT>6i@to7_gCL{0nQX@A7=~exYdnX6L(6|cbT{J42Qdv3^xqwE*|GWxz(X9mE6IB zxguYR5XSc#G-KQ>EN|z=KV9J1&oX#Rrx^`0sERweXV#eEK?N$`N*HvK!QI7qQ4{=c zm$+8OE+(+B{4B>~jRdZ=I8}2@u_x9_xK0eK-;Y#1B3UhVQ@6!KK~imEt&6kV2~c7! z%Zw@{36fUB{rwjioxPZ6W>7)>x~SBw6Ux3Una(N#wTc6@WCUJ($idPv!Yl(o?KN<4p(ZjK=OA=mRa=$NfTOIIm7(Rg+Qf zU5y~~>HJ(j&jT*M1MS36O47qWdlLPgmCJKKaQv-sKX-E~KMpMxZXiFZ^kz*8~Ery Dvm-O{ literal 0 HcmV?d00001 From ccf72ed9409f2be8c580fd454c2c45e7ae5812eb Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Thu, 18 Jun 2026 15:57:37 +0200 Subject: [PATCH 2/6] ci(temp): dry-run release build on the packaging branch (revert before merge) --- .github/workflows/release.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a8a13b0..de71753 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,6 +6,9 @@ name: Release on: push: tags: ["v*"] + # TEMP (remove before merging to main): dry-run the build/packaging job on this branch. + # The `release` job stays gated to `v*` tags, so branch pushes build artifacts but never publish. + branches: ["phase-5-packaging"] workflow_dispatch: concurrency: From b1cbd4a70089799160c313202ae7395ef4e3fdc6 Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Thu, 18 Jun 2026 16:03:46 +0200 Subject: [PATCH 3/6] fix(ci): build the release binary on Linux/Windows before packaging --- .github/workflows/release.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index de71753..7766e6f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -51,6 +51,12 @@ jobs: - name: Install cargo-packager run: cargo binstall --no-confirm cargo-packager + # No before-packaging-command in the manifest, so build the release binary explicitly. + # (macOS builds its own universal binary via lipo in the step below.) + - name: Build release binary (Linux/Windows) + if: runner.os != 'macOS' + run: cargo build --release -p posel-app + # macOS: build both arches, lipo into the default profile dir, then package WITHOUT the # default build hook (empty beforePackagingCommand) so it bundles the universal binary as-is. - name: Package (macOS — universal .app + .dmg) From 128a66a09e7f182eb9f7d8992296ddda3ba6679b Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Thu, 18 Jun 2026 16:35:23 +0200 Subject: [PATCH 4/6] fix(ci): drop --config on macOS packaging (it replaces the whole config) --- .github/workflows/release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7766e6f..5d19722 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,8 +57,9 @@ jobs: if: runner.os != 'macOS' run: cargo build --release -p posel-app - # macOS: build both arches, lipo into the default profile dir, then package WITHOUT the - # default build hook (empty beforePackagingCommand) so it bundles the universal binary as-is. + # macOS: build both arches, lipo into target/release, then package. No build hook in the + # manifest, so `--release` simply bundles the universal binary already sitting there. + # (Do NOT pass `--config` — it REPLACES the manifest config, dropping product-name/binaries.) - name: Package (macOS — universal .app + .dmg) if: runner.os == 'macOS' run: | @@ -70,8 +71,7 @@ jobs: target/aarch64-apple-darwin/release/posel \ target/x86_64-apple-darwin/release/posel lipo -info target/release/posel - cargo packager --formats app,dmg --manifest-path crates/app/Cargo.toml --out-dir "${{ github.workspace }}/dist" \ - --config '{"beforePackagingCommand": ""}' + cargo packager --release --formats app,dmg --manifest-path crates/app/Cargo.toml --out-dir "${{ github.workspace }}/dist" # Guard: the binary inside the bundle must be universal. lipo -info "$(find dist -path '*Posel.app/Contents/MacOS/posel')" # Signing is intentionally OFF (unsigned). To enable later, set these from secrets and add a From dc3e8584e18c20ca47f8697fb6a0da9d867f808d Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Thu, 18 Jun 2026 16:41:42 +0200 Subject: [PATCH 5/6] fix(ci): make cargo-packager install robust (verify + source fallback) --- .github/workflows/release.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5d19722..1702317 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -49,7 +49,13 @@ jobs: - uses: cargo-bins/cargo-binstall@main - name: Install cargo-packager - run: cargo binstall --no-confirm cargo-packager + shell: bash + run: | + # binstall is fast but sometimes exits 0 without installing; verify the binary is really + # present and fall back to a source build, then assert it's runnable. + cargo binstall --no-confirm cargo-packager || true + command -v cargo-packager >/dev/null || cargo install cargo-packager --locked + cargo packager --version # No before-packaging-command in the manifest, so build the release binary explicitly. # (macOS builds its own universal binary via lipo in the step below.) From 7e9d0b86edfe520e1a04cfef9a267baf5c4a0286 Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Thu, 18 Jun 2026 17:10:31 +0200 Subject: [PATCH 6/6] ci: drop temporary dry-run branch trigger (revert pre-merge) --- .github/workflows/release.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1702317..0f5b165 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,9 +6,6 @@ name: Release on: push: tags: ["v*"] - # TEMP (remove before merging to main): dry-run the build/packaging job on this branch. - # The `release` job stays gated to `v*` tags, so branch pushes build artifacts but never publish. - branches: ["phase-5-packaging"] workflow_dispatch: concurrency: