Skip to content
Open
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
192 changes: 150 additions & 42 deletions .github/workflows/code-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ jobs:
APP_VERSION: ${{ steps.version.outputs.version }}
run: |
# Pre-create a single draft release so every parallel publish job uploads
# into the same release. Without this, electron-forge's GitHub publisher
# creates-if-missing from each job at once, producing multiple releases for
# one tag and scattering assets (the orphans get left as drafts).
# into the same release. Without this, parallel jobs each create-if-missing
# at once, producing multiple releases for one tag and scattering assets
# (the orphans get left as drafts).
if gh release view "v$APP_VERSION" --repo PostHog/code >/dev/null 2>&1; then
echo "Release v$APP_VERSION already exists — reusing it"
else
Expand Down Expand Up @@ -68,13 +68,11 @@ jobs:
POSTHOG_SOURCEMAP_API_KEY: ${{ secrets.POSTHOG_SOURCEMAP_API_KEY }}
POSTHOG_ENV_ID: ${{ secrets.POSTHOG_ENV_ID }}
POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }}
APPLE_CODESIGN_IDENTITY: ${{ secrets.APPLE_CODESIGN_IDENTITY }}
CSC_LINK: ${{ secrets.APPLE_CODESIGN_CERT_BASE64 }}
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CODESIGN_CERT_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_CODESIGN_CERT_BASE64: ${{ secrets.APPLE_CODESIGN_CERT_BASE64 }}
APPLE_CODESIGN_CERT_PASSWORD: ${{ secrets.APPLE_CODESIGN_CERT_PASSWORD }}
APPLE_CODESIGN_KEYCHAIN_PASSWORD: ${{ secrets.APPLE_CODESIGN_KEYCHAIN_PASSWORD }}
steps:
- name: Get app token
id: app-token
Expand Down Expand Up @@ -145,35 +143,49 @@ jobs:
- name: Build agent package
run: pnpm --filter @posthog/agent run build

- name: Import code signing certificate
if: env.APPLE_CODESIGN_IDENTITY != ''
- name: Build release artifacts
env:
CERT_BASE64: ${{ env.APPLE_CODESIGN_CERT_BASE64 }}
CERT_PASSWORD: ${{ env.APPLE_CODESIGN_CERT_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ env.APPLE_CODESIGN_KEYCHAIN_PASSWORD }}
APP_VERSION: ${{ steps.version.outputs.version }}
working-directory: apps/code
run: |
if [ -z "$CERT_BASE64" ] || [ -z "$CERT_PASSWORD" ] || [ -z "$KEYCHAIN_PASSWORD" ]; then
echo "Missing code signing certificate secrets"
exit 1
node scripts/build.mjs
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
pnpm exec electron-builder build --mac --arm64 --publish never --config electron-builder.config.cjs
else
pnpm exec electron-builder build --mac --x64 --publish never --config electron-builder.config.cjs
fi
KEYCHAIN="$RUNNER_TEMP/codesign.keychain-db"
echo "$CERT_BASE64" | base64 --decode > "$RUNNER_TEMP/certificate.p12"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
security set-keychain-settings -lut 21600 "$KEYCHAIN"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
security import "$RUNNER_TEMP/certificate.p12" -k "$KEYCHAIN" -P "$CERT_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security
security list-keychains -d user -s "$KEYCHAIN" $(security list-keychains -d user | tr -d '"')
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
rm "$RUNNER_TEMP/certificate.p12"

- name: Build native modules
run: pnpm --filter code run build-native

