Skip to content

Commit 49b293f

Browse files
authored
Merge pull request #1 from Toolbase-AI/gching/workflow
Add in workflow to build and publish for macOS and Windows
2 parents 4188619 + f44313b commit 49b293f

File tree

8 files changed

+515
-166
lines changed

8 files changed

+515
-166
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
name: Build and Publish
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
jobs:
9+
build:
10+
runs-on: ${{ matrix.platform }}
11+
12+
strategy:
13+
matrix:
14+
platform: [macos-latest, macos-13, windows-latest]
15+
16+
defaults:
17+
run:
18+
working-directory: packages/app
19+
20+
steps:
21+
- name: Check out Git repository
22+
uses: actions/checkout@v4
23+
24+
- name: Install Deno
25+
uses: denoland/setup-deno@v2
26+
with:
27+
deno-version: v2.x
28+
29+
- name: Install Node.js
30+
uses: actions/setup-node@v4
31+
with:
32+
node-version: "22.x"
33+
cache: "npm"
34+
cache-dependency-path: packages/app/package-lock.json
35+
36+
- name: Install dependencies
37+
run: npm ci
38+
39+
- name: Install Apple Certificate
40+
if: matrix.platform == 'macos-latest' || matrix.platform == 'macos-13'
41+
env:
42+
BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_BUILD_CERTIFICATE_BASE64 }}
43+
P12_PASSWORD: ${{ secrets.APPLE_P12_PASSWORD }}
44+
KEYCHAIN_PASSWORD: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
45+
run: |
46+
# create variables
47+
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
48+
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
49+
50+
# import certificate and provisioning profile from secrets
51+
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
52+
53+
# create temporary keychain
54+
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
55+
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
56+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
57+
58+
# import certificate to keychain
59+
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
60+
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
61+
security list-keychain -d user -s $KEYCHAIN_PATH
62+
63+
- name: Package application
64+
env:
65+
APPLE_IDENTITY: ${{ secrets.APPLE_IDENTITY }}
66+
APPLE_ID: ${{ secrets.APPLE_ID }}
67+
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
68+
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
69+
run: npm run package
70+
71+
- name: Sign Windows Package
72+
if: matrix.platform == 'windows-latest'
73+
uses: azure/[email protected]
74+
with:
75+
files-folder: packages/app/out
76+
files-folder-filter: exe,dll,sys,efi,scr,node,msi,appx,appxbundle,msix,msixbundle,cat,cab,xap,vbs,wsf,ps1
77+
files-folder-recurse: true
78+
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
79+
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
80+
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
81+
endpoint: ${{ secrets.AZURE_ENDPOINT }}
82+
trusted-signing-account-name: ${{ secrets.AZURE_CODE_SIGNING_NAME }}
83+
certificate-profile-name: ${{ secrets.AZURE_CERT_PROFILE_NAME }}
84+
85+
- name: Make distributables
86+
run: npm run make -- --skip-package
87+
88+
- name: Publish to GitHub
89+
run: npm run publish -- --from-dry-run

packages/app/forge.config.cts

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,16 @@ import { exec } from 'node:child_process';
22
import * as fs from 'node:fs';
33
import * as path from 'node:path';
44
import { MakerDMG } from '@electron-forge/maker-dmg';
5+
import { MakerSquirrel } from '@electron-forge/maker-squirrel';
56
import { MakerZIP } from '@electron-forge/maker-zip';
67
import { FusesPlugin } from '@electron-forge/plugin-fuses';
78
import { VitePlugin } from '@electron-forge/plugin-vite';
8-
import type { ForgeConfig } from '@electron-forge/shared-types';
9+
import { PublisherGithub } from '@electron-forge/publisher-github';
10+
import { type ForgeConfig } from '@electron-forge/shared-types';
911
import { FuseV1Options, FuseVersion } from '@electron/fuses';
12+
import { type TargetPlatform } from '@electron/packager';
1013

11-
// function getRunnerTarget (platform: string, arch: string) => {
12-
// if (platform === 'darwin') {
13-
// if (arch === 'arm64') {
14-
// return 'aarch64-apple-darwin';
15-
// } else if (arch === 'x64') {
16-
// return 'x86_64-apple-darwin';
17-
// } else {
18-
// throw new Error(`Unsupported architecture: ${arch}`);
19-
// }
20-
// } else {
21-
// throw new Error(`Unsupported platform: ${platform}`);
22-
// }
23-
// };
14+
const runnerPackageDirPath = path.join(__dirname, '../runner');
2415

