Skip to content

Merge pull request #7 from off-grid-ai/release-core #34

Merge pull request #7 from off-grid-ai/release-core

Merge pull request #7 from off-grid-ai/release-core #34

Workflow file for this run

name: Build and Release
on:
push:
branches:
- main
permissions:
contents: write
concurrency:
group: release
cancel-in-progress: false
# macOS-only for now. ONE signed + notarized DMG: the build bundles the private pro
# source (cloned from off-grid-ai/desktop-pro) and is license-gated at runtime —
# free = unlicensed (pro tabs locked), a valid Keygen key unlocks in place (no
# re-download). The ASAR integrity fuse (electron-builder.yml) makes a tampered
# app.asar refuse to load — our local-first anti-tamper lever (we don't phone home).
# Actions are pinned to commit SHAs. Windows is parked.
jobs:
# Bump the version once and push it so the build job builds that exact commit.
version:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
runs-on: ubuntu-latest
outputs:
version: ${{ steps.bump.outputs.version }}
sha: ${{ steps.bump.outputs.sha }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
- name: Bump patch version
id: bump
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
npm version patch --no-git-tag-version
VERSION=$(node -p "require('./package.json').version")
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
git add package.json package-lock.json
git commit -m "chore: bump version to $VERSION [skip ci]"
git push
# Pin the build to THIS exact commit, not floating main (avoids the
# concurrent-bump version race).
echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
# Single build: pro code bundled, license-gated. Publishes to the default update
# channel (latest-mac.yml).
build-mac:
needs: version
runs-on: macos-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ needs.version.outputs.sha }} # the exact bumped commit
fetch-depth: 0
lfs: true # resources/bin/* (llama-server, sd-cli, whisper, ffmpeg, dylibs)
# are Git LFS — without this CI bundles pointer stubs and every
# runtime spawn fails with ENOEXEC.
- name: Pull LFS binaries
run: git lfs pull
# Private pro source into pro/ → __OFFGRID_PRO__ true. The checkout action
# injects the token as an http.extraheader (never in a clone URL) and scrubs
# it afterwards — safer than embedding ${TOKEN} in a git URL.
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
repository: off-grid-ai/desktop-pro
token: ${{ secrets.PRO_REPO_TOKEN }}
path: pro
fetch-depth: 1
- name: Drop nested .git from pro/
run: rm -rf pro/.git # don't nest a repo inside the build tree
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build (typecheck + bundle)
run: npm run build
- name: Package, sign, notarize & publish (DMG + auto-update metadata)
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
APPLE_API_KEY_CONTENT: ${{ 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 }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# notarytool needs the API key as a file; write it from the secret.
printf '%s' "$APPLE_API_KEY_CONTENT" > "$RUNNER_TEMP/AuthKey.p8"
export APPLE_API_KEY="$RUNNER_TEMP/AuthKey.p8"
# ONE signed + notarized build, published to the default update channel
# (the flow that shipped 0.0.22–0.0.24). electron-builder uploads the DMG
# (human download) plus the zip + latest-mac.yml + blockmap that
# electron-updater needs, so existing users keep auto-updating.
npx electron-builder --mac \
-c.dmg.artifactName='OffGrid-${version}.${ext}' \
--publish always
- name: Migrate legacy Pro update channel (publish pro-mac.yml)
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ needs.version.outputs.version }}
run: |
# Older Pro builds poll a SEPARATE channel (pro-mac.yml); the single build
# now publishes only the default latest-mac.yml. Upload a copy as
# pro-mac.yml (identical - same signed zip + version) so those installs see
# this release, auto-update, and land on the default channel. After that
# they follow latest-mac.yml. One-time bridge so no Pro user is orphaned.
cp dist/latest-mac.yml dist/pro-mac.yml
gh release upload "v$VERSION" dist/pro-mac.yml --clobber