Compare commits

..

15 Commits

Author SHA1 Message Date
Sylvia Crowe 550e93e62a fix: change size of dummy key to 2048
This fixes the CodeQL scan issue for using a weak key.
2024-02-15 12:12:34 -08:00
Sylvia Crowe 42963f4287 merge branch 'main' into ssh--auth-control 2024-02-15 12:09:21 -08:00
Sylvia Crowe a356df3396 fix: allow 60 second timeouts for ssh inputs
With the previous change, it is now possible to extend the timeout for
manual inputs. 60 seconds should be a reasonable starting point.
2024-02-13 17:57:23 -08:00
Sylvia Crowe 0eab1e3973 merge branch 'main' into ssh--auth-control 2024-02-13 17:54:30 -08:00
Sylvia Crowe 5abff8075b merge branch 'main' into 'ssh--auth-control'
This was mostly straightforward, but it appears that a previous commit
to main broke the user input modals by deleting a function. This adds
that back in addition to the merge.
2024-02-13 16:30:07 -08:00
Sylvia Crowe 6bd60e8330 deactivate timer while connecting to new ssh
The new ssh setup handles timers differently from the old one due to the
possibility of asking for user input multiple times. This limited the
user input to entirely be done within 15 seconds. This removes that
restriction which will allow those timers to increase. It does not
impact the legacy ssh systems or the local connections on the new
system.
2024-02-13 14:10:07 -08:00
Sylvia Crowe e62540bdbe fix: fix auth ordering and identity files
The last few commits introduced a few bugs that are fixed here. The
first is that the auth ordering is parsed as a single string and not a
list. This is fixed by manually splitting the string into a list. The
second is that the copy of identity files was not long enough to copy
the contents of the original. This is now updated to use the length of
the original in its construction.
2024-02-10 00:55:58 -08:00
Sylvia Crowe 85156bd6c2 feat: add batch mode support
BatchMode turns off user input to enter passwords for ssh. Because we
save passwords, we can still attempt these methods but we disable the
user interactive prompts in this case.
2024-02-09 23:44:53 -08:00
Sylvia Crowe d4a64fa8c2 feat: allow attempting auth methods in any order
While waveterm does not provide the control over which order to attempt
yet, it is possible to provide that information in the ssh_config. This
change allows that order to take precedence in a case where it is set.
2024-02-09 23:35:45 -08:00
Sylvia Crowe 618a08fe54 refactor: move logic for wave and config options
The logic for making decisions between details made available from wave
and details made available from ssh_config was spread out. This change
condenses it into one function for gathering those details and one for
picking between them.