2516
function execAsync(
2617
command: string,
@@ -37,20 +28,39 @@ function execAsync(
3728
});
3829
}
3930

40-
// Get runner build path
41-
const binRunnerBinaryPath = path.join(__dirname, 'bin/toolbase-runner');
42-
const runnerPackageDirPath = path.join(__dirname, '../runner');
43-
const runnerPackageBinaryPath = path.join(
44-
runnerPackageDirPath,
45-
`out/toolbase-runner`,
46-
);
31+
function getRunnerPaths(platform: TargetPlatform) {
32+
switch (platform) {
33+
case 'darwin':
34+
case 'mas':
35+
case 'linux':
36+
return {
37+
binLocalRunnerRelativePath: './bin/toolbase-runner',
38+
binRunnerBinaryPath: path.join(__dirname, 'bin/toolbase-runner'),
39+
runnerPackageBinaryPath: path.join(
40+
runnerPackageDirPath,
41+
`out/toolbase-runner`,
42+
),
43+
};
44+
case 'win32':
45+
return {
46+
binLocalRunnerRelativePath: './bin/toolbase-runner.exe',
47+
binRunnerBinaryPath: path.join(__dirname, 'bin/toolbase-runner.exe'),
48+
runnerPackageBinaryPath: path.join(
49+
runnerPackageDirPath,
50+
`out/toolbase-runner.exe`,
51+
),
52+
};
53+
}
54+
55+
throw new Error(`Unsupported platform: ${platform}`);
56+
}
4757

4858
const config: ForgeConfig = {
4959
packagerConfig: {
5060
asar: true,
5161
icon: './icons/icon',
5262
// Include the runner binary
53-
extraResource: ['./bin/toolbase-runner'],
63+
// extraResource: ['./bin/toolbase-runner', './bin/toolbase-runner.exe'],
5464
osxSign: {
5565
identity: process.env.APPLE_IDENTITY,
5666
},
@@ -61,7 +71,7 @@ const config: ForgeConfig = {
6171
},
6272
},
6373
hooks: {
64-
async generateAssets() {
74+
async generateAssets(config, platform, arch) {
6575
// @important - This does some smart logic of only rebuilding the runner if necessary, but feels like it could cause lots of headaches.
6676
// toolbase-runner exists in bin/
6777
// if (fs.existsSync(binRunnerBinaryPath)) {
@@ -88,27 +98,52 @@ const config: ForgeConfig = {
8898
// return;
8999
// }
90100

101+
const {
102+
binLocalRunnerRelativePath,
103+
binRunnerBinaryPath,
104+
runnerPackageBinaryPath,
105+
} = getRunnerPaths(platform);
106+
91107
// Create it if it doesn't exist
92108
fs.mkdirSync(path.dirname(binRunnerBinaryPath), { recursive: true });
93109

94110
// Build on demand for the target platform and architecture and copy
95-
await execAsync('deno task build', runnerPackageDirPath);
111+
const { stdout, stderr } = await execAsync(
112+
`deno task build -p ${platform} -a ${arch}`,
113+
runnerPackageDirPath,
114+
);
115+
116+
console.log(stdout, stderr);
117+
96118
fs.copyFileSync(runnerPackageBinaryPath, binRunnerBinaryPath);
97119

98120
console.log(
99-
`Built and copied "toolbase-runner" from "${runnerPackageBinaryPath}" to "${binRunnerBinaryPath}"`,
121+
`Built and copied "toolbase-runner" from "${runnerPackageBinaryPath}" to "${binRunnerBinaryPath} for ${platform}-${arch}"`,
100122
);
123+
124+
// Add to our config
125+
config.packagerConfig.extraResource = [binLocalRunnerRelativePath];
101126
},
102127
},
103128
rebuildConfig: {},
104129
makers: [
130+
new MakerSquirrel({}),
105131
new MakerZIP({}, ['darwin']),
106132
//@ts-expect-error MakerDMS has incorrect types.
107133
new MakerDMG({
108134
overwrite: true,
109135
icon: './icons/icon.icns',
110136
}),
111137
],
138+
publishers: [
139+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
140+
new PublisherGithub({
141+
repository: { owner: 'toolbase-ai', name: 'toolbase' },
142+
prerelease: false,
143+
draft: true,
144+
generateReleaseNotes: true,
145+
}),
146+
],
112147
plugins: [
113148
new VitePlugin({
114149
// `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc.

0 commit comments

Comments
 (0)