[Feature] Open Data Platform Desktop Application (#7238)

* add desktop app code to repository

* fix headers

* bump version

* one more file to bump version in

* cargo fmt

* add permissions to release jobs

* codespell

* Need this folder to exist

* NSNumber apparently

* cargo fmt

* test expectation that didn't get updated

* intel mac runner is macos-15-intel

* empty line at bottom of file..

* apparently didn't save permissions step

* unused windows import

* cargo fmt again

* draft-release workflow

* fix windows test

* try as reusable workflow

* beforeBundleCommand

* relative path

* absolute path...

* the file definitely exists...

* seems that the file was not actually added....

* this file definitely exists

* undo temp edit of draft-release
This commit is contained in:
Danglewood
2025-10-14 08:52:04 -07:00
committed by GitHub
parent 9e3cb50bf6
commit 039c183c60
178 changed files with 114251 additions and 5726 deletions

View File

@@ -0,0 +1,112 @@
name: build-macos-x64
on:
workflow_call:
inputs:
release:
required: false
type: boolean
default: false
jobs:
build-and-sign:
runs-on: "macos-15-intel"
permissions:
contents: write
defaults:
run:
working-directory: desktop
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Import Code Signing Certificate
uses: apple-actions/import-codesign-certs@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
with:
p12-file-base64: ${{ secrets.MACOS_CERTIFICATE }}
p12-password: ${{ secrets.MACOS_CERTIFICATE_PWD }}
- name: Install OpenSSL
run: brew install openssl
- name: Setup Cargo Cache
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: macos-x64-cargo-registry-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
macos-x64-cargo-registry-
- name: Setup Node Cache
uses: actions/cache@v4
with:
path: ~/.npm
key: macos-x64-node-${{ hashFiles('desktop/**/package-lock.json') }}
restore-keys: |
macos-x64-node-
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install cyclonedx-npm
run: npm install -g @cyclonedx/cyclonedx-npm
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
targets: "x86_64-apple-darwin"
- name: Install Modules
run: |
npm install
cyclonedx-npm --output-format XML --gather-license-texts --output-file src-tauri/open-data-platform-SBOM-npm.cdx.xml
- name: Install cargo-cyclonedx
run: |
cargo install cargo-cyclonedx
cargo cyclonedx
if [ -f "src-tauri/openbb-platform.cdx.xml" ]; then
mv src-tauri/openbb-platform.cdx.xml "src-tauri/open-data-platform-SBOM-cargo.cdx.xml"
fi
- name: Build Tauri App
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
APPLE_ID: ${{ secrets.NOTARIZE_APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.NOTARIZE_APPLE_PWD }}
APPLE_TEAM_ID: ${{ secrets.NOTARIZE_APPLE_TEAM_ID }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: npm run tauri build
- name: Rename artifacts
run: |
VERSION=$(jq -r .version src-tauri/tauri.conf.json)
cd target/release/bundle/dmg
for file in *.dmg; do mv "$file" "Open-Data-Platform_${VERSION}_x86_64.dmg"; done
cd ../macos
for file in *.app.tar.gz; do mv "$file" "Open-Data-Platform_${VERSION}_x86_64.app.tar.gz"; done
for file in *.app.tar.gz.sig; do mv "$file" "Open-Data-Platform_${VERSION}_x86_64.app.tar.gz.sig"; done
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: macos-x64-artifacts
path: |
desktop/target/release/bundle/dmg/*.dmg
desktop/target/release/bundle/macos/*.app.tar.gz
desktop/target/release/bundle/macos/*.app.tar.gz.sig
- name: Cleanup Artifacts
if: always()
run: cargo clean

View File

@@ -0,0 +1,127 @@
name: build-macos-arm
on:
workflow_call:
inputs:
release:
required: false
type: boolean
default: false
jobs:
build-and-sign:
runs-on: "macos-latest"
permissions:
contents: write
defaults:
run:
working-directory: desktop
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Debug - List files
run: |
echo "Current directory:"
pwd
echo "Files in current directory:"
ls -la
echo "Files in src-tauri:"
ls -la src-tauri/
echo "Files in src-tauri/scripts:"
ls -la src-tauri/scripts/ || echo "scripts directory does not exist"
echo "Looking for fix_dylibs.sh:"
find . -name "fix_dylibs.sh" -type f || echo "fix_dylibs.sh not found"
- name: Import Code Signing Certificate
uses: apple-actions/import-codesign-certs@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
with:
p12-file-base64: ${{ secrets.MACOS_CERTIFICATE }}
p12-password: ${{ secrets.MACOS_CERTIFICATE_PWD }}
- name: Install OpenSSL
run: brew install openssl
- name: Setup Cargo Cache
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: macos-arm-cargo-registry-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
macos-arm-cargo-registry-
- name: Setup Node Cache
uses: actions/cache@v4
with:
path: ~/.npm
key: macos-arm-node-${{ hashFiles('desktop/**/package-lock.json') }}
restore-keys: |
macos-arm-node-
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install cyclonedx-npm
run: npm install -g @cyclonedx/cyclonedx-npm
- name: install Rust stable
uses: dtolnay/rust-toolchain@v1
with:
toolchain: stable
targets: "aarch64-apple-darwin"
- name: Install Modules
run: |
npm install
cyclonedx-npm --output-format XML --gather-license-texts --output-file src-tauri/open-data-platform-SBOM-npm.cdx.xml
- name: Install cargo-cyclonedx
run: |
cargo install cargo-cyclonedx
cargo cyclonedx
if [ -f "src-tauri/openbb-platform.cdx.xml" ]; then
mv src-tauri/openbb-platform.cdx.xml "src-tauri/open-data-platform-SBOM-cargo.cdx.xml"
fi
- name: Build Tauri App
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
APPLE_ID: ${{ secrets.NOTARIZE_APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.NOTARIZE_APPLE_PWD }}
APPLE_TEAM_ID: ${{ secrets.NOTARIZE_APPLE_TEAM_ID }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: npm run tauri build
- name: Rename artifacts
run: |
VERSION=$(jq -r .version src-tauri/tauri.conf.json)
cd target/release/bundle/dmg
for file in *.dmg; do mv "$file" "Open-Data-Platform_${VERSION}_aarch64.dmg"; done
cd ../macos
for file in *.app.tar.gz; do mv "$file" "Open-Data-Platform_${VERSION}_aarch64.app.tar.gz"; done
for file in *.app.tar.gz.sig; do mv "$file" "Open-Data-Platform_${VERSION}_aarch64.app.tar.gz.sig"; done
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: macos-arm-artifacts
path: |
desktop/target/release/bundle/dmg/*.dmg
desktop/target/release/bundle/macos/*.app.tar.gz
desktop/target/release/bundle/macos/*.app.tar.gz.sig
- name: Cleanup Artifacts
if: always()
run: cargo clean

View File

@@ -0,0 +1,175 @@
name: build-windows-x64
on:
workflow_call:
inputs:
release:
required: false
type: boolean
default: false
jobs:
build-and-sign:
runs-on: windows-latest
permissions:
contents: write
defaults:
run:
working-directory: desktop
env:
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
steps:
- uses: actions/checkout@v4
- name: Cache vcpkg
uses: actions/cache@v4
with:
path: ${{ env.VCPKG_ROOT }}
key: ${{ runner.os }}-vcpkg-${{ hashFiles('desktop/**/vcpkg.json') }}
restore-keys: |
${{ runner.os }}-vcpkg-
- name: Bootstrap vcpkg
working-directory: ${{ github.workspace }}
run: |
if (-not (Test-Path ${{ env.VCPKG_ROOT }})) {
git clone https://github.com/microsoft/vcpkg.git ${{ env.VCPKG_ROOT }}
}
${{ env.VCPKG_ROOT }}/bootstrap-vcpkg.bat
shell: pwsh
- name: Install OpenSSL using vcpkg
working-directory: ${{ github.workspace }}
run: ${{ env.VCPKG_ROOT }}/vcpkg install openssl:x64-windows-static --vcpkg-root ${{ env.VCPKG_ROOT }}
env:
VCPKG_DEFAULT_TRIPLET: x64-windows-static
- name: Set OpenSSL env
shell: bash
run: |
echo "OPENSSL_DIR=${{ env.VCPKG_ROOT }}/installed/x64-windows-static" >> $GITHUB_ENV
echo "OPENSSL_INCLUDE_DIR=${{ env.VCPKG_ROOT }}/installed/x64-windows-static/include" >> $GITHUB_ENV
echo "OPENSSL_LIB_DIR=${{ env.VCPKG_ROOT }}/installed/x64-windows-static/lib" >> $GITHUB_ENV
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install cyclonedx-npm
run: npm install -g @cyclonedx/cyclonedx-npm
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: windows-x64-cargo-registry-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
windows-x64-cargo-registry-
- name: Cache cargo build
uses: actions/cache@v4
with:
path: desktop/target
key: windows-x64-cargo-build-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
windows-x64-cargo-build-
- name: Install Modules
run: |
npm install
cyclonedx-npm --output-format XML --gather-license-texts --output-file src-tauri/open-data-platform-SBOM-npm.cdx.xml
- name: Install cargo-cyclonedx
shell: pwsh
run: |
cargo install cargo-cyclonedx
cargo cyclonedx
if (Test-Path "src-tauri/openbb-platform.cdx.xml") {
Move-Item "src-tauri/openbb-platform.cdx.xml" "src-tauri/open-data-platform-SBOM-cargo.cdx.xml" -Force
}
- name: Build Tauri App (without bundling)
run: npm run tauri build -- --target x86_64-pc-windows-msvc --no-bundle
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create backup of unsigned executable
shell: pwsh
run: |
Copy-Item -Path "${{ github.workspace }}/desktop/target/x86_64-pc-windows-msvc/release/openbb-platform.exe" -Destination "${{ github.workspace }}/desktop/target/x86_64-pc-windows-msvc/release/openbb-platform-unsigned.exe"
- name: Create temp directory for signing
shell: pwsh
run: New-Item -ItemType Directory -Force -Path "${{ github.workspace }}/desktop/temp-sign"
- name: Sign the executable
uses: sslcom/esigner-codesign@v1.3.1
with:
command: sign
username: ${{ secrets.ESIGNER_USERNAME }}
password: ${{ secrets.ESIGNER_PASSWORD }}
credential_id: ${{ secrets.ESIGNER_CREDENTIAL_ID }}
totp_secret: ${{ secrets.ESIGNER_TOTP_SECRET }}
file_path: ${{ github.workspace }}/desktop/target/x86_64-pc-windows-msvc/release/openbb-platform.exe
output_path: ${{ github.workspace }}/desktop/temp-sign
malware_block: false
- name: Replace unsigned executable with signed one
shell: pwsh
run: |
Copy-Item -Path "${{ github.workspace }}/desktop/temp-sign/openbb-platform.exe" -Destination "${{ github.workspace }}/desktop/target/x86_64-pc-windows-msvc/release/openbb-platform.exe" -Force
- name: Bundle the signed executable into installer
run: npm run tauri bundle -- --target x86_64-pc-windows-msvc --bundles nsis
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
- name: Get Installer Path
id: get_installer_path
shell: pwsh
run: |
$installerPath = (Get-ChildItem -Path "${{ github.workspace }}/desktop/target/x86_64-pc-windows-msvc/release/bundle/nsis/*.exe").FullName
echo "installer_path=$installerPath" >> $env:GITHUB_OUTPUT
- name: Create directory for signed installer
shell: pwsh
run: New-Item -ItemType Directory -Force -Path "${{ github.workspace }}/desktop/signed-installer"
- name: Sign Installer
uses: sslcom/esigner-codesign@v1.3.1
with:
command: sign
username: ${{ secrets.ESIGNER_USERNAME }}
password: ${{ secrets.ESIGNER_PASSWORD }}
credential_id: ${{ secrets.ESIGNER_CREDENTIAL_ID }}
totp_secret: ${{ secrets.ESIGNER_TOTP_SECRET }}
file_path: ${{ steps.get_installer_path.outputs.installer_path }}
output_path: ${{ github.workspace }}/desktop/signed-installer
malware_block: true
- name: Organize artifacts
shell: pwsh
run: |
$version = (Get-Content src-tauri/tauri.conf.json | ConvertFrom-Json).version
$sigFile = (Get-ChildItem -Path "${{ github.workspace }}/desktop/target/x86_64-pc-windows-msvc/release/bundle/nsis/*.sig").FullName
Copy-Item -Path $sigFile -Destination "${{ github.workspace }}/desktop/signed-installer/"
cd ${{ github.workspace }}/desktop/signed-installer
Get-ChildItem -Path "*.exe" | Rename-Item -NewName "Open-Data-Platform_${version}_x86_64.exe"
Get-ChildItem -Path "*.sig" | Rename-Item -NewName "Open-Data-Platform_${version}_x86_64.exe.sig"
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: windows-x64-artifacts
path: ${{ github.workspace }}/desktop/signed-installer/

View File

@@ -1,222 +0,0 @@
name: MacOS Build
env:
OPENBB_LOG_COLLECT: false
OPENBB_USE_PROMPT_TOOLKIT: false
OPENBB_FILE_OVERWRITE: true
PIP_DEFAULT_TIMEOUT: 100
PYTHONNOUSERSITE: 1
on: workflow_dispatch
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
M1-MacOs-Build:
name: M1 MacOS Build
runs-on: [self-hosted, macos, ARM64]
permissions:
contents: read
steps:
# Checkout repository main branch. this allows for the commit hashes to line up
- name: Checkout
uses: actions/checkout@v3
- name: Git Log
run: git log
# The following commands to clear previous PATHS and restore to defaults since we have to maintain the instance ourselves
- name: Clean Previous Path
run: |
export PATH=""
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
echo $PATH
# Set up caching for conda env so that the workflow runs quickly after the first time
- name: Setup Conda Caching
uses: actions/cache@v3
with:
path: ~/conda_pkgs_dir
key: conda-macos-3-10-${{ hashFiles('build/conda/environments/constructor.yml') }}
# Set up miniconda using the environment yaml file within the repo
- name: Setup Miniconda
uses: conda-incubator/setup-miniconda@v3.0.4
with:
miniconda-version: "latest"
auto-update-conda: true
channels: conda-forge,defaults
show-channel-urls: true
channel-priority: flexible
environment-file: build/conda/environments/constructor.yml
activate-environment: constructor
auto-activate-base: false
- name: Creating Application Keychain
env:
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
MACOS_KEYCHAIN_PWD: ${{ secrets.MACOS_KEYCHAIN_PWD }}
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
run:
| # when pushing to main, make to generate new cert, and utilize secrets to store new password, and identity
echo "Ensuring Keychain with same name does not exist"
rm -rf /Users/openbb/Library/Keychains/build.keychain-db
echo "Decoding certificate"
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
echo "Creating Keychain"
security create-keychain -p $MACOS_KEYCHAIN_PWD build.keychain
echo "Setting Default Keychain"
security default-keychain -s build.keychain
echo "Unlocking Keychain"
security unlock-keychain -p $MACOS_KEYCHAIN_PWD build.keychain
echo "Importing Keychain"
security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign
echo "Setting Partition List"
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $MACOS_KEYCHAIN_PWD build.keychain
- name: Create Signed Package
env:
MACOS_INSTALLER_KEYCHAIN_PWD: ${{ secrets.MACOS_INSTALLER_KEYCHAIN_PWD }}
MACOS_INSTALLER_SIGNING_IDENTITY_NAME: ${{ secrets.MACOS_CODESIGN_INSTALLER_IDENTITY_NAME }}
MACOS_APPLICATION_SIGNING_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
run: |
security unlock-keychain -p $MACOS_INSTALLER_KEYCHAIN_PWD install.keychain
echo "signing_identity_name: $MACOS_INSTALLER_SIGNING_IDENTITY_NAME" >> build/conda/installer/construct.yaml
echo "notarization_identity_name: $MACOS_APPLICATION_SIGNING_IDENTITY" >> build/conda/installer/construct.yaml
cd build/conda && constructor installer/. && cd ../../
mv build/conda/OpenBB-Platform-MacOSX-arm64.pkg OpenBB-Platform-MacOSX-arm64.pkg
shell: bash -l {0}
- name: Deleting Previous Keychain
run: |
echo "Deleting Previous Keychain to Clean Instance"
rm -rf /Users/openbb/Library/Keychains/build.keychain-db
- name: Clean up Build Artifacts
run: |
rm -rf build/conda/tmp
- name: Notarize DMG
env:
NOTARIZE_APPLE_ID: ${{ secrets.NOTARIZE_APPLE_ID }}
NOTARIZE_APPLE_PWD: ${{ secrets.NOTARIZE_APPLE_PWD }}
NOTARIZE_APPLE_TEAM_ID: ${{ secrets.NOTARIZE_APPLE_TEAM_ID }}
run: |
xcrun notarytool submit OpenBB-Platform-MacOSX-arm64.pkg --apple-id "$NOTARIZE_APPLE_ID" --password "$NOTARIZE_APPLE_PWD" --team-id "$NOTARIZE_APPLE_TEAM_ID" --wait
- name: Staple
run: |
xcrun stapler staple OpenBB-Platform-MacOSX-arm64.pkg
- name: Save Build Artifact PKG
uses: actions/upload-artifact@v4
with:
name: OpenBBM1.pkg
path: OpenBB-Platform-MacOSX-arm64.pkg
- name: Clean up Build Artifacts
run: |
rm OpenBB-Platform-MacOSX-arm64.pkg
# Job to build the MacOS Intel version of the Terminal===================================
Intel-MacOs-Build:
name: Intel MacOS Build
runs-on: [self-hosted, macos, x64]
permissions:
contents: read
steps:
# Checkout repository main branch. this allows for the commit hashes to line up
- name: Checkout
uses: actions/checkout@v3
- name: Git Log
run: git log
# The following commands to clear previous PATHS and restore to defaults since we have to maintain the instance ourselves
- name: Clean Previous Path
run: |
export PATH=""
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
echo $PATH
# Set up caching for conda env so that the workflow runs quickly after the first time
- name: Setup Conda Caching
uses: actions/cache@v3
with:
path: ~/conda_pkgs_dir
key: conda-macos-3-10-${{ hashFiles('build/conda/environments/constructor.yml') }}
# Set up miniconda using the environment yaml file within the repo
- name: Setup Miniconda
uses: conda-incubator/setup-miniconda@v3.0.4
with:
miniconda-version: "latest"
auto-update-conda: true
channels: conda-forge,defaults
show-channel-urls: true
channel-priority: flexible
environment-file: build/conda/environments/constructor.yml
activate-environment: constructor
auto-activate-base: false
- name: Creating Application Keychain
env:
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
MACOS_KEYCHAIN_PWD: ${{ secrets.MACOS_KEYCHAIN_PWD }}
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
run:
| # when pushing to main, make to generate new cert, and utilize secrets to store new password, and identity
echo "Ensuring Keychain with same name does not exist"
rm -rf /Users/openbb/Library/Keychains/build.keychain-db
echo "Decoding certificate"
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
echo "Creating Keychain"
security create-keychain -p $MACOS_KEYCHAIN_PWD build.keychain
echo "Setting Default Keychain"
security default-keychain -s build.keychain
echo "Unlocking Keychain"
security unlock-keychain -p $MACOS_KEYCHAIN_PWD build.keychain
echo "Importing Keychain"
security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign
echo "Setting Partition List"
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $MACOS_KEYCHAIN_PWD build.keychain
- name: Create Signed Package
env:
MACOS_INSTALLER_KEYCHAIN_PWD: ${{ secrets.MACOS_INSTALLER_KEYCHAIN_PWD }}
MACOS_INSTALLER_SIGNING_IDENTITY_NAME: ${{ secrets.MACOS_CODESIGN_INSTALLER_IDENTITY_NAME }}
MACOS_APPLICATION_SIGNING_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
run: |
security unlock-keychain -p $MACOS_INSTALLER_KEYCHAIN_PWD install.keychain
echo "signing_identity_name: $MACOS_INSTALLER_SIGNING_IDENTITY_NAME" >> build/conda/installer/construct.yaml
echo "notarization_identity_name: $MACOS_APPLICATION_SIGNING_IDENTITY" >> build/conda/installer/construct.yaml
cd build/conda && constructor installer/. && cd ../../
mv build/conda/OpenBB-Platform-MacOSX-x86_64.pkg OpenBB-Platform-MacOSX-x86_64.pkg
shell: bash -l {0}
- name: Deleting Previous Keychain
run: |
echo "Deleting Previous Keychain to Clean Instance"
rm -rf /Users/openbb/Library/Keychains/build.keychain-db
- name: Clean up Build Artifacts
run: |
rm -rf build/conda/tmp
- name: Notarize DMG
env:
NOTARIZE_APPLE_ID: ${{ secrets.NOTARIZE_APPLE_ID }}
NOTARIZE_APPLE_PWD: ${{ secrets.NOTARIZE_APPLE_PWD }}
NOTARIZE_APPLE_TEAM_ID: ${{ secrets.NOTARIZE_APPLE_TEAM_ID }}
run: |
xcrun notarytool submit OpenBB-Platform-MacOSX-x86_64.pkg --apple-id "$NOTARIZE_APPLE_ID" --password "$NOTARIZE_APPLE_PWD" --team-id "$NOTARIZE_APPLE_TEAM_ID" --wait
- name: Staple
run: |
xcrun stapler staple OpenBB-Platform-MacOSX-x86_64.pkg
- name: Save Build Artifact PKG
uses: actions/upload-artifact@v4
with:
name: OpenBBIntel.pkg
path: OpenBB-Platform-MacOSX-x86_64.pkg
- name: Clean up Build Artifacts
run: |
rm OpenBB-Platform-MacOSX-x86_64.pkg

219
.github/workflows/release-desktop.yml vendored Normal file
View File

@@ -0,0 +1,219 @@
name: Release ODP Desktop
on:
workflow_call:
inputs:
tag:
required: true
type: string
draft:
required: true
type: boolean
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Tag for release"
required: false
default: ""
draft:
description: "Create as draft release"
required: false
default: "false"
jobs:
build-windows:
uses: ./.github/workflows/build-desktop-win64.yml
with:
release: true
secrets: inherit
permissions:
contents: write
build-macos-arm:
uses: ./.github/workflows/build-desktop-osxARM.yml
with:
release: true
secrets: inherit
permissions:
contents: write
build-macos-x64:
uses: ./.github/workflows/build-desktop-osx64.yml
with:
release: true
secrets: inherit
permissions:
contents: write
publish:
needs: [build-windows, build-macos-arm, build-macos-x64]
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.extract_version.outputs.version }}
tag: ${{ steps.extract_version.outputs.tag }}
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Sanitize artifact filenames
run: |
find ./artifacts -depth -name "* *" | while read -r file; do mv "$file" "$(echo "$file" | tr ' ' '-')"; done
- name: Extract Version and Tag
id: extract_version
run: |
# Use input tag if provided, otherwise extract from artifacts
if [ -n "${{ github.event.inputs.tag }}" ]; then
TAG="${{ github.event.inputs.tag }}"
VERSION=$(echo "$TAG" | sed 's/^[^0-9]*//')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "release_name=Open Data Platform $TAG" >> $GITHUB_OUTPUT
echo "tag=$TAG" >> $GITHUB_OUTPUT
else
INSTALLER_FILE=$(find ./artifacts -name "*.exe" -o -name "*.dmg" | head -n 1)
if [ -z "$INSTALLER_FILE" ]; then
echo "::error::No installer file found in artifacts."
exit 1
fi
VERSION=$(basename "$INSTALLER_FILE" | sed -n 's/.*_\([0-9]\+\.[0-9]\+\.[0-9]\+\)_.*/\1/p')
if [ -z "$VERSION" ]; then
echo "::error::Could not extract version from filename: $(basename "$INSTALLER_FILE")"
exit 1
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "release_name=Open Data Platform v$VERSION" >> $GITHUB_OUTPUT
echo "tag=Open-Data-Platform-v$VERSION" >> $GITHUB_OUTPUT
fi
- name: Prepare assets and generate release.json
id: prep_assets
run: |
mkdir ./release_assets
find ./artifacts -type f -print -exec cp {} ./release_assets/ \;
cd ./release_assets
VERSION="${{ steps.extract_version.outputs.version }}"
RELEASE_NAME="${{ steps.extract_version.outputs.release_name }}"
TAG="${{ steps.extract_version.outputs.tag }}"
cat << EOF > release.json
{
"version": "$VERSION",
"notes": "Release for $RELEASE_NAME",
"pub_date": "$(date -u +'%Y-%m-%dT%H:%M:%SZ')",
"platforms": {
EOF
WIN_EXE=$(find . -name "*_x86_64.exe" | head -n 1)
if [ -n "$WIN_EXE" ]; then
WIN_SIG_FILE="${WIN_EXE}.sig"
WIN_SIG=$(cat "$WIN_SIG_FILE")
WIN_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/$(basename "$WIN_EXE")"
cat << EOF >> release.json
"windows-x86_64": {
"signature": "$WIN_SIG",
"url": "$WIN_URL"
}
EOF
fi
MAC_ARM_TAR=$(find . -name "*_aarch64.app.tar.gz" | head -n 1)
if [ -n "$MAC_ARM_TAR" ]; then
if [ -n "$WIN_EXE" ]; then
echo "," >> release.json
fi
MAC_ARM_SIG=$(cat "${MAC_ARM_TAR}.sig")
MAC_ARM_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/$(basename "$MAC_ARM_TAR")"
cat << EOF >> release.json
"darwin-aarch64": {
"signature": "$MAC_ARM_SIG",
"url": "$MAC_ARM_URL"
}
EOF
fi
MAC_X64_TAR=$(find . -name "*_x86_64.app.tar.gz" | head -n 1)
if [ -n "$MAC_X64_TAR" ]; then
if [ -n "$WIN_EXE" ] || [ -n "$MAC_ARM_TAR" ]; then
echo "," >> release.json
fi
MAC_X64_SIG=$(cat "${MAC_X64_TAR}.sig")
MAC_X64_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/$(basename "$MAC_X64_TAR")"
cat << EOF >> release.json
"darwin-x86_64": {
"signature": "$MAC_X64_SIG",
"url": "$MAC_X64_URL"
}
EOF
fi
cat << EOF >> release.json
}
}
EOF
echo "Generated release.json:"
cat release.json
cd ..
echo "assets_path=./release_assets" >> $GITHUB_OUTPUT
- name: Upload release assets
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.extract_version.outputs.tag }}
name: ${{ steps.extract_version.outputs.release_name }}
files: ${{ steps.prep_assets.outputs.assets_path }}/*
draft: ${{ github.event.inputs.draft == 'true' }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload release.json as artifact for odp job
uses: actions/upload-artifact@v4
with:
name: release-json
path: ./release_assets/release.json
update-latest-tag:
needs: publish
# Only run this job if not a draft release
if: github.event.inputs.draft != 'true'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download release artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Delete existing odp tag and release
continue-on-error: true
run: |
gh release delete odp --yes || true
git push origin :refs/tags/odp || true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Prepare latest assets
run: |
mkdir ./odp_assets
find ./artifacts -name "*.exe" -exec cp {} ./odp_assets/ \;
find ./artifacts -name "*.dmg" -exec cp {} ./odp_assets/ \;
if [ -f ./artifacts/release-json/release.json ]; then
cp ./artifacts/release-json/release.json ./odp_assets/latest.json
fi
- name: Create latest release
uses: softprops/action-gh-release@v1
with:
tag_name: odp
name: Latest Release
body: |
This is the latest stable release.
For version-specific details, see the corresponding versioned release.
files: ./odp_assets/*
prerelease: false
draft: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -0,0 +1,83 @@
name: Test macOS x64
on:
pull_request:
branches:
- develop
paths:
- 'desktop/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
test-macos-x64:
runs-on: macos-15-intel
permissions:
contents: read
defaults:
run:
working-directory: desktop
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
components: clippy, rustfmt
override: true
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: macos-x64-cargo-registry-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
macos-x64-cargo-registry-
- name: Cache cargo build
uses: actions/cache@v4
with:
path: desktop/target
key: macos-x64-cargo-build-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
macos-x64-cargo-build-
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy linter
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Run tests
run: cargo test --all
- name: Cache node_modules
uses: actions/cache@v4
with:
path: desktop/node_modules
key: macos-x64-node-modules-${{ hashFiles('desktop/**/package-lock.json') }}
restore-keys: |
macos-x64-node-modules-
- name: Install frontend dependencies
run: npm ci
- name: Lint frontend code
run: npm run lint
- name: Type check
run: ./node_modules/.bin/tsc --noEmit
- name: Run frontend tests
run: npm run test -- --watch=false

