diff --git a/.github/scripts/electron-checksum.py b/.github/scripts/electron-checksum.py new file mode 100644 index 000000000..fba4ff609 --- /dev/null +++ b/.github/scripts/electron-checksum.py @@ -0,0 +1,28 @@ +import hashlib +import base64 +import sys + +def hash_file(file_path): + # Create a SHA-512 hash object + sha512 = hashlib.sha512() + + # Read and update the hash object with the content of the file + with open(file_path, 'rb') as f: + while True: + data = f.read(1024 * 1024) # Read in 1 MB chunks + if not data: + break + sha512.update(data) + + # Obtain the hash result and encode it in base64 + hash_base64 = base64.b64encode(sha512.digest()).decode('utf-8') + return hash_base64 + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Usage: python3 script.py ") + sys.exit(1) + + file_path = sys.argv[1] + hash_base64_output = hash_file(file_path) + print(hash_base64_output) diff --git a/.github/scripts/icon-beta.png b/.github/scripts/icon-beta.png new file mode 100644 index 000000000..4b715494d Binary files /dev/null and b/.github/scripts/icon-beta.png differ diff --git a/.github/scripts/icon-nightly.png b/.github/scripts/icon-nightly.png new file mode 100644 index 000000000..23f532947 Binary files /dev/null and b/.github/scripts/icon-nightly.png differ diff --git a/.github/scripts/rename-tauri-app.sh b/.github/scripts/rename-tauri-app.sh new file mode 100644 index 000000000..12a1fadb7 --- /dev/null +++ b/.github/scripts/rename-tauri-app.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Check if the correct number of arguments is provided +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +INPUT_JSON_FILE="$1" + +CHANNEL="$2" + +if [ "$CHANNEL" == "nightly" ]; then + UPDATER="latest" +else + UPDATER="beta" +fi + +# Check if the input file exists +if [ ! -f "$INPUT_JSON_FILE" ]; then + echo "Input file not found: $INPUT_JSON_FILE" + exit 1 +fi + +# Use jq to transform the content +jq --arg channel "$CHANNEL" --arg updater "$UPDATER" ' + .productName = "Jan-\($channel)" | + .identifier = "jan-\($channel).ai.app" +' "$INPUT_JSON_FILE" > ./tauri.conf.json.tmp + +cat ./tauri.conf.json.tmp + +rm $INPUT_JSON_FILE +mv ./tauri.conf.json.tmp $INPUT_JSON_FILE + +# Update the layout file +# LAYOUT_FILE_PATH="web/app/layout.tsx" + +# if [ ! -f "$LAYOUT_FILE_PATH" ]; then +# echo "File does not exist: $LAYOUT_FILE_PATH" +# exit 1 +# fi + +# Perform the replacements +# sed -i -e "s#Jan#Jan-$CHANNEL#g" "$LAYOUT_FILE_PATH" + +# Notify completion +# echo "File has been updated: $LAYOUT_FILE_PATH" diff --git a/.github/workflows/jan-electron-build-beta.yml b/.github/workflows/jan-electron-build-beta.yml index 61ff717ac..c16b08244 100644 --- a/.github/workflows/jan-electron-build-beta.yml +++ b/.github/workflows/jan-electron-build-beta.yml @@ -8,9 +8,33 @@ jobs: # Job create Update app version based on latest release tag with build number and save to output get-update-version: uses: ./.github/workflows/template-get-update-version.yml + create-draft-release: + runs-on: ubuntu-latest + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + outputs: + upload_url: ${{ steps.create_release.outputs.upload_url }} + version: ${{ steps.get_version.outputs.version }} + permissions: + contents: write + steps: + - name: Extract tag name without v prefix + id: get_version + run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV && echo "::set-output name=version::${GITHUB_REF#refs/tags/v}" + env: + GITHUB_REF: ${{ github.ref }} + - name: Create Draft Release + id: create_release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.ref_name }} + token: ${{ secrets.GITHUB_TOKEN }} + name: "${{ env.VERSION }}" + draft: true + prerelease: false + generate_release_notes: true - build-macos: - uses: ./.github/workflows/template-build-macos.yml + build-electron-macos: + uses: ./.github/workflows/template-electron-build-macos.yml secrets: inherit needs: [get-update-version] with: @@ -21,8 +45,8 @@ jobs: nightly: false cortex_api_port: "39271" - build-windows-x64: - uses: ./.github/workflows/template-build-windows-x64.yml + build-electron-windows-x64: + uses: ./.github/workflows/template-electron-build-windows-x64.yml secrets: inherit needs: [get-update-version] with: @@ -33,8 +57,8 @@ jobs: nightly: false cortex_api_port: "39271" - build-linux-x64: - uses: ./.github/workflows/template-build-linux-x64.yml + build-electron-linux-x64: + uses: ./.github/workflows/template-electron-build-linux-x64.yml secrets: inherit needs: [get-update-version] with: @@ -45,8 +69,51 @@ jobs: nightly: false cortex_api_port: "39271" + build-tauri-macos: + uses: ./.github/workflows/template-tauri-build-macos-preview.yml + secrets: inherit + needs: [get-update-version, create-draft-release] + with: + ref: ${{ github.ref }} + public_provider: github + new_version: ${{ needs.get-update-version.outputs.new_version }} + channel: beta + cortex_api_port: "39271" + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + + build-tauri-windows-x64: + uses: ./.github/workflows/template-tauri-build-windows-x64-preview.yml + secrets: inherit + needs: [get-update-version, create-draft-release] + with: + ref: ${{ github.ref }} + public_provider: github + new_version: ${{ needs.get-update-version.outputs.new_version }} + channel: beta + cortex_api_port: "39271" + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + + build-tauri-linux-x64: + uses: ./.github/workflows/template-tauri-build-linux-x64-preview.yml + secrets: inherit + needs: [get-update-version, create-draft-release] + with: + ref: ${{ github.ref }} + public_provider: github + new_version: ${{ needs.get-update-version.outputs.new_version }} + channel: beta + cortex_api_port: "39271" + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + sync-temp-to-latest: - needs: [build-macos, build-windows-x64, build-linux-x64] + needs: [ + build-electron-windows-x64, + build-electron-linux-x64, + build-electron-macos, + build-tauri-windows-x64, + build-tauri-linux-x64, + build-tauri-macos + ] runs-on: ubuntu-latest permissions: contents: write @@ -64,7 +131,16 @@ jobs: AWS_EC2_METADATA_DISABLED: "true" noti-discord-and-update-url-readme: - needs: [build-macos, get-update-version, build-windows-x64, build-linux-x64, sync-temp-to-latest] + needs: [ + get-update-version, + sync-temp-to-latest, + build-electron-windows-x64, + build-electron-linux-x64, + build-electron-macos, + build-tauri-windows-x64, + build-tauri-linux-x64, + build-tauri-macos + ] runs-on: ubuntu-latest steps: - name: Set version to environment variable @@ -78,9 +154,14 @@ jobs: with: args: | Jan-beta App version {{ VERSION }}, has been released, use the following links to download the app with faster speed or visit the Github release page for more information: - - Windows: https://delta.jan.ai/beta/jan-beta-win-x64-{{ VERSION }}.exe - - macOS Universal: https://delta.jan.ai/beta/jan-beta-mac-universal-{{ VERSION }}.dmg - - Linux Deb: https://delta.jan.ai/beta/jan-beta-linux-amd64-{{ VERSION }}.deb - - Linux AppImage: https://delta.jan.ai/beta/jan-beta-linux-x86_64-{{ VERSION }}.AppImage + - Windows Electron: https://delta.jan.ai/beta/jan-beta-win-x64-{{ VERSION }}.exe + - macOS Electron Universal: https://delta.jan.ai/beta/jan-beta-mac-universal-{{ VERSION }}.dmg + - Linux Electron Deb: https://delta.jan.ai/beta/jan-beta-linux-amd64-{{ VERSION }}.deb + - Linux Electron AppImage: https://delta.jan.ai/beta/jan-beta-linux-x86_64-{{ VERSION }}.AppImage + - Windows Tauri Preview: https://delta.jan.ai/beta/Jan-beta_{{ VERSION }}_x64-setup-preview.exe + - macOS Taupri Preview Universal: https://delta.jan.ai/beta/Jan-beta_{{ VERSION }}_universal-preview.dmg + - Linux Tauri Preview Deb: https://delta.jan.ai/beta/Jan-beta_{{ VERSION }}_amd64-preview.deb + - Linux Tauri Preview AppImage: https://delta.jan.ai/beta/Jan-beta_{{ VERSION }}_amd64-preview.AppImage + env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_JAN_BETA }} \ No newline at end of file diff --git a/.github/workflows/jan-electron-build-nightly.yml b/.github/workflows/jan-electron-build-nightly.yml index af5bab195..00da06d37 100644 --- a/.github/workflows/jan-electron-build-nightly.yml +++ b/.github/workflows/jan-electron-build-nightly.yml @@ -14,6 +14,9 @@ on: default: none pull_request_review: types: [submitted] + pull_request: + branches: + - chore/tauri-cicd jobs: set-public-provider: @@ -47,8 +50,41 @@ jobs: get-update-version: uses: ./.github/workflows/template-get-update-version.yml - build-macos: - uses: ./.github/workflows/template-build-macos.yml + build-tauri-macos: + uses: ./.github/workflows/template-tauri-build-macos-preview.yml + secrets: inherit + needs: [get-update-version, set-public-provider] + with: + ref: ${{ needs.set-public-provider.outputs.ref }} + public_provider: ${{ needs.set-public-provider.outputs.public_provider }} + new_version: ${{ needs.get-update-version.outputs.new_version }} + channel: nightly + cortex_api_port: "39261" + + build-tauri-windows-x64: + uses: ./.github/workflows/template-tauri-build-windows-x64-preview.yml + secrets: inherit + needs: [get-update-version, set-public-provider] + with: + ref: ${{ needs.set-public-provider.outputs.ref }} + public_provider: ${{ needs.set-public-provider.outputs.public_provider }} + new_version: ${{ needs.get-update-version.outputs.new_version }} + channel: nightly + cortex_api_port: "39261" + + build-tauri-linux-x64: + uses: ./.github/workflows/template-tauri-build-linux-x64-preview.yml + secrets: inherit + needs: [get-update-version, set-public-provider] + with: + ref: ${{ needs.set-public-provider.outputs.ref }} + public_provider: ${{ needs.set-public-provider.outputs.public_provider }} + new_version: ${{ needs.get-update-version.outputs.new_version }} + channel: nightly + cortex_api_port: "39261" + + build-electron-macos: + uses: ./.github/workflows/template-electron-build-macos.yml needs: [get-update-version, set-public-provider] secrets: inherit with: @@ -59,8 +95,8 @@ jobs: beta: false cortex_api_port: "39261" - build-windows-x64: - uses: ./.github/workflows/template-build-windows-x64.yml + build-electron-windows-x64: + uses: ./.github/workflows/template-electron-build-windows-x64.yml secrets: inherit needs: [get-update-version, set-public-provider] with: @@ -70,8 +106,8 @@ jobs: nightly: true beta: false cortex_api_port: "39261" - build-linux-x64: - uses: ./.github/workflows/template-build-linux-x64.yml + build-electron-linux-x64: + uses: ./.github/workflows/template-electron-build-linux-x64.yml secrets: inherit needs: [get-update-version, set-public-provider] with: @@ -83,8 +119,16 @@ jobs: cortex_api_port: "39261" sync-temp-to-latest: - needs: [set-public-provider, build-windows-x64, build-linux-x64, build-macos] runs-on: ubuntu-latest + needs: [ + set-public-provider, + build-electron-windows-x64, + build-electron-linux-x64, + build-electron-macos, + build-tauri-windows-x64, + build-tauri-linux-x64, + build-tauri-macos + ] steps: - name: Sync temp to latest if: ${{ needs.set-public-provider.outputs.public_provider == 'aws-s3' }} @@ -97,7 +141,17 @@ jobs: AWS_EC2_METADATA_DISABLED: "true" noti-discord-nightly-and-update-url-readme: - needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, sync-temp-to-latest] + needs: [ + build-electron-macos, + build-electron-windows-x64, + build-electron-linux-x64, + build-tauri-macos, + build-tauri-windows-x64, + build-tauri-linux-x64, + get-update-version, + set-public-provider, + sync-temp-to-latest + ] secrets: inherit if: github.event_name == 'schedule' uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml @@ -108,7 +162,17 @@ jobs: new_version: ${{ needs.get-update-version.outputs.new_version }} noti-discord-pre-release-and-update-url-readme: - needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, sync-temp-to-latest] + needs: [ + build-electron-macos, + build-electron-windows-x64, + build-electron-linux-x64, + build-tauri-macos, + build-tauri-windows-x64, + build-tauri-linux-x64, + get-update-version, + set-public-provider, + sync-temp-to-latest + ] secrets: inherit if: github.event_name == 'push' uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml @@ -119,7 +183,17 @@ jobs: new_version: ${{ needs.get-update-version.outputs.new_version }} noti-discord-manual-and-update-url-readme: - needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, sync-temp-to-latest] + needs: [ + build-electron-macos, + build-electron-windows-x64, + build-electron-linux-x64, + build-tauri-macos, + build-tauri-windows-x64, + build-tauri-linux-x64, + get-update-version, + set-public-provider, + sync-temp-to-latest + ] secrets: inherit if: github.event_name == 'workflow_dispatch' && github.event.inputs.public_provider == 'aws-s3' uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml @@ -131,7 +205,17 @@ jobs: comment-pr-build-url: - needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, sync-temp-to-latest] + needs: [ + build-electron-macos, + build-electron-windows-x64, + build-electron-linux-x64, + build-tauri-macos, + build-tauri-windows-x64, + build-tauri-linux-x64, + get-update-version, + set-public-provider, + sync-temp-to-latest + ] runs-on: ubuntu-latest if: github.event_name == 'pull_request_review' steps: @@ -147,4 +231,4 @@ jobs: PR_URL=${{ github.event.pull_request.html_url }} RUN_ID=${{ github.run_id }} COMMENT="This is the build for this pull request. You can download it from the Artifacts section here: [Build URL](https://github.com/${{ github.repository }}/actions/runs/${RUN_ID})." - gh pr comment $PR_URL --body "$COMMENT" + gh pr comment $PR_URL --body "$COMMENT" \ No newline at end of file diff --git a/.github/workflows/jan-electron-build.yml b/.github/workflows/jan-electron-build.yml index 7d69a5c12..c41376f49 100644 --- a/.github/workflows/jan-electron-build.yml +++ b/.github/workflows/jan-electron-build.yml @@ -33,8 +33,8 @@ jobs: draft: true prerelease: false - build-macos: - uses: ./.github/workflows/template-build-macos.yml + build-electron-macos: + uses: ./.github/workflows/template-electron-build-macos.yml secrets: inherit needs: [get-update-version] with: @@ -44,8 +44,8 @@ jobs: nightly: false new_version: ${{ needs.get-update-version.outputs.new_version }} - build-windows-x64: - uses: ./.github/workflows/template-build-windows-x64.yml + build-electron-windows-x64: + uses: ./.github/workflows/template-electron-build-windows-x64.yml secrets: inherit needs: [get-update-version] with: @@ -55,8 +55,8 @@ jobs: nightly: false new_version: ${{ needs.get-update-version.outputs.new_version }} - build-linux-x64: - uses: ./.github/workflows/template-build-linux-x64.yml + build-electron-linux-x64: + uses: ./.github/workflows/template-electron-build-linux-x64.yml secrets: inherit needs: [get-update-version] with: @@ -65,9 +65,48 @@ jobs: beta: false nightly: false new_version: ${{ needs.get-update-version.outputs.new_version }} + build-tauri-macos: + uses: ./.github/workflows/template-tauri-build-macos-preview.yml + secrets: inherit + needs: [get-update-version, create-draft-release] + with: + ref: ${{ github.ref }} + public_provider: github + channel: stable + new_version: ${{ needs.get-update-version.outputs.new_version }} + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + + build-tauri-windows-x64: + uses: ./.github/workflows/template-tauri-build-windows-x64-preview.yml + secrets: inherit + needs: [get-update-version, create-draft-release] + with: + ref: ${{ github.ref }} + public_provider: github + channel: stable + new_version: ${{ needs.get-update-version.outputs.new_version }} + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + + build-tauri-linux-x64: + uses: ./.github/workflows/template-tauri-build-linux-x64-preview.yml + secrets: inherit + needs: [get-update-version, create-draft-release] + with: + ref: ${{ github.ref }} + public_provider: github + channel: stable + new_version: ${{ needs.get-update-version.outputs.new_version }} + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} update_release_draft: - needs: [build-macos, build-windows-x64, build-linux-x64] + needs: [ + build-electron-windows-x64, + build-electron-linux-x64, + build-electron-macos, + build-tauri-windows-x64, + build-tauri-linux-x64, + build-tauri-macos + ] permissions: # write permission is required to create a github release contents: write diff --git a/.github/workflows/jan-tauri-build-beta.yml b/.github/workflows/jan-tauri-build-beta.yml new file mode 100644 index 000000000..476293d71 --- /dev/null +++ b/.github/workflows/jan-tauri-build-beta.yml @@ -0,0 +1,156 @@ +name: Tauri Builder - Beta Build + +on: + push: + tags: ["v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+-beta"] + +jobs: + # Job create Update app version based on latest release tag with build number and save to output + get-update-version: + uses: ./.github/workflows/template-get-update-version.yml + create-draft-release: + runs-on: ubuntu-latest + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + outputs: + upload_url: ${{ steps.create_release.outputs.upload_url }} + version: ${{ steps.get_version.outputs.version }} + permissions: + contents: write + steps: + - name: Extract tag name without v prefix + id: get_version + run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV && echo "::set-output name=version::${GITHUB_REF#refs/tags/v}" + env: + GITHUB_REF: ${{ github.ref }} + - name: Create Draft Release + id: create_release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.ref_name }} + token: ${{ secrets.GITHUB_TOKEN }} + name: "${{ env.VERSION }}" + draft: true + prerelease: false + generate_release_notes: true + + build-macos: + uses: ./.github/workflows/template-tauri-build-macos.yml + secrets: inherit + needs: [get-update-version, create-draft-release] + with: + ref: ${{ github.ref }} + public_provider: github + new_version: ${{ needs.get-update-version.outputs.new_version }} + channel: beta + cortex_api_port: "39271" + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + + build-windows-x64: + uses: ./.github/workflows/template-tauri-build-windows-x64.yml + secrets: inherit + needs: [get-update-version, create-draft-release] + with: + ref: ${{ github.ref }} + public_provider: github + new_version: ${{ needs.get-update-version.outputs.new_version }} + channel: beta + cortex_api_port: "39271" + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + + build-linux-x64: + uses: ./.github/workflows/template-tauri-build-linux-x64.yml + secrets: inherit + needs: [get-update-version, create-draft-release] + with: + ref: ${{ github.ref }} + public_provider: github + new_version: ${{ needs.get-update-version.outputs.new_version }} + channel: beta + cortex_api_port: "39271" + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + + sync-temp-to-latest: + needs: [create-draft-release, get-update-version, build-macos, build-windows-x64, build-linux-x64] + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Getting the repo + uses: actions/checkout@v3 + + - name: create latest.json file + run: | + + VERSION=${{ needs.get-update-version.outputs.new_version }} + PUB_DATE=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ") + LINUX_SIGNATURE="${{ needs.build-linux-x64.outputs.APPIMAGE_SIG }}" + LINUX_URL="https://delta.jan.ai/beta/${{ needs.build-linux-x64.outputs.APPIMAGE_FILE_NAME }}" + WINDOWS_SIGNATURE="${{ needs.build-windows-x64.outputs.WIN_SIG }}" + WINDOWS_URL="https://delta.jan.ai/beta/${{ needs.build-windows-x64.outputs.FILE_NAME }}" + DARWIN_SIGNATURE="${{ needs.build-macos.outputs.MAC_UNIVERSAL_SIG }}" + DARWIN_URL="https://delta.jan.ai/beta/Jan-beta_${{ needs.get-update-version.outputs.new_version }}.app.tar.gz" + + jq --arg version "$VERSION" \ + --arg pub_date "$PUB_DATE" \ + --arg linux_signature "$LINUX_SIGNATURE" \ + --arg linux_url "$LINUX_URL" \ + --arg windows_signature "$WINDOWS_SIGNATURE" \ + --arg windows_url "$WINDOWS_URL" \ + --arg darwin_arm_signature "$DARWIN_SIGNATURE" \ + --arg darwin_arm_url "$DARWIN_URL" \ + --arg darwin_amd_signature "$DARWIN_SIGNATURE" \ + --arg darwin_amd_url "$DARWIN_URL" \ + '.version = $version + | .pub_date = $pub_date + | .platforms["linux-x86_64"].signature = $linux_signature + | .platforms["linux-x86_64"].url = $linux_url + | .platforms["windows-x86_64"].signature = $windows_signature + | .platforms["windows-x86_64"].url = $windows_url + | .platforms["darwin-aarch64"].signature = $darwin_arm_signature + | .platforms["darwin-aarch64"].url = $darwin_arm_url + | .platforms["darwin-x86_64"].signature = $darwin_amd_signature + | .platforms["darwin-x86_64"].url = $darwin_amd_url' \ + src-tauri/latest.json.template > latest.json + cat latest.json + - name: Sync temp to latest + run: | + # sync temp-beta to beta by copy files that are different or new + aws s3 cp ./latest.json s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-beta/latest.json + aws s3 sync "s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-beta/" "s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/beta/" + env: + AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.DELTA_AWS_REGION }} + AWS_EC2_METADATA_DISABLED: "true" + + - name: Upload release assert if public provider is github + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + asset_path: ./latest.json + asset_name: latest.json + asset_content_type: text/json + + noti-discord-and-update-url-readme: + needs: [build-macos, get-update-version, build-windows-x64, build-linux-x64, sync-temp-to-latest] + runs-on: ubuntu-latest + steps: + - name: Set version to environment variable + run: | + VERSION=${{ needs.get-update-version.outputs.new_version }} + VERSION="${VERSION#v}" + echo "VERSION=$VERSION" >> $GITHUB_ENV + + - name: Notify Discord + uses: Ilshidur/action-discord@master + with: + args: | + Jan-beta App version {{ VERSION }}, has been released, use the following links to download the app with faster speed or visit the Github release page for more information: + - Windows: https://delta.jan.ai/beta/Jan-beta_{{ VERSION }}_x64-setup.exe + - macOS Universal: https://delta.jan.ai/beta/Jan-beta_{{ VERSION }}_universal.dmg + - Linux Deb: https://delta.jan.ai/beta/Jan-beta_{{ VERSION }}_amd64.deb + - Linux AppImage: https://delta.jan.ai/beta/Jan-beta_{{ VERSION }}_amd64.AppImage + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_JAN_BETA }} \ No newline at end of file diff --git a/.github/workflows/jan-tauri-build-nightly.yml b/.github/workflows/jan-tauri-build-nightly.yml new file mode 100644 index 000000000..ba21e89f1 --- /dev/null +++ b/.github/workflows/jan-tauri-build-nightly.yml @@ -0,0 +1,186 @@ +name: Tauri Builder - Nightly / Manual + +on: + schedule: + - cron: '0 20 * * 1,2,3' # At 8 PM UTC on Monday, Tuesday, and Wednesday which is 3 AM UTC+7 Tuesday, Wednesday, and Thursday + workflow_dispatch: + inputs: + public_provider: + type: choice + description: 'Public Provider' + options: + - none + - aws-s3 + default: none + pull_request_review: + types: [submitted] + +jobs: + set-public-provider: + runs-on: ubuntu-latest + outputs: + public_provider: ${{ steps.set-public-provider.outputs.public_provider }} + ref: ${{ steps.set-public-provider.outputs.ref }} + steps: + - name: Set public provider + id: set-public-provider + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "::set-output name=public_provider::${{ github.event.inputs.public_provider }}" + echo "::set-output name=ref::${{ github.ref }}" + else + if [ "${{ github.event_name }}" == "schedule" ]; then + echo "::set-output name=public_provider::aws-s3" + echo "::set-output name=ref::refs/heads/dev" + elif [ "${{ github.event_name }}" == "push" ]; then + echo "::set-output name=public_provider::aws-s3" + echo "::set-output name=ref::${{ github.ref }}" + elif [ "${{ github.event_name }}" == "pull_request_review" ]; then + echo "::set-output name=public_provider::none" + echo "::set-output name=ref::${{ github.ref }}" + else + echo "::set-output name=public_provider::none" + echo "::set-output name=ref::${{ github.ref }}" + fi + fi + # Job create Update app version based on latest release tag with build number and save to output + get-update-version: + uses: ./.github/workflows/template-get-update-version.yml + + build-macos: + uses: ./.github/workflows/template-tauri-build-macos.yml + needs: [get-update-version, set-public-provider] + secrets: inherit + with: + ref: ${{ needs.set-public-provider.outputs.ref }} + public_provider: ${{ needs.set-public-provider.outputs.public_provider }} + new_version: ${{ needs.get-update-version.outputs.new_version }} + channel: nightly + cortex_api_port: "39261" + + build-windows-x64: + uses: ./.github/workflows/template-tauri-build-windows-x64.yml + secrets: inherit + needs: [get-update-version, set-public-provider] + with: + ref: ${{ needs.set-public-provider.outputs.ref }} + public_provider: ${{ needs.set-public-provider.outputs.public_provider }} + new_version: ${{ needs.get-update-version.outputs.new_version }} + channel: nightly + cortex_api_port: "39261" + build-linux-x64: + uses: ./.github/workflows/template-tauri-build-linux-x64.yml + secrets: inherit + needs: [get-update-version, set-public-provider] + with: + ref: ${{ needs.set-public-provider.outputs.ref }} + public_provider: ${{ needs.set-public-provider.outputs.public_provider }} + new_version: ${{ needs.get-update-version.outputs.new_version }} + channel: nightly + cortex_api_port: "39261" + + sync-temp-to-latest: + needs: [get-update-version, set-public-provider, build-windows-x64, build-linux-x64, build-macos] + runs-on: ubuntu-latest + steps: + - name: Getting the repo + uses: actions/checkout@v3 + - name: Install jq + uses: dcarbone/install-jq-action@v2.0.1 + - name: create latest.json file + run: | + + VERSION=${{ needs.get-update-version.outputs.new_version }} + PUB_DATE=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ") + LINUX_SIGNATURE="${{ needs.build-linux-x64.outputs.APPIMAGE_SIG }}" + LINUX_URL="https://delta.jan.ai/nightly/${{ needs.build-linux-x64.outputs.APPIMAGE_FILE_NAME }}" + WINDOWS_SIGNATURE="${{ needs.build-windows-x64.outputs.WIN_SIG }}" + WINDOWS_URL="https://delta.jan.ai/nightly/${{ needs.build-windows-x64.outputs.FILE_NAME }}" + DARWIN_SIGNATURE="${{ needs.build-macos.outputs.MAC_UNIVERSAL_SIG }}" + DARWIN_URL="https://delta.jan.ai/nightly/Jan-nightly_${{ needs.get-update-version.outputs.new_version }}.app.tar.gz" + + jq --arg version "$VERSION" \ + --arg pub_date "$PUB_DATE" \ + --arg linux_signature "$LINUX_SIGNATURE" \ + --arg linux_url "$LINUX_URL" \ + --arg windows_signature "$WINDOWS_SIGNATURE" \ + --arg windows_url "$WINDOWS_URL" \ + --arg darwin_arm_signature "$DARWIN_SIGNATURE" \ + --arg darwin_arm_url "$DARWIN_URL" \ + --arg darwin_amd_signature "$DARWIN_SIGNATURE" \ + --arg darwin_amd_url "$DARWIN_URL" \ + '.version = $version + | .pub_date = $pub_date + | .platforms["linux-x86_64"].signature = $linux_signature + | .platforms["linux-x86_64"].url = $linux_url + | .platforms["windows-x86_64"].signature = $windows_signature + | .platforms["windows-x86_64"].url = $windows_url + | .platforms["darwin-aarch64"].signature = $darwin_arm_signature + | .platforms["darwin-aarch64"].url = $darwin_arm_url + | .platforms["darwin-x86_64"].signature = $darwin_amd_signature + | .platforms["darwin-x86_64"].url = $darwin_amd_url' \ + src-tauri/latest.json.template > latest.json + cat latest.json + - name: Sync temp to latest + if: ${{ needs.set-public-provider.outputs.public_provider == 'aws-s3' }} + run: | + aws s3 cp ./latest.json s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-nightly/latest.json + aws s3 sync s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-nightly/ s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/nightly/ + env: + AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.DELTA_AWS_REGION }} + AWS_EC2_METADATA_DISABLED: "true" + + noti-discord-nightly-and-update-url-readme: + needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, sync-temp-to-latest] + secrets: inherit + if: github.event_name == 'schedule' + uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml + with: + ref: refs/heads/dev + build_reason: Nightly + push_to_branch: dev + new_version: ${{ needs.get-update-version.outputs.new_version }} + + noti-discord-pre-release-and-update-url-readme: + needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, sync-temp-to-latest] + secrets: inherit + if: github.event_name == 'push' + uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml + with: + ref: refs/heads/dev + build_reason: Pre-release + push_to_branch: dev + new_version: ${{ needs.get-update-version.outputs.new_version }} + + noti-discord-manual-and-update-url-readme: + needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, sync-temp-to-latest] + secrets: inherit + if: github.event_name == 'workflow_dispatch' && github.event.inputs.public_provider == 'aws-s3' + uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml + with: + ref: refs/heads/dev + build_reason: Manual + push_to_branch: dev + new_version: ${{ needs.get-update-version.outputs.new_version }} + + + comment-pr-build-url: + needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider, sync-temp-to-latest] + runs-on: ubuntu-latest + if: github.event_name == 'pull_request_review' + steps: + - name: Set up GitHub CLI + run: | + curl -sSL https://github.com/cli/cli/releases/download/v2.33.0/gh_2.33.0_linux_amd64.tar.gz | tar xz + sudo cp gh_2.33.0_linux_amd64/bin/gh /usr/local/bin/ + + - name: Comment build URL on PR + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + PR_URL=${{ github.event.pull_request.html_url }} + RUN_ID=${{ github.run_id }} + COMMENT="This is the build for this pull request. You can download it from the Artifacts section here: [Build URL](https://github.com/${{ github.repository }}/actions/runs/${RUN_ID})." + gh pr comment $PR_URL --body "$COMMENT" diff --git a/.github/workflows/jan-tauri-build.yml b/.github/workflows/jan-tauri-build.yml new file mode 100644 index 000000000..1dc22f2e4 --- /dev/null +++ b/.github/workflows/jan-tauri-build.yml @@ -0,0 +1,145 @@ +name: Tauri Builder - Tag + +on: + push: + tags: ["v[0-9]+.[0-9]+.[0-9]+"] + +jobs: + # Job create Update app version based on latest release tag with build number and save to output + get-update-version: + uses: ./.github/workflows/template-get-update-version.yml + + create-draft-release: + runs-on: ubuntu-latest + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + outputs: + upload_url: ${{ steps.create_release.outputs.upload_url }} + version: ${{ steps.get_version.outputs.version }} + permissions: + contents: write + steps: + - name: Extract tag name without v prefix + id: get_version + run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV && echo "::set-output name=version::${GITHUB_REF#refs/tags/v}" + env: + GITHUB_REF: ${{ github.ref }} + - name: Create Draft Release + id: create_release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.ref_name }} + token: ${{ secrets.GITHUB_TOKEN }} + name: "${{ env.VERSION }}" + draft: true + prerelease: false + + build-macos: + uses: ./.github/workflows/template-tauri-build-macos.yml + secrets: inherit + needs: [get-update-version, create-draft-release] + with: + ref: ${{ github.ref }} + public_provider: github + channel: stable + new_version: ${{ needs.get-update-version.outputs.new_version }} + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + + build-windows-x64: + uses: ./.github/workflows/template-tauri-build-windows-x64.yml + secrets: inherit + needs: [get-update-version, create-draft-release] + with: + ref: ${{ github.ref }} + public_provider: github + channel: stable + new_version: ${{ needs.get-update-version.outputs.new_version }} + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + + build-linux-x64: + uses: ./.github/workflows/template-tauri-build-linux-x64.yml + secrets: inherit + needs: [get-update-version, create-draft-release] + with: + ref: ${{ github.ref }} + public_provider: github + channel: stable + new_version: ${{ needs.get-update-version.outputs.new_version }} + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + + sync-temp-to-latest: + needs: [create-draft-release, get-update-version, build-macos, build-windows-x64, build-linux-x64] + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Getting the repo + uses: actions/checkout@v3 + + - name: create latest.json file + run: | + + VERSION=${{ needs.get-update-version.outputs.new_version }} + PUB_DATE=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ") + LINUX_SIGNATURE="${{ needs.build-linux-x64.outputs.APPIMAGE_SIG }}" + LINUX_URL="https://github.com/menloresearch/jan/releases/download/v${{ needs.get-update-version.outputs.new_version }}/${{ needs.build-linux-x64.outputs.APPIMAGE_FILE_NAME }}" + WINDOWS_SIGNATURE="${{ needs.build-windows-x64.outputs.WIN_SIG }}" + WINDOWS_URL="https://github.com/menloresearch/jan/releases/download/v${{ needs.get-update-version.outputs.new_version }}/${{ needs.build-windows-x64.outputs.FILE_NAME }}" + DARWIN_SIGNATURE="${{ needs.build-macos.outputs.MAC_UNIVERSAL_SIG }}" + DARWIN_URL="https://github.com/menloresearch/jan/releases/download/v${{ needs.get-update-version.outputs.new_version }}/${{ needs.build-macos.outputs.TAR_NAME }}" + + jq --arg version "$VERSION" \ + --arg pub_date "$PUB_DATE" \ + --arg linux_signature "$LINUX_SIGNATURE" \ + --arg linux_url "$LINUX_URL" \ + --arg windows_signature "$WINDOWS_SIGNATURE" \ + --arg windows_url "$WINDOWS_URL" \ + --arg darwin_arm_signature "$DARWIN_SIGNATURE" \ + --arg darwin_arm_url "$DARWIN_URL" \ + --arg darwin_amd_signature "$DARWIN_SIGNATURE" \ + --arg darwin_amd_url "$DARWIN_URL" \ + '.version = $version + | .pub_date = $pub_date + | .platforms["linux-x86_64"].signature = $linux_signature + | .platforms["linux-x86_64"].url = $linux_url + | .platforms["windows-x86_64"].signature = $windows_signature + | .platforms["windows-x86_64"].url = $windows_url + | .platforms["darwin-aarch64"].signature = $darwin_arm_signature + | .platforms["darwin-aarch64"].url = $darwin_arm_url + | .platforms["darwin-x86_64"].signature = $darwin_amd_signature + | .platforms["darwin-x86_64"].url = $darwin_amd_url' \ + src-tauri/latest.json.template > latest.json + cat latest.json + + - name: Upload release assert if public provider is github + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + asset_path: ./latest.json + asset_name: latest.json + asset_content_type: text/json + + update_release_draft: + needs: [build-macos, build-windows-x64, build-linux-x64] + permissions: + # write permission is required to create a github release + contents: write + # write permission is required for autolabeler + # otherwise, read permission is required at least + pull-requests: write + runs-on: ubuntu-latest + steps: + # (Optional) GitHub Enterprise requires GHE_HOST variable set + #- name: Set GHE_HOST + # run: | + # echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV + + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v5 + # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml + # with: + # config-name: my-config.yml + # disable-autolabeler: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/nightly-integrate-cortex-cpp.yml b/.github/workflows/nightly-integrate-cortex-cpp.yml deleted file mode 100644 index 066fbd28e..000000000 --- a/.github/workflows/nightly-integrate-cortex-cpp.yml +++ /dev/null @@ -1,127 +0,0 @@ -name: Nightly Update cortex cpp - -on: - schedule: - - cron: '30 19 * * 1-5' # At 01:30 on every day-of-week from Monday through Friday UTC +7 - workflow_dispatch: - -jobs: - update-submodule: - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - actions: write - - outputs: - pr_number: ${{ steps.check-update.outputs.pr_number }} - pr_created: ${{ steps.check-update.outputs.pr_created }} - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - submodules: recursive - ref: dev - fetch-depth: 0 - token: ${{ secrets.PAT_SERVICE_ACCOUNT }} - - - name: Configure Git - run: | - git config --global user.name 'github-actions[bot]' - git config --global user.email 'github-actions[bot]@users.noreply.github.com' - - - name: Update submodule to latest release - id: check-update - env: - GITHUB_TOKEN: ${{ secrets.PAT_SERVICE_ACCOUNT }} - run: | - curl -s https://api.github.com/repos/menloresearch/cortex/releases > /tmp/github_api_releases.json - latest_prerelease_name=$(cat /tmp/github_api_releases.json | jq -r '.[] | select(.prerelease) | .name' | head -n 1) - - get_asset_count() { - local version_name=$1 - cat /tmp/github_api_releases.json | jq -r --arg version_name "$version_name" '.[] | select(.name == $version_name) | .assets | length' - } - - cortex_cpp_version_file_path="extensions/inference-nitro-extension/bin/version.txt" - current_version_name=$(cat "$cortex_cpp_version_file_path" | head -n 1) - - current_version_asset_count=$(get_asset_count "$current_version_name") - latest_prerelease_asset_count=$(get_asset_count "$latest_prerelease_name") - - if [ "$current_version_name" = "$latest_prerelease_name" ]; then - echo "cortex cpp remote repo doesn't have update today, skip update cortex.cpp for today nightly build" - echo "::set-output name=pr_created::false" - exit 0 - fi - - if [ "$current_version_asset_count" != "$latest_prerelease_asset_count" ]; then - echo "Latest prerelease version has different number of assets, somethink went wrong, skip update cortex.cpp for today nightly build" - echo "::set-output name=pr_created::false" - exit 1 - fi - - echo $latest_prerelease_name > $cortex_cpp_version_file_path - echo "Updated version from $current_version_name to $latest_prerelease_name." - echo "::set-output name=pr_created::true" - - git add -f $cortex_cpp_version_file_path - git commit -m "Update cortex cpp nightly to version $latest_prerelease_name" - branch_name="update-nightly-$(date +'%Y-%m-%d-%H-%M')" - git checkout -b $branch_name - git push origin $branch_name - - pr_title="Update cortex cpp nightly to version $latest_prerelease_name" - pr_body="This PR updates the Update cortex cpp nightly to version $latest_prerelease_name" - - gh pr create --title "$pr_title" --body "$pr_body" --head $branch_name --base dev --reviewer Van-QA - - pr_number=$(gh pr list --head $branch_name --json number --jq '.[0].number') - echo "::set-output name=pr_number::$pr_number" - - check-and-merge-pr: - needs: update-submodule - if: needs.update-submodule.outputs.pr_created == 'true' - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - submodules: recursive - fetch-depth: 0 - token: ${{ secrets.PAT_SERVICE_ACCOUNT }} - - - name: Wait for CI to pass - env: - GITHUB_TOKEN: ${{ secrets.PAT_SERVICE_ACCOUNT }} - run: | - pr_number=${{ needs.update-submodule.outputs.pr_number }} - while true; do - ci_completed=$(gh pr checks $pr_number --json completedAt --jq '.[].completedAt') - if echo "$ci_completed" | grep -q "0001-01-01T00:00:00Z"; then - echo "CI is still running, waiting..." - sleep 60 - else - echo "CI has completed, checking states..." - ci_states=$(gh pr checks $pr_number --json state --jq '.[].state') - if echo "$ci_states" | grep -vqE "SUCCESS|SKIPPED"; then - echo "CI failed, exiting..." - exit 1 - else - echo "CI passed, merging PR..." - break - fi - fi - done - - - name: Merge the PR - env: - GITHUB_TOKEN: ${{ secrets.PAT_SERVICE_ACCOUNT }} - run: | - pr_number=${{ needs.update-submodule.outputs.pr_number }} - gh pr merge $pr_number --merge --admin diff --git a/.github/workflows/template-build-linux-x64.yml b/.github/workflows/template-electron-build-linux-x64.yml similarity index 98% rename from .github/workflows/template-build-linux-x64.yml rename to .github/workflows/template-electron-build-linux-x64.yml index 58b566931..e13c8371e 100644 --- a/.github/workflows/template-build-linux-x64.yml +++ b/.github/workflows/template-electron-build-linux-x64.yml @@ -176,12 +176,12 @@ jobs: if: inputs.public_provider != 'github' uses: actions/upload-artifact@v4 with: - name: jan-linux-amd64-${{ inputs.new_version }}-deb + name: jan-electron-linux-amd64-${{ inputs.new_version }}-deb path: ./electron/dist/*.deb - name: Upload Artifact .AppImage file if: inputs.public_provider != 'github' uses: actions/upload-artifact@v4 with: - name: jan-linux-amd64-${{ inputs.new_version }}-AppImage + name: jan-electron-linux-amd64-${{ inputs.new_version }}-AppImage path: ./electron/dist/*.AppImage \ No newline at end of file diff --git a/.github/workflows/template-build-macos.yml b/.github/workflows/template-electron-build-macos.yml similarity index 99% rename from .github/workflows/template-build-macos.yml rename to .github/workflows/template-electron-build-macos.yml index a5e5cc724..f0c69d5f1 100644 --- a/.github/workflows/template-build-macos.yml +++ b/.github/workflows/template-electron-build-macos.yml @@ -229,5 +229,5 @@ jobs: if: inputs.public_provider != 'github' uses: actions/upload-artifact@v4 with: - name: jan-mac-universal-${{ inputs.new_version }} + name: jan-electron-mac-universal-${{ inputs.new_version }} path: ./electron/dist/*.dmg \ No newline at end of file diff --git a/.github/workflows/template-build-windows-x64.yml b/.github/workflows/template-electron-build-windows-x64.yml similarity index 99% rename from .github/workflows/template-build-windows-x64.yml rename to .github/workflows/template-electron-build-windows-x64.yml index 9be028e15..7ba296504 100644 --- a/.github/workflows/template-build-windows-x64.yml +++ b/.github/workflows/template-electron-build-windows-x64.yml @@ -225,5 +225,5 @@ jobs: if: inputs.public_provider != 'github' uses: actions/upload-artifact@v4 with: - name: jan-win-x64-${{ inputs.new_version }} + name: jan-electron-win-x64-${{ inputs.new_version }} path: ./electron/dist/*.exe \ No newline at end of file diff --git a/.github/workflows/template-get-update-version.yml b/.github/workflows/template-get-update-version.yml index 97340be81..70f5eace9 100644 --- a/.github/workflows/template-get-update-version.yml +++ b/.github/workflows/template-get-update-version.yml @@ -44,9 +44,12 @@ jobs: exit 1 } - if ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}; then + if ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}; then echo "Tag detected, set output follow tag" - echo "::set-output name=new_version::${{ steps.tag.outputs.tag }}" + sanitized_tag="${{ steps.tag.outputs.tag }}" + # Remove the 'v' prefix if it exists + sanitized_tag="${sanitized_tag#v}" + echo "::set-output name=new_version::$sanitized_tag" else # Get the latest release tag from GitHub API LATEST_TAG=$(get_latest_tag) diff --git a/.github/workflows/template-noti-discord-and-update-url-readme.yml b/.github/workflows/template-noti-discord-and-update-url-readme.yml index 282e0aa76..eaaee7e50 100644 --- a/.github/workflows/template-noti-discord-and-update-url-readme.yml +++ b/.github/workflows/template-noti-discord-and-update-url-readme.yml @@ -47,10 +47,10 @@ jobs: with: args: | Jan App ${{ inputs.build_reason }} build artifact version {{ VERSION }}: - - Windows: https://delta.jan.ai/nightly/jan-nightly-win-x64-{{ VERSION }}.exe - - macOS Universal: https://delta.jan.ai/nightly/jan-nightly-mac-universal-{{ VERSION }}.dmg - - Linux Deb: https://delta.jan.ai/nightly/jan-nightly-linux-amd64-{{ VERSION }}.deb - - Linux AppImage: https://delta.jan.ai/nightly/jan-nightly-linux-x86_64-{{ VERSION }}.AppImage + - Windows: https://delta.jan.ai/nightly/Jan-nightly_{{ VERSION }}_x64-setup.exe + - macOS Universal: https://delta.jan.ai/nightly/Jan-nightly_{{ VERSION }}_universal.dmg + - Linux Deb: https://delta.jan.ai/nightly/Jan-nightly_{{ VERSION }}_amd64.deb + - Linux AppImage: https://delta.jan.ai/nightly/Jan-nightly_{{ VERSION }}_amd64.AppImage - Github action run: https://github.com/menloresearch/jan/actions/runs/{{ GITHUB_RUN_ID }} env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} diff --git a/.github/workflows/template-tauri-build-linux-x64-preview.yml b/.github/workflows/template-tauri-build-linux-x64-preview.yml new file mode 100644 index 000000000..8192a60e1 --- /dev/null +++ b/.github/workflows/template-tauri-build-linux-x64-preview.yml @@ -0,0 +1,262 @@ +name: tauri-build-linux-x64 +on: + workflow_call: + inputs: + ref: + required: true + type: string + default: 'refs/heads/main' + public_provider: + required: true + type: string + default: none + description: 'none: build only, github: build and publish to github, aws s3: build and publish to aws s3' + new_version: + required: true + type: string + default: '' + cortex_api_port: + required: false + type: string + default: "" + upload_url: + required: false + type: string + default: '' + channel: + required: true + type: string + default: 'nightly' + description: 'The channel to use for this job' + secrets: + DELTA_AWS_S3_BUCKET_NAME: + required: false + DELTA_AWS_ACCESS_KEY_ID: + required: false + DELTA_AWS_SECRET_ACCESS_KEY: + required: false + TAURI_SIGNING_PRIVATE_KEY: + required: false + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: + required: false + TAURI_SIGNING_PUBLIC_KEY: + required: false + outputs: + DEB_SIG: + value: ${{ jobs.build-linux-x64.outputs.DEB_SIG }} + APPIMAGE_SIG: + value: ${{ jobs.build-linux-x64.outputs.APPIMAGE_SIG }} + APPIMAGE_FILE_NAME: + value: ${{ jobs.build-linux-x64.outputs.APPIMAGE_FILE_NAME }} +jobs: + build-linux-x64: + runs-on: ubuntu-22.04 + outputs: + DEB_SIG: ${{ steps.packageinfo.outputs.DEB_SIG }} + APPIMAGE_SIG: ${{ steps.packageinfo.outputs.APPIMAGE_SIG }} + APPIMAGE_FILE_NAME: ${{ steps.packageinfo.outputs.APPIMAGE_FILE_NAME }} + environment: production + permissions: + contents: write + steps: + - name: Getting the repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + + - name: Free Disk Space Before Build + run: | + echo "Disk space before cleanup:" + df -h + sudo rm -rf /usr/local/.ghcup + sudo rm -rf /opt/hostedtoolcache/CodeQL + sudo rm -rf /usr/local/lib/android/sdk/ndk + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf /usr/local/share/boost + sudo apt-get clean + echo "Disk space after cleanup:" + df -h + + - name: Replace Icons for Beta Build + if: inputs.channel != 'stable' + shell: bash + run: | + cp .github/scripts/icon-${{ inputs.channel }}.png src-tauri/icons/icon.png + + - name: Installing node + uses: actions/setup-node@v1 + with: + node-version: 20 + + - name: Install jq + uses: dcarbone/install-jq-action@v2.0.1 + + - name: Install ctoml + run: | + cargo install ctoml + + - name: Install Tauri dependecies + run: | + sudo apt update + sudo apt install -y libglib2.0-dev libatk1.0-dev libpango1.0-dev libgtk-3-dev libsoup-3.0-dev libwebkit2gtk-4.1-dev librsvg2-dev libfuse2 + + - name: Update app version base public_provider + run: | + echo "Version: ${{ inputs.new_version }}" + # Update tauri.conf.json + jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = true | .bundle.resources = ["resources/themes/**/*", "resources/pre-install/**/*"] | .bundle.externalBin = ["binaries/cortex-server", "resources/bin/uv"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + if [ "${{ inputs.channel }}" != "stable" ]; then + jq '.bundle.linux.deb.files = {"usr/bin/bun": "resources/bin/bun", "usr/lib/Jan-${{ inputs.channel }}/binaries/engines": "binaries/engines"}' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + else + jq '.bundle.linux.deb.files = {"usr/bin/bun": "resources/bin/bun", "usr/lib/Jan/binaries/engines": "binaries/engines"}' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + fi + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + jq --arg version "${{ inputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json + mv /tmp/package.json web/package.json + + ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" + cat ./src-tauri/Cargo.toml + + # Change app name for beta and nightly builds + if [ "${{ inputs.channel }}" != "stable" ]; then + jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + + chmod +x .github/scripts/rename-tauri-app.sh + .github/scripts/rename-tauri-app.sh ./src-tauri/tauri.conf.json ${{ inputs.channel }} + + cat ./src-tauri/tauri.conf.json + + # Update Cargo.toml + ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}" + echo "------------------" + cat ./src-tauri/Cargo.toml + + chmod +x .github/scripts/rename-workspace.sh + .github/scripts/rename-workspace.sh ./package.json ${{ inputs.channel }} + cat ./package.json + fi + - name: Build app + run: | + make build-tauri + # Copy engines and bun to appimage + wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O ./appimagetool + chmod +x ./appimagetool + if [ "${{ inputs.channel }}" != "stable" ]; then + cp ./src-tauri/resources/bin/bun ./src-tauri/target/release/bundle/appimage/Jan-${{ inputs.channel }}.AppDir/usr/bin/bun + cp -rf ./src-tauri/binaries/engines ./src-tauri/target/release/bundle/appimage/Jan-${{ inputs.channel }}.AppDir/usr/lib/Jan-${{ inputs.channel }}/engines + ./appimagetool ./src-tauri/target/release/bundle/appimage/Jan-${{ inputs.channel }}.AppDir $(ls ./src-tauri/target/release/bundle/appimage/ | grep AppImage) + else + cp ./src-tauri/resources/bin/bun ./src-tauri/target/release/bundle/appimage/Jan.AppDir/usr/bin/bun + cp -rf ./src-tauri/binaries/engines ./src-tauri/target/release/bundle/appimage/Jan.AppDir/usr/lib/Jan/engines + ./appimagetool ./src-tauri/target/release/bundle/appimage/Jan.AppDir $(ls ./src-tauri/target/release/bundle/appimage/ | grep AppImage) + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }} + POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }} + # CORTEX_API_PORT: ${{ inputs.cortex_api_port }} + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + TAURI_SIGNING_PUBLIC_KEY: ${{ secrets.TAURI_SIGNING_PUBLIC_KEY }} + + # Publish app + + ## Artifacts, for dev and test + - name: Upload Artifact + if: inputs.public_provider != 'github' + uses: actions/upload-artifact@v4 + with: + name: jan-${{ inputs.channel }}-tauri-linux-amd64-${{ inputs.new_version }}-deb + path: ./src-tauri/target/release/bundle/deb/*.deb + + - name: Upload Artifact + if: inputs.public_provider != 'github' + uses: actions/upload-artifact@v4 + with: + name: jan-tauri-linux-amd64-${{ inputs.new_version }}-AppImage + path: ./src-tauri/target/release/bundle/appimage/*.AppImage + + ## create zip file and latest-linux.yml for linux electron auto updater + - name: Create zip file and latest-linux.yml for linux electron auto updater + id: packageinfo + run: | + cd ./src-tauri/target/release/bundle + + if [ "${{ inputs.channel }}" != "stable" ]; then + DEB_FILE_NAME=Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb + APPIMAGE_FILE_NAME=Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage + DEB_SIG=$(cat deb/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb.sig) + APPIMAGE_SIG=$(cat appimage/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage.sig) + else + DEB_FILE_NAME=Jan_${{ inputs.new_version }}_amd64.deb + APPIMAGE_FILE_NAME=Jan_${{ inputs.new_version }}_amd64.AppImage + DEB_SIG=$(cat deb/Jan_${{ inputs.new_version }}_amd64.deb.sig) + APPIMAGE_SIG=$(cat appimage/Jan_${{ inputs.new_version }}_amd64.AppImage.sig) + fi + + echo "DEB_SIG=$DEB_SIG" >> $GITHUB_OUTPUT + echo "APPIMAGE_SIG=$APPIMAGE_SIG" >> $GITHUB_OUTPUT + echo "DEB_FILE_NAME=$DEB_FILE_NAME" >> $GITHUB_OUTPUT + echo "APPIMAGE_FILE_NAME=$APPIMAGE_FILE_NAME" >> $GITHUB_OUTPUT + + ## Upload to s3 for nightly and beta + - name: upload to aws s3 if public provider is aws + if: inputs.public_provider == 'aws-s3' || inputs.channel == 'beta' || inputs.channel == 'nightly' + run: | + cd ./src-tauri/target/release/bundle + + # Upload for tauri updater + aws s3 cp ./deb/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64-preview.deb + aws s3 cp ./appimage/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64-preview.AppImage + env: + AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.DELTA_AWS_REGION }} + AWS_EC2_METADATA_DISABLED: "true" + + ## Upload to github release for stable release + - name: Upload release assert if public provider is github + if: inputs.channel == 'stable' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/latest-linux.yml + asset_name: latest-linux.yml + asset_content_type: text/yaml + + - name: Upload release assert if public provider is github + if: inputs.channel == 'beta' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/beta-linux.yml + asset_name: beta-linux.yml + asset_content_type: text/yaml + - name: Upload release assert if public provider is github + if: inputs.public_provider == 'github' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/appimage/${{ steps.packageinfo.outputs.APPIMAGE_FILE_NAME }} + asset_name: ${{ steps.packageinfo.outputs.APPIMAGE_FILE_NAME }} + asset_content_type: application/octet-stream + + - name: Upload release assert if public provider is github + if: inputs.public_provider == 'github' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/deb/${{ steps.packageinfo.outputs.DEB_FILE_NAME }} + asset_name: ${{ steps.packageinfo.outputs.DEB_FILE_NAME }} + asset_content_type: application/octet-stream diff --git a/.github/workflows/template-tauri-build-linux-x64.yml b/.github/workflows/template-tauri-build-linux-x64.yml new file mode 100644 index 000000000..3baa742ce --- /dev/null +++ b/.github/workflows/template-tauri-build-linux-x64.yml @@ -0,0 +1,296 @@ +name: tauri-build-linux-x64 +on: + workflow_call: + inputs: + ref: + required: true + type: string + default: 'refs/heads/main' + public_provider: + required: true + type: string + default: none + description: 'none: build only, github: build and publish to github, aws s3: build and publish to aws s3' + new_version: + required: true + type: string + default: '' + cortex_api_port: + required: false + type: string + default: "" + upload_url: + required: false + type: string + default: '' + channel: + required: true + type: string + default: 'nightly' + description: 'The channel to use for this job' + secrets: + DELTA_AWS_S3_BUCKET_NAME: + required: false + DELTA_AWS_ACCESS_KEY_ID: + required: false + DELTA_AWS_SECRET_ACCESS_KEY: + required: false + TAURI_SIGNING_PRIVATE_KEY: + required: false + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: + required: false + TAURI_SIGNING_PUBLIC_KEY: + required: false + outputs: + DEB_SIG: + value: ${{ jobs.build-linux-x64.outputs.DEB_SIG }} + APPIMAGE_SIG: + value: ${{ jobs.build-linux-x64.outputs.APPIMAGE_SIG }} + APPIMAGE_FILE_NAME: + value: ${{ jobs.build-linux-x64.outputs.APPIMAGE_FILE_NAME }} +jobs: + build-linux-x64: + runs-on: ubuntu-22.04 + outputs: + DEB_SIG: ${{ steps.packageinfo.outputs.DEB_SIG }} + APPIMAGE_SIG: ${{ steps.packageinfo.outputs.APPIMAGE_SIG }} + APPIMAGE_FILE_NAME: ${{ steps.packageinfo.outputs.APPIMAGE_FILE_NAME }} + environment: production + permissions: + contents: write + steps: + - name: Getting the repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + + - name: Free Disk Space Before Build + run: | + echo "Disk space before cleanup:" + df -h + sudo rm -rf /usr/local/.ghcup + sudo rm -rf /opt/hostedtoolcache/CodeQL + sudo rm -rf /usr/local/lib/android/sdk/ndk + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf /usr/local/share/boost + sudo apt-get clean + echo "Disk space after cleanup:" + df -h + + - name: Replace Icons for Beta Build + if: inputs.channel != 'stable' + shell: bash + run: | + cp .github/scripts/icon-${{ inputs.channel }}.png src-tauri/icons/icon.png + + - name: Installing node + uses: actions/setup-node@v1 + with: + node-version: 20 + + - name: Install jq + uses: dcarbone/install-jq-action@v2.0.1 + + - name: Install ctoml + run: | + cargo install ctoml + + - name: Install Tauri dependecies + run: | + sudo apt update + sudo apt install -y libglib2.0-dev libatk1.0-dev libpango1.0-dev libgtk-3-dev libsoup-3.0-dev libwebkit2gtk-4.1-dev librsvg2-dev libfuse2 + + - name: Update app version base public_provider + run: | + echo "Version: ${{ inputs.new_version }}" + # Update tauri.conf.json + jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = true | .bundle.resources = ["resources/themes/**/*", "resources/pre-install/**/*"] | .bundle.externalBin = ["binaries/cortex-server", "resources/bin/uv"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + if [ "${{ inputs.channel }}" != "stable" ]; then + jq '.bundle.linux.deb.files = {"usr/bin/bun": "resources/bin/bun", "usr/lib/Jan-${{ inputs.channel }}/binaries/engines": "binaries/engines"}' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + else + jq '.bundle.linux.deb.files = {"usr/bin/bun": "resources/bin/bun", "usr/lib/Jan/binaries/engines": "binaries/engines"}' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + fi + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + jq --arg version "${{ inputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json + mv /tmp/package.json web/package.json + + ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" + cat ./src-tauri/Cargo.toml + + # Change app name for beta and nightly builds + if [ "${{ inputs.channel }}" != "stable" ]; then + jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + + chmod +x .github/scripts/rename-tauri-app.sh + .github/scripts/rename-tauri-app.sh ./src-tauri/tauri.conf.json ${{ inputs.channel }} + + cat ./src-tauri/tauri.conf.json + + # Update Cargo.toml + ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}" + echo "------------------" + cat ./src-tauri/Cargo.toml + + chmod +x .github/scripts/rename-workspace.sh + .github/scripts/rename-workspace.sh ./package.json ${{ inputs.channel }} + cat ./package.json + fi + - name: Build app + run: | + make build-tauri + # Copy engines and bun to appimage + wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O ./appimagetool + chmod +x ./appimagetool + if [ "${{ inputs.channel }}" != "stable" ]; then + cp ./src-tauri/resources/bin/bun ./src-tauri/target/release/bundle/appimage/Jan-${{ inputs.channel }}.AppDir/usr/bin/bun + cp -rf ./src-tauri/binaries/engines ./src-tauri/target/release/bundle/appimage/Jan-${{ inputs.channel }}.AppDir/usr/lib/Jan-${{ inputs.channel }}/engines + ./appimagetool ./src-tauri/target/release/bundle/appimage/Jan-${{ inputs.channel }}.AppDir $(ls ./src-tauri/target/release/bundle/appimage/ | grep AppImage) + else + cp ./src-tauri/resources/bin/bun ./src-tauri/target/release/bundle/appimage/Jan.AppDir/usr/bin/bun + cp -rf ./src-tauri/binaries/engines ./src-tauri/target/release/bundle/appimage/Jan.AppDir/usr/lib/Jan/engines + ./appimagetool ./src-tauri/target/release/bundle/appimage/Jan.AppDir $(ls ./src-tauri/target/release/bundle/appimage/ | grep AppImage) + fi + + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }} + POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }} + # CORTEX_API_PORT: ${{ inputs.cortex_api_port }} + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + TAURI_SIGNING_PUBLIC_KEY: ${{ secrets.TAURI_SIGNING_PUBLIC_KEY }} + + # Publish app + + ## Artifacts, for dev and test + - name: Upload Artifact + if: inputs.public_provider != 'github' + uses: actions/upload-artifact@v4 + with: + name: jan-linux-amd64-${{ inputs.new_version }}-deb + path: ./src-tauri/target/release/bundle/deb/*.deb + + - name: Upload Artifact + if: inputs.public_provider != 'github' + uses: actions/upload-artifact@v4 + with: + name: jan-linux-amd64-${{ inputs.new_version }}-AppImage + path: ./src-tauri/target/release/bundle/appimage/*.AppImage + + ## create zip file and latest-linux.yml for linux electron auto updater + - name: Create zip file and latest-linux.yml for linux electron auto updater + id: packageinfo + run: | + cd ./src-tauri/target/release/bundle + + if [ "${{ inputs.channel }}" != "stable" ]; then + DEB_FILE_NAME=Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb + APPIMAGE_FILE_NAME=Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage + DEB_SIG=$(cat deb/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb.sig) + APPIMAGE_SIG=$(cat appimage/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage.sig) + else + DEB_FILE_NAME=Jan_${{ inputs.new_version }}_amd64.deb + APPIMAGE_FILE_NAME=Jan_${{ inputs.new_version }}_amd64.AppImage + DEB_SIG=$(cat deb/Jan_${{ inputs.new_version }}_amd64.deb.sig) + APPIMAGE_SIG=$(cat appimage/Jan_${{ inputs.new_version }}_amd64.AppImage.sig) + fi + + DEB_FILE_SIZE=$(stat -c%s deb/$DEB_FILE_NAME) + APPIMAGE_FILE_SIZE=$(stat -c%s appimage/$APPIMAGE_FILE_NAME) + echo "deb file size: $DEB_FILE_SIZE" + echo "appimage file size: $APPIMAGE_FILE_SIZE" + + DEB_SH512_CHECKSUM=$(python3 ../../../../.github/scripts/electron-checksum.py deb/$DEB_FILE_NAME) + APPIMAGE_SH512_CHECKSUM=$(python3 ../../../../.github/scripts/electron-checksum.py appimage/$APPIMAGE_FILE_NAME) + echo "deb sh512 checksum: $DEB_SH512_CHECKSUM" + echo "appimage sh512 checksum: $APPIMAGE_SH512_CHECKSUM" + + CURRENT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ") + echo "releaseDate: $CURRENT_TIME" + + # Create latest-linux.yml file + echo "version: ${{ inputs.new_version }}" > latest-linux.yml + echo "files:" >> latest-linux.yml + echo " - url: $DEB_FILE_NAME" >> latest-linux.yml + echo " sha512: $DEB_SH512_CHECKSUM" >> latest-linux.yml + echo " size: $DEB_FILE_SIZE" >> latest-linux.yml + echo " - url: $APPIMAGE_FILE_NAME" >> latest-linux.yml + echo " sha512: $APPIMAGE_SH512_CHECKSUM" >> latest-linux.yml + echo " size: $APPIMAGE_FILE_SIZE" >> latest-linux.yml + echo "path: $APPIMAGE_FILE_NAME" >> latest-linux.yml + echo "sha512: $APPIMAGE_SH512_CHECKSUM" >> latest-linux.yml + echo "releaseDate: $CURRENT_TIME" >> latest-linux.yml + + cat latest-linux.yml + cp latest-linux.yml beta-linux.yml + + echo "DEB_SIG=$DEB_SIG" >> $GITHUB_OUTPUT + echo "APPIMAGE_SIG=$APPIMAGE_SIG" >> $GITHUB_OUTPUT + echo "DEB_FILE_NAME=$DEB_FILE_NAME" >> $GITHUB_OUTPUT + echo "APPIMAGE_FILE_NAME=$APPIMAGE_FILE_NAME" >> $GITHUB_OUTPUT + + ## Upload to s3 for nightly and beta + - name: upload to aws s3 if public provider is aws + if: inputs.public_provider == 'aws-s3' || inputs.channel == 'beta' + run: | + cd ./src-tauri/target/release/bundle + + # Upload for electron updater + aws s3 cp ./latest-linux.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/latest-linux.yml + aws s3 cp ./beta-linux.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/beta-linux.yml + + # Upload for tauri updater + aws s3 cp ./appimage/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage + aws s3 cp ./deb/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb + env: + AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.DELTA_AWS_REGION }} + AWS_EC2_METADATA_DISABLED: "true" + + ## Upload to github release for stable release + - name: Upload release assert if public provider is github + if: inputs.channel == 'stable' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/latest-linux.yml + asset_name: latest-linux.yml + asset_content_type: text/yaml + + - name: Upload release assert if public provider is github + if: inputs.channel == 'beta' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/beta-linux.yml + asset_name: beta-linux.yml + asset_content_type: text/yaml + - name: Upload release assert if public provider is github + if: inputs.public_provider == 'github' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/appimage/${{ steps.packageinfo.outputs.APPIMAGE_FILE_NAME }} + asset_name: ${{ steps.packageinfo.outputs.APPIMAGE_FILE_NAME }} + asset_content_type: application/octet-stream + + - name: Upload release assert if public provider is github + if: inputs.public_provider == 'github' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/deb/${{ steps.packageinfo.outputs.DEB_FILE_NAME }} + asset_name: ${{ steps.packageinfo.outputs.DEB_FILE_NAME }} + asset_content_type: application/octet-stream diff --git a/.github/workflows/template-tauri-build-macos-preview.yml b/.github/workflows/template-tauri-build-macos-preview.yml new file mode 100644 index 000000000..67195f7f2 --- /dev/null +++ b/.github/workflows/template-tauri-build-macos-preview.yml @@ -0,0 +1,282 @@ +name: tauri-build-macos +on: + workflow_call: + inputs: + ref: + required: true + type: string + default: 'refs/heads/main' + public_provider: + required: true + type: string + default: none + description: 'none: build only, github: build and publish to github, aws s3: build and publish to aws s3' + new_version: + required: true + type: string + default: '' + cortex_api_port: + required: false + type: string + default: "" + upload_url: + required: false + type: string + default: '' + channel: + required: true + type: string + default: 'nightly' + description: 'The channel to use for this job' + secrets: + DELTA_AWS_S3_BUCKET_NAME: + required: false + DELTA_AWS_ACCESS_KEY_ID: + required: false + DELTA_AWS_SECRET_ACCESS_KEY: + required: false + CODE_SIGN_P12_BASE64: + required: false + CODE_SIGN_P12_PASSWORD: + required: false + APPLE_ID: + required: false + APPLE_APP_SPECIFIC_PASSWORD: + required: false + DEVELOPER_ID: + required: false + TAURI_SIGNING_PRIVATE_KEY: + required: false + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: + required: false + TAURI_SIGNING_PUBLIC_KEY: + required: false + outputs: + MAC_UNIVERSAL_SIG: + value: ${{ jobs.build-macos.outputs.MAC_UNIVERSAL_SIG }} + TAR_NAME: + value: ${{ jobs.build-macos.outputs.TAR_NAME }} + +jobs: + build-macos: + runs-on: macos-latest + outputs: + MAC_UNIVERSAL_SIG: ${{ steps.metadata.outputs.MAC_UNIVERSAL_SIG }} + TAR_NAME: ${{ steps.metadata.outputs.TAR_NAME }} + environment: production + permissions: + contents: write + steps: + - name: Getting the repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + - name: Replace Icons for Beta Build + if: inputs.channel != 'stable' + shell: bash + run: | + cp .github/scripts/icon-${{ inputs.channel }}.png src-tauri/icons/icon.png + + - name: Installing node + uses: actions/setup-node@v1 + with: + node-version: 20 + + - name: Install jq + uses: dcarbone/install-jq-action@v2.0.1 + + - name: Install ctoml + run: | + cargo install ctoml + + - name: Create bun and uv universal + run: | + mkdir -p ./src-tauri/resources/bin/ + cd ./src-tauri/resources/bin/ + curl -L -o bun-darwin-x64.zip https://github.com/oven-sh/bun/releases/download/bun-v1.2.10/bun-darwin-x64.zip + curl -L -o bun-darwin-aarch64.zip https://github.com/oven-sh/bun/releases/download/bun-v1.2.10/bun-darwin-aarch64.zip + unzip bun-darwin-x64.zip + unzip bun-darwin-aarch64.zip + lipo -create -output bun-universal-apple-darwin bun-darwin-x64/bun bun-darwin-aarch64/bun + cp -f bun-darwin-aarch64/bun bun-aarch64-apple-darwin + cp -f bun-darwin-x64/bun bun-x86_64-apple-darwin + cp -f bun-universal-apple-darwin bun + + curl -L -o uv-x86_64.tar.gz https://github.com/astral-sh/uv/releases/download/0.6.17/uv-x86_64-apple-darwin.tar.gz + curl -L -o uv-arm64.tar.gz https://github.com/astral-sh/uv/releases/download/0.6.17/uv-aarch64-apple-darwin.tar.gz + tar -xzf uv-x86_64.tar.gz + tar -xzf uv-arm64.tar.gz + mv uv-x86_64-apple-darwin uv-x86_64 + mv uv-aarch64-apple-darwin uv-aarch64 + lipo -create -output uv-universal-apple-darwin uv-x86_64/uv uv-aarch64/uv + cp -f uv-x86_64/uv uv-x86_64-apple-darwin + cp -f uv-aarch64/uv uv-aarch64-apple-darwin + cp -f uv-universal-apple-darwin uv + ls -la + + - name: Update app version based on latest release tag with build number + run: | + echo "Version: ${{ inputs.new_version }}" + # Update tauri.conf.json + jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = true' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + jq --arg version "${{ inputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json + mv /tmp/package.json web/package.json + + ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" + cat ./src-tauri/Cargo.toml + + # Change app name for beta and nightly builds + if [ "${{ inputs.channel }}" != "stable" ]; then + jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + + chmod +x .github/scripts/rename-tauri-app.sh + .github/scripts/rename-tauri-app.sh ./src-tauri/tauri.conf.json ${{ inputs.channel }} + + cat ./src-tauri/tauri.conf.json + + # Update Cargo.toml + ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}" + echo "------------------" + cat ./src-tauri/Cargo.toml + + chmod +x .github/scripts/rename-workspace.sh + .github/scripts/rename-workspace.sh ./package.json ${{ inputs.channel }} + cat ./package.json + fi + - name: Get key for notarize + run: base64 -d <<< "$NOTARIZE_P8_BASE64" > /tmp/notary-key.p8 + shell: bash + env: + NOTARIZE_P8_BASE64: ${{ secrets.NOTARIZE_P8_BASE64 }} + + - uses: apple-actions/import-codesign-certs@v2 + continue-on-error: true + with: + p12-file-base64: ${{ secrets.CODE_SIGN_P12_BASE64 }} + p12-password: ${{ secrets.CODE_SIGN_P12_PASSWORD }} + + - name: Build app + run: | + rustup target add x86_64-apple-darwin + make build-tauri + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + APP_PATH: '.' + POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }} + POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }} + # CORTEX_API_PORT: ${{ inputs.cortex_api_port }} + APPLE_CERTIFICATE: ${{ secrets.CODE_SIGN_P12_BASE64 }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.CODE_SIGN_P12_PASSWORD }} + APPLE_API_ISSUER: ${{ secrets.NOTARY_ISSUER }} + APPLE_API_KEY: ${{ secrets.NOTARY_KEY_ID }} + APPLE_API_KEY_PATH: /tmp/notary-key.p8 + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + TAURI_SIGNING_PUBLIC_KEY: ${{ secrets.TAURI_SIGNING_PUBLIC_KEY }} + + # Publish app + + ## Artifacts, for dev and test + - name: Upload Artifact + if: inputs.public_provider != 'github' + uses: actions/upload-artifact@v4 + with: + name: jan-${{ inputs.channel }}-tauri-mac-universal-${{ inputs.new_version }}.dmg + path: | + ./src-tauri/target/universal-apple-darwin/release/bundle/dmg/*.dmg + + ## create zip file and latest-mac.yml for mac electron auto updater + - name: create zip file and latest-mac.yml for mac electron auto updater + run: | + cd ./src-tauri/target/universal-apple-darwin/release/bundle/macos + if [ "${{ inputs.channel }}" != "stable" ]; then + zip -r jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.zip Jan-${{ inputs.channel }}.app + FILE_NAME=jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.zip + DMG_NAME=Jan-${{ inputs.channel }}_${{ inputs.new_version }}_universal.dmg + MAC_UNIVERSAL_SIG=$(cat Jan-${{ inputs.channel }}.app.tar.gz.sig) + TAR_NAME=Jan-${{ inputs.channel }}.app.tar.gz + else + zip -r jan-mac-universal-${{ inputs.new_version }}.zip Jan.app + FILE_NAME=jan-mac-universal-${{ inputs.new_version }}.zip + MAC_UNIVERSAL_SIG=$(cat Jan.app.tar.gz.sig) + DMG_NAME=Jan_${{ inputs.new_version }}_universal.dmg + TAR_NAME=Jan.app.tar.gz + fi + + echo "::set-output name=MAC_UNIVERSAL_SIG::$MAC_UNIVERSAL_SIG" + echo "::set-output name=FILE_NAME::$FILE_NAME" + echo "::set-output name=DMG_NAME::$DMG_NAME" + echo "::set-output name=TAR_NAME::$TAR_NAME" + id: metadata + ## Upload to s3 for nightly and beta + - name: upload to aws s3 if public provider is aws + if: inputs.public_provider == 'aws-s3' || inputs.channel == 'beta' || inputs.channel == 'nightly' + run: | + cd ./src-tauri/target/universal-apple-darwin/release/bundle + + # Upload for tauri updater + aws s3 cp ./dmg/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_universal.dmg s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_universal-preview.dmg + aws s3 cp ./macos/Jan-${{ inputs.channel }}.app.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}-preview.app.tar.gz + env: + AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.DELTA_AWS_REGION }} + AWS_EC2_METADATA_DISABLED: "true" + + ## Upload to github release for stable release + - name: Upload release assert if public provider is github + if: inputs.channel == 'stable' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/universal-apple-darwin/release/bundle/macos/latest-mac.yml + asset_name: latest-mac.yml + asset_content_type: text/yaml + + - name: Upload release assert if public provider is github + if: inputs.channel == 'beta' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/universal-apple-darwin/release/bundle/macos/beta-mac.yml + asset_name: beta-mac.yml + asset_content_type: text/yaml + + - name: Upload release assert if public provider is github + if: inputs.public_provider == 'github' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/universal-apple-darwin/release/bundle/macos/${{ steps.metadata.outputs.FILE_NAME }} + asset_name: ${{ steps.metadata.outputs.FILE_NAME }} + asset_content_type: application/gzip + + - name: Upload release assert if public provider is github + if: inputs.public_provider == 'github' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/universal-apple-darwin/release/bundle/dmg/${{ steps.metadata.outputs.DMG_NAME }} + asset_name: ${{ steps.metadata.outputs.DMG_NAME }} + asset_content_type: application/octet-stream + + - name: Upload release assert if public provider is github + if: inputs.public_provider == 'github' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/universal-apple-darwin/release/bundle/macos/${{ steps.metadata.outputs.TAR_NAME }} + asset_name: ${{ steps.metadata.outputs.TAR_NAME }} + asset_content_type: application/gzip \ No newline at end of file diff --git a/.github/workflows/template-tauri-build-macos.yml b/.github/workflows/template-tauri-build-macos.yml new file mode 100644 index 000000000..a68f4487d --- /dev/null +++ b/.github/workflows/template-tauri-build-macos.yml @@ -0,0 +1,310 @@ +name: tauri-build-macos +on: + workflow_call: + inputs: + ref: + required: true + type: string + default: 'refs/heads/main' + public_provider: + required: true + type: string + default: none + description: 'none: build only, github: build and publish to github, aws s3: build and publish to aws s3' + new_version: + required: true + type: string + default: '' + cortex_api_port: + required: false + type: string + default: "" + upload_url: + required: false + type: string + default: '' + channel: + required: true + type: string + default: 'nightly' + description: 'The channel to use for this job' + secrets: + DELTA_AWS_S3_BUCKET_NAME: + required: false + DELTA_AWS_ACCESS_KEY_ID: + required: false + DELTA_AWS_SECRET_ACCESS_KEY: + required: false + CODE_SIGN_P12_BASE64: + required: false + CODE_SIGN_P12_PASSWORD: + required: false + APPLE_ID: + required: false + APPLE_APP_SPECIFIC_PASSWORD: + required: false + DEVELOPER_ID: + required: false + TAURI_SIGNING_PRIVATE_KEY: + required: false + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: + required: false + TAURI_SIGNING_PUBLIC_KEY: + required: false + outputs: + MAC_UNIVERSAL_SIG: + value: ${{ jobs.build-macos.outputs.MAC_UNIVERSAL_SIG }} + TAR_NAME: + value: ${{ jobs.build-macos.outputs.TAR_NAME }} + +jobs: + build-macos: + runs-on: macos-latest + outputs: + MAC_UNIVERSAL_SIG: ${{ steps.metadata.outputs.MAC_UNIVERSAL_SIG }} + TAR_NAME: ${{ steps.metadata.outputs.TAR_NAME }} + environment: production + permissions: + contents: write + steps: + - name: Getting the repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + - name: Replace Icons for Beta Build + if: inputs.channel != 'stable' + shell: bash + run: | + cp .github/scripts/icon-${{ inputs.channel }}.png src-tauri/icons/icon.png + + - name: Installing node + uses: actions/setup-node@v1 + with: + node-version: 20 + + - name: Install jq + uses: dcarbone/install-jq-action@v2.0.1 + + - name: Install ctoml + run: | + cargo install ctoml + + - name: Create bun and uv universal + run: | + mkdir -p ./src-tauri/resources/bin/ + cd ./src-tauri/resources/bin/ + curl -L -o bun-darwin-x64.zip https://github.com/oven-sh/bun/releases/download/bun-v1.2.10/bun-darwin-x64.zip + curl -L -o bun-darwin-aarch64.zip https://github.com/oven-sh/bun/releases/download/bun-v1.2.10/bun-darwin-aarch64.zip + unzip bun-darwin-x64.zip + unzip bun-darwin-aarch64.zip + lipo -create -output bun-universal-apple-darwin bun-darwin-x64/bun bun-darwin-aarch64/bun + cp -f bun-darwin-aarch64/bun bun-aarch64-apple-darwin + cp -f bun-darwin-x64/bun bun-x86_64-apple-darwin + cp -f bun-universal-apple-darwin bun + + curl -L -o uv-x86_64.tar.gz https://github.com/astral-sh/uv/releases/download/0.6.17/uv-x86_64-apple-darwin.tar.gz + curl -L -o uv-arm64.tar.gz https://github.com/astral-sh/uv/releases/download/0.6.17/uv-aarch64-apple-darwin.tar.gz + tar -xzf uv-x86_64.tar.gz + tar -xzf uv-arm64.tar.gz + mv uv-x86_64-apple-darwin uv-x86_64 + mv uv-aarch64-apple-darwin uv-aarch64 + lipo -create -output uv-universal-apple-darwin uv-x86_64/uv uv-aarch64/uv + cp -f uv-x86_64/uv uv-x86_64-apple-darwin + cp -f uv-aarch64/uv uv-aarch64-apple-darwin + cp -f uv-universal-apple-darwin uv + ls -la + + - name: Update app version based on latest release tag with build number + run: | + echo "Version: ${{ inputs.new_version }}" + # Update tauri.conf.json + jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = true' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + jq --arg version "${{ inputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json + mv /tmp/package.json web/package.json + + ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" + cat ./src-tauri/Cargo.toml + + # Change app name for beta and nightly builds + if [ "${{ inputs.channel }}" != "stable" ]; then + jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + + chmod +x .github/scripts/rename-tauri-app.sh + .github/scripts/rename-tauri-app.sh ./src-tauri/tauri.conf.json ${{ inputs.channel }} + + cat ./src-tauri/tauri.conf.json + + # Update Cargo.toml + ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}" + echo "------------------" + cat ./src-tauri/Cargo.toml + + chmod +x .github/scripts/rename-workspace.sh + .github/scripts/rename-workspace.sh ./package.json ${{ inputs.channel }} + cat ./package.json + fi + - name: Get key for notarize + run: base64 -d <<< "$NOTARIZE_P8_BASE64" > /tmp/notary-key.p8 + shell: bash + env: + NOTARIZE_P8_BASE64: ${{ secrets.NOTARIZE_P8_BASE64 }} + + - uses: apple-actions/import-codesign-certs@v2 + continue-on-error: true + with: + p12-file-base64: ${{ secrets.CODE_SIGN_P12_BASE64 }} + p12-password: ${{ secrets.CODE_SIGN_P12_PASSWORD }} + + - name: Build app + run: | + rustup target add x86_64-apple-darwin + make build-tauri + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + APP_PATH: '.' + POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }} + POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }} + # CORTEX_API_PORT: ${{ inputs.cortex_api_port }} + APPLE_CERTIFICATE: ${{ secrets.CODE_SIGN_P12_BASE64 }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.CODE_SIGN_P12_PASSWORD }} + APPLE_API_ISSUER: ${{ secrets.NOTARY_ISSUER }} + APPLE_API_KEY: ${{ secrets.NOTARY_KEY_ID }} + APPLE_API_KEY_PATH: /tmp/notary-key.p8 + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + TAURI_SIGNING_PUBLIC_KEY: ${{ secrets.TAURI_SIGNING_PUBLIC_KEY }} + + # Publish app + + ## Artifacts, for dev and test + - name: Upload Artifact + if: inputs.public_provider != 'github' + uses: actions/upload-artifact@v4 + with: + name: jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.dmg + path: | + ./src-tauri/target/universal-apple-darwin/release/bundle/dmg/*.dmg + + + ## create zip file and latest-mac.yml for mac electron auto updater + - name: create zip file and latest-mac.yml for mac electron auto updater + run: | + cd ./src-tauri/target/universal-apple-darwin/release/bundle/macos + if [ "${{ inputs.channel }}" != "stable" ]; then + zip -r jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.zip Jan-${{ inputs.channel }}.app + FILE_NAME=jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.zip + DMG_NAME=Jan-${{ inputs.channel }}_${{ inputs.new_version }}_universal.dmg + MAC_UNIVERSAL_SIG=$(cat Jan-${{ inputs.channel }}.app.tar.gz.sig) + TAR_NAME=Jan-${{ inputs.channel }}.app.tar.gz + else + zip -r jan-mac-universal-${{ inputs.new_version }}.zip Jan.app + FILE_NAME=jan-mac-universal-${{ inputs.new_version }}.zip + MAC_UNIVERSAL_SIG=$(cat Jan.app.tar.gz.sig) + DMG_NAME=Jan_${{ inputs.new_version }}_universal.dmg + TAR_NAME=Jan.app.tar.gz + fi + + FILE_SIZE=$(stat -f%z $FILE_NAME) + echo "size: $FILE_SIZE" + + SH512_CHECKSUM=$(python3 ../../../../../../.github/scripts/electron-checksum.py $FILE_NAME) + echo "sha512: $SH512_CHECKSUM" + CURRENT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ") + echo "releaseDate: $CURRENT_TIME" + + # Create latest-mac.yml file + echo "version: ${{ inputs.new_version }}" > latest-mac.yml + echo "files:" >> latest-mac.yml + echo " - url: $FILE_NAME" >> latest-mac.yml + echo " sha512: $SH512_CHECKSUM" >> latest-mac.yml + echo " size: $FILE_NAME" >> latest-mac.yml + echo "path: $FILE_NAME" >> latest-mac.yml + echo "sha512: $SH512_CHECKSUM" >> latest-mac.yml + echo "releaseDate: $CURRENT_TIME" >> latest-mac.yml + + cat latest-mac.yml + cp latest-mac.yml beta-mac.yml + + echo "::set-output name=MAC_UNIVERSAL_SIG::$MAC_UNIVERSAL_SIG" + echo "::set-output name=FILE_NAME::$FILE_NAME" + echo "::set-output name=DMG_NAME::$DMG_NAME" + echo "::set-output name=TAR_NAME::$TAR_NAME" + id: metadata + + ## Upload to s3 for nightly and beta + - name: upload to aws s3 if public provider is aws + if: inputs.public_provider == 'aws-s3' || inputs.channel == 'beta' + run: | + cd ./src-tauri/target/universal-apple-darwin/release/bundle + + # Upload for electron updater + aws s3 cp ./macos/latest-mac.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/latest-mac.yml + aws s3 cp ./macos/beta-mac.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/beta-mac.yml + aws s3 cp ./macos/jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.zip s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.zip + + # Upload for tauri updater + aws s3 cp ./dmg/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_universal.dmg s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_universal.dmg + aws s3 cp ./macos/Jan-${{ inputs.channel }}.app.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}//Jan-${{ inputs.channel }}_${{ inputs.new_version }}.app.tar.gz + env: + AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.DELTA_AWS_REGION }} + AWS_EC2_METADATA_DISABLED: "true" + + ## Upload to github release for stable release + - name: Upload release assert if public provider is github + if: inputs.channel == 'stable' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/universal-apple-darwin/release/bundle/macos/latest-mac.yml + asset_name: latest-mac.yml + asset_content_type: text/yaml + + - name: Upload release assert if public provider is github + if: inputs.channel == 'beta' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/universal-apple-darwin/release/bundle/macos/beta-mac.yml + asset_name: beta-mac.yml + asset_content_type: text/yaml + + - name: Upload release assert if public provider is github + if: inputs.public_provider == 'github' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/universal-apple-darwin/release/bundle/macos/${{ steps.metadata.outputs.FILE_NAME }} + asset_name: ${{ steps.metadata.outputs.FILE_NAME }} + asset_content_type: application/gzip + + - name: Upload release assert if public provider is github + if: inputs.public_provider == 'github' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/universal-apple-darwin/release/bundle/dmg/${{ steps.metadata.outputs.DMG_NAME }} + asset_name: ${{ steps.metadata.outputs.DMG_NAME }} + asset_content_type: application/octet-stream + + - name: Upload release assert if public provider is github + if: inputs.public_provider == 'github' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/universal-apple-darwin/release/bundle/macos/${{ steps.metadata.outputs.TAR_NAME }} + asset_name: ${{ steps.metadata.outputs.TAR_NAME }} + asset_content_type: application/gzip \ No newline at end of file diff --git a/.github/workflows/template-tauri-build-windows-x64-preview.yml b/.github/workflows/template-tauri-build-windows-x64-preview.yml new file mode 100644 index 000000000..01a0d07fb --- /dev/null +++ b/.github/workflows/template-tauri-build-windows-x64-preview.yml @@ -0,0 +1,259 @@ +name: tauri-build-windows-x64 +on: + workflow_call: + inputs: + ref: + required: true + type: string + default: "refs/heads/main" + public_provider: + required: true + type: string + default: none + description: "none: build only, github: build and publish to github, aws s3: build and publish to aws s3" + new_version: + required: true + type: string + default: '' + cortex_api_port: + required: false + type: string + default: "" + upload_url: + required: false + type: string + default: '' + channel: + required: true + type: string + default: 'nightly' + description: 'The channel to use for this job' + secrets: + DELTA_AWS_S3_BUCKET_NAME: + required: false + DELTA_AWS_ACCESS_KEY_ID: + required: false + DELTA_AWS_SECRET_ACCESS_KEY: + required: false + AZURE_KEY_VAULT_URI: + required: false + AZURE_CLIENT_ID: + required: false + AZURE_TENANT_ID: + required: false + AZURE_CLIENT_SECRET: + required: false + AZURE_CERT_NAME: + required: false + TAURI_SIGNING_PRIVATE_KEY: + required: false + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: + required: false + TAURI_SIGNING_PUBLIC_KEY: + required: false + outputs: + WIN_SIG: + value: ${{ jobs.build-windows-x64.outputs.WIN_SIG }} + FILE_NAME: + value: ${{ jobs.build-windows-x64.outputs.FILE_NAME }} + +jobs: + build-windows-x64: + runs-on: windows-latest + outputs: + WIN_SIG: ${{ steps.metadata.outputs.WIN_SIG }} + FILE_NAME: ${{ steps.metadata.outputs.FILE_NAME }} + permissions: + contents: write + steps: + - name: Getting the repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + + - name: Replace Icons for Beta Build + if: inputs.channel != 'stable' + shell: bash + run: | + cp .github/scripts/icon-${{ inputs.channel }}.png src-tauri/icons/icon.png + + - name: Installing node + uses: actions/setup-node@v1 + with: + node-version: 20 + + - name: Install jq + uses: dcarbone/install-jq-action@v2.0.1 + + - name: Install ctoml + run: | + cargo install ctoml + + - name: Update app version base on tag + id: version_update + shell: bash + run: | + echo "Version: ${{ inputs.new_version }}" + # Update tauri.conf.json + jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = true' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + jq --arg version "${{ inputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json + mv /tmp/package.json web/package.json + + ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" + cat ./src-tauri/Cargo.toml + + generate_build_version() { + ### Examble + ### input 0.5.6 output will be 0.5.6 and 0.5.6.0 + ### input 0.5.6-rc2-beta output will be 0.5.6 and 0.5.6.2 + ### input 0.5.6-1213 output will be 0.5.6 and and 0.5.6.1213 + local new_version="$1" + local base_version + local t_value + + # Check if it has a "-" + if [[ "$new_version" == *-* ]]; then + base_version="${new_version%%-*}" # part before - + suffix="${new_version#*-}" # part after - + + # Check if it is rcX-beta + if [[ "$suffix" =~ ^rc([0-9]+)-beta$ ]]; then + t_value="${BASH_REMATCH[1]}" + else + t_value="$suffix" + fi + else + base_version="$new_version" + t_value="0" + fi + + # Export two values + new_base_version="$base_version" + new_build_version="${base_version}.${t_value}" + } + generate_build_version ${{ inputs.new_version }} + sed -i "s/jan_version/$new_base_version/g" ./src-tauri/tauri.bundle.windows.nsis.template + sed -i "s/jan_build/$new_build_version/g" ./src-tauri/tauri.bundle.windows.nsis.template + echo "------------------" + cat ./src-tauri/tauri.bundle.windows.nsis.template + + # Change app name for beta and nightly builds + if [ "${{ inputs.channel }}" != "stable" ]; then + jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + + chmod +x .github/scripts/rename-tauri-app.sh + .github/scripts/rename-tauri-app.sh ./src-tauri/tauri.conf.json ${{ inputs.channel }} + + cat ./src-tauri/tauri.conf.json + + # Update Cargo.toml + ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}" + echo "------------------" + cat ./src-tauri/Cargo.toml + + chmod +x .github/scripts/rename-workspace.sh + .github/scripts/rename-workspace.sh ./package.json ${{ inputs.channel }} + cat ./package.json + + sed -i "s/jan_productname/Jan-${{ inputs.channel }}/g" ./src-tauri/tauri.bundle.windows.nsis.template + sed -i "s/jan_mainbinaryname/jan-${{ inputs.channel }}/g" ./src-tauri/tauri.bundle.windows.nsis.template + fi + + - name: Install AzureSignTool + run: | + dotnet tool install --global --version 6.0.0 AzureSignTool + + - name: Build app + shell: bash + run: | + make build-tauri + env: + AZURE_KEY_VAULT_URI: ${{ secrets.AZURE_KEY_VAULT_URI }} + AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} + AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} + AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} + AZURE_CERT_NAME: ${{ secrets.AZURE_CERT_NAME }} + AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: auto + AWS_EC2_METADATA_DISABLED: "true" + AWS_MAX_ATTEMPTS: "5" + POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }} + POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }} + # CORTEX_API_PORT: ${{ inputs.cortex_api_port }} + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + TAURI_SIGNING_PUBLIC_KEY: ${{ secrets.TAURI_SIGNING_PUBLIC_KEY }} + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: jan-${{ inputs.channel }}-tauri-windows-${{ inputs.new_version }} + path: | + ./src-tauri/target/release/bundle/nsis/*.exe + + ## create zip file and latest.yml for windows electron auto updater + - name: create zip file and latest.yml for windows electron auto updater + shell: bash + run: | + cd ./src-tauri/target/release/bundle/nsis + if [ "${{ inputs.channel }}" != "stable" ]; then + FILE_NAME=Jan-${{ inputs.channel }}_${{ inputs.new_version }}_x64-setup.exe + WIN_SIG=$(cat Jan-${{ inputs.channel }}_${{ inputs.new_version }}_x64-setup.exe.sig) + else + FILE_NAME=Jan_${{ inputs.new_version }}_x64-setup.exe + WIN_SIG=$(cat Jan_${{ inputs.new_version }}_x64-setup.exe.sig) + fi + + echo "::set-output name=WIN_SIG::$WIN_SIG" + echo "::set-output name=FILE_NAME::$FILE_NAME" + id: metadata + + ## Upload to s3 for nightly and beta + - name: upload to aws s3 if public provider is aws + shell: bash + if: inputs.public_provider == 'aws-s3' || inputs.channel == 'beta' || inputs.channel == 'nightly' + run: | + cd ./src-tauri/target/release/bundle/nsis + aws s3 cp ./Jan-${{ inputs.channel }}_${{ inputs.new_version }}_x64-setup.exe s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_x64-setup-preview.exe + env: + AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.DELTA_AWS_REGION }} + AWS_EC2_METADATA_DISABLED: "true" + + ## Upload to github release for stable release + - name: Upload release assert if public provider is github + if: inputs.channel == 'stable' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/nsis/latest.yml + asset_name: latest.yml + asset_content_type: text/yaml + + - name: Upload release assert if public provider is github + if: inputs.channel == 'beta' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/nsis/beta.yml + asset_name: beta.yml + asset_content_type: text/yaml + + - name: Upload release assert if public provider is github + if: inputs.public_provider == 'github' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/nsis/${{ steps.metadata.outputs.FILE_NAME }} + asset_name: ${{ steps.metadata.outputs.FILE_NAME }} + asset_content_type: application/octet-stream \ No newline at end of file diff --git a/.github/workflows/template-tauri-build-windows-x64.yml b/.github/workflows/template-tauri-build-windows-x64.yml new file mode 100644 index 000000000..dcccf3001 --- /dev/null +++ b/.github/workflows/template-tauri-build-windows-x64.yml @@ -0,0 +1,286 @@ +name: tauri-build-windows-x64 +on: + workflow_call: + inputs: + ref: + required: true + type: string + default: "refs/heads/main" + public_provider: + required: true + type: string + default: none + description: "none: build only, github: build and publish to github, aws s3: build and publish to aws s3" + new_version: + required: true + type: string + default: '' + cortex_api_port: + required: false + type: string + default: "" + upload_url: + required: false + type: string + default: '' + channel: + required: true + type: string + default: 'nightly' + description: 'The channel to use for this job' + secrets: + DELTA_AWS_S3_BUCKET_NAME: + required: false + DELTA_AWS_ACCESS_KEY_ID: + required: false + DELTA_AWS_SECRET_ACCESS_KEY: + required: false + AZURE_KEY_VAULT_URI: + required: false + AZURE_CLIENT_ID: + required: false + AZURE_TENANT_ID: + required: false + AZURE_CLIENT_SECRET: + required: false + AZURE_CERT_NAME: + required: false + TAURI_SIGNING_PRIVATE_KEY: + required: false + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: + required: false + TAURI_SIGNING_PUBLIC_KEY: + required: false + outputs: + WIN_SIG: + value: ${{ jobs.build-windows-x64.outputs.WIN_SIG }} + FILE_NAME: + value: ${{ jobs.build-windows-x64.outputs.FILE_NAME }} + +jobs: + build-windows-x64: + runs-on: windows-latest + outputs: + WIN_SIG: ${{ steps.metadata.outputs.WIN_SIG }} + FILE_NAME: ${{ steps.metadata.outputs.FILE_NAME }} + permissions: + contents: write + steps: + - name: Getting the repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + + - name: Replace Icons for Beta Build + if: inputs.channel != 'stable' + shell: bash + run: | + cp .github/scripts/icon-${{ inputs.channel }}.png src-tauri/icons/icon.png + + - name: Installing node + uses: actions/setup-node@v1 + with: + node-version: 20 + + - name: Install jq + uses: dcarbone/install-jq-action@v2.0.1 + + - name: Install ctoml + run: | + cargo install ctoml + + - name: Update app version base on tag + id: version_update + shell: bash + run: | + echo "Version: ${{ inputs.new_version }}" + # Update tauri.conf.json + jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = true' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + jq --arg version "${{ inputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json + mv /tmp/package.json web/package.json + + ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" + cat ./src-tauri/Cargo.toml + + generate_build_version() { + ### Examble + ### input 0.5.6 output will be 0.5.6 and 0.5.6.0 + ### input 0.5.6-rc2-beta output will be 0.5.6 and 0.5.6.2 + ### input 0.5.6-1213 output will be 0.5.6 and and 0.5.6.1213 + local new_version="$1" + local base_version + local t_value + + # Check if it has a "-" + if [[ "$new_version" == *-* ]]; then + base_version="${new_version%%-*}" # part before - + suffix="${new_version#*-}" # part after - + + # Check if it is rcX-beta + if [[ "$suffix" =~ ^rc([0-9]+)-beta$ ]]; then + t_value="${BASH_REMATCH[1]}" + else + t_value="$suffix" + fi + else + base_version="$new_version" + t_value="0" + fi + + # Export two values + new_base_version="$base_version" + new_build_version="${base_version}.${t_value}" + } + generate_build_version ${{ inputs.new_version }} + sed -i "s/jan_version/$new_base_version/g" ./src-tauri/tauri.bundle.windows.nsis.template + sed -i "s/jan_build/$new_build_version/g" ./src-tauri/tauri.bundle.windows.nsis.template + echo "------------------" + cat ./src-tauri/tauri.bundle.windows.nsis.template + + # Change app name for beta and nightly builds + if [ "${{ inputs.channel }}" != "stable" ]; then + jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + + chmod +x .github/scripts/rename-tauri-app.sh + .github/scripts/rename-tauri-app.sh ./src-tauri/tauri.conf.json ${{ inputs.channel }} + + cat ./src-tauri/tauri.conf.json + + # Update Cargo.toml + ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}" + echo "------------------" + cat ./src-tauri/Cargo.toml + + chmod +x .github/scripts/rename-workspace.sh + .github/scripts/rename-workspace.sh ./package.json ${{ inputs.channel }} + cat ./package.json + + sed -i "s/jan_productname/Jan-${{ inputs.channel }}/g" ./src-tauri/tauri.bundle.windows.nsis.template + sed -i "s/jan_mainbinaryname/jan-${{ inputs.channel }}/g" ./src-tauri/tauri.bundle.windows.nsis.template + fi + + - name: Install AzureSignTool + run: | + dotnet tool install --global --version 6.0.0 AzureSignTool + + - name: Build app + shell: bash + run: | + make build-tauri + env: + AZURE_KEY_VAULT_URI: ${{ secrets.AZURE_KEY_VAULT_URI }} + AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} + AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} + AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} + AZURE_CERT_NAME: ${{ secrets.AZURE_CERT_NAME }} + AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: auto + AWS_EC2_METADATA_DISABLED: "true" + AWS_MAX_ATTEMPTS: "5" + POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }} + POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }} + # CORTEX_API_PORT: ${{ inputs.cortex_api_port }} + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + TAURI_SIGNING_PUBLIC_KEY: ${{ secrets.TAURI_SIGNING_PUBLIC_KEY }} + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: jan-windows-${{ inputs.new_version }} + path: | + ./src-tauri/target/release/bundle/nsis/*.exe + + ## create zip file and latest.yml for windows electron auto updater + - name: create zip file and latest.yml for windows electron auto updater + shell: bash + run: | + cd ./src-tauri/target/release/bundle/nsis + if [ "${{ inputs.channel }}" != "stable" ]; then + FILE_NAME=Jan-${{ inputs.channel }}_${{ inputs.new_version }}_x64-setup.exe + WIN_SIG=$(cat Jan-${{ inputs.channel }}_${{ inputs.new_version }}_x64-setup.exe.sig) + else + FILE_NAME=Jan_${{ inputs.new_version }}_x64-setup.exe + WIN_SIG=$(cat Jan_${{ inputs.new_version }}_x64-setup.exe.sig) + fi + + FILE_SIZE=$(stat -c %s $FILE_NAME) + echo "size: $FILE_SIZE" + + SH512_CHECKSUM=$(python3 ../../../../../.github/scripts/electron-checksum.py $FILE_NAME) + echo "sha512: $SH512_CHECKSUM" + CURRENT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ") + echo "releaseDate: $CURRENT_TIME" + + # Create latest.yml file + echo "version: ${{ inputs.new_version }}" > latest.yml + echo "files:" >> latest.yml + echo " - url: $FILE_NAME" >> latest.yml + echo " sha512: $SH512_CHECKSUM" >> latest.yml + echo " size: $FILE_NAME" >> latest.yml + echo "path: $FILE_NAME" >> latest.yml + echo "sha512: $SH512_CHECKSUM" >> latest.yml + echo "releaseDate: $CURRENT_TIME" >> latest.yml + + cat latest.yml + cp latest.yml beta.yml + + echo "::set-output name=WIN_SIG::$WIN_SIG" + echo "::set-output name=FILE_NAME::$FILE_NAME" + id: metadata + + ## Upload to s3 for nightly and beta + - name: upload to aws s3 if public provider is aws + shell: bash + if: inputs.public_provider == 'aws-s3' || inputs.channel == 'beta' + run: | + cd ./src-tauri/target/release/bundle/nsis + + # Upload for electron updater + aws s3 cp ./latest.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/latest.yml + aws s3 cp ./beta.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/beta.yml + + # Upload for tauri updater + aws s3 cp ./${{ steps.metadata.outputs.FILE_NAME }} s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/${{ steps.metadata.outputs.FILE_NAME }} + env: + AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.DELTA_AWS_REGION }} + AWS_EC2_METADATA_DISABLED: "true" + + ## Upload to github release for stable release + - name: Upload release assert if public provider is github + if: inputs.channel == 'stable' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/nsis/latest.yml + asset_name: latest.yml + asset_content_type: text/yaml + + - name: Upload release assert if public provider is github + if: inputs.channel == 'beta' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/nsis/beta.yml + asset_name: beta.yml + asset_content_type: text/yaml + + - name: Upload release assert if public provider is github + if: inputs.public_provider == 'github' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-release-asset@v1.0.1 + with: + upload_url: ${{ inputs.upload_url }} + asset_path: ./src-tauri/target/release/bundle/nsis/${{ steps.metadata.outputs.FILE_NAME }} + asset_name: ${{ steps.metadata.outputs.FILE_NAME }} + asset_content_type: application/octet-stream \ No newline at end of file diff --git a/Makefile b/Makefile index 176140a64..2803641fa 100644 --- a/Makefile +++ b/Makefile @@ -120,6 +120,9 @@ build-and-publish: check-file-counts build: check-file-counts yarn build +build-tauri: check-file-counts + yarn build-tauri + clean: ifeq ($(OS),Windows_NT) -powershell -Command "Get-ChildItem -Path . -Include node_modules, .next, dist, build, out, .turbo, .yarn -Recurse -Directory | Remove-Item -Recurse -Force" diff --git a/extensions/engine-management-extension/rolldown.config.mjs b/extensions/engine-management-extension/rolldown.config.mjs index 98bbf1d7f..a385f1efd 100644 --- a/extensions/engine-management-extension/rolldown.config.mjs +++ b/extensions/engine-management-extension/rolldown.config.mjs @@ -15,7 +15,7 @@ export default defineConfig([ `http://127.0.0.1:${process.env.CORTEX_API_PORT ?? '39291'}` ), PLATFORM: JSON.stringify(process.platform), - CORTEX_ENGINE_VERSION: JSON.stringify('b5350'), + CORTEX_ENGINE_VERSION: JSON.stringify('b5371'), DEFAULT_REMOTE_ENGINES: JSON.stringify(engines), DEFAULT_REMOTE_MODELS: JSON.stringify(models), DEFAULT_REQUEST_PAYLOAD_TRANSFORM: JSON.stringify( @@ -38,7 +38,7 @@ export default defineConfig([ file: 'dist/node/index.cjs.js', }, define: { - CORTEX_ENGINE_VERSION: JSON.stringify('b5350'), + CORTEX_ENGINE_VERSION: JSON.stringify('b5371'), }, }, ]) diff --git a/extensions/inference-cortex-extension/download.bat b/extensions/inference-cortex-extension/download.bat index 775602b81..ec6e68560 100644 --- a/extensions/inference-cortex-extension/download.bat +++ b/extensions/inference-cortex-extension/download.bat @@ -2,7 +2,7 @@ set BIN_PATH=./bin set SHARED_PATH=./../../electron/shared set /p CORTEX_VERSION=<./bin/version.txt -set ENGINE_VERSION=b5350 +set ENGINE_VERSION=b5371 @REM Download llama.cpp binaries set DOWNLOAD_URL=https://github.com/menloresearch/llama.cpp/releases/download/%ENGINE_VERSION%/llama-%ENGINE_VERSION%-bin-win @@ -15,11 +15,11 @@ call .\node_modules\.bin\download %DOWNLOAD_URL%-avx2-cuda-cu12.0-x64.tar.gz -e call .\node_modules\.bin\download %DOWNLOAD_URL%-avx2-cuda-cu11.7-x64.tar.gz -e --strip 2 -o %SHARED_PATH%/engines/llama.cpp/win-avx2-cuda-cu11.7-x64/%ENGINE_VERSION% call .\node_modules\.bin\download %DOWNLOAD_URL%-noavx-cuda-cu12.0-x64.tar.gz -e --strip 2 -o %SHARED_PATH%/engines/llama.cpp/win-noavx-cuda-cu12.0-x64/%ENGINE_VERSION% call .\node_modules\.bin\download %DOWNLOAD_URL%-noavx-cuda-cu11.7-x64.tar.gz -e --strip 2 -o %SHARED_PATH%/engines/llama.cpp/win-noavx-cuda-cu11.7-x64/%ENGINE_VERSION% -@REM call .\node_modules\.bin\download %DOWNLOAD_GGML_URL%-noavx-x64.zip -e --strip 1 -o %SHARED_PATH%/engines/llama.cpp/win-noavx-x64/%ENGINE_VERSION% -@REM call .\node_modules\.bin\download %DOWNLOAD_GGML_URL%-avx-x64.zip -e --strip 1 -o %SHARED_PATH%/engines/llama.cpp/win-avx-x64/%ENGINE_VERSION% -@REM call .\node_modules\.bin\download %DOWNLOAD_GGML_URL%-avx2-x64.zip -e --strip 1 -o %SHARED_PATH%/engines/llama.cpp/win-avx2-x64/%ENGINE_VERSION% -@REM call .\node_modules\.bin\download %DOWNLOAD_GGML_URL%-avx512-x64.zip -e --strip 1 -o %SHARED_PATH%/engines/llama.cpp/win-avx512-x64/%ENGINE_VERSION% -@REM call .\node_modules\.bin\download %DOWNLOAD_GGML_URL%-vulkan-x64.zip -e --strip 1 -o %SHARED_PATH%/engines/llama.cpp/win-vulkan-x64/%ENGINE_VERSION% +call .\node_modules\.bin\download %DOWNLOAD_URL%-noavx-x64.tar.gz -e --strip 2 -o %SHARED_PATH%/engines/llama.cpp/win-noavx-x64/%ENGINE_VERSION% +call .\node_modules\.bin\download %DOWNLOAD_URL%-avx-x64.tar.gz -e --strip 2 -o %SHARED_PATH%/engines/llama.cpp/win-avx-x64/%ENGINE_VERSION% +call .\node_modules\.bin\download %DOWNLOAD_URL%-avx2-x64.tar.gz -e --strip 2 -o %SHARED_PATH%/engines/llama.cpp/win-avx2-x64/%ENGINE_VERSION% +call .\node_modules\.bin\download %DOWNLOAD_URL%-avx512-x64.tar.gz -e --strip 2 -o %SHARED_PATH%/engines/llama.cpp/win-avx512-x64/%ENGINE_VERSION% +call .\node_modules\.bin\download %DOWNLOAD_GGML_URL%-vulkan-x64.zip -e --strip 1 -o %SHARED_PATH%/engines/llama.cpp/win-vulkan-x64/%ENGINE_VERSION% call .\node_modules\.bin\download %CUDA_DOWNLOAD_URL%/cudart-llama-bin-win-cu12.0-x64.tar.gz -e --strip 1 -o %BIN_PATH% call .\node_modules\.bin\download %CUDA_DOWNLOAD_URL%/cudart-llama-bin-win-cu11.7-x64.tar.gz -e --strip 1 -o %BIN_PATH% diff --git a/extensions/inference-cortex-extension/download.sh b/extensions/inference-cortex-extension/download.sh index 47ee14d65..6d3ea4639 100755 --- a/extensions/inference-cortex-extension/download.sh +++ b/extensions/inference-cortex-extension/download.sh @@ -2,7 +2,7 @@ # Read CORTEX_VERSION CORTEX_VERSION=$(cat ./bin/version.txt) -ENGINE_VERSION=b5350 +ENGINE_VERSION=b5371 CORTEX_RELEASE_URL="https://github.com/menloresearch/cortex.cpp/releases/download" ENGINE_DOWNLOAD_URL=https://github.com/menloresearch/llama.cpp/releases/download/${ENGINE_VERSION}/llama-${ENGINE_VERSION}-bin CUDA_DOWNLOAD_URL=https://github.com/menloresearch/llama.cpp/releases/download/${ENGINE_VERSION} diff --git a/extensions/inference-cortex-extension/rolldown.config.mjs b/extensions/inference-cortex-extension/rolldown.config.mjs index ae6e42331..6c0df4933 100644 --- a/extensions/inference-cortex-extension/rolldown.config.mjs +++ b/extensions/inference-cortex-extension/rolldown.config.mjs @@ -19,7 +19,7 @@ export default defineConfig([ CORTEX_SOCKET_URL: JSON.stringify( `ws://127.0.0.1:${process.env.CORTEX_API_PORT ?? '39291'}` ), - CORTEX_ENGINE_VERSION: JSON.stringify('b5350'), + CORTEX_ENGINE_VERSION: JSON.stringify('b5371'), }, }, { diff --git a/package.json b/package.json index de8248786..dcbf93831 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,9 @@ "install:cortex": "run-script-os", "download:bin": "node ./scripts/download-bin.mjs", "dev:tauri": "yarn build:icon && yarn copy:assets:tauri && tauri dev", + "build:tauri:linux:win32": "yarn download:bin && yarn install:cortex && yarn build:icon && yarn copy:assets:tauri && yarn tauri build --verbose", + "build:tauri:darwin": "yarn install:cortex && yarn build:icon && yarn copy:assets:tauri && yarn tauri build --verbose --target universal-apple-darwin", + "build:tauri": "run-script-os", "build:icon": "tauri icon ./src-tauri/icons/icon.png", "build:server": "cd server && yarn build", "build:core": "cd core && yarn build && yarn pack", @@ -37,6 +40,7 @@ "build:extensions": "rimraf ./pre-install/*.tgz || true && yarn workspace @janhq/core build && cd extensions && yarn install && yarn workspaces foreach -Apt run build:publish", "build:test": "yarn copy:assets && yarn workspace @janhq/web build && cpx \"web/out/**\" \"electron/renderer/\" && yarn workspace jan build:test", "build": "yarn build:web && yarn build:electron", + "build-tauri": "yarn build:web && yarn build:tauri", "build:publish": "yarn copy:assets && yarn build:web && yarn workspace jan build:publish", "dev:joi": "yarn workspace @janhq/joi install && yarn workspace @janhq/joi dev", "build:joi": "yarn workspace @janhq/joi build", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 4cbdde105..5ed527678 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,15 +1,13 @@ [package] -name = "app" -version = "0.1.0" -description = "A Tauri App" -authors = ["you"] -license = "" -repository = "" +name = "Jan" +version = "0.5.16" +description = "Use offline LLMs with your own data. Run open source models like Llama2 or Falcon on your internal computers/servers." +authors = ["Jan "] +license = "MIT" +repository = "https://github.com/menloresearch/jan" edition = "2021" rust-version = "1.77.2" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [lib] name = "app_lib" crate-type = ["staticlib", "cdylib", "rlib"] diff --git a/src-tauri/binaries/download.bat b/src-tauri/binaries/download.bat index 7172a1ac4..7eaee17c6 100644 --- a/src-tauri/binaries/download.bat +++ b/src-tauri/binaries/download.bat @@ -1,25 +1,24 @@ @echo off set CORTEX_VERSION=1.0.13-rc6 -set ENGINE_VERSION=b5350 +set ENGINE_VERSION=b5371 set ENGINE_DOWNLOAD_URL=https://github.com/menloresearch/llama.cpp/releases/download/%ENGINE_VERSION%/llama-%ENGINE_VERSION%-bin-win set ENGINE_DOWNLOAD_GGML_URL=https://github.com/ggml-org/llama.cpp/releases/download/%ENGINE_VERSION%/llama-%ENGINE_VERSION%-bin-win set CUDA_DOWNLOAD_URL=https://github.com/menloresearch/cortex.llamacpp/releases/download/v%ENGINE_VERSION% -set SUBFOLDERS=windows-amd64-noavx-cuda-12-0 windows-amd64-noavx-cuda-11-7 windows-amd64-avx2-cuda-12-0 windows-amd64-avx2-cuda-11-7 windows-amd64-noavx windows-amd64-avx windows-amd64-avx2 windows-amd64-avx512 windows-amd64-vulkan +@REM set SUBFOLDERS=windows-amd64-noavx-cuda-12-0 windows-amd64-noavx-cuda-11-7 windows-amd64-avx2-cuda-12-0 windows-amd64-avx2-cuda-11-7 windows-amd64-noavx windows-amd64-avx windows-amd64-avx2 windows-amd64-avx512 windows-amd64-vulkan set BIN_PATH="./" set DOWNLOAD_TOOL=..\..\extensions\inference-cortex-extension\node_modules\.bin\download -@REM Download cortex.llamacpp binaries - +@REM Download llama.cpp binaries call %DOWNLOAD_TOOL% -e --strip 1 -o %BIN_PATH% https://github.com/menloresearch/cortex.cpp/releases/download/v%CORTEX_VERSION%/cortex-%CORTEX_VERSION%-windows-amd64.tar.gz call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_URL%-avx2-cuda-cu12.0-x64.tar.gz -e --strip 2 -o./engines/llama.cpp/win-avx2-cuda-cu12.0-x64/%ENGINE_VERSION% call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_URL%-avx2-cuda-cu11.7-x64.tar.gz -e --strip 2 -o./engines/llama.cpp/win-avx2-cuda-cu11.7-x64/%ENGINE_VERSION% -call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_URL%-noavx-cuda-cu12.0-x64.tar.gz -e --strip 2 -o./engines/llama.cpp/win-noavx-cuda-cu12.0-x64/%ENGINE_VERSION% -call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_URL%-noavx-cuda-cu11.7-x64.tar.gz -e --strip 2 -o./engines/llama.cpp/win-noavx-cuda-cu11.7-x64/%ENGINE_VERSION% -call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_GGML_URL%-noavx-x64.zip -e --strip 1 -o./engines/llama.cpp/win-noavx-x64/%ENGINE_VERSION% -call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_GGML_URL%-avx-x64.zip -e --strip 1 -o./engines/llama.cpp/win-avx-x64/%ENGINE_VERSION% -call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_GGML_URL%-avx2-x64.zip -e --strip 1 -o./engines/llama.cpp/win-avx2-x64/%ENGINE_VERSION% -call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_GGML_URL%-avx512-x64.zip -e --strip 1 -o./engines/llama.cpp/win-avx512-x64/%ENGINE_VERSION% +@REM call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_URL%-noavx-cuda-cu12.0-x64.tar.gz -e --strip 2 -o./engines/llama.cpp/win-noavx-cuda-cu12.0-x64/%ENGINE_VERSION% +@REM call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_URL%-noavx-cuda-cu11.7-x64.tar.gz -e --strip 2 -o./engines/llama.cpp/win-noavx-cuda-cu11.7-x64/%ENGINE_VERSION% +call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_URL%-noavx-x64.tar.gz -e --strip 2 -o./engines/llama.cpp/win-noavx-x64/%ENGINE_VERSION% +call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_URL%-avx-x64.tar.gz -e --strip 2 -o./engines/llama.cpp/win-avx-x64/%ENGINE_VERSION% +call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_URL%-avx2-x64.tar.gz -e --strip 2 -o./engines/llama.cpp/win-avx2-x64/%ENGINE_VERSION% +call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_URL%-avx512-x64.tar.gz -e --strip 2 -o./engines/llama.cpp/win-avx512-x64/%ENGINE_VERSION% call %DOWNLOAD_TOOL% %ENGINE_DOWNLOAD_GGML_URL%-vulkan-x64.zip -e --strip 1 -o./engines/llama.cpp/win-vulkan-x64/%ENGINE_VERSION% call %DOWNLOAD_TOOL% %CUDA_DOWNLOAD_URL%/cudart-llama-bin-win-cu12.0-x64.tar.gz -e --strip 1 -o %BIN_PATH% call %DOWNLOAD_TOOL% %CUDA_DOWNLOAD_URL%/cudart-llama-bin-win-cu11.7-x64.tar.gz -e --strip 1 -o %BIN_PATH% diff --git a/src-tauri/binaries/download.sh b/src-tauri/binaries/download.sh index bd63273e4..e1ad30db9 100755 --- a/src-tauri/binaries/download.sh +++ b/src-tauri/binaries/download.sh @@ -15,7 +15,7 @@ download() { # Read CORTEX_VERSION CORTEX_VERSION=1.0.13-rc6 -ENGINE_VERSION=b5350 +ENGINE_VERSION=b5371 CORTEX_RELEASE_URL="https://github.com/menloresearch/cortex.cpp/releases/download" ENGINE_DOWNLOAD_URL=https://github.com/menloresearch/llama.cpp/releases/download/${ENGINE_VERSION}/llama-${ENGINE_VERSION}-bin CUDA_DOWNLOAD_URL=https://github.com/menloresearch/llama.cpp/releases/download/${ENGINE_VERSION} diff --git a/src-tauri/latest.json.template b/src-tauri/latest.json.template new file mode 100644 index 000000000..50a570c9e --- /dev/null +++ b/src-tauri/latest.json.template @@ -0,0 +1,23 @@ +{ + "version": "", + "notes": "", + "pub_date": "", + "platforms": { + "linux-x86_64": { + "signature": "", + "url": "" + }, + "windows-x86_64": { + "signature": "", + "url": "" + }, + "darwin-aarch64": { + "signature": "", + "url": "" + }, + "darwin-x86_64": { + "signature": "", + "url": "" + } + } +} \ No newline at end of file diff --git a/src-tauri/sign.ps1 b/src-tauri/sign.ps1 new file mode 100644 index 000000000..a54d525fe --- /dev/null +++ b/src-tauri/sign.ps1 @@ -0,0 +1,12 @@ +param ( + [string]$Target +) + +AzureSignTool.exe sign ` + -tr http://timestamp.digicert.com ` + -kvu $env:AZURE_KEY_VAULT_URI ` + -kvi $env:AZURE_CLIENT_ID ` + -kvt $env:AZURE_TENANT_ID ` + -kvs $env:AZURE_CLIENT_SECRET ` + -kvc $env:AZURE_CERT_NAME ` + -v $Target \ No newline at end of file diff --git a/src-tauri/src/core/cmd.rs b/src-tauri/src/core/cmd.rs index 3d7d921ee..a9f90ca80 100644 --- a/src-tauri/src/core/cmd.rs +++ b/src-tauri/src/core/cmd.rs @@ -101,6 +101,7 @@ pub fn get_jan_data_folder_path(app_handle: tauri::AppHandle) -> } let app_configurations = get_app_configurations(app_handle); + log::info!("data_folder: {}", app_configurations.data_folder); PathBuf::from(app_configurations.data_folder) } @@ -158,7 +159,18 @@ pub fn get_configuration_file_path(app_handle: tauri::AppHandle) PathBuf::from(home_dir) }); - app_path.join(CONFIGURATION_FILE_NAME) + let package_name = env!("CARGO_PKG_NAME"); + log::info!("Package name: {}", package_name); + let old_data_dir = app_path + .clone() + .parent() + .unwrap_or(&app_path.join("../")) + .join(package_name); + if old_data_dir.exists() { + return old_data_dir.join(CONFIGURATION_FILE_NAME); + } else { + return app_path.join(CONFIGURATION_FILE_NAME); + } } #[tauri::command] diff --git a/src-tauri/src/core/setup.rs b/src-tauri/src/core/setup.rs index b83cc8973..d70af1c70 100644 --- a/src-tauri/src/core/setup.rs +++ b/src-tauri/src/core/setup.rs @@ -19,7 +19,9 @@ use super::{ }; pub fn install_extensions(app: tauri::AppHandle, force: bool) -> Result<(), String> { - let store = app.store("store.json").expect("Store not initialized"); + let mut store_path = get_jan_data_folder_path(app.clone()); + store_path.push("store.json"); + let store = app.store(store_path).expect("Store not initialized"); let stored_version = store .get("version") .and_then(|v| v.as_str().map(String::from)) @@ -35,7 +37,12 @@ pub fn install_extensions(app: tauri::AppHandle, force: bool) -> Result<(), Stri return Ok(()); } let extensions_path = get_jan_extensions_path(app.clone()); - let pre_install_path = PathBuf::from("./resources/pre-install"); + let pre_install_path = app + .path() + .resource_dir() + .unwrap() + .join("resources") + .join("pre-install"); // Attempt to remove extensions folder if extensions_path.exists() { @@ -198,29 +205,19 @@ pub fn setup_sidecar(app: &App) -> Result<(), String> { // Setup sidecar let app_state = app.state::(); + let app_data_dir = get_jan_data_folder_path(app.handle().clone()); let mut sidecar_command = app.shell().sidecar("cortex-server").unwrap().args([ "--start-server", "--port", "39291", "--config_file_path", - app.app_handle() - .path() - .app_data_dir() - .unwrap() - .join(".janrc") - .to_str() - .unwrap(), + app_data_dir.join(".janrc").to_str().unwrap(), "--data_folder_path", - app.app_handle() - .path() - .app_data_dir() - .unwrap() - .to_str() - .unwrap(), + app_data_dir.to_str().unwrap(), "--cors", "ON", "--allowed_origins", - "http://localhost:3000", + "http://localhost:3000,tauri://localhost,http://tauri.localhost", "config", "--api_keys", app_state.inner().app_token.as_deref().unwrap_or(""), @@ -286,7 +283,7 @@ fn copy_dir_all(src: PathBuf, dst: PathBuf) -> Result<(), String> { pub fn setup_engine_binaries(app: &App) -> Result<(), String> { // Copy engine binaries to app_data - let app_data_dir = app.handle().path().app_data_dir().unwrap(); + let app_data_dir = get_jan_data_folder_path(app.handle().clone()); let binaries_dir = app.handle().path().resource_dir().unwrap().join("binaries"); let themes_dir = app .handle() diff --git a/src-tauri/tauri.bundle.windows.nsis.template b/src-tauri/tauri.bundle.windows.nsis.template new file mode 100644 index 000000000..bb3463e12 --- /dev/null +++ b/src-tauri/tauri.bundle.windows.nsis.template @@ -0,0 +1,1031 @@ +Unicode true +ManifestDPIAware true +; Add in `dpiAwareness` `PerMonitorV2` to manifest for Windows 10 1607+ (note this should not affect lower versions since they should be able to ignore this and pick up `dpiAware` `true` set by `ManifestDPIAware true`) +; Currently undocumented on NSIS's website but is in the Docs folder of source tree, see +; https://github.com/kichik/nsis/blob/5fc0b87b819a9eec006df4967d08e522ddd651c9/Docs/src/attributes.but#L286-L300 +; https://github.com/tauri-apps/tauri/pull/10106 +ManifestDPIAwareness PerMonitorV2 + +!if "lzma" == "none" + SetCompress off +!else + ; Set the compression algorithm. We default to LZMA. + SetCompressor /SOLID "lzma" +!endif + +!include MUI2.nsh +!include FileFunc.nsh +!include x64.nsh +!include WordFunc.nsh +!include "utils.nsh" +!include "FileAssociation.nsh" +!include "Win\COM.nsh" +!include "Win\Propkey.nsh" +!include "StrFunc.nsh" +${StrCase} +${StrLoc} + + +!define WEBVIEW2APPGUID "{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" + +!define MANUFACTURER "ai" +!define PRODUCTNAME "jan_productname" +!define VERSION "jan_version" +!define VERSIONWITHBUILD "jan_build" +!define HOMEPAGE "" +!define INSTALLMODE "currentUser" +!define LICENSE "" +!define INSTALLERICON "D:\a\jan\jan\src-tauri\icons\icon.ico" +!define SIDEBARIMAGE "" +!define HEADERIMAGE "" +!define MAINBINARYNAME "jan_mainbinaryname" +!define MAINBINARYSRCPATH "D:\a\jan\jan\src-tauri\target\release\jan_mainbinaryname.exe" +!define BUNDLEID "jan_mainbinaryname.ai.app" +!define COPYRIGHT "" +!define OUTFILE "nsis-output.exe" +!define ARCH "x64" +!define ADDITIONALPLUGINSPATH "D:\a\jan\jan\src-tauri\target\release\nsis\x64\Plugins\x86-unicode\additional" +!define ALLOWDOWNGRADES "true" +!define DISPLAYLANGUAGESELECTOR "false" +!define INSTALLWEBVIEW2MODE "downloadBootstrapper" +!define WEBVIEW2INSTALLERARGS "/silent" +!define WEBVIEW2BOOTSTRAPPERPATH "" +!define WEBVIEW2INSTALLERPATH "" +!define MINIMUMWEBVIEW2VERSION "" +!define UNINSTKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCTNAME}" +!define MANUKEY "Software\${MANUFACTURER}" +!define MANUPRODUCTKEY "${MANUKEY}\${PRODUCTNAME}" +!define UNINSTALLERSIGNCOMMAND "$\"powershell$\" $\"-ExecutionPolicy$\" $\"Bypass$\" $\"-File$\" $\"./sign.ps1$\" $\"%1$\"" +!define ESTIMATEDSIZE "793795" +!define STARTMENUFOLDER "" + +Var PassiveMode +Var UpdateMode +Var NoShortcutMode +Var WixMode +Var OldMainBinaryName + +Name "${PRODUCTNAME}" +BrandingText "${COPYRIGHT}" +OutFile "${OUTFILE}" + +ShowInstDetails nevershow +ShowUninstDetails nevershow + +; We don't actually use this value as default install path, +; it's just for nsis to append the product name folder in the directory selector +; https://nsis.sourceforge.io/Reference/InstallDir +!define PLACEHOLDER_INSTALL_DIR "placeholder\${PRODUCTNAME}" +InstallDir "${PLACEHOLDER_INSTALL_DIR}" + +VIProductVersion "${VERSIONWITHBUILD}" +VIAddVersionKey "ProductName" "${PRODUCTNAME}" +VIAddVersionKey "FileDescription" "${PRODUCTNAME}" +VIAddVersionKey "LegalCopyright" "${COPYRIGHT}" +VIAddVersionKey "FileVersion" "${VERSION}" +VIAddVersionKey "ProductVersion" "${VERSION}" + +# additional plugins +!addplugindir "${ADDITIONALPLUGINSPATH}" + +; Uninstaller signing command +!if "${UNINSTALLERSIGNCOMMAND}" != "" + !uninstfinalize '${UNINSTALLERSIGNCOMMAND}' +!endif + +; Handle install mode, `perUser`, `perMachine` or `both` +!if "${INSTALLMODE}" == "perMachine" + RequestExecutionLevel highest +!endif + +!if "${INSTALLMODE}" == "currentUser" + RequestExecutionLevel user +!endif + +!if "${INSTALLMODE}" == "both" + !define MULTIUSER_MUI + !define MULTIUSER_INSTALLMODE_INSTDIR "${PRODUCTNAME}" + !define MULTIUSER_INSTALLMODE_COMMANDLINE + !if "${ARCH}" == "x64" + !define MULTIUSER_USE_PROGRAMFILES64 + !else if "${ARCH}" == "arm64" + !define MULTIUSER_USE_PROGRAMFILES64 + !endif + !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "${UNINSTKEY}" + !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "CurrentUser" + !define MULTIUSER_INSTALLMODEPAGE_SHOWUSERNAME + !define MULTIUSER_INSTALLMODE_FUNCTION RestorePreviousInstallLocation + !define MULTIUSER_EXECUTIONLEVEL Highest + !include MultiUser.nsh +!endif + +; Installer icon +!if "${INSTALLERICON}" != "" + !define MUI_ICON "${INSTALLERICON}" +!endif + +; Installer sidebar image +!if "${SIDEBARIMAGE}" != "" + !define MUI_WELCOMEFINISHPAGE_BITMAP "${SIDEBARIMAGE}" +!endif + +; Installer header image +!if "${HEADERIMAGE}" != "" + !define MUI_HEADERIMAGE + !define MUI_HEADERIMAGE_BITMAP "${HEADERIMAGE}" +!endif + +; Define registry key to store installer language +!define MUI_LANGDLL_REGISTRY_ROOT "HKCU" +!define MUI_LANGDLL_REGISTRY_KEY "${MANUPRODUCTKEY}" +!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language" + +; Installer pages, must be ordered as they appear +; 1. Welcome Page +!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive +!insertmacro MUI_PAGE_WELCOME + +; 2. License Page (if defined) +!if "${LICENSE}" != "" + !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive + !insertmacro MUI_PAGE_LICENSE "${LICENSE}" +!endif + +; 3. Install mode (if it is set to `both`) +!if "${INSTALLMODE}" == "both" + !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive + !insertmacro MULTIUSER_PAGE_INSTALLMODE +!endif + +; 4. Custom page to ask user if he wants to reinstall/uninstall +; only if a previous installation was detected +Var ReinstallPageCheck +Page custom PageReinstall PageLeaveReinstall +Function PageReinstall + ; Uninstall previous WiX installation if exists. + ; + ; A WiX installer stores the installation info in registry + ; using a UUID and so we have to loop through all keys under + ; `HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall` + ; and check if `DisplayName` and `Publisher` keys match ${PRODUCTNAME} and ${MANUFACTURER} + ; + ; This has a potential issue that there maybe another installation that matches + ; our ${PRODUCTNAME} and ${MANUFACTURER} but wasn't installed by our WiX installer, + ; however, this should be fine since the user will have to confirm the uninstallation + ; and they can chose to abort it if doesn't make sense. + StrCpy $0 0 + wix_loop: + EnumRegKey $1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" $0 + StrCmp $1 "" wix_loop_done ; Exit loop if there is no more keys to loop on + IntOp $0 $0 + 1 + ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "DisplayName" + ReadRegStr $R1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "Publisher" + StrCmp "$R0$R1" "${PRODUCTNAME}${MANUFACTURER}" 0 wix_loop + ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "UninstallString" + ${StrCase} $R1 $R0 "L" + ${StrLoc} $R0 $R1 "msiexec" ">" + StrCmp $R0 0 0 wix_loop_done + StrCpy $WixMode 1 + StrCpy $R6 "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" + Goto compare_version + wix_loop_done: + + ; Check if there is an existing installation, if not, abort the reinstall page + ReadRegStr $R0 SHCTX "${UNINSTKEY}" "" + ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString" + ${IfThen} "$R0$R1" == "" ${|} Abort ${|} + + ; Compare this installar version with the existing installation + ; and modify the messages presented to the user accordingly + compare_version: + StrCpy $R4 "$(older)" + ${If} $WixMode = 1 + ReadRegStr $R0 HKLM "$R6" "DisplayVersion" + ${Else} + ReadRegStr $R0 SHCTX "${UNINSTKEY}" "DisplayVersion" + ${EndIf} + ${IfThen} $R0 == "" ${|} StrCpy $R4 "$(unknown)" ${|} + + nsis_tauri_utils::SemverCompare "${VERSION}" $R0 + Pop $R0 + ; Reinstalling the same version + ${If} $R0 = 0 + StrCpy $R1 "$(alreadyInstalledLong)" + StrCpy $R2 "$(addOrReinstall)" + StrCpy $R3 "$(uninstallApp)" + !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(chooseMaintenanceOption)" + ; Upgrading + ${ElseIf} $R0 = 1 + StrCpy $R1 "$(olderOrUnknownVersionInstalled)" + StrCpy $R2 "$(uninstallBeforeInstalling)" + StrCpy $R3 "$(dontUninstall)" + !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)" + ; Downgrading + ${ElseIf} $R0 = -1 + StrCpy $R1 "$(newerVersionInstalled)" + StrCpy $R2 "$(uninstallBeforeInstalling)" + !if "${ALLOWDOWNGRADES}" == "true" + StrCpy $R3 "$(dontUninstall)" + !else + StrCpy $R3 "$(dontUninstallDowngrade)" + !endif + !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)" + ${Else} + Abort + ${EndIf} + + ; Skip showing the page if passive + ; + ; Note that we don't call this earlier at the begining + ; of this function because we need to populate some variables + ; related to current installed version if detected and whether + ; we are downgrading or not. + ${If} $PassiveMode = 1 + Call PageLeaveReinstall + ${Else} + nsDialogs::Create 1018 + Pop $R4 + ${IfThen} $(^RTL) = 1 ${|} nsDialogs::SetRTL $(^RTL) ${|} + + ${NSD_CreateLabel} 0 0 100% 24u $R1 + Pop $R1 + + ${NSD_CreateRadioButton} 30u 50u -30u 8u $R2 + Pop $R2 + ${NSD_OnClick} $R2 PageReinstallUpdateSelection + + ${NSD_CreateRadioButton} 30u 70u -30u 8u $R3 + Pop $R3 + ; Disable this radio button if downgrading and downgrades are disabled + !if "${ALLOWDOWNGRADES}" == "false" + ${IfThen} $R0 = -1 ${|} EnableWindow $R3 0 ${|} + !endif + ${NSD_OnClick} $R3 PageReinstallUpdateSelection + + ; Check the first radio button if this the first time + ; we enter this page or if the second button wasn't + ; selected the last time we were on this page + ${If} $ReinstallPageCheck <> 2 + SendMessage $R2 ${BM_SETCHECK} ${BST_CHECKED} 0 + ${Else} + SendMessage $R3 ${BM_SETCHECK} ${BST_CHECKED} 0 + ${EndIf} + + ${NSD_SetFocus} $R2 + nsDialogs::Show + ${EndIf} +FunctionEnd +Function PageReinstallUpdateSelection + ${NSD_GetState} $R2 $R1 + ${If} $R1 == ${BST_CHECKED} + StrCpy $ReinstallPageCheck 1 + ${Else} + StrCpy $ReinstallPageCheck 2 + ${EndIf} +FunctionEnd +Function PageLeaveReinstall + ${NSD_GetState} $R2 $R1 + + ; If migrating from Wix, always uninstall + ${If} $WixMode = 1 + Goto reinst_uninstall + ${EndIf} + + ; In update mode, always proceeds without uninstalling + ${If} $UpdateMode = 1 + Goto reinst_done + ${EndIf} + + ; $R0 holds whether same(0)/upgrading(1)/downgrading(-1) version + ; $R1 holds the radio buttons state: + ; 1 => first choice was selected + ; 0 => second choice was selected + ${If} $R0 = 0 ; Same version, proceed + ${If} $R1 = 1 ; User chose to add/reinstall + Goto reinst_done + ${Else} ; User chose to uninstall + Goto reinst_uninstall + ${EndIf} + ${ElseIf} $R0 = 1 ; Upgrading + ${If} $R1 = 1 ; User chose to uninstall + Goto reinst_uninstall + ${Else} + Goto reinst_done ; User chose NOT to uninstall + ${EndIf} + ${ElseIf} $R0 = -1 ; Downgrading + ${If} $R1 = 1 ; User chose to uninstall + Goto reinst_uninstall + ${Else} + Goto reinst_done ; User chose NOT to uninstall + ${EndIf} + ${EndIf} + + reinst_uninstall: + HideWindow + ClearErrors + + ${If} $WixMode = 1 + ReadRegStr $R1 HKLM "$R6" "UninstallString" + ExecWait '$R1' $0 + ${Else} + ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" "" + ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString" + ${IfThen} $UpdateMode = 1 ${|} StrCpy $R1 "$R1 /UPDATE" ${|} ; append /UPDATE + ${IfThen} $PassiveMode = 1 ${|} StrCpy $R1 "$R1 /P" ${|} ; append /P + StrCpy $R1 "$R1 _?=$4" ; append uninstall directory + ExecWait '$R1' $0 + ${EndIf} + + BringToFront + + ${IfThen} ${Errors} ${|} StrCpy $0 2 ${|} ; ExecWait failed, set fake exit code + + ${If} $0 <> 0 + ${OrIf} ${FileExists} "$INSTDIR\${MAINBINARYNAME}.exe" + ; User cancelled wix uninstaller? return to select un/reinstall page + ${If} $WixMode = 1 + ${AndIf} $0 = 1602 + Abort + ${EndIf} + + ; User cancelled NSIS uninstaller? return to select un/reinstall page + ${If} $0 = 1 + Abort + ${EndIf} + + ; Other erros? show generic error message and return to select un/reinstall page + MessageBox MB_ICONEXCLAMATION "$(unableToUninstall)" + Abort + ${EndIf} + reinst_done: +FunctionEnd + +; 5. Choose install directory page +!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive +!insertmacro MUI_PAGE_DIRECTORY + +; 6. Start menu shortcut page +Var AppStartMenuFolder +!if "${STARTMENUFOLDER}" != "" + !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive + !define MUI_STARTMENUPAGE_DEFAULTFOLDER "${STARTMENUFOLDER}" +!else + !define MUI_PAGE_CUSTOMFUNCTION_PRE Skip +!endif +!insertmacro MUI_PAGE_STARTMENU Application $AppStartMenuFolder + +; 7. Installation page +!insertmacro MUI_PAGE_INSTFILES + +; 8. Finish page +; +; Don't auto jump to finish page after installation page, +; because the installation page has useful info that can be used debug any issues with the installer. +!define MUI_FINISHPAGE_NOAUTOCLOSE +; Use show readme button in the finish page as a button create a desktop shortcut +!define MUI_FINISHPAGE_SHOWREADME +!define MUI_FINISHPAGE_SHOWREADME_TEXT "$(createDesktop)" +!define MUI_FINISHPAGE_SHOWREADME_FUNCTION CreateOrUpdateDesktopShortcut +; Show run app after installation. +!define MUI_FINISHPAGE_RUN +!define MUI_FINISHPAGE_RUN_FUNCTION RunMainBinary +!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive +!insertmacro MUI_PAGE_FINISH + +Function RunMainBinary + nsis_tauri_utils::RunAsUser "$INSTDIR\${MAINBINARYNAME}.exe" "" +FunctionEnd + +; Uninstaller Pages +; 1. Confirm uninstall page +Var DeleteAppDataCheckbox +Var DeleteAppDataCheckboxState +!define /ifndef WS_EX_LAYOUTRTL 0x00400000 +!define MUI_PAGE_CUSTOMFUNCTION_SHOW un.ConfirmShow +Function un.ConfirmShow ; Add add a `Delete app data` check box + ; $1 inner dialog HWND + ; $2 window DPI + ; $3 style + ; $4 x + ; $5 y + ; $6 width + ; $7 height + FindWindow $1 "#32770" "" $HWNDPARENT ; Find inner dialog + System::Call "user32::GetDpiForWindow(p r1) i .r2" + ${If} $(^RTL) = 1 + StrCpy $3 "${__NSD_CheckBox_EXSTYLE} | ${WS_EX_LAYOUTRTL}" + IntOp $4 50 * $2 + ${Else} + StrCpy $3 "${__NSD_CheckBox_EXSTYLE}" + IntOp $4 0 * $2 + ${EndIf} + IntOp $5 100 * $2 + IntOp $6 400 * $2 + IntOp $7 25 * $2 + IntOp $4 $4 / 96 + IntOp $5 $5 / 96 + IntOp $6 $6 / 96 + IntOp $7 $7 / 96 + System::Call 'user32::CreateWindowEx(i r3, w "${__NSD_CheckBox_CLASS}", w "$(deleteAppData)", i ${__NSD_CheckBox_STYLE}, i r4, i r5, i r6, i r7, p r1, i0, i0, i0) i .s' + Pop $DeleteAppDataCheckbox + SendMessage $HWNDPARENT ${WM_GETFONT} 0 0 $1 + SendMessage $DeleteAppDataCheckbox ${WM_SETFONT} $1 1 +FunctionEnd +!define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.ConfirmLeave +Function un.ConfirmLeave + SendMessage $DeleteAppDataCheckbox ${BM_GETCHECK} 0 0 $DeleteAppDataCheckboxState +FunctionEnd +!define MUI_PAGE_CUSTOMFUNCTION_PRE un.SkipIfPassive +!insertmacro MUI_UNPAGE_CONFIRM + +; 2. Uninstalling Page +!insertmacro MUI_UNPAGE_INSTFILES + +;Languages +!insertmacro MUI_LANGUAGE "English" +!insertmacro MUI_RESERVEFILE_LANGDLL + !include "D:\a\jan\jan\src-tauri\target\release\nsis\x64\English.nsh" + +Function .onInit + ${GetOptions} $CMDLINE "/P" $PassiveMode + ${IfNot} ${Errors} + StrCpy $PassiveMode 1 + ${EndIf} + ; always run in passive mode + StrCpy $PassiveMode 1 + + ${GetOptions} $CMDLINE "/NS" $NoShortcutMode + ${IfNot} ${Errors} + StrCpy $NoShortcutMode 1 + ${EndIf} + + ${GetOptions} $CMDLINE "/UPDATE" $UpdateMode + ${IfNot} ${Errors} + StrCpy $UpdateMode 1 + ${EndIf} + + !if "${DISPLAYLANGUAGESELECTOR}" == "true" + !insertmacro MUI_LANGDLL_DISPLAY + !endif + + !insertmacro SetContext + + ${If} $INSTDIR == "${PLACEHOLDER_INSTALL_DIR}" + ; Set default install location + !if "${INSTALLMODE}" == "perMachine" + ${If} ${RunningX64} + !if "${ARCH}" == "x64" + StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCTNAME}" + !else if "${ARCH}" == "arm64" + StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCTNAME}" + !else + StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCTNAME}" + !endif + ${Else} + StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCTNAME}" + ${EndIf} + !else if "${INSTALLMODE}" == "currentUser" + StrCpy $INSTDIR "$LOCALAPPDATA\Programs\${PRODUCTNAME}" + !endif + + Call RestorePreviousInstallLocation + ${EndIf} + + ; Remove old Jan if it exists + ${If} ${FileExists} "$INSTDIR\LICENSE.electron.txt" + DeleteRegKey HKLM "Software\${PRODUCTNAME}" + RMDir /r "$INSTDIR" + Delete "$INSTDIR\*.*" + ${EndIf} + + !if "${INSTALLMODE}" == "both" + !insertmacro MULTIUSER_INIT + !endif +FunctionEnd + + +Section EarlyChecks + ; Abort silent installer if downgrades is disabled + !if "${ALLOWDOWNGRADES}" == "false" + ${If} ${Silent} + ; If downgrading + ${If} $R0 = -1 + System::Call 'kernel32::AttachConsole(i -1)i.r0' + ${If} $0 <> 0 + System::Call 'kernel32::GetStdHandle(i -11)i.r0' + System::call 'kernel32::SetConsoleTextAttribute(i r0, i 0x0004)' ; set red color + FileWrite $0 "$(silentDowngrades)" + ${EndIf} + Abort + ${EndIf} + ${EndIf} + !endif + +SectionEnd + +Section WebView2 + ; Check if Webview2 is already installed and skip this section + ${If} ${RunningX64} + ReadRegStr $4 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\${WEBVIEW2APPGUID}" "pv" + ${Else} + ReadRegStr $4 HKLM "SOFTWARE\Microsoft\EdgeUpdate\Clients\${WEBVIEW2APPGUID}" "pv" + ${EndIf} + ${If} $4 == "" + ReadRegStr $4 HKCU "SOFTWARE\Microsoft\EdgeUpdate\Clients\${WEBVIEW2APPGUID}" "pv" + ${EndIf} + + ${If} $4 == "" + ; Webview2 installation + ; + ; Skip if updating + ${If} $UpdateMode <> 1 + !if "${INSTALLWEBVIEW2MODE}" == "downloadBootstrapper" + Delete "$TEMP\MicrosoftEdgeWebview2Setup.exe" + DetailPrint "$(webview2Downloading)" + NSISdl::download "https://go.microsoft.com/fwlink/p/?LinkId=2124703" "$TEMP\MicrosoftEdgeWebview2Setup.exe" + Pop $0 + ${If} $0 == "success" + DetailPrint "$(webview2DownloadSuccess)" + ${Else} + DetailPrint "$(webview2DownloadError)" + Abort "$(webview2AbortError)" + ${EndIf} + StrCpy $6 "$TEMP\MicrosoftEdgeWebview2Setup.exe" + Goto install_webview2 + !endif + + !if "${INSTALLWEBVIEW2MODE}" == "embedBootstrapper" + Delete "$TEMP\MicrosoftEdgeWebview2Setup.exe" + File "/oname=$TEMP\MicrosoftEdgeWebview2Setup.exe" "${WEBVIEW2BOOTSTRAPPERPATH}" + DetailPrint "$(installingWebview2)" + StrCpy $6 "$TEMP\MicrosoftEdgeWebview2Setup.exe" + Goto install_webview2 + !endif + + !if "${INSTALLWEBVIEW2MODE}" == "offlineInstaller" + Delete "$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" + File "/oname=$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" "${WEBVIEW2INSTALLERPATH}" + DetailPrint "$(installingWebview2)" + StrCpy $6 "$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" + Goto install_webview2 + !endif + + Goto webview2_done + + install_webview2: + DetailPrint "$(installingWebview2)" + ; $6 holds the path to the webview2 installer + ExecWait "$6 ${WEBVIEW2INSTALLERARGS} /install" $1 + ${If} $1 = 0 + DetailPrint "$(webview2InstallSuccess)" + ${Else} + DetailPrint "$(webview2InstallError)" + Abort "$(webview2AbortError)" + ${EndIf} + webview2_done: + ${EndIf} + ${Else} + !if "${MINIMUMWEBVIEW2VERSION}" != "" + ${VersionCompare} "${MINIMUMWEBVIEW2VERSION}" "$4" $R0 + ${If} $R0 = 1 + update_webview: + DetailPrint "$(installingWebview2)" + ${If} ${RunningX64} + ReadRegStr $R1 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate" "path" + ${Else} + ReadRegStr $R1 HKLM "SOFTWARE\Microsoft\EdgeUpdate" "path" + ${EndIf} + ${If} $R1 == "" + ReadRegStr $R1 HKCU "SOFTWARE\Microsoft\EdgeUpdate" "path" + ${EndIf} + ${If} $R1 != "" + ; Chromium updater docs: https://source.chromium.org/chromium/chromium/src/+/main:docs/updater/user_manual.md + ; Modified from "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft EdgeWebView\ModifyPath" + ExecWait `"$R1" /install appguid=${WEBVIEW2APPGUID}&needsadmin=true` $1 + ${If} $1 = 0 + DetailPrint "$(webview2InstallSuccess)" + ${Else} + MessageBox MB_ICONEXCLAMATION|MB_ABORTRETRYIGNORE "$(webview2InstallError)" IDIGNORE ignore IDRETRY update_webview + Quit + ignore: + ${EndIf} + ${EndIf} + ${EndIf} + !endif + ${EndIf} +SectionEnd + +Section Install + SetDetailsPrint none + SetOutPath $INSTDIR + + !ifmacrodef NSIS_HOOK_PREINSTALL + !insertmacro NSIS_HOOK_PREINSTALL + !endif + + !insertmacro CheckIfAppIsRunning + + ; Copy main executable + File "${MAINBINARYSRCPATH}" + + ; Copy resources + CreateDirectory "$INSTDIR\resources\themes\joi-light" + CreateDirectory "$INSTDIR\resources\pre-install" + CreateDirectory "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55" + CreateDirectory "$INSTDIR\resources\themes\night-blue" + CreateDirectory "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55" + CreateDirectory "$INSTDIR\resources\themes\joi-dark" + CreateDirectory "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55" + CreateDirectory "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55" + CreateDirectory "$INSTDIR\resources\themes\dark-dimmed" + CreateDirectory "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\engine.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\engine.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\msvcp140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\msvcp140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\vcomp140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\vcomp140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\vcruntime140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\vcruntime140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\vcruntime140_1.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\vcruntime140_1.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\version.txt" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\version.txt" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\engine.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\engine.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\msvcp140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\msvcp140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\vcomp140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\vcomp140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\vcruntime140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\vcruntime140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\vcruntime140_1.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\vcruntime140_1.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\version.txt" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\version.txt" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\engine.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\engine.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\msvcp140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\msvcp140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\vcomp140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\vcomp140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\vcruntime140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\vcruntime140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\vcruntime140_1.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\vcruntime140_1.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\version.txt" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\version.txt" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\engine.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\engine.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\msvcp140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\msvcp140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\vcomp140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\vcomp140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\vcruntime140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\vcruntime140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\vcruntime140_1.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\vcruntime140_1.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\version.txt" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\version.txt" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\engine.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\engine.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\msvcp140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\msvcp140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\vcomp140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\vcomp140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\vcruntime140.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\vcruntime140.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\vcruntime140_1.dll" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\vcruntime140_1.dll" + File /a "/oname=binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\version.txt" "D:\a\jan\jan\src-tauri\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\version.txt" + File /a "/oname=resources\pre-install\janhq-assistant-extension-1.0.2.tgz" "D:\a\jan\jan\src-tauri\resources\pre-install\janhq-assistant-extension-1.0.2.tgz" + File /a "/oname=resources\pre-install\janhq-conversational-extension-1.0.0.tgz" "D:\a\jan\jan\src-tauri\resources\pre-install\janhq-conversational-extension-1.0.0.tgz" + File /a "/oname=resources\pre-install\janhq-engine-management-extension-1.0.3.tgz" "D:\a\jan\jan\src-tauri\resources\pre-install\janhq-engine-management-extension-1.0.3.tgz" + File /a "/oname=resources\pre-install\janhq-hardware-management-extension-1.0.0.tgz" "D:\a\jan\jan\src-tauri\resources\pre-install\janhq-hardware-management-extension-1.0.0.tgz" + File /a "/oname=resources\pre-install\janhq-inference-cortex-extension-1.0.25.tgz" "D:\a\jan\jan\src-tauri\resources\pre-install\janhq-inference-cortex-extension-1.0.25.tgz" + File /a "/oname=resources\pre-install\janhq-model-extension-1.0.36.tgz" "D:\a\jan\jan\src-tauri\resources\pre-install\janhq-model-extension-1.0.36.tgz" + File /a "/oname=resources\themes\dark-dimmed\theme.json" "D:\a\jan\jan\src-tauri\resources\themes\dark-dimmed\theme.json" + File /a "/oname=resources\themes\joi-dark\theme.json" "D:\a\jan\jan\src-tauri\resources\themes\joi-dark\theme.json" + File /a "/oname=resources\themes\joi-light\theme.json" "D:\a\jan\jan\src-tauri\resources\themes\joi-light\theme.json" + File /a "/oname=resources\themes\night-blue\theme.json" "D:\a\jan\jan\src-tauri\resources\themes\night-blue\theme.json" + + ; Copy external binaries + File /a "/oname=cortex-server.exe" "D:\a\jan\jan\src-tauri\binaries\cortex-server-x86_64-pc-windows-msvc.exe" + + ; Create file associations + + ; Register deep links + + ; Create uninstaller + WriteUninstaller "$INSTDIR\uninstall.exe" + + ; Save $INSTDIR in registry for future installations + WriteRegStr SHCTX "${MANUPRODUCTKEY}" "" $INSTDIR + + !if "${INSTALLMODE}" == "both" + ; Save install mode to be selected by default for the next installation such as updating + ; or when uninstalling + WriteRegStr SHCTX "${UNINSTKEY}" $MultiUser.InstallMode 1 + !endif + + ; Remove old main binary if it doesn't match new main binary name + ReadRegStr $OldMainBinaryName SHCTX "${UNINSTKEY}" "MainBinaryName" + ${If} $OldMainBinaryName != "" + ${AndIf} $OldMainBinaryName != "${MAINBINARYNAME}.exe" + Delete "$INSTDIR\$OldMainBinaryName" + ${EndIf} + + ; Save current MAINBINARYNAME for future updates + WriteRegStr SHCTX "${UNINSTKEY}" "MainBinaryName" "${MAINBINARYNAME}.exe" + + ; Registry information for add/remove programs + WriteRegStr SHCTX "${UNINSTKEY}" "DisplayName" "${PRODUCTNAME}" + WriteRegStr SHCTX "${UNINSTKEY}" "DisplayIcon" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\"" + WriteRegStr SHCTX "${UNINSTKEY}" "DisplayVersion" "${VERSION}" + WriteRegStr SHCTX "${UNINSTKEY}" "Publisher" "${MANUFACTURER}" + WriteRegStr SHCTX "${UNINSTKEY}" "InstallLocation" "$\"$INSTDIR$\"" + WriteRegStr SHCTX "${UNINSTKEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" + WriteRegDWORD SHCTX "${UNINSTKEY}" "NoModify" "1" + WriteRegDWORD SHCTX "${UNINSTKEY}" "NoRepair" "1" + + ${GetSize} "$INSTDIR" "/M=uninstall.exe /S=0K /G=0" $0 $1 $2 + IntOp $0 $0 + ${ESTIMATEDSIZE} + IntFmt $0 "0x%08X" $0 + WriteRegDWORD SHCTX "${UNINSTKEY}" "EstimatedSize" "$0" + + !if "${HOMEPAGE}" != "" + WriteRegStr SHCTX "${UNINSTKEY}" "URLInfoAbout" "${HOMEPAGE}" + WriteRegStr SHCTX "${UNINSTKEY}" "URLUpdateInfo" "${HOMEPAGE}" + WriteRegStr SHCTX "${UNINSTKEY}" "HelpLink" "${HOMEPAGE}" + !endif + + ; Create start menu shortcut + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + Call CreateOrUpdateStartMenuShortcut + !insertmacro MUI_STARTMENU_WRITE_END + + ; Create desktop shortcut for silent and passive installers + ; because finish page will be skipped + ${If} $PassiveMode = 1 + ${OrIf} ${Silent} + Call CreateOrUpdateDesktopShortcut + ${EndIf} + + !ifmacrodef NSIS_HOOK_POSTINSTALL + !insertmacro NSIS_HOOK_POSTINSTALL + !endif + + ; Auto close this page for passive mode + ${If} $PassiveMode = 1 + SetAutoClose true + ${EndIf} +SectionEnd + +Function .onInstSuccess + ; Check for `/R` flag only in silent and passive installers because + ; GUI installer has a toggle for the user to (re)start the app + ${If} $PassiveMode = 1 + ${OrIf} ${Silent} + ; ${GetOptions} $CMDLINE "/R" $R0 + ; ${IfNot} ${Errors} + ${GetOptions} $CMDLINE "/ARGS" $R0 + nsis_tauri_utils::RunAsUser "$INSTDIR\${MAINBINARYNAME}.exe" "$R0" + ; ${EndIf} + ${EndIf} +FunctionEnd + +Function un.onInit + !insertmacro SetContext + + !if "${INSTALLMODE}" == "both" + !insertmacro MULTIUSER_UNINIT + !endif + + !insertmacro MUI_UNGETLANGUAGE + + ${GetOptions} $CMDLINE "/P" $PassiveMode + ${IfNot} ${Errors} + StrCpy $PassiveMode 1 + ${EndIf} + + ${GetOptions} $CMDLINE "/UPDATE" $UpdateMode + ${IfNot} ${Errors} + StrCpy $UpdateMode 1 + ${EndIf} +FunctionEnd + +Section Uninstall + SetDetailsPrint none + + !ifmacrodef NSIS_HOOK_PREUNINSTALL + !insertmacro NSIS_HOOK_PREUNINSTALL + !endif + + !insertmacro CheckIfAppIsRunning + + ; Delete the app directory and its content from disk + ; Copy main executable + Delete "$INSTDIR\${MAINBINARYNAME}.exe" + + ; Delete resources + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\engine.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\msvcp140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\vcomp140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\vcruntime140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\vcruntime140_1.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55\version.txt" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\engine.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\msvcp140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\vcomp140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\vcruntime140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\vcruntime140_1.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55\version.txt" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\engine.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\msvcp140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\vcomp140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\vcruntime140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\vcruntime140_1.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55\version.txt" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\engine.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\msvcp140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\vcomp140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\vcruntime140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\vcruntime140_1.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55\version.txt" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\engine.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\msvcp140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\vcomp140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\vcruntime140.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\vcruntime140_1.dll" + Delete "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55\version.txt" + Delete "$INSTDIR\resources\pre-install\janhq-assistant-extension-1.0.2.tgz" + Delete "$INSTDIR\resources\pre-install\janhq-conversational-extension-1.0.0.tgz" + Delete "$INSTDIR\resources\pre-install\janhq-engine-management-extension-1.0.3.tgz" + Delete "$INSTDIR\resources\pre-install\janhq-hardware-management-extension-1.0.0.tgz" + Delete "$INSTDIR\resources\pre-install\janhq-inference-cortex-extension-1.0.25.tgz" + Delete "$INSTDIR\resources\pre-install\janhq-model-extension-1.0.36.tgz" + Delete "$INSTDIR\resources\themes\dark-dimmed\theme.json" + Delete "$INSTDIR\resources\themes\joi-dark\theme.json" + Delete "$INSTDIR\resources\themes\joi-light\theme.json" + Delete "$INSTDIR\resources\themes\night-blue\theme.json" + + ; Delete external binaries + Delete "$INSTDIR\cortex-server.exe" + + ; Delete app associations + + ; Delete deep links + + + ; Delete uninstaller + Delete "$INSTDIR\uninstall.exe" + + RMDir /REBOOTOK "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx\v0.1.55" + RMDir /REBOOTOK "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx2\v0.1.55" + RMDir /REBOOTOK "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx512\v0.1.55" + RMDir /REBOOTOK "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-noavx\v0.1.55" + RMDir /REBOOTOK "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-vulkan\v0.1.55" + RMDir /REBOOTOK "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx" + RMDir /REBOOTOK "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx2" + RMDir /REBOOTOK "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-avx512" + RMDir /REBOOTOK "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-noavx" + RMDir /REBOOTOK "$INSTDIR\binaries\engines\cortex.llamacpp\windows-amd64-vulkan" + RMDir /REBOOTOK "$INSTDIR\binaries\engines\cortex.llamacpp" + RMDir /REBOOTOK "$INSTDIR\resources\themes\dark-dimmed" + RMDir /REBOOTOK "$INSTDIR\resources\themes\joi-dark" + RMDir /REBOOTOK "$INSTDIR\resources\themes\joi-light" + RMDir /REBOOTOK "$INSTDIR\resources\themes\night-blue" + RMDir /REBOOTOK "$INSTDIR\binaries\engines" + RMDir /REBOOTOK "$INSTDIR\resources\pre-install" + RMDir /REBOOTOK "$INSTDIR\resources\themes" + RMDir /REBOOTOK "$INSTDIR\binaries" + RMDir /REBOOTOK "$INSTDIR\resources" + RMDir "$INSTDIR" + + ; Remove shortcuts if not updating + ${If} $UpdateMode <> 1 + !insertmacro DeleteAppUserModelId + + ; Remove start menu shortcut + !insertmacro MUI_STARTMENU_GETFOLDER Application $AppStartMenuFolder + !insertmacro IsShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + Pop $0 + ${If} $0 = 1 + !insertmacro UnpinShortcut "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" + Delete "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" + RMDir "$SMPROGRAMS\$AppStartMenuFolder" + ${EndIf} + !insertmacro IsShortcutTarget "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + Pop $0 + ${If} $0 = 1 + !insertmacro UnpinShortcut "$SMPROGRAMS\${PRODUCTNAME}.lnk" + Delete "$SMPROGRAMS\${PRODUCTNAME}.lnk" + ${EndIf} + + ; Remove desktop shortcuts + !insertmacro IsShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + Pop $0 + ${If} $0 = 1 + !insertmacro UnpinShortcut "$DESKTOP\${PRODUCTNAME}.lnk" + Delete "$DESKTOP\${PRODUCTNAME}.lnk" + ${EndIf} + ${EndIf} + + ; Remove registry information for add/remove programs + !if "${INSTALLMODE}" == "both" + DeleteRegKey SHCTX "${UNINSTKEY}" + !else if "${INSTALLMODE}" == "perMachine" + DeleteRegKey HKLM "${UNINSTKEY}" + !else + DeleteRegKey HKCU "${UNINSTKEY}" + !endif + + ; Removes the Autostart entry for ${PRODUCTNAME} from the HKCU Run key if it exists. + ; This ensures the program does not launch automatically after uninstallation if it exists. + ; If it doesn't exist, it does nothing. + ; We do this when not updating (to preserve the registry value on updates) + ${If} $UpdateMode <> 1 + DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "${PRODUCTNAME}" + ${EndIf} + + ; Delete app data if the checkbox is selected + ; and if not updating + ${If} $DeleteAppDataCheckboxState = 1 + ${AndIf} $UpdateMode <> 1 + ; Clear the install location $INSTDIR from registry + DeleteRegKey SHCTX "${MANUPRODUCTKEY}" + DeleteRegKey /ifempty SHCTX "${MANUKEY}" + + ; Clear the install language from registry + DeleteRegValue HKCU "${MANUPRODUCTKEY}" "Installer Language" + DeleteRegKey /ifempty HKCU "${MANUPRODUCTKEY}" + DeleteRegKey /ifempty HKCU "${MANUKEY}" + + SetShellVarContext current + RmDir /r "$APPDATA\${BUNDLEID}" + RmDir /r "$LOCALAPPDATA\${BUNDLEID}" + ${EndIf} + + !ifmacrodef NSIS_HOOK_POSTUNINSTALL + !insertmacro NSIS_HOOK_POSTUNINSTALL + !endif + + ; Auto close if passive mode or updating + ${If} $PassiveMode = 1 + ${OrIf} $UpdateMode = 1 + SetAutoClose true + ${EndIf} +SectionEnd + +Function RestorePreviousInstallLocation + ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" "" + StrCmp $4 "" +2 0 + StrCpy $INSTDIR $4 +FunctionEnd + +Function Skip + Abort +FunctionEnd + +Function SkipIfPassive + ${IfThen} $PassiveMode = 1 ${|} Abort ${|} +FunctionEnd +Function un.SkipIfPassive + ${IfThen} $PassiveMode = 1 ${|} Abort ${|} +FunctionEnd + +Function CreateOrUpdateStartMenuShortcut + ; We used to use product name as MAINBINARYNAME + ; migrate old shortcuts to target the new MAINBINARYNAME + StrCpy $R0 0 + + !insertmacro IsShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\$OldMainBinaryName" + Pop $0 + ${If} $0 = 1 + !insertmacro SetShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + StrCpy $R0 1 + ${EndIf} + + !insertmacro IsShortcutTarget "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\$OldMainBinaryName" + Pop $0 + ${If} $0 = 1 + !insertmacro SetShortcutTarget "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + StrCpy $R0 1 + ${EndIf} + + ${If} $R0 = 1 + Return + ${EndIf} + + ; Skip creating shortcut if in update mode or no shortcut mode + ; but always create if migrating from wix + ${If} $WixMode = 0 + ${If} $UpdateMode = 1 + ${OrIf} $NoShortcutMode = 1 + Return + ${EndIf} + ${EndIf} + + !if "${STARTMENUFOLDER}" != "" + CreateDirectory "$SMPROGRAMS\$AppStartMenuFolder" + CreateShortcut "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" + !else + CreateShortcut "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\${PRODUCTNAME}.lnk" + !endif +FunctionEnd + +Function CreateOrUpdateDesktopShortcut + ; We used to use product name as MAINBINARYNAME + ; migrate old shortcuts to target the new MAINBINARYNAME + !insertmacro IsShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\$OldMainBinaryName" + Pop $0 + ${If} $0 = 1 + !insertmacro SetShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + Return + ${EndIf} + + ; Skip creating shortcut if in update mode or no shortcut mode + ; but always create if migrating from wix + ${If} $WixMode = 0 + ${If} $UpdateMode = 1 + ${OrIf} $NoShortcutMode = 1 + Return + ${EndIf} + ${EndIf} + + CreateShortcut "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + !insertmacro SetLnkAppUserModelId "$DESKTOP\${PRODUCTNAME}.lnk" +FunctionEnd diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 3e74e9fc7..35e7b1fa5 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,8 +1,8 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Jan", - "version": "0.1.0", - "identifier": "jan.ai", + "version": "0.5.16", + "identifier": "jan.ai.app", "build": { "frontendDist": "../web/out", "devUrl": "http://localhost:3000", @@ -22,7 +22,12 @@ "transparent": true, "titleBarStyle": "Overlay", "windowEffects": { - "effects": ["fullScreenUI", "mica", "blur", "acrylic"], + "effects": [ + "fullScreenUI", + "mica", + "blur", + "acrylic" + ], "state": "active" } } @@ -30,33 +35,46 @@ "security": { "csp": { "default-src": "'self' customprotocol: asset: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*", - "connect-src": "ipc: http://ipc.localhost", - "font-src": ["https://fonts.gstatic.com blob: data:"], + "connect-src": "ipc: http://ipc.localhost http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:* https://registry.npmjs.org", + "font-src": [ + "https://fonts.gstatic.com blob: data:" + ], "img-src": "'self' asset: http://asset.localhost blob: data:", "style-src": "'unsafe-inline' 'self' https://fonts.googleapis.com", - "script-src": "'self' asset: $APPDATA/**.*" + "script-src": "'self' asset: $APPDATA/**.* http://asset.localhost" }, "assetProtocol": { "enable": true, "scope": { "requireLiteralLeadingDot": false, - "allow": ["**/*"] + "allow": [ + "**/*" + ] } } } }, "plugins": { "updater": { - "pubkey": "", + "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDJFNDEzMEVCMUEzNUFENDQKUldSRXJUVWE2ekJCTGc1Mm1BVXgrWmtES3huUlBFR0lCdG5qbWFvMzgyNDhGN3VTTko5Q1NtTW0K", "endpoints": [ "https://github.com/menloresearch/jan/releases/latest/download/latest.json" - ] + ], + "windows": { + "installMode": "passive" + } } }, "bundle": { "active": true, - "targets": "all", - "createUpdaterArtifacts": true, + "targets": [ + "nsis", + "app", + "dmg", + "deb", + "appimage" + ], + "createUpdaterArtifacts": false, "icon": [ "icons/32x32.png", "icons/128x128.png", @@ -69,6 +87,25 @@ "resources/themes/**/*", "resources/pre-install/**/*" ], - "externalBin": ["binaries/cortex-server", "resources/bin/bun", "resources/bin/uv"] + "externalBin": [ + "binaries/cortex-server", + "resources/bin/bun", + "resources/bin/uv" + ], + "linux": { + "appimage": { + "bundleMediaFramework": false, + "files": {} + }, + "deb": { + "files": { + "usr/bin/bun": "resources/bin/bun", + "usr/lib/Jan/binaries/engines": "binaries/engines" + } + } + }, + "windows": { + "signCommand": "powershell -ExecutionPolicy Bypass -File ./sign.ps1 %1" + } } -} +} \ No newline at end of file diff --git a/web/screens/Hub/ModelPage/index.tsx b/web/screens/Hub/ModelPage/index.tsx index dcd0c833b..904a73cda 100644 --- a/web/screens/Hub/ModelPage/index.tsx +++ b/web/screens/Hub/ModelPage/index.tsx @@ -144,10 +144,10 @@ const ModelPage = ({ model, onGoBack }: Props) => { {model.type !== 'cloud' && ( <> - + Format - + Size diff --git a/web/screens/Settings/Engines/RemoteEngineSettings.tsx b/web/screens/Settings/Engines/RemoteEngineSettings.tsx index e773b1957..fa3f7a668 100644 --- a/web/screens/Settings/Engines/RemoteEngineSettings.tsx +++ b/web/screens/Settings/Engines/RemoteEngineSettings.tsx @@ -168,8 +168,7 @@ const RemoteEngineSettings = ({

{!customEngineLogo ? ( - Enter your authentication key to activate this - engine.{' '} + Enter your authentication key to activate this engine.{' '} ) : (