Skip to content

Update README: live download badges, mark completed TODO items #18

Update README: live download badges, mark completed TODO items

Update README: live download badges, mark completed TODO items #18

Workflow file for this run

name: Build & Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
dry_run:
description: 'Build only (skip release creation)'
required: false
default: 'false'
permissions:
contents: write
jobs:
build:
name: Build (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
include:
- os: ubuntu-latest
script: linux
artifact_glob: |
dist/*.AppImage
dist/*.deb
- os: windows-latest
script: win
artifact_glob: |
dist/*.exe
- os: macos-latest
script: mac
artifact_glob: |
dist/*.dmg
dist/*.zip
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
# electron-builder reads `version` from package.json for artifact
# naming (e.g. OpenCluely-1.0.0-x64.dmg). When we build from a
# git tag (v1.0.7) the package.json still says 1.0.0 by default,
# so artifact names drift from the release tag. Sync them here.
# `npm pkg set` is cross-platform and doesn't touch git.
- name: Sync package.json version from tag
if: startsWith(github.ref, 'refs/tags/v')
shell: bash
run: |
VERSION="${GITHUB_REF_NAME#v}"
echo "Tag version: $VERSION"
CURRENT=$(node -p "require('./package.json').version")
echo "Current package.json version: $CURRENT"
if [ "$VERSION" != "$CURRENT" ]; then
npm pkg set "version=$VERSION"
echo "Updated package.json to $VERSION"
else
echo "Version already matches tag"
fi
# Linux: install LinuxBuild dependencies so electron-builder can produce .deb / .AppImage
- name: Install Linux build dependencies
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
fakeroot dpkg rpm \
libgtk-3-0 libnotify4 libnss3 libxss1 libxtst6 \
xauth xvfb libasound2t64 ffmpeg \
python3 python3-venv python3-pip
# Windows: enable long paths for electron-builder
- name: Enable Windows long paths
if: matrix.os == 'windows-latest'
shell: pwsh
run: git config --system core.longpaths true
- name: Build
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Intentionally do NOT set CSC_LINK / WIN_CSC_LINK etc.
# electron-builder treats empty strings as "set but invalid"
# and tries to resolve them as certificate paths, producing
# "Env WIN_CSC_LINK is not correct" errors. Code signing is
# opt-in: add the secrets to the repo and wire them in here
# only when you have real certificates.
CSC_IDENTITY_AUTO_DISCOVERY: 'false'
run: npm run build:${{ matrix.script }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: opencluely-${{ matrix.os }}
path: ${{ matrix.artifact_glob }}
if-no-files-found: warn
release:
name: Create GitHub Release
needs: build
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- name: Checkout (full history for changelog)
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate commit changelog
id: changelog
shell: bash
run: |
CURRENT_TAG="${GITHUB_REF_NAME}"
# Find the most recent tag that is not the current one
PREV_TAG=$(git tag --sort=-version:refname | grep -v "^${CURRENT_TAG}$" | head -1)
if [ -z "$PREV_TAG" ]; then
# First ever release — include all commits
COMMIT_LOG=$(git log --pretty=format:"- \`%h\` %s" --reverse)
RANGE_LABEL="Initial release"
else
COMMIT_LOG=$(git log "${PREV_TAG}..${CURRENT_TAG}" --pretty=format:"- \`%h\` %s" --reverse)
RANGE_LABEL="[\`${PREV_TAG}..${CURRENT_TAG}\`](https://github.com/${{ github.repository }}/compare/${PREV_TAG}...${CURRENT_TAG})"
fi
# Write combined body to file (multiline-safe)
cat > RELEASE_BODY.md << 'BODY_EOF'
## Installation
Choose the artifact for your platform:
| Platform | File | Notes |
|---|---|---|
| **Windows** | `OpenCluely-Setup-*.exe` | NSIS installer — installs app + adds to Start Menu |
| **macOS (Apple Silicon)** | `*-arm64.dmg` | M1/M2/M3/M4 Macs |
| **macOS (Intel)** | `*-x64.dmg` | Older Intel Macs |
| **Linux** | `*.deb` | Debian/Ubuntu — auto-pulls system deps (Python, ffmpeg, GTK) |
| **Linux** | `*.AppImage` | Universal — no install, just `chmod +x` and run |
## First Run
On first launch, OpenCluely opens the **Settings** window automatically for your **Google Gemini API key**.
Get a free key from [Google AI Studio](https://aistudio.google.com/). You can also edit `.env` directly.
## Optional: Local Whisper (offline speech)
Install **Python 3.10+** and **ffmpeg**, then run:
```bash
./setup.sh --skip-install-system-deps
```
## Checksums
See `SHA256SUMS.txt` attached to this release.
BODY_EOF
# Append the changelog section
{
echo ""
echo "## What's Changed"
echo ""
echo "**Full Changelog**: ${RANGE_LABEL}"
echo ""
echo "${COMMIT_LOG}"
} >> RELEASE_BODY.md
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Flatten artifacts
run: |
mkdir -p release
# Pick only the primary installer per platform (max 2-3 per
# platform). This intentionally drops:
# - Windows portable EXE (we ship the NSIS installer)
# - macOS .zip (the DMG is the canonical macOS installer)
# - .blockmap files (electron-updater diff metadata)
# - latest-*.yml (electron-updater channel metadata)
# - Source archives (GitHub auto-generates these from the tag)
#
# The order below is the order files appear in the release page.
find artifacts -type f -name 'OpenCluely-Setup-*.exe' \
-exec cp -v {} release/ \;
# macOS DMGs — electron-builder omits the arch suffix for the
# default (x64) arch, so we keep every OpenCluely-*.dmg.
find artifacts -type f -name 'OpenCluely-*.dmg' \
-exec cp -v {} release/ \;
find artifacts -type f -name 'opencluely_*_amd64.deb' \
-exec cp -v {} release/ \;
find artifacts -type f -name '*.AppImage' \
-exec cp -v {} release/ \;
echo "--- Files selected for release ---"
ls -la release/
- name: Generate SHA256 checksums
working-directory: release
run: |
sha256sum * > SHA256SUMS.txt
cat SHA256SUMS.txt
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: OpenCluely ${{ github.ref_name }}
draft: false
prerelease: false
body_path: RELEASE_BODY.md
files: |
release/*
fail_on_unmatched_files: false