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
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*
!linux-unpacked
!linux-unpacked/**
201 changes: 198 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ name: release
on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: write
packages: write

env:
CSC_IDENTITY_AUTO_DISCOVERY: false

jobs:
release:
tag:
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.calver.outputs.tag }}
semver: ${{ steps.calver.outputs.semver }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
Expand All @@ -18,6 +26,7 @@ jobs:
- name: compute calver tag
id: calver
run: |
set -euo pipefail
base="$(date -u +%Y.%m.%d)"
git fetch --tags --quiet
tag="$base"
Expand All @@ -28,9 +37,195 @@ jobs:
done
tag="$base-$n"
fi
if [[ "$tag" =~ ^([0-9]{4})\.([0-9]{2})\.([0-9]{2})(-([0-9]+))?$ ]]; then
semver="$((10#${BASH_REMATCH[1]})).$((10#${BASH_REMATCH[2]})).$((10#${BASH_REMATCH[3]}))"
if [[ -n "${BASH_REMATCH[5]:-}" ]]; then
semver="${semver}-${BASH_REMATCH[5]}"
fi
else
echo "invalid calver tag: $tag" >&2
exit 1
fi
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "semver=$semver" >> "$GITHUB_OUTPUT"

- name: create release
run: gh release create "${{ steps.calver.outputs.tag }}" --generate-notes --title "${{ steps.calver.outputs.tag }}"
- name: create draft release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ steps.calver.outputs.tag }}
run: |
set -euo pipefail
notes="$(gh api "repos/${GITHUB_REPOSITORY}/releases/generate-notes" -f tag_name="$TAG" --jq .body)"
{
echo "## Install"
echo
echo "| Platform | Artefact |"
echo "|---|---|"
echo "| macOS Apple silicon | \`pidex-mac-arm64.dmg\` |"
echo "| macOS Intel | \`pidex-mac-x64.dmg\` |"
echo "| Windows | \`pidex-win-x64.exe\` |"
echo "| Linux | \`pidex-linux-x64.AppImage\` |"
echo "| Docker | \`docker pull ghcr.io/echohello-dev/pidex:${TAG}\` |"
echo
echo "macOS via Homebrew:"
echo
echo '```'
echo "brew tap echohello-dev/tap"
echo "brew install --cask pidex"
echo '```'
echo
echo "Windows via the same tap (WinGet cannot add a GitHub repo as a source):"
echo
echo '```'
echo "irm https://raw.githubusercontent.com/echohello-dev/homebrew-tap/main/winget/install-pidex.ps1 | iex"
echo '```'
echo
echo "$notes"
} > /tmp/notes.md
gh release create "$TAG" --draft --title "$TAG" --notes-file /tmp/notes.md

package:
needs: tag
strategy:
fail-fast: false
matrix:
include:
- os: macos-latest
args: --mac --arm64 --x64
- os: windows-latest
args: --win --x64
- os: ubuntu-latest
args: --linux --x64
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: jdx/mise-action@dad1bfd3df957f44999b559dd69dc1671cb4e9ea # v4.2.1
with:
install: true
- run: bun install --frozen-lockfile
- name: bundle
run: mise run bundle
- name: package
env:
SEMVER: ${{ needs.tag.outputs.semver }}
run: bunx electron-builder ${{ matrix.args }} -c.extraMetadata.version="$SEMVER" --publish never
- name: upload installers
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ needs.tag.outputs.tag }}
run: |
set -euo pipefail
shopt -s nullglob
assets=(release/pidex-*.dmg release/pidex-*.zip release/pidex-*.exe release/pidex-*.AppImage release/pidex-*.deb release/pidex-*.blockmap release/latest*.yml)
if [[ ${#assets[@]} -eq 0 ]]; then
echo "no installer artefacts in release/" >&2
ls -la release/ >&2 || true
exit 1
fi
gh release upload "$TAG" "${assets[@]}" --clobber
- name: stash linux unpacked app
if: runner.os == 'Linux'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: linux-unpacked
path: release/linux-unpacked
if-no-files-found: error

docker:
needs: [tag, package]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: linux-unpacked
path: linux-unpacked
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
id: meta
with:
images: ghcr.io/echohello-dev/pidex
tags: |
type=raw,value=${{ needs.tag.outputs.tag }}
type=raw,value=latest
- uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
file: Dockerfile
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

manifests:
needs: [tag, package]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: jdx/mise-action@dad1bfd3df957f44999b559dd69dc1671cb4e9ea # v4.2.1
with:
install: true
- name: download release artefacts
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ needs.tag.outputs.tag }}
run: gh release download "$TAG" --dir /tmp/rel --pattern 'pidex-*'
- name: write checksums and store manifests
env:
TAG: ${{ needs.tag.outputs.tag }}
run: |
set -euo pipefail
python3 - <<'PY'
import hashlib, json, pathlib
out = {}
lines = []
for path in sorted(pathlib.Path("/tmp/rel").glob("pidex-*")):
if path.name.endswith(".blockmap"):
continue
digest = hashlib.sha256(path.read_bytes()).hexdigest()
out[path.name] = digest
lines.append(f"{digest} {path.name}")
pathlib.Path("checksums.json").write_text(json.dumps(out, indent=2) + "\n")
pathlib.Path("SHA256SUMS.txt").write_text("\n".join(lines) + "\n")
PY
bun scripts/write-release-manifests.ts --tag "$TAG" --out /tmp/manifests --checksums checksums.json
- name: upload manifests
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ needs.tag.outputs.tag }}
run: |
gh release upload "$TAG" \
SHA256SUMS.txt \
/tmp/manifests/pidex.rb \
/tmp/manifests/echoHello.Pidex.yaml \
/tmp/manifests/pidex.json \
--clobber

publish:
needs: [tag, package, docker, manifests]
runs-on: ubuntu-latest
steps:
- name: publish release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ needs.tag.outputs.tag }}
run: gh release edit "$TAG" --draft=false --latest
- name: notify homebrew tap
env:
GH_TOKEN: ${{ secrets.TAP_TOKEN }}
TAG: ${{ needs.tag.outputs.tag }}
run: |
set -euo pipefail
if [ -z "${GH_TOKEN:-}" ]; then
echo "TAP_TOKEN unset; tap will pick up $TAG on its hourly cron"
exit 0
fi
gh api repos/echohello-dev/homebrew-tap/dispatches -f event_type=pidex-release
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules/
dist/
release/
.vite/
.DS_Store
*.log
Expand Down
19 changes: 16 additions & 3 deletions .mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,29 @@ run = [
"bunx electron .",
]

[tasks.bundle]
description = "Compile main, preload, and renderer"
run = [
"bunx tsc -p tsconfig.main.json",
"bunx tsc -p tsconfig.preload.json",
"bunx vite build",
]

[tasks.build]
description = "Production build: lint, typecheck, test, bundle"
run = [
"bun run lint",
"bun run typecheck",
"bun run test:unit",
"bun run test:integration",
"bunx tsc -p tsconfig.main.json",
"bunx tsc -p tsconfig.preload.json",
"bunx vite build",
"mise run bundle",
]

[tasks.package]
description = "Build native installers for this platform"
run = [
"mise run bundle",
"bunx electron-builder --publish never",
]

[tasks.start]
Expand Down
21 changes: 21 additions & 0 deletions Casks/pidex.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
cask "pidex" do
arch arm: "arm64", intel: "x64"

version :latest
sha256 :no_check

url "https://github.com/echohello-dev/pidex/releases/latest/download/pidex-mac-#{arch}.dmg"
name "pidex"
desc "Desktop workbench for the Pi coding agent"
homepage "https://github.com/echohello-dev/pidex"

depends_on macos: :sonoma

app "pidex.app"

zap trash: [
"~/Library/Application Support/pidex",
"~/Library/Preferences/dev.echohello.pidex.plist",
"~/Library/Saved Application State/dev.echohello.pidex.savedState",
]
end
36 changes: 36 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Linux desktop image for X11/Wayland forwarding. The native installers
# (DMG, NSIS, AppImage) are the supported way to run pidex day to day.
FROM debian:bookworm-slim

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libatspi2.0-0 \
libcairo2 \
libcups2 \
libdbus-1-3 \
libdrm2 \
libgbm1 \
libgtk-3-0 \
libnspr4 \
libnss3 \
libpango-1.0-0 \
libx11-6 \
libxcb1 \
libxcomposite1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxkbcommon0 \
libxrandr2 \
libxshmfence1 \
&& rm -rf /var/lib/apt/lists/*

COPY linux-unpacked /opt/pidex
RUN chmod +x /opt/pidex/pidex

ENV ELECTRON_DISABLE_SECURITY_WARNINGS=1
ENTRYPOINT ["/opt/pidex/pidex"]
Loading
Loading