Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Todesktop - Windows Mac Build/Sign Complete #133

Merged
merged 17 commits into from
Oct 28, 2024
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
2 changes: 0 additions & 2 deletions .github/actions/build/windows/todesktop/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ runs:
shell: cmd
- run: yarn set version --yarn-path self
shell: cmd
- run: yarn install --immutable
shell: cmd
- name: Make app
shell: powershell
env:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"@electron/windows-sign": "^1.1.3",
"@playwright/test": "^1.47.2",
"@sentry/wizard": "^3.30.0",
"@todesktop/cli": "^1.9.6",
"@todesktop/cli": "^1.9.7",
"@types/adm-zip": "^0.5.5",
"@types/electron-squirrel-startup": "^1.0.2",
"@types/jest": "^29.5.13",
Expand Down
38 changes: 24 additions & 14 deletions scripts/signPython.sh
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
python -m pip install --upgrade pip
pip install comfy-cli
cd ../..
echo $(dirname $0)
python -m pip install --upgrade pip >/dev/null
wait
pip install comfy-cli >/dev/null
wait
ls
cd assets
comfy --skip-prompt --here install --fast-deps --m-series --manager-url https://github.com/Comfy-Org/manager-core
comfy --skip-prompt --here install --fast-deps --m-series --manager-url https://github.com/Comfy-Org/manager-core >/dev/null
wait
cd ComfyUI
cd ..
comfy --here standalone --platform macos
comfy --here standalone --platform macos
wait
comfy standalone --rehydrate
rmdir ComfyUI/custom_nodes/ComfyUI-Manager/.git
wait
rm -rf ComfyUI/custom_nodes/ComfyUI-Manager/.git
mkdir python2/
tar -xzf python.tgz -C python2/
rm python.tgz
find . -type l ! -exec test -e {} \; -delete
wait
find . -name '*.tar.gz' -delete
wait
ls
echo Sign Libs and Bins
cd python2/python/
filelist=("lib/libpython3.12.dylib" "lib/python3.12/lib-dynload/_crypt.cpython-312-darwin.so" "bin/uv" "bin/uvx" "bin/python3.12")
for file in ${filelist[@]}; do codesign --sign 6698D856280DC1662A8E01E5B63428CB6D6651BB --force --timestamp --options runtime --entitlements ../../../scripts/entitlements.mac.plist "$file"; done
echo Rezip
cd ../..
mv python python3
mv python2/python python
tar -czf python.tgz python/
mkdir output
rm -rf python2
rm -rf python3
cd python
filelist=("lib/libpython3.12.dylib" "lib/python3.12/lib-dynload/_crypt.cpython-312-darwin.so" "bin/uv" "bin/uvx" "bin/python3.12")
for file in ${filelist[@]}; do mkdir -p `dirname ../output/$file` && mv "$file" ../output/"$file"; done
cd ..
rmdir ./.git
echo Rezip
tar -czf python.tgz python/
rm -rf python
85 changes: 84 additions & 1 deletion scripts/todesktop/afterPack.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
const os = require('os');
const fs = require('fs/promises');
const path = require('path');
const { exec } = require('child_process');