View File

@@ -0,0 +1,86 @@
name: Test macOS ARM64
on:
pull_request:
branches:
- develop
paths:
- 'desktop/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
test-macos-arm64:
runs-on: macos-latest
permissions:
contents: read
defaults:
run:
working-directory: desktop
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
components: clippy, rustfmt
override: true
- name: Add Rust target (macOS ARM only)
run: rustup target add aarch64-apple-darwin
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: macos-arm64-cargo-registry-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
macos-arm64-cargo-registry-
- name: Cache cargo build
uses: actions/cache@v4
with:
path: desktop/target
key: macos-arm64-cargo-build-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
macos-arm64-cargo-build-
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy linter
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Run tests
run: cargo test --all
- name: Cache node_modules
uses: actions/cache@v4
with:
path: desktop/node_modules
key: macos-arm64-node-modules-${{ hashFiles('desktop/**/package-lock.json') }}
restore-keys: |
macos-arm64-node-modules-
- name: Install frontend dependencies
run: npm ci
- name: Lint frontend code
run: npm run lint
- name: Type check
run: ./node_modules/.bin/tsc --noEmit
- name: Run frontend tests
run: npm run test -- --watch=false

View File

@@ -0,0 +1,115 @@
name: Test Windows x64
on:
pull_request:
branches:
- develop
paths:
- 'desktop/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
test-windows-x64:
runs-on: windows-latest
permissions:
contents: read
defaults:
run:
working-directory: desktop
env:
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
steps:
- uses: actions/checkout@v4
- name: Cache vcpkg
uses: actions/cache@v4
with:
path: ${{ env.VCPKG_ROOT }}
key: ${{ runner.os }}-vcpkg-${{ hashFiles('desktop/**/vcpkg.json') }}
restore-keys: |
${{ runner.os }}-vcpkg-
- name: Bootstrap vcpkg
working-directory: ${{ github.workspace }}
run: |
if (-not (Test-Path ${{ env.VCPKG_ROOT }})) {
git clone https://github.com/microsoft/vcpkg.git ${{ env.VCPKG_ROOT }}
}
${{ env.VCPKG_ROOT }}/bootstrap-vcpkg.bat
shell: pwsh
- name: Install OpenSSL using vcpkg
working-directory: ${{ github.workspace }}
run: ${{ env.VCPKG_ROOT }}/vcpkg install openssl:x64-windows-static --vcpkg-root ${{ env.VCPKG_ROOT }}
env:
VCPKG_DEFAULT_TRIPLET: x64-windows-static
- name: Set OpenSSL env
shell: bash
run: |
echo "OPENSSL_DIR=${{ env.VCPKG_ROOT }}/installed/x64-windows-static" >> $GITHUB_ENV
echo "OPENSSL_INCLUDE_DIR=${{ env.VCPKG_ROOT }}/installed/x64-windows-static/include" >> $GITHUB_ENV
echo "OPENSSL_LIB_DIR=${{ env.VCPKG_ROOT }}/installed/x64-windows-static/lib" >> $GITHUB_ENV
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
components: clippy, rustfmt
override: true
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: windows-x64-cargo-registry-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
windows-x64-cargo-registry-
- name: Cache cargo build
uses: actions/cache@v4
with:
path: desktop/target
key: windows-x64-cargo-build-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
windows-x64-cargo-build-
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy linter
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Run tests
run: cargo test --all
- name: Cache node_modules
uses: actions/cache@v4
with:
path: desktop/node_modules
key: windows-x64-node-modules-${{ hashFiles('desktop/**/package-lock.json') }}
restore-keys: |
windows-x64-node-modules-
- name: Install frontend dependencies
run: npm ci
- name: Lint frontend code
run: npm run lint
- name: Type check
run: ./node_modules/.bin/tsc --noEmit
- name: Run frontend tests
run: npm run test -- --watch=false