- name: Build release artifacts
env:
APP_VERSION: ${{ steps.version.outputs.version }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
run: pnpm --filter code exec electron-forge publish --dry-run --arch=${{ matrix.arch }} --platform=darwin
- name: Verify package
run: |
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
APP_BUNDLE="apps/code/out/mac-arm64/PostHog Code.app"
else
APP_BUNDLE="apps/code/out/mac/PostHog Code.app"
fi
RESOURCES="$APP_BUNDLE/Contents/Resources"
UNPACKED="$RESOURCES/app.asar.unpacked/node_modules"

if [[ ! -f "$RESOURCES/app-update.yml" ]]; then
echo "FAIL: app-update.yml missing at $RESOURCES/app-update.yml"
exit 1
fi
echo "OK: app-update.yml"

for mod in node-pty better-sqlite3 "@parcel/watcher"; do
if [[ ! -d "$UNPACKED/$mod" ]]; then
echo "FAIL: $mod missing in app.asar.unpacked/node_modules"
exit 1
fi
echo "OK: $mod"
done

for bin in claude-cli codex-acp; do
if [[ ! -d "$RESOURCES/app.asar.unpacked/.vite/build/$bin" ]]; then
echo "FAIL: $bin missing in bundled binaries"
exit 1
fi
echo "OK: $bin"
done

- name: Install Playwright
run: pnpm --filter code exec playwright install
Expand All @@ -192,11 +204,22 @@ jobs:
path: apps/code/playwright-report/
retention-days: 7

- name: Publish release artifacts
- name: Upload release artifacts
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
APP_VERSION: ${{ steps.version.outputs.version }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
run: pnpm --filter code exec electron-forge publish --from-dry-run
run: |
gh release upload "v$APP_VERSION" --repo PostHog/code --clobber \
apps/code/out/*.dmg \
apps/code/out/*-mac.zip \
apps/code/out/*.blockmap

- name: Upload mac manifest artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: mac-manifest-${{ matrix.arch }}
path: apps/code/out/latest-mac.yml
retention-days: 1

publish-windows:
needs: [prepare-release]
Expand Down Expand Up @@ -274,18 +297,46 @@ jobs:
- name: Build agent package
run: pnpm --filter @posthog/agent run build

- name: Publish with Electron Forge
- name: Build release artifacts
env:
APP_VERSION: ${{ steps.version.outputs.version }}
working-directory: apps/code
run: |
node scripts/build.mjs
pnpm exec electron-builder build --win --x64 --publish never --config electron-builder.config.cjs

- name: Upload release artifacts
shell: pwsh
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
APP_VERSION: ${{ steps.version.outputs.version }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
run: pnpm --filter code run publish
run: |
$out = "apps/code/out"
$sq = Join-Path $out "squirrel-windows"
$items = @()
# NSIS installer + electron-updater metadata live in the output root.
$items += Get-ChildItem $out -File -Filter "*.exe"
$items += Get-ChildItem $out -File -Filter "latest.yml"
$items += Get-ChildItem $out -File -Filter "*.blockmap"
# Squirrel.Windows artifacts (nupkg + RELEASES + Setup) land in out/squirrel-windows.
if (Test-Path $sq) {
$items += Get-ChildItem $sq -File -Filter "*.nupkg"
$items += Get-ChildItem $sq -File -Filter "RELEASES"
$items += Get-ChildItem $sq -File -Filter "*.exe"
}
$files = $items | Select-Object -ExpandProperty FullName
gh release upload "v$env:APP_VERSION" --repo PostHog/code --clobber @files

publish-linux:
needs: [prepare-release]
strategy:
fail-fast: false
matrix:
runner: [ubuntu-24.04, ubuntu-24.04-arm]
include:
- runner: ubuntu-24.04
arch: x64
- runner: ubuntu-24.04-arm
arch: arm64
runs-on: ${{ matrix.runner }}
permissions:
id-token: write
Expand Down Expand Up @@ -362,11 +413,27 @@ jobs:
- name: Build agent package
run: pnpm --filter @posthog/agent run build

- name: Publish with Electron Forge
- name: Build release artifacts
env:
APP_VERSION: ${{ steps.version.outputs.version }}
working-directory: apps/code
run: |
node scripts/build.mjs
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
pnpm exec electron-builder build --linux --arm64 --publish never --config electron-builder.config.cjs
else
pnpm exec electron-builder build --linux --x64 --publish never --config electron-builder.config.cjs
fi

- name: Upload release artifacts
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
APP_VERSION: ${{ steps.version.outputs.version }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
run: pnpm --filter code run publish
run: |
gh release upload "v$APP_VERSION" --repo PostHog/code --clobber \
apps/code/out/*.AppImage \
apps/code/out/*.deb \
apps/code/out/*.rpm

finalize-release:
needs: [publish-macos, publish-windows, publish-linux]
Expand All @@ -391,6 +458,47 @@ jobs:
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
echo "version=$TAG_VERSION" >> "$GITHUB_OUTPUT"

- name: Checkout merge script
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout: |
apps/code/scripts/merge-mac-manifests.mjs
sparse-checkout-cone-mode: false

- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22

- name: Install yaml dependency
run: npm install --prefix apps/code yaml

- name: Download arm64 mac manifest
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: mac-manifest-arm64
path: /tmp/mac-manifests/arm64

- name: Download x64 mac manifest
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: mac-manifest-x64
path: /tmp/mac-manifests/x64

- name: Merge mac manifests
run: |
node apps/code/scripts/merge-mac-manifests.mjs \
/tmp/mac-manifests/arm64/latest-mac.yml \
/tmp/mac-manifests/x64/latest-mac.yml \
/tmp/latest-mac.yml

- name: Upload merged mac manifest
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
APP_VERSION: ${{ steps.version.outputs.version }}
run: |
gh release upload "v$APP_VERSION" --repo PostHog/code --clobber /tmp/latest-mac.yml

- name: Publish GitHub release
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,6 @@ jobs:
pnpm --filter agent build &
wait

- name: Build native modules
run: pnpm --filter code run build-native

- name: Package Electron app
run: pnpm --filter code run package
env:
Expand Down
14 changes: 14 additions & 0 deletions apps/code/build/entitlements.mac.inherit.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>
Loading
Loading