module.exports = async ({ appOutDir, packager }) => {
module.exports = async ({ appOutDir, packager, outDir }) => {
/**
* appPkgName - string - the name of the app package
* appId - string - the app id
Expand All @@ -9,4 +13,83 @@ module.exports = async ({ appOutDir, packager }) => {
* packager - object - the packager object
* arch - number - the architecture of the app. ia32 = 0, x64 = 1, armv7l = 2, arm64 = 3, universal = 4.
*/

async function removeInvalidSymlinks(appPath) {
const invalidSymlinksInManyLines = await new Promise((resolve, reject) => {
exec(`find ${appPath} -type l ! -exec test -e {} \\; -print`, (error, stdout, stderr) => {
console.log(`command: find ${appPath} -type l ! -exec test -e {} \\; -print`)
if (error) {
console.error(`error: ${error.message}`);
return reject(error);
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return reject(stderr);
}
console.log(`stdout: ${stdout}`);
resolve(stdout);
})
});

console.log("======invalidSymlinksInManyLines======")
console.log(invalidSymlinksInManyLines)
console.log("===========================")

const invalidSymlinksInArray = invalidSymlinksInManyLines.split("\n")
.map((invalidSymlink) => invalidSymlink.trim())
.filter((maybeEmptyPath) => maybeEmptyPath !== '');

console.log("======invalidSymlinksInArray======")
console.log(invalidSymlinksInArray)
console.log("===========================")

const waitUntilAllInvalidSymlinksRemoved = invalidSymlinksInArray.map((invalidSymlink) => {
return new Promise((resolve) => {
exec(`rm ${invalidSymlink}`, (error, stdout, stderr) => {
console.log(`command: rm ${invalidSymlink}`)

if (error) {
console.error(`error: ${error.message}`);
return reject(error);
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return reject(stderr);
}
console.log(`stdout: ${stdout}`);
resolve(stdout);
})
})
})

try {
await Promise.all(waitUntilAllInvalidSymlinksRemoved);
} catch (e) {
console.log(`error happened while removing all invalid symlinks. message: ${e.message}`);
}

return;
}

if (os.platform() === "darwin") {
const appName = packager.appInfo.productFilename;
const appPath = path.join(`${appOutDir}`, `${appName}.app`);
const mainPath = path.dirname(outDir);
const assetPath = path.join(mainPath, 'app-wrapper', 'app', 'assets');
const resourcePath = path.join(appPath, "Contents", "Resources");
const result = await fs.rm(path.join(assetPath, "ComfyUI", ".git"), { recursive: true, force: true });
const result2 = await fs.cp(assetPath, resourcePath, { recursive: true });
console.log("rm" , result);
console.log("cp" , result2);
await removeInvalidSymlinks(mainPath);
}

if (os.platform() === 'win32') {
const appName = packager.appInfo.productFilename;
const appPath = path.join(`${appOutDir}`, `${appName}.exe`);
const mainPath = path.dirname(outDir);
const assetPath = path.join(mainPath, 'app-wrapper', 'app', 'assets');
const resourcePath = path.join(path.dirname(appPath), "resources");
await fs.cp(assetPath, resourcePath, { recursive: true });
}
}
8 changes: 3 additions & 5 deletions scripts/todesktop/beforeInstall.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { exec, execSync } = require("child_process");
const { exec, execSync, spawnSync } = require("child_process");
const path = require("path");
const os = require('os');

Expand All @@ -24,12 +24,10 @@ module.exports = async ({ pkgJsonPath, pkgJson, appDir, hookName }) => {

if (os.platform() === "win32")
{
const result1 = execSync('curl -s https://www.python.org/ftp/python/3.12.7/python-3.12.7-amd64.exe',execOutput).toString();
const result1 = spawnSync('curl' ,['-s', 'https://www.python.org/ftp/python/3.12.7/python-3.12.7-amd64.exe'],{shell:true,stdio: 'ignore'},execOutput).toString();
console.log(result1);
const result2 = execSync('./python-3.12.7-amd64.exe /quiet PrependPath=1 Include_test=0',execOutput).toString();
const result2 = spawnSync('python-3.12.7-amd64.exe', ['/quiet', 'InstallAllUsers=1','PrependPath=1', 'Include_test=0'],{shell:true,stdio: 'ignore'},execOutput).toString();
console.log(result2);
const result3 = execSync(`python --version`,execOutput).toString();
console.log(result3);

}

Expand Down
32 changes: 23 additions & 9 deletions scripts/todesktop/postInstall.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const { exec, execSync } = require("child_process");
const { exec, execSync, spawnSync, spawn } = require("child_process");
const path = require("path");
const os = require('os');
const process = require("process");
const fs = require('fs-extra');

async function postInstall() {
/**
Expand All @@ -11,6 +12,7 @@ async function postInstall() {
* hookName - string - the name of the hook ("todesktop:beforeInstall" or "todesktop:afterPack")
*/


const firstInstallOnToDesktopServers =
process.env.TODESKTOP_CI && process.env.TODESKTOP_INITIAL_INSTALL_PHASE;

Expand All @@ -33,24 +35,36 @@ async function postInstall() {
if (os.platform() === "win32")
{
console.log("win ver");
const result1 = execSync(`python --version`,execOutput).toString();
const result1 = execSync(`py -0`,execOutput).toString();
console.log(result1);
const result4 = execSync(`python -3.12 -m pip install --upgrade pip`).toString();
const result4 = spawnSync(`py`, ['-3.12', '-m', 'pip' ,'install' ,'--upgrade pip'],{shell:true,stdio: 'ignore'}).toString();
console.log(result4);
const result2 = execSync(`python -3.12 -m pip install comfy-cli`, execOutput).toString();
const result2 = spawnSync(`py`, ['-3.12 ','-m' ,'pip' ,'install comfy-cli'], {shell:true,stdio: 'ignore'}).toString();
console.log(result2);
console.log("finish pip");
const result3 = execSync(`yarn run make:assets:nvidia`, execOutput).toString();
const result3 = spawnSync('set PATH=C:\\hostedtoolcache\\windows\\Python\\3.12.7\\x64\\Scripts;%PATH% && cd assets && comfy-cli --skip-prompt --here install --fast-deps --nvidia --manager-url https://github.com/Comfy-Org/manager-core && comfy-cli --here standalone && mkdir -p ComfyUI/user/default' ,[''],{shell:true,stdio: 'inherit'}).toString();
console.log(result3);
const result5 = spawnSync('set PATH=C:\\hostedtoolcache\\windows\\Python\\3.12.7\\x64\\Scripts;%PATH% && cd assets && comfy-cli --here standalone' ,[''],{shell:true,stdio: 'inherit'}).toString();
console.log(result5);
const result = spawnSync('mkdir -p assets\\ComfyUI\\user\\default' ,[''],{shell:true,stdio: 'inherit'}).toString();
console.log("finish yarn run");
spawnSync('cd assets && dir' ,[''],{shell:true,stdio: 'inherit'}).toString();
}

if (os.platform() === "darwin") {
console.log("mac ver");

const result = execSync(`sh ${path.join(dirPath, 'scripts', 'signPython.sh')}`, execOutput).toString();
console.log(result);
console.log("finish python");
const shPath = path.join(dirPath, 'scripts', 'signPython.sh');
const result2 = spawnSync('sed', [`-i ''` , `'s/\\r//g'` , shPath],{shell:true,stdio:'inherit'});
const result = spawnSync('sh', [shPath],{shell:true,stdio: 'pipe'});
console.log(result.stdout.toString());
console.log(result.stderr.toString());
// console.log(result);
fs.createFileSync('./src/macpip.txt');
fs.writeFileSync('./src/macpip.txt',JSON.stringify({
log: result.stdout.toString(),
err:result.stderr.toString()
}));
console.log("finish python");
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ const spawnPythonAsync = (
options = { stdx: true }
): Promise<{ exitCode: number | null }> => {
return new Promise((resolve, reject) => {
log.info(`Spawning python process with command: ${cmd.join(' ')} in directory: ${cwd}`);
log.info(`Spawning python process with command: ${pythonInterpreterPath} ${cmd.join(' ')} in directory: ${cwd}`);
const pythonProcess: ChildProcess = spawn(pythonInterpreterPath, cmd, { cwd });

const cleanup = () => {
Expand Down
24 changes: 24 additions & 0 deletions src/pythonEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export class PythonEnvironment {
*/
readonly requirementsCompiledPath: string;

readonly macExtraFiles: Array<string>;

constructor(
public pythonInstallPath: string,
public appResourcesPath: string,
Expand All @@ -45,6 +47,13 @@ export class PythonEnvironment {
this.pythonTarPath = path.join(appResourcesPath, 'python.tgz');
this.wheelsPath = path.join(this.pythonRootPath, 'wheels');
this.requirementsCompiledPath = path.join(this.pythonRootPath, 'requirements.compiled');
this.macExtraFiles = [
'lib/libpython3.12.dylib',
'lib/python3.12/lib-dynload/_crypt.cpython-312-darwin.so',
'bin/uv',
'bin/uvx',
'bin/python3.12',
];
}

async isInstalled(): Promise<boolean> {
Expand Down Expand Up @@ -91,6 +100,21 @@ export class PythonEnvironment {
strict: true,
});

if (process.platform === 'darwin') {
this.macExtraFiles.forEach(async (fileName) => {
await fsPromises.cp(
path.join(this.appResourcesPath, 'output', fileName),
path.join(this.pythonRootPath, fileName)
);
});
try {
// This is a cleanup step, and is non critical if failed.
await fsPromises.rm(path.join(this.appResourcesPath, 'output'), { recursive: true, force: true });
} catch (error) {
null;
}
}

const exitCode = await this.installRequirements();

if (exitCode === 0) {
Expand Down
2 changes: 1 addition & 1 deletion todesktop.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"appPath": ".",
"appFiles": ["src/**", "scripts/**", "assets/**", "dist/**", ".vite/**", ".yarnrc.yml", ".yarn/**"],
"extraResources": [{ "from": "./assets" }],
"filesForDistribution": ["!.yarn/**", "!.yarnrc.yml"]
"filesForDistribution": ["!assets/**", "!dist/**", "!.yarn/**", "!.yarnrc.yml"]
}
Loading
Loading