It also adds a few new keywords but the logic for those hasn't been
implemented yet.
2024-02-09 22:44:55 -08:00
Sylvia Crowe b788a5e4af merge branch 'main' into ssh--auth-control
This only has a few bug fixes.
2024-02-09 15:07:32 -08:00
Sylvia Crowe 2e76556cac chore: remove old publicKey auth check
With the new callback in place, we no longer need this, so it has been
removed.
2024-02-09 13:30:07 -08:00
Sylvia Crowe d66287fcc6 chore: remove unnecessary print in sshclient.go 2024-02-08 22:45:52 -08:00
Sylvia Crowe f25892ba40 chore: remove unnecessary print in updatebus.go 2024-02-08 21:49:02 -08:00
Sylvia Crowe 37ff5f8c3e feat: parse multiple identity files in ssh
While this does not make it possible to discover multiple identity files
in every case, it does make it possible to parse them individually and
check for user input if it's required for each one.
2024-02-08 21:47:06 -08:00
194 changed files with 11525 additions and 6814 deletions
+66 -51
View File
@@ -1,44 +1,76 @@
name: "Build Helper"
on: workflow_dispatch
env:
WAVETERM_VERSION: 0.6.1
GO_VERSION: "1.21.5"
NODE_VERSION: "21.5.0"
jobs:
runbuild:
outputs:
WAVETERM_VERSION: ${{ steps.set-version.outputs.WAVETERM_VERSION }}
strategy:
matrix:
include:
- platform: "darwin"
arch: "universal"
runner: "macos-latest-xlarge"
scripthaus: "build-package"
- platform: "linux"
arch: "amd64"
runner: "ubuntu-latest"
scripthaus: "build-package-linux"
runs-on: ${{ matrix.runner }}
runbuild-darwin-x64:
name: "Build MacOS x64"
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: ${{env.GO_VERSION}}
cache-dependency-path: |
wavesrv/go.sum
waveshell/go.sum
- run: brew tap scripthaus-dev/scripthaus
- run: brew install scripthaus
- uses: actions/setup-node@v4
with:
node-version: ${{env.NODE_VERSION}}
cache: "yarn"
- run: yarn --frozen-lockfile
- run: scripthaus run build-package
- uses: actions/upload-artifact@v4
with:
name: waveterm-build-darwin-x64
path: out/make/zip/darwin/x64/*.zip
retention-days: 2
runbuild-darwin-arm64:
name: "Build MacOS arm64"
runs-on: macos-latest-xlarge
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: ${{env.GO_VERSION}}
cache-dependency-path: |
wavesrv/go.sum
waveshell/go.sum
- run: brew tap scripthaus-dev/scripthaus
- run: brew install scripthaus
- uses: actions/setup-node@v4
with:
node-version: ${{env.NODE_VERSION}}
cache: "yarn"
- run: yarn --frozen-lockfile
- run: scripthaus run build-package
- uses: actions/upload-artifact@v4
with:
name: waveterm-build-darwin-arm64
path: out/make/zip/darwin/arm64/*.zip
retention-days: 2
runbuild-linux:
name: "Build Linux x64"
runs-on: ubuntu-latest
needs: [runbuild-darwin-x64, runbuild-darwin-arm64]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
repository: scripthaus-dev/scripthaus
path: scripthaus
- name: Install Linux Build Dependencies
if: matrix.platform == 'linux'
run: |
sudo apt-get update
sudo apt-get install rpm
- uses: actions/setup-go@v5
- uses: actions/setup-go@v4
with:
go-version: ${{env.GO_VERSION}}
cache-dependency-path: |
wavesrv/go.sum
waveshell/go.sum
scripthaus/go.sum
- name: Install Scripthaus
run: |
- run: |
go work use ./scripthaus;
cd scripthaus;
go get ./...;
@@ -47,39 +79,22 @@ jobs:
with:
node-version: ${{env.NODE_VERSION}}
cache: "yarn"
- name: Set Version
id: set-version
run: |
VERSION=$(node -e 'console.log(require("./version.js"))')
echo "WAVETERM_VERSION=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Install Yarn Dependencies
run: yarn --frozen-lockfile
- name: Build ${{ matrix.platform }}/${{ matrix.arch }}
run: ./scripthaus/scripthaus run ${{ matrix.scripthaus }}
env:
GOARCH: ${{ matrix.arch }}
- uses: actions/upload-artifact@v4
with:
name: waveterm-build-${{ matrix.platform }}
path: make/*.* # only upload files from the make directory, not subdirectories
retention-days: 2
upload:
name: "Upload Builds"
runs-on: ubuntu-latest
needs: [runbuild]
steps:
- run: yarn --frozen-lockfile
- run: ./scripthaus/scripthaus run build-package-linux
- uses: actions/download-artifact@v4
with:
merge-multiple: true
path: buildtemp
- name: Set `version.txt`
run: |
echo "${{ needs.runbuild.outputs.WAVETERM_VERSION }}" >> buildtemp/version.txt
- name: Zip Builds
run: (cd buildtemp; zip -q ../waveterm-builds.zip *)
- name: Upload to S3
run: aws s3 cp waveterm-builds.zip s3://waveterm-github-artifacts/
- run: |
mv out/make/zip/linux/x64/Wave-linux-x64-$WAVETERM_VERSION.zip buildtemp/waveterm-linux-x64-v$WAVETERM_VERSION.zip
- run: (cd buildtemp; zip ../waveterm-builds.zip *)
- run: aws s3 cp waveterm-builds.zip s3://waveterm-github-artifacts/
env:
AWS_ACCESS_KEY_ID: "${{ secrets.S3_USERID }}"
AWS_SECRET_ACCESS_KEY: "${{ secrets.S3_SECRETKEY }}"
AWS_DEFAULT_REGION: us-west-2
- uses: actions/upload-artifact@v4
with:
name: waveterm-builds
path: buildtemp
retention-days: 2
+56 -55
View File
@@ -12,69 +12,70 @@
name: "CodeQL"
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
schedule:
- cron: "36 5 * * 5"
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
schedule:
- cron: '36 5 * * 5'
jobs:
analyze:
name: Analyze
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners
# Consider using larger runners for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
permissions:
actions: read
contents: read
security-events: write
analyze:
name: Analyze
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners
# Consider using larger runners for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: ["go", "javascript-typescript"]
# CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ]
# Use only 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
strategy:
fail-fast: false
matrix:
language: [ 'go', 'javascript-typescript' ]
# CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ]
# Use only 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v4
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
-26
View File
@@ -1,26 +0,0 @@
name: TestDriver.ai Regression Testing
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
schedule:
- cron: "0 21 * * *" # every day at 9pm
workflow_dispatch:
jobs:
test:
name: "TestDriver"
runs-on: ubuntu-latest
steps:
- uses: dashcamio/testdriver@main
id: testdriver
# note that .testdriver/prerun.sh runs before this, so the app has launched already
with:
prompt: |
2. click "Continue"
2. focus the Wave input with the keyboard shorcut Command + I
3. type 'ls' into the input
4. press return
5. validate Wave shows the result of 'ls'
-2
View File
@@ -20,5 +20,3 @@ temp.sql
.idea/
test/
.vscode/
make/
waveterm-builds.zip
-17
View File
@@ -1,17 +0,0 @@
rm ~/Desktop/WITH-LOVE-FROM-AMERICA.txt
cd ~/actions-runner/_work/testdriver/testdriver/
brew install go
brew tap scripthaus-dev/scripthaus
brew install scripthaus
npm install -g yarn
scripthaus run build-backend
echo "Yarn"
yarn
echo "Rebuild"
scripthaus run electron-rebuild
echo "Webpack"
scripthaus run webpack-build
echo "Starting Electron"
scripthaus run electron 1>/dev/null 2>&1 &
echo "Electron Done"
exit
+4 -4
View File
@@ -1,15 +1,15 @@
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="./assets/waveterm-logo-horizontal-dark.png">
<source media="(prefers-color-scheme: light)" srcset="./assets/waveterm-logo-horizontal-light.png">
<img alt="Wave Terminal Logo" src="./assets/waveterm-logo-horizontal-light.png" width="240" height="80" style="max-width: 100%;">
<source media="(prefers-color-scheme: dark)" srcset="./assets/wave-logo_horizontal-coloronblack.svg">
<source media="(prefers-color-scheme: light)" srcset="./assets/wave-logo_horizontal-coloronwhite.svg">
<img alt="Wave Terminal Logo" src="./assets/wave-logo_horizontal-coloronwhite.svg" width="352" height="59" style="max-width: 100%;">
</picture>
<br/>
</p>
# Wave Terminal
An open-source, cross-platform, AI-integrated, modern terminal for seamless workflows.
A open-source, cross-platform, AI-integrated, modern terminal for seamless workflows.
Wave isn't just another terminal emulator; it's a rethink on how terminals are built. Wave combines command line with the power of the open web to help veteran CLI users and new developers alike.
+4 -4
View File
@@ -179,11 +179,11 @@ THE SOFTWARE.
-----
## github.com/google/go-github/v59/github
## github.com/google/go-github/v57/github
* Name: github.com/google/go-github/v59/github
* Version: v59.0.0
* License: [BSD-3-Clause](https://github.com/google/go-github/blob/v59.0.0/LICENSE)
* Name: github.com/google/go-github/v57/github
* Version: v57.0.0
* License: [BSD-3-Clause](https://github.com/google/go-github/blob/v57.0.0/LICENSE)
```txt
Copyright (c) 2013 The go-github AUTHORS. All rights reserved.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

+2 -2
View File
@@ -1,3 +1,3 @@
*/
temp/
*.zip
*.dmg
*.dmg
-67
View File
@@ -1,67 +0,0 @@
# Building for release
## Build Helper workflow
Our release builds are managed by the "Build Helper" GitHub Action, which is defined
in [`build-helper.yml`](../.github/workflows/build-helper.yml).
Under the hood, this will call the `build-package` and `build-package-linux` scripts in
[`scripthaus.md`](../scripthaus.md), which will build the Electron codebase using
WebPack and then the `wavesrv` and `mshell` binaries, then it will call `electron-builder`
to generate the distributable app packages. The configuration for `electron-builder`
is [`electron-builder.config.js`](../electron-builder.config.js).
We are working to fully automate the building of release artifacts. For now,
manual steps are still required to sign and notarize the macOS artifacts. The
Linux artifacts do not require additional modification before being published.
## Local signing and notarizing for macOS
The [`prepare-macos.sh`](./prepare-macos.sh) script will download the latest build
artifacts from S3 and sign and notarize the macOS binaries within it. It will then
generate a DMG and a new ZIP archive with the new signed app.
This will call a few different JS scripts to perform more complicated operations.
[`osx-sign.js`](./osx-sign.js) and [`osx-notarize.js`](./osx-notarize.js) call
underlying Electron APIs to sign and notarize the package.
[`update-latest-mac.js`](./update-latest-mac.js) will then update the `latest-mac.yml`
file with the SHA512 checksum and file size of the new signed and notarized installer. This
is important for the `electron-updater` auto-update mechanism to then find and validate new releases.
## Uploading release artifacts for distribution
### Upload script
Once the build has been fully validated and is ready to be released, the
[`upload-release.sh`](./upload-release.sh) script is then used to grab the completed
artifacts and upload them to the `dl.waveterm.dev` S3 bucket for distribution.
### Homebrew
Homebrew currently requires a manual bump of the version, but now that we have auto-updates,
we should add our cask to the list of apps that can be automatically bumped.
### Linux
We do not currently submit the Linux packages to any of the package repositories. We
are working on addressing this in the near future.
## `electron-build` configuration
Most of our configuration is fairly standard. The main exception to this is that we exclude
our Go binaries from the ASAR archive that Electron generates. ASAR files cannot be executed
by NodeJS because they are not seen as files and therefore cannot be executed via a Shell
command. More information can be found
[here](https://www.electronjs.org/docs/latest/tutorial/asar-archives#executing-binaries-inside-asar-archive).
We also exclude most of our `node_modules` from packaging, as WebPack handles packaging
of any dependencies for us. The one exception is `monaco-editor`.
## Automatic updates
Thanks to `electron-updater`, we are able to provide automatic app updates for macOS and Linux,
as long as the app was distributed as a DMG, AppImage, RPM, or DEB file.
With each release, `latest-mac.yml` and `latest-linux.yml` files will be produced that point to the
newest release. These also include file sizes and checksums to aid in validating the packages. The app
will check these files in our S3 bucket every hour to see if a new version is available.
+20
View File
@@ -0,0 +1,20 @@
const eu = require("@electron/universal");
const path = require("path");
let x64Path = path.resolve(__dirname, "temp", "x64", "Wave.app")
let arm64Path = path.resolve(__dirname, "temp", "arm64", "Wave.app")
let outPath = path.resolve(__dirname, "temp", "Wave.app")
console.log("building universal package");
console.log("x64 path", x64Path);
console.log("arm64 path", arm64Path);
console.log("output path", outPath);
(async () => {
await eu.makeUniversalApp({
x64AppPath: x64Path,
arm64AppPath: arm64Path,
outAppPath: outPath,
});
console.log("created macos universal app");
})();
+62
View File
@@ -0,0 +1,62 @@
#!/bin/bash
# assumes we have Wave-darwin-x64-[version].zip and Wave-darwin-arm64-[version].zip in current directory
VERSION=0.6.1
rm -rf temp
rm -rf builds
mkdir temp
mkdir temp/x64
aws s3 cp s3://waveterm-github-artifacts/waveterm-builds.zip .
BUILDS_ZIP=waveterm-builds.zip
if ! [ -f $BUILDS_ZIP ]; then
echo "no $BUILDS_ZIP found";
exit 1;
fi
echo "unzipping $BUILDS_ZIP"
unzip -q $BUILDS_ZIP -d builds
X64_ZIP="builds/Wave-darwin-x64-$VERSION.zip"
ARM64_ZIP="builds/Wave-darwin-arm64-$VERSION.zip"
if ! [ -f $X64_ZIP ]; then
echo "no $X64_ZIP found";
exit 1;
fi
if ! [ -f $ARM64_ZIP ]; then
echo "no $ARM64_ZIP found"
exit 1;
fi
set -e
echo "unzipping version v$VERSION zip files"
ls -l "$X64_ZIP" "$ARM64_ZIP"
unzip -q $X64_ZIP -d temp/x64
mkdir temp/arm64
unzip -q $ARM64_ZIP -d temp/arm64
lipo -create -output temp/wavesrv temp/x64/Wave.app/Contents/Resources/app/bin/wavesrv temp/arm64/Wave.app/Contents/Resources/app/bin/wavesrv
rm -rf temp/arm64/Wave.app/Contents/Resources/app
mv temp/x64/Wave.app/Contents/Resources/app temp/
cp temp/wavesrv temp/app/bin/wavesrv
mkdir temp/x64/Wave.app/Contents/Resources/app
mkdir temp/arm64/Wave.app/Contents/Resources/app
node build-universal.js
rm -rf temp/Wave.app/Contents/Resources/app
mv temp/app temp/Wave.app/Contents/Resources/app
node osx-sign.js
DEBUG=electron-notarize node osx-notarize.js
echo "universal app creation success (build/sign/notarize)"
echo "creating universal dmg"
rm -f *.dmg
DMG_VERSION=$(node -e 'console.log(require("../version.js"))')
DMG_NAME="waveterm-macos-universal-${DMG_VERSION}.dmg"
../../create-dmg/create-dmg \
--volname "WaveTerm" \
--window-pos 200 120 \
--window-size 600 300 \
--icon-size 100 \
--icon "Wave.app" 200 130 \
--hide-extension "Wave.app" \
--app-drop-link 400 125 \
$DMG_NAME \
"temp/Wave.app"
echo "success, created $DMG_NAME"
mv $DMG_NAME builds/
rm builds/Wave-darwin-*.zip
spctl -a -vvv -t install temp/Wave.app/
-46
View File
@@ -1,46 +0,0 @@
// Usage: node generate-hash.js <path-to-installer>
// Example: node generate-hash.js ./make/Wave-0.0.1.dmg
// This script will generate a hash of the installer file, as defined by electron-builder.
// Courtesy of https://github.com/electron-userland/electron-builder/issues/3913#issuecomment-504698845
const path = require("path");
const fs = require("fs");
const crypto = require("crypto");
/**
* Generate a hash of a file, as defined by electron-builder
* @param {string} file - Path to the file
* @param {string} algorithm - Hash algorithm to use
* @param {string} encoding - Encoding to use
* @returns {Promise<string>} - The hash of the file
*/
async function hashFile(file, algorithm = "sha512", encoding = "base64") {
return new Promise((resolve, reject) => {
const hash = crypto.createHash(algorithm);
hash.on("error", reject).setEncoding(encoding);
fs.createReadStream(file, {
highWaterMark: 1024 * 1024,
/* better to use more memory but hash faster */
})
.on("error", reject)
.on("end", () => {
hash.end();
resolve(hash.read());
})
.pipe(hash, {
end: false,
});
});
}
if (require.main === module) {
const installerPath = path.resolve(process.cwd(), process.argv[2]);
(async () => {
const hash = await hashFile(installerPath);
console.log(`hash of ${installerPath}: ${hash}`);
})();
}
module.exports = {
hashFile,
};
+13 -36
View File
@@ -1,37 +1,14 @@
// Notarize the Wave.app for macOS
const { notarize } = require('@electron/notarize');
// DEBUG=electron-notarize
const { notarize } = require("@electron/notarize");
const path = require("path");
/**
* Notarize the Wave.app for macOS
* @param {string} waveAppPath - Path to the Wave.app
* @returns {Promise<void>}
*/
async function notarizeApp(waveAppPath) {
return notarize({
appPath: waveAppPath,
tool: "notarytool",
keychainProfile: "notarytool-creds",
})
.then(() => {
console.log("notarize success");
})
.catch((e) => {
console.log("notarize error", e);
process.exit(1);
});
}
if (require.main === module) {
console.log("running osx-notarize");
const waveAppPath = path.resolve(__dirname, "temp", "Wave.app");
(async () => {
await notarizeApp(waveAppPath);
console.log("notarization complete");
})();
}
module.exports = {
notarizeApp,
};
console.log("running osx-notarize");
notarize({
appPath: "temp/Wave.app",
tool: "notarytool",
keychainProfile: "notarytool-creds",
}).then(() => {
console.log("notarize success");
}).catch((e) => {
console.log("notarize error", e);
process.exit(1);
});
+18 -43
View File
@@ -1,45 +1,20 @@
// Sign the app and binaries for macOS
const { signAsync } = require("@electron/osx-sign");
const path = require("path");
const fs = require("fs");
// DEBUG="electron-osx-sign*"
/**
* Sign the app and binaries for macOS
* @param {string} waveAppPath - Path to the Wave.app
* @returns {Promise<void>}
*/
async function signApp(waveAppPath) {
const binDirPath = path.resolve(waveAppPath, "Contents", "Resources", "app.asar.unpacked", "bin");
const binFilePaths = fs
.readdirSync(binDirPath, { recursive: true, withFileTypes: true })
.filter((f) => f.isFile())
.map((f) => path.resolve(binDirPath, f.path, f.name));
console.log("waveAppPath", waveAppPath);
console.log("binDirPath", binDirPath);
console.log("binFilePaths", binFilePaths);
return signAsync({
app: waveAppPath,
binaries: binFilePaths,
})
.then(() => {
console.log("signing success");
})
.catch((e) => {
console.log("signing error", e);
process.exit(1);
});
}
if (require.main === module) {
console.log("running osx-sign");
const waveAppPath = path.resolve(__dirname, "temp", "Wave.app");
(async () => {
await signApp(waveAppPath);
console.log("signing complete");
})();
}
module.exports = {
signApp,
};
console.log("running osx-sign");
let waveAppPath = "temp/Wave.app";
signAsync({
app: "temp/Wave.app",
binaries: [
waveAppPath + "/Contents/Resources/app/bin/wavesrv",
waveAppPath + "/Contents/Resources/app/bin/mshell/mshell-v0.4-linux.amd64",
waveAppPath + "/Contents/Resources/app/bin/mshell/mshell-v0.4-linux.arm64",
waveAppPath + "/Contents/Resources/app/bin/mshell/mshell-v0.4-darwin.amd64",
waveAppPath + "/Contents/Resources/app/bin/mshell/mshell-v0.4-darwin.arm64",
],
}).then(() => {
console.log("signing success");
}).catch((e) => {
console.log("signing error", e);
process.exit(1);
});
-88
View File
@@ -1,88 +0,0 @@
#!/bin/bash
# This script is used to sign and notarize the universal app for macOS
# Gets the directory of the script
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
# Remove old files and dirs, create new ones
rm -f *.zip *.dmg
ZIP_DIR=$SCRIPT_DIR/zip
rm -rf $ZIP_DIR
mkdir $ZIP_DIR
TEMP_DIR=$SCRIPT_DIR/temp
rm -rf $TEMP_DIR
mkdir $TEMP_DIR
BUILDS_DIR=$SCRIPT_DIR/builds
rm -rf $BUILDS_DIR
# Download the builds zip
aws s3 cp s3://waveterm-github-artifacts/waveterm-builds.zip .
BUILDS_ZIP=waveterm-builds.zip
if ! [ -f $BUILDS_ZIP ]; then
echo "no $BUILDS_ZIP found";
exit 1;
fi
echo "unzipping $BUILDS_ZIP"
unzip -q $BUILDS_ZIP -d $BUILDS_DIR
rm $BUILDS_ZIP
# Finds a file in a directory matching a filename pattern. Ensures there is exactly one match.
find_file()
{
local FILE_DIR=$1
local FILE_PATTERN=$2
local FILE_PATH=$(find $FILE_DIR -type f -iname "$FILE_PATTERN")
local NUM_MATCHES=$(echo $FILE_PATH | wc -l)
if [ "0" -eq "$NUM_MATCHES" ]; then
echo "no $FILE_PATTERN found in $FILE_DIR"
exit 1
elif [ "1" -lt "$NUM_MATCHES" ]; then
echo "multiple $FILE_PATTERN found in $FILE_DIR"
exit 1
fi
echo $FILE_PATH
}
# Unzip Mac build
MAC_ZIP=$(find_file $BUILDS_DIR "Wave-darwin-universal-*.zip")
unzip -q $MAC_ZIP -d $TEMP_DIR
# Sign and notarize the app
node $SCRIPT_DIR/osx-sign.js
DEBUG=electron-notarize node $SCRIPT_DIR/osx-notarize.js
# Zip and move
echo "creating universal zip"
ZIP_NAME=$(basename $MAC_ZIP)
TEMP_WAVE_DIR_UNIVERSAL=$TEMP_DIR/Wave.app
ditto $TEMP_WAVE_DIR_UNIVERSAL $ZIP_DIR/Wave.app
cd $ZIP_DIR
zip -9yqr $ZIP_NAME Wave.app
mv $ZIP_NAME $BUILDS_DIR/
cd $SCRIPT_DIR
# Create a dmg
# Expects create-dmg repo to be cloned in the same parent directory as the waveterm repo.
echo "creating universal dmg"
DMG_NAME=$(echo $ZIP_NAME | sed 's/\.zip/\.dmg/')
$SCRIPT_DIR/../../create-dmg/create-dmg \
--volname "WaveTerm" \
--window-pos 200 120 \
--window-size 600 300 \
--icon-size 100 \
--icon "Wave.app" 200 130 \
--hide-extension "Wave.app" \
--app-drop-link 400 125 \
$DMG_NAME \
"$TEMP_WAVE_DIR_UNIVERSAL"
echo "success, created $DMG_NAME"
mv $DMG_NAME $BUILDS_DIR/
spctl -a -vvv -t install $TEMP_WAVE_DIR_UNIVERSAL/
# Update latest-mac.yml
echo "updating latest-mac.yml"
LATEST_MAC_YML=$BUILDS_DIR/latest-mac.yml
node $SCRIPT_DIR/update-latest-mac.js $MAC_ZIP $LATEST_MAC_YML
# Clean up
rm -rf $TEMP_DIR $ZIP_DIR
+50
View File
@@ -0,0 +1,50 @@
## MacOS Universal Build Notes
This doesn't work out of the box and doesn't seem to be well documented anywhere.
The basic idea is that we have to create separate x64 and a arm64 builds and
then link them together using @electron/universal. Seems easy, but in
practice it isn't.
(1) The separate x64 and arm64 builds *cannot* be signed (osx-sign). This
makes sense because once we lipo the executables together they need to be
resigned (their SHA sums will change). If you accidentally sign them
@electron/universal will also refuse to work.
(2) We already deal with architecture specific builds with Go for wavesrv and
waveshell. This upsets @electron/universal as well since these are *binaries*
and we don't want to lipo them together.
(3) Small differences in waveterm.js. The non-executable files must be
*identical*. Well, that's a problem when we inject build times into the files.
Other small differences can also happen (like different go toolchains, etc.).
(4) ASAR builds. By default if there are differences in the "app" folder
@electron/universal plays some neat tricks to separate out the x64 from the
arm64 code using a app.asar stub. That's great for standard electron builds
where the entrypoint is hardcoded to index.js. Ours isn't so this doesn't work.
(5) ASAR builds and unpacked files. I don't know all the details here, but
for Wave to work we have to have some files unpacked (not in ASAR format).
The reason is that we execute them directly (e.g. wavesrv and waveshell), they
aren't just loaded by electron.
(6) Ignoring and skipping files in @electron/universal is hard because
it just takes one minimatch pattern.
---
## Solution
1. Create unsigned builds on x64 and arm64
2. Move the builds to the core build machine and *extract* their "app" directories.
In theory because we aren't using any native node modules they function the same in
both environments.
3. Run @electron/universal on the two unsigned builds (without their app directories).
4. lipo wavesrv from x64 and arm64 manually to create a universal wavesrv binary.
5. Copy our extracted "app" directory (with the newly created universal "wavesrv")
back into the universal Wave.app created by @electron/universal.
6. Manually run osx-sign to sign the new universal build (make sure to
pass the wavesrv and waveshell programs as extra binaries).
7. Manually create the new universal dmg (using create-dmg).
-40
View File
@@ -1,40 +0,0 @@
// Updates the latest-mac.yml file with the signed and notarized version of the latest installer
// Usage: node update-latest.js <path-to-installer>
const path = require("path");
const fs = require("fs");
const { hashFile } = require("./generate-hash");
const yaml = require("yaml");
/**
* Updates the latest-mac.yml file with the signed and notarized version of the latest installer
* @param {string} installerPath - Path to the installer
* @param {string} ymlPath - Path to the latest-mac.yml file
* @returns {Promise<void>}
*/
async function updateLatestMac(installerPath, ymlPath) {
const hash = (await hashFile(installerPath)).trim();
const size = fs.statSync(installerPath).size;
const yml = yaml.parse(fs.readFileSync(ymlPath, "utf8"));
for (const file of yml.files) {
if (file.url === path.basename(installerPath)) {
file.sha512 = hash;
file.size = size;
}
}
yml.sha512 = hash;
fs.writeFileSync(ymlPath, yaml.stringify(yml));
}
if (require.main === module) {
const installerPath = path.resolve(process.cwd(), process.argv[2]);
const ymlPath = path.resolve(process.cwd(), process.argv[3]);
(async () => {
await updateLatestMac(installerPath, ymlPath);
console.log("latest-mac.yml updated");
})();
}
module.exports = {
updateLatestMac,
};
-35
View File
@@ -1,35 +0,0 @@
#!/bin/bash
# This script is used to upload signed and notarized releases to S3 and update the Electron auto-update release feeds.
# Gets the directory of the script
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
BUILDS_DIR=$SCRIPT_DIR/builds
TEMP2_DIR=$SCRIPT_DIR/temp2
AUTOUPDATE_RELEASE_PATH="dl.waveterm.dev/releases"
# Copy the builds to the temp2 directory
echo "Copying builds to temp2"
rm -rf $TEMP2_DIR
mkdir -p $TEMP2_DIR
cp -r $BUILDS_DIR/* $TEMP2_DIR
UVERSION=$(cat $TEMP2_DIR/version.txt)
if [ -z "$UVERSION" ]; then
echo "version.txt is empty"
exit 1
fi
# Remove files we don't want to upload
rm $TEMP2_DIR/version.txt
rm $TEMP2_DIR/builder-*.yml
# Upload the artifacts
echo "Uploading build artifacts to $AUTOUPDATE_RELEASE_PATH"
aws s3 cp $TEMP2_DIR/ s3://$AUTOUPDATE_RELEASE_PATH/ --recursive
# Clean up
echo "Cleaning up"
rm -rf $TEMP2_DIR

Some files were not shown because too many files have changed in this diff Show More