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
125 changes: 125 additions & 0 deletions .github/workflows/electron-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
name: Build Electron App

on:
push:
tags:
- '*' # Triggers on version tags like v1.0.0
workflow_dispatch: # Allows manual triggering

jobs:
build:
strategy:
matrix:
# os: [macos-latest, windows-latest]
os: [windows-latest]

runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '>=1.18.0'

- name: Build frontend
env:
CI: ""
NODE_OPTIONS: "--max-old-space-size=4096"
run: |
cd web
bun install
DISABLE_ESLINT_PLUGIN='true' VITE_REACT_APP_VERSION=$(git describe --tags) bun run build
cd ..

# - name: Build Go binary (macos/Linux)
# if: runner.os != 'Windows'
# run: |
# go mod download
# go build -ldflags "-s -w -X 'one-api/common.Version=$(git describe --tags)' -extldflags '-static'" -o new-api

- name: Build Go binary (Windows)
if: runner.os == 'Windows'
run: |
go mod download
go build -ldflags "-s -w -X 'one-api/common.Version=$(git describe --tags)'" -o new-api.exe

- name: Update Electron version
run: |
cd electron
VERSION=$(git describe --tags)
VERSION=${VERSION#v} # Remove 'v' prefix if present
npm version $VERSION --no-git-tag-version --allow-same-version

- name: Install Electron dependencies
run: |
cd electron
npm install

# - name: Build Electron app (macOS)
# if: runner.os == 'macOS'
# run: |
# cd electron
# npm run build:mac
# env:
# CSC_IDENTITY_AUTO_DISCOVERY: false # Skip code signing

- name: Build Electron app (Windows)
if: runner.os == 'Windows'
run: |
cd electron
npm run build:win

# - name: Upload artifacts (macOS)
# if: runner.os == 'macOS'
# uses: actions/upload-artifact@v4
# with:
# name: macos-build
# path: |
# electron/dist/*.dmg
# electron/dist/*.zip

- name: Upload artifacts (Windows)
if: runner.os == 'Windows'
uses: actions/upload-artifact@v4
with:
name: windows-build
path: |
electron/dist/*.exe

release:
needs: build
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')

steps:
- name: Download all artifacts
uses: actions/download-artifact@v4

- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: |
# macos-build/*
windows-build/*
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
11 changes: 6 additions & 5 deletions .github/workflows/linux-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,22 @@ jobs:
- name: Build Backend (amd64)
run: |
go mod download
go build -ldflags "-s -w -X 'one-api/common.Version=$(git describe --tags)' -extldflags '-static'" -o new-api
VERSION=$(git describe --tags)
go build -ldflags "-s -w -X 'one-api/common.Version=$VERSION' -extldflags '-static'" -o new-api-$VERSION

- name: Build Backend (arm64)
run: |
sudo apt-get update
DEBIAN_FRONTEND=noninteractive sudo apt-get install -y gcc-aarch64-linux-gnu
CC=aarch64-linux-gnu-gcc CGO_ENABLED=1 GOOS=linux GOARCH=arm64 go build -ldflags "-s -w -X 'one-api/common.Version=$(git describe --tags)' -extldflags '-static'" -o new-api-arm64
VERSION=$(git describe --tags)
CC=aarch64-linux-gnu-gcc CGO_ENABLED=1 GOOS=linux GOARCH=arm64 go build -ldflags "-s -w -X 'one-api/common.Version=$VERSION' -extldflags '-static'" -o new-api-arm64-$VERSION

- name: Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
new-api
new-api-arm64
new-api-*
draft: true
generate_release_notes: true
env:
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/macos-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ jobs:
- name: Build Backend
run: |
go mod download
go build -ldflags "-X 'one-api/common.Version=$(git describe --tags)'" -o new-api-macos
VERSION=$(git describe --tags)
go build -ldflags "-X 'one-api/common.Version=$VERSION'" -o new-api-macos-$VERSION
- name: Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: new-api-macos
files: new-api-macos-*
draft: true
generate_release_notes: true
env:
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/windows-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ jobs:
- name: Build Backend
run: |
go mod download
go build -ldflags "-s -w -X 'one-api/common.Version=$(git describe --tags)'" -o new-api.exe
VERSION=$(git describe --tags)
go build -ldflags "-s -w -X 'one-api/common.Version=$VERSION'" -o new-api-$VERSION.exe
- name: Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: new-api.exe
files: new-api-*.exe
draft: true
generate_release_notes: true
env:
Expand Down
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ logs
web/dist
.env
one-api
new-api
.DS_Store
tiktoken_cache
.eslintcache
.eslintcache

electron/node_modules
electron/dist
73 changes: 73 additions & 0 deletions electron/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# New API Electron Desktop App

This directory contains the Electron wrapper for New API, providing a native desktop application with system tray support for Windows, macOS, and Linux.

## Prerequisites

### 1. Go Binary (Required)
The Electron app requires the compiled Go binary to function. You have two options:

**Option A: Use existing binary (without Go installed)**
```bash
# If you have a pre-built binary (e.g., new-api-macos)
cp ../new-api-macos ../new-api
```

**Option B: Build from source (requires Go)**
TODO

### 3. Electron Dependencies
```bash
cd electron
npm install
```

## Development

Run the app in development mode:
```bash
npm start
```

This will:
- Start the Go backend on port 3000
- Open an Electron window with DevTools enabled
- Create a system tray icon (menu bar on macOS)
- Store database in `../data/new-api.db`

## Building for Production

### Quick Build
```bash
# Ensure Go binary exists in parent directory
ls ../new-api # Should exist

# Build for current platform
npm run build

# Platform-specific builds
npm run build:mac # Creates .dmg and .zip
npm run build:win # Creates .exe installer
npm run build:linux # Creates .AppImage and .deb
```

### Build Output
- Built applications are in `electron/dist/`
- macOS: `.dmg` (installer) and `.zip` (portable)
- Windows: `.exe` (installer) and portable exe
- Linux: `.AppImage` and `.deb`

## Configuration

### Port
Default port is 3000. To change, edit `main.js`:
```javascript
const PORT = 3000; // Change to desired port
```

### Database Location
- **Development**: `../data/new-api.db` (project directory)
- **Production**:
- macOS: `~/Library/Application Support/New API/data/`
- Windows: `%APPDATA%/New API/data/`
- Linux: `~/.config/New API/data/`
41 changes: 41 additions & 0 deletions electron/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash

set -e

echo "Building New API Electron App..."

echo "Step 1: Building frontend..."
cd ../web
DISABLE_ESLINT_PLUGIN='true' bun run build
cd ../electron
Comment thread
coderabbitai[bot] marked this conversation as resolved.

echo "Step 2: Building Go backend..."
cd ..

if [[ "$OSTYPE" == "darwin"* ]]; then
echo "Building for macOS..."
CGO_ENABLED=1 go build -ldflags="-s -w" -o new-api

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

❓ Verification inconclusive

Verify CGO is required before enabling it.

Setting CGO_ENABLED=1 increases build complexity, requires C toolchain dependencies, and reduces binary portability. Many Go applications do not require CGO.

If CGO is not required, remove CGO_ENABLED=1 to simplify builds and improve portability.


🏁 Script executed:

#!/bin/bash
# Check if the codebase uses CGO

# Search for CGO-specific imports
rg -n -C2 'import\s+"C"' --type=go

# Search for CGO build tags
rg -n -C2 '//\s*go:build.*cgo' --type=go

# Search for .c, .cpp, .h files (C/C++ sources)
fd -e c -e cpp -e h -e cc

Length of output: 0


Remove CGO_ENABLED=1 from electron/build.sh
No CGO imports, build tags, or C/C++ sources detected—omit CGO for simpler, portable builds.

🤖 Prompt for AI Agents
In electron/build.sh around line 17, the go build invocation prefixes the
command with CGO_ENABLED=1 even though there are no CGO imports or C/C++
sources; remove the CGO_ENABLED=1 prefix (or set it to 0) so the build runs
without enabling cgo, leaving the rest of the build flags and output name
unchanged and committing that change.

cd electron
npm install
npm run build:mac
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
echo "Building for Linux..."
CGO_ENABLED=1 go build -ldflags="-s -w" -o new-api
cd electron
npm install
npm run build:linux
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" || "$OSTYPE" == "win32" ]]; then
echo "Building for Windows..."
CGO_ENABLED=1 go build -ldflags="-s -w" -o new-api.exe
cd electron
npm install
npm run build:win
else
echo "Unknown OS, building for current platform..."
CGO_ENABLED=1 go build -ldflags="-s -w" -o new-api
cd electron
npm install
npm run build
fi

echo "Build complete! Check electron/dist/ for output."
60 changes: 60 additions & 0 deletions electron/create-tray-icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Create a simple tray icon for macOS
// Run: node create-tray-icon.js

const fs = require('fs');
const { createCanvas } = require('canvas');

function createTrayIcon() {
// For macOS, we'll use a Template image (black and white)
// Size should be 22x22 for Retina displays (@2x would be 44x44)
const canvas = createCanvas(22, 22);
const ctx = canvas.getContext('2d');

// Clear canvas
ctx.clearRect(0, 0, 22, 22);

// Draw a simple "API" icon
ctx.fillStyle = '#000000';
ctx.font = 'bold 10px system-ui';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('API', 11, 11);

// Save as PNG
const buffer = canvas.toBuffer('image/png');
fs.writeFileSync('tray-icon.png', buffer);

// For Template images on macOS (will adapt to menu bar theme)
fs.writeFileSync('tray-iconTemplate.png', buffer);
fs.writeFileSync('tray-iconTemplate@2x.png', buffer);

console.log('Tray icon created successfully!');
}

// Check if canvas is installed
try {
createTrayIcon();
} catch (err) {
console.log('Canvas module not installed.');
console.log('For now, creating a placeholder. Install canvas with: npm install canvas');

// Create a minimal 1x1 transparent PNG as placeholder
const minimalPNG = Buffer.from([
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
0x01, 0x03, 0x00, 0x00, 0x00, 0x25, 0xDB, 0x56,
0xCA, 0x00, 0x00, 0x00, 0x03, 0x50, 0x4C, 0x54,
0x45, 0x00, 0x00, 0x00, 0xA7, 0x7A, 0x3D, 0xDA,
0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4E, 0x53,
0x00, 0x40, 0xE6, 0xD8, 0x66, 0x00, 0x00, 0x00,
0x0A, 0x49, 0x44, 0x41, 0x54, 0x08, 0x1D, 0x62,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x0A, 0x2D, 0xCB, 0x59, 0x00, 0x00,
0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42,
0x60, 0x82
]);

fs.writeFileSync('tray-icon.png', minimalPNG);
console.log('Created placeholder tray icon.');
}
Loading