janhq/jan

26 workflows · maturity 17% · 10 patterns · GitHub ↗

Security 0/100

Practices

✓ Matrix○ Permissions○ Security scan○ AI review○ Cache○ Concurrency✓ Reusable workflows

Detected patterns

Security dimensions

permissions
0
security scan
0
supply chain
0
secret handling
0
harden runner
0

Workflows (26)

auto-assign-author .github/workflows/auto-assign-author.yml
Triggers
pull_request
Runs on
ubuntu-latest
Jobs
assign-author
Actions
toshimaru/auto-author-assign
View raw YAML
# Auto assign author, tags, and reviewers to pull requests
name: "Auto Assign Author"
on:
  pull_request:
    types: [opened]
jobs:
  assign-author:
    runs-on: ubuntu-latest
    if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
    permissions:
      pull-requests: write
    steps:
      - uses: toshimaru/auto-author-assign@v1.1.0
        with:
          repo-token: "${{ secrets.GITHUB_TOKEN }}"
auto-assign-milestone .github/workflows/auto-assign-milestone.yml
Triggers
pull_request
Runs on
ubuntu-latest
Jobs
assign_milestone
View raw YAML
# Pipeline auto assign current milestone for PR after the PR is merge
name: Assign Milestone
on:
  pull_request:
    types: [closed]

jobs:
  assign_milestone:
    runs-on: ubuntu-latest
    if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
    permissions:
      pull-requests: write
      issues: write
    steps:
      - name: Assign Milestone
        uses: actions/github-script@v3
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const { owner, repo } = context.repo;
            const { number, merged } = context.payload.pull_request;
            if (merged) {
              const { data: milestones } = await github.issues.listMilestones({
                owner,
                repo,
                state: 'open',
              });

              const mergedDate = new Date(context.payload.pull_request.merged_at);
              const currentMilestone = milestones
              .filter(milestone => milestone.due_on !== null)
              .find((milestone) => {
                const dueDate = new Date(milestone.due_on);
                return mergedDate <= dueDate;
              });

              if (currentMilestone) {
                await github.issues.update({
                  owner,
                  repo,
                  issue_number: number,
                  milestone: currentMilestone.number
                });
              }
            }
          debug: true

auto-label-conventional-commits .github/workflows/auto-label-conventional-commits.yaml
Triggers
pull_request
Runs on
ubuntu-latest
Jobs
label_prs
Commands
  • ISSUE_TITLE=$(gh issue view ${{ github.event.number }} --json title -q ".title") case "$ISSUE_TITLE" in chore:*) LABEL="type: chore" ;; feat:*) LABEL="type: feature request" ;; perf:*) LABEL="type: enhancement" ;; fix:*) LABEL="type: bug" ;; docs:*) LABEL="type: documentation" ;; ci:*) LABEL="type: ci" ;; build:*) LABEL="type: ci" ;; test:*) LABEL="type: chore" ;; style:*) LABEL="type: chore" ;; refactor:*) LABEL="type: chore" ;; *) LABEL="" ;; esac if [ -n "$LABEL" ]; then gh issue edit ${{ github.event.number }} --add-label "$LABEL" fi
View raw YAML
name: "Auto Label Conventional Commits"
on:
  pull_request:
    types:
      - reopened
      - opened
jobs:
  label_prs:
    if: github.event.pull_request.head.repo.full_name == github.repository
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Label PRs
        run: |
          ISSUE_TITLE=$(gh issue view ${{ github.event.number }} --json title -q ".title")
          case "$ISSUE_TITLE" in
            chore:*) LABEL="type: chore" ;;
            feat:*) LABEL="type: feature request" ;;
            perf:*) LABEL="type: enhancement" ;;
            fix:*) LABEL="type: bug" ;;
            docs:*) LABEL="type: documentation" ;;
            ci:*) LABEL="type: ci" ;;
            build:*) LABEL="type: ci" ;;
            test:*) LABEL="type: chore" ;;
            style:*) LABEL="type: chore" ;;
            refactor:*) LABEL="type: chore" ;;
            *) LABEL="" ;;
          esac
          if [ -n "$LABEL" ]; then
            gh issue edit ${{ github.event.number }} --add-label "$LABEL"
          fi
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
autoqa-manual-trigger .github/workflows/autoqa-manual-trigger.yml
Triggers
workflow_dispatch
Runs on
Jobs
call-autoqa-template
View raw YAML
name: Manual trigger AutoQA Test Runner

on:
  workflow_dispatch:
    inputs:
      jan_app_url_windows:
        description: 'URL to download Jan app for Windows (.exe)'
        required: true
        type: string
        default: 'https://delta.jan.ai/nightly/Jan-nightly_0.6.5-758_x64-setup.exe'
      jan_app_url_ubuntu:
        description: 'URL to download Jan app for Ubuntu (.deb)'
        required: true
        type: string
        default: 'https://delta.jan.ai/nightly/Jan-nightly_0.6.5-758_amd64.deb'
      jan_app_url_macos:
        description: 'URL to download Jan app for macOS (.dmg)'
        required: true
        type: string
        default: 'https://delta.jan.ai/nightly/Jan-nightly_0.6.5-758_universal.dmg'
      is_nightly:
        description: 'Is this a nightly build?'
        required: true
        type: boolean
        default: true

jobs:
  call-autoqa-template:
    uses: ./.github/workflows/autoqa-template.yml
    with:
      jan_app_windows_source: ${{ inputs.jan_app_url_windows }}
      jan_app_ubuntu_source: ${{ inputs.jan_app_url_ubuntu }}
      jan_app_macos_source: ${{ inputs.jan_app_url_macos }}
      is_nightly: ${{ inputs.is_nightly }}
      source_type: 'url'
    secrets:
      RP_TOKEN: ${{ secrets.RP_TOKEN }}
autoqa-migration .github/workflows/autoqa-migration.yml
Triggers
workflow_dispatch
Runs on
windows-11-nvidia-gpu, ubuntu-22-04-nvidia-gpu, macos-selfhosted-15-arm64-cua
Jobs
migration-windows, migration-ubuntu, migration-macos
Commands
  • .\autoqa\scripts\windows_cleanup.ps1 -IsNightly $false
  • # Download OLD installer using existing script .\autoqa\scripts\windows_download.ps1 ` -WorkflowInputUrl "${{ inputs.old_windows_installer }}" ` -WorkflowInputIsNightly "false" ` -RepoVariableUrl "" ` -RepoVariableIsNightly "" ` -DefaultUrl "" ` -DefaultIsNightly "" $oldSrc = Join-Path $env:TEMP 'jan-installer.exe' $oldOut = Join-Path $env:TEMP 'jan-old.exe' Copy-Item -Path $oldSrc -Destination $oldOut -Force # Download NEW installer using existing script .\autoqa\scripts\windows_download.ps1 ` -WorkflowInputUrl "${{ inputs.new_windows_installer }}" ` -WorkflowInputIsNightly "false" ` -RepoVariableUrl "" ` -RepoVariableIsNightly "" ` -DefaultUrl "" ` -DefaultIsNightly "" $newSrc = Join-Path $env:TEMP 'jan-installer.exe' $newOut = Join-Path $env:TEMP 'jan-new.exe' Copy-Item -Path $newSrc -Destination $newOut -Force Write-Host "OLD installer: $oldOut" Write-Host "NEW installer: $newOut" echo "OLD_VERSION=$oldOut" | Out-File -FilePath $env:GITHUB_ENV -Append echo "NEW_VERSION=$newOut" | Out-File -FilePath $env:GITHUB_ENV -Append
  • python -m pip install --upgrade pip pip install -r requirements.txt
  • $case = "${{ inputs.migration_test_case }}" $caseArg = "" if ($case -and $case.Trim() -ne "") { $caseArg = "--migration-test-case `"$case`"" } python main.py --enable-migration-test --old-version "$env:OLD_VERSION" --new-version "$env:NEW_VERSION" --max-turns ${{ inputs.max_turns }} $caseArg
  • .\autoqa\scripts\windows_post_cleanup.ps1 -IsNightly $false
  • sudo apt-get update sudo apt-get install -y \ x11-utils \ python3-tk \ python3-dev \ wmctrl \ xdotool \ libnss3-dev \ libgconf-2-4 \ libxss1 \ libasound2 \ libxtst6 \ libgtk-3-0 \ libgbm-dev \ libxshmfence1 \ libxrandr2 \ libpangocairo-1.0-0 \ libatk1.0-0 \ libcairo-gobject2 \ libgdk-pixbuf2.0-0 \ gnome-screenshot \ xvfb
  • chmod +x autoqa/scripts/setup_permissions.sh || true ./autoqa/scripts/setup_permissions.sh || true
  • ./autoqa/scripts/ubuntu_cleanup.sh
View raw YAML
name: AutoQA Migration (Manual)

on:
  workflow_dispatch:
    inputs:
      old_windows_installer:
        description: 'Windows OLD installer URL or path (.exe)'
        required: true
        type: string
      new_windows_installer:
        description: 'Windows NEW installer URL or path (.exe)'
        required: true
        type: string
      old_ubuntu_installer:
        description: 'Ubuntu OLD installer URL or path (.deb)'
        required: false
        type: string
        default: ''
      new_ubuntu_installer:
        description: 'Ubuntu NEW installer URL or path (.deb)'
        required: false
        type: string
        default: ''
      old_macos_installer:
        description: 'macOS OLD installer URL or path (.dmg)'
        required: false
        type: string
        default: ''
      new_macos_installer:
        description: 'macOS NEW installer URL or path (.dmg)'
        required: false
        type: string
        default: ''
      migration_test_case:
        description: 'Specific migration test case key (leave empty to run all)'
        required: false
        type: string
        default: ''
      max_turns:
        description: 'Maximum turns per test phase'
        required: false
        type: number
        default: 65

jobs:
  migration-windows:
    runs-on: windows-11-nvidia-gpu
    timeout-minutes: 60
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Python 3.13
        uses: actions/setup-python@v4
        with:
          python-version: '3.13'

      - name: Clean existing Jan installations
        shell: powershell
        run: |
          .\autoqa\scripts\windows_cleanup.ps1 -IsNightly $false

      - name: Download OLD and NEW installers
        shell: powershell
        run: |
          # Download OLD installer using existing script
          .\autoqa\scripts\windows_download.ps1 `
            -WorkflowInputUrl "${{ inputs.old_windows_installer }}" `
            -WorkflowInputIsNightly "false" `
            -RepoVariableUrl "" `
            -RepoVariableIsNightly "" `
            -DefaultUrl "" `
            -DefaultIsNightly ""

          $oldSrc = Join-Path $env:TEMP 'jan-installer.exe'
          $oldOut = Join-Path $env:TEMP 'jan-old.exe'
          Copy-Item -Path $oldSrc -Destination $oldOut -Force

          # Download NEW installer using existing script
          .\autoqa\scripts\windows_download.ps1 `
            -WorkflowInputUrl "${{ inputs.new_windows_installer }}" `
            -WorkflowInputIsNightly "false" `
            -RepoVariableUrl "" `
            -RepoVariableIsNightly "" `
            -DefaultUrl "" `
            -DefaultIsNightly ""

          $newSrc = Join-Path $env:TEMP 'jan-installer.exe'
          $newOut = Join-Path $env:TEMP 'jan-new.exe'
          Copy-Item -Path $newSrc -Destination $newOut -Force

          Write-Host "OLD installer: $oldOut"
          Write-Host "NEW installer: $newOut"
          echo "OLD_VERSION=$oldOut" | Out-File -FilePath $env:GITHUB_ENV -Append
          echo "NEW_VERSION=$newOut" | Out-File -FilePath $env:GITHUB_ENV -Append

      - name: Install Python dependencies
        working-directory: autoqa
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Run migration tests (Windows)
        working-directory: autoqa
        shell: powershell
        env:
          RP_TOKEN: ${{ secrets.RP_TOKEN }}
          ENABLE_REPORTPORTAL: 'true'
          RP_ENDPOINT: 'https://reportportal.menlo.ai'
          RP_PROJECT: 'default_personal'
        run: |
          $case = "${{ inputs.migration_test_case }}"
          $caseArg = ""
          if ($case -and $case.Trim() -ne "") { $caseArg = "--migration-test-case `"$case`"" }
          python main.py --enable-migration-test --old-version "$env:OLD_VERSION" --new-version "$env:NEW_VERSION" --max-turns ${{ inputs.max_turns }} $caseArg

      - name: Upload screen recordings
        if: always()
        uses: actions/upload-artifact@v4
        continue-on-error: true
        with:
          name: migration-recordings-${{ github.run_number }}-windows
          path: autoqa/recordings/

      - name: Upload trajectories
        if: always()
        uses: actions/upload-artifact@v4
        continue-on-error: true
        with:
          name: migration-trajectories-${{ github.run_number }}-windows
          path: autoqa/trajectories/

      - name: Cleanup after tests
        if: always()
        shell: powershell
        run: |
          .\autoqa\scripts\windows_post_cleanup.ps1 -IsNightly $false

  migration-ubuntu:
    if: inputs.old_ubuntu_installer != '' && inputs.new_ubuntu_installer != ''
    runs-on: ubuntu-22-04-nvidia-gpu
    timeout-minutes: 60
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Python 3.13
        uses: actions/setup-python@v4
        with:
          python-version: '3.13'

      - name: Install system dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y \
            x11-utils \
            python3-tk \
            python3-dev \
            wmctrl \
            xdotool \
            libnss3-dev \
            libgconf-2-4 \
            libxss1 \
            libasound2 \
            libxtst6 \
            libgtk-3-0 \
            libgbm-dev \
            libxshmfence1 \
            libxrandr2 \
            libpangocairo-1.0-0 \
            libatk1.0-0 \
            libcairo-gobject2 \
            libgdk-pixbuf2.0-0 \
            gnome-screenshot \
            xvfb

      - name: Setup script permissions
        run: |
          chmod +x autoqa/scripts/setup_permissions.sh || true
          ./autoqa/scripts/setup_permissions.sh || true

      - name: Clean existing Jan installations
        run: |
          ./autoqa/scripts/ubuntu_cleanup.sh

      - name: Download OLD and NEW installers
        run: |
          set -e
          # Download OLD installer using existing script
          ./autoqa/scripts/ubuntu_download.sh \
            "${{ inputs.old_ubuntu_installer }}" \
            "false" \
            "" \
            "" \
            "" \
            ""
          cp /tmp/jan-installer.deb /tmp/jan-old.deb

          # Download NEW installer using existing script
          ./autoqa/scripts/ubuntu_download.sh \
            "${{ inputs.new_ubuntu_installer }}" \
            "false" \
            "" \
            "" \
            "" \
            ""
          cp /tmp/jan-installer.deb /tmp/jan-new.deb

          echo "OLD_VERSION=/tmp/jan-old.deb" >> $GITHUB_ENV
          echo "NEW_VERSION=/tmp/jan-new.deb" >> $GITHUB_ENV

      - name: Install Python dependencies
        working-directory: autoqa
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Run migration tests (Ubuntu)
        working-directory: autoqa
        run: |
          case="${{ inputs.migration_test_case }}"
          caseArg=""
          if [ -n "${case}" ]; then caseArg="--migration-test-case \"${case}\""; fi
          xvfb-run -a python main.py --enable-migration-test --old-version "${OLD_VERSION}" --new-version "${NEW_VERSION}" --max-turns ${{ inputs.max_turns }} ${caseArg}

      - name: Upload screen recordings
        if: always()
        uses: actions/upload-artifact@v4
        continue-on-error: true
        with:
          name: migration-recordings-${{ github.run_number }}-ubuntu
          path: autoqa/recordings/

      - name: Upload trajectories
        if: always()
        uses: actions/upload-artifact@v4
        continue-on-error: true
        with:
          name: migration-trajectories-${{ github.run_number }}-ubuntu
          path: autoqa/trajectories/

      - name: Cleanup after tests
        if: always()
        run: |
          ./autoqa/scripts/ubuntu_post_cleanup.sh "false"

  migration-macos:
    if: inputs.old_macos_installer != '' && inputs.new_macos_installer != ''
    runs-on: macos-selfhosted-15-arm64-cua
    timeout-minutes: 60
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Python 3.13
        uses: actions/setup-python@v4
        with:
          python-version: '3.13'

      - name: Setup script permissions
        run: |
          chmod +x autoqa/scripts/setup_permissions.sh || true
          ./autoqa/scripts/setup_permissions.sh || true

      - name: Clean existing Jan installations
        run: |
          ./autoqa/scripts/macos_cleanup.sh

      - name: Download OLD and NEW installers
        run: |
          set -e
          # Download OLD installer using existing script
          ./autoqa/scripts/macos_download.sh \
            "${{ inputs.old_macos_installer }}" \
            "false" \
            "" \
            "" \
            "" \
            ""
          cp /tmp/jan-installer.dmg /tmp/jan-old.dmg

          # Download NEW installer using existing script
          ./autoqa/scripts/macos_download.sh \
            "${{ inputs.new_macos_installer }}" \
            "false" \
            "" \
            "" \
            "" \
            ""
          cp /tmp/jan-installer.dmg /tmp/jan-new.dmg

          echo "OLD_VERSION=/tmp/jan-old.dmg" >> $GITHUB_ENV
          echo "NEW_VERSION=/tmp/jan-new.dmg" >> $GITHUB_ENV

      - name: Install Python dependencies
        working-directory: autoqa
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Run migration tests (macOS)
        working-directory: autoqa
        run: |
          case="${{ inputs.migration_test_case }}"
          caseArg=""
          if [ -n "${case}" ]; then caseArg="--migration-test-case \"${case}\""; fi
          python main.py --enable-migration-test --old-version "${OLD_VERSION}" --new-version "${NEW_VERSION}" --max-turns ${{ inputs.max_turns }} ${caseArg}

      - name: Upload screen recordings
        if: always()
        uses: actions/upload-artifact@v4
        continue-on-error: true
        with:
          name: migration-recordings-${{ github.run_number }}-macos
          path: autoqa/recordings/

      - name: Upload trajectories
        if: always()
        uses: actions/upload-artifact@v4
        continue-on-error: true
        with:
          name: migration-trajectories-${{ github.run_number }}-macos
          path: autoqa/trajectories/

      - name: Cleanup after tests
        if: always()
        run: |
          ./autoqa/scripts/macos_post_cleanup.sh


autoqa-reliability .github/workflows/autoqa-reliability.yml
Triggers
workflow_dispatch
Runs on
windows-11-nvidia-gpu
Jobs
reliability-windows
Commands
  • .\autoqa\scripts\windows_cleanup.ps1 -IsNightly "${{ inputs.is_nightly }}"
  • .\autoqa\scripts\windows_download.ps1 ` -WorkflowInputUrl "${{ inputs.jan_app_windows_source }}" ` -WorkflowInputIsNightly "${{ inputs.is_nightly }}" ` -RepoVariableUrl "${{ vars.JAN_APP_URL }}" ` -RepoVariableIsNightly "${{ vars.IS_NIGHTLY }}" ` -DefaultUrl "$env:DEFAULT_JAN_APP_URL" ` -DefaultIsNightly "$env:DEFAULT_IS_NIGHTLY"
  • .\autoqa\scripts\windows_install.ps1 -IsNightly "$env:IS_NIGHTLY"
  • python -m pip install --upgrade pip pip install -r requirements.txt
  • $runs = "${{ inputs.reliability_runs }}" $runsArg = "" if ([int]$runs -gt 0) { $runsArg = "--reliability-runs $runs" } python main.py --enable-reliability-test --reliability-phase "${{ inputs.reliability_phase }}" --reliability-test-path "${{ inputs.reliability_test_path }}" $runsArg
  • .\autoqa\scripts\windows_post_cleanup.ps1 -IsNightly "${{ inputs.is_nightly }}"
View raw YAML
name: AutoQA Reliability (Manual)

on:
  workflow_dispatch:
    inputs:
      source_type:
        description: 'App source type (url)'
        required: true
        type: choice
        options: [url]
        default: url
      jan_app_windows_source:
        description: 'Windows installer URL path (used when source_type=url or to select artifact)'
        required: true
        type: string
        default: 'https://catalog.jan.ai/windows/Jan_0.6.8_x64-setup.exe'
      jan_app_ubuntu_source:
        description: 'Ubuntu .deb URL path'
        required: true
        type: string
        default: 'https://delta.jan.ai/nightly/Jan-nightly_0.6.4-728_amd64.deb'
      jan_app_macos_source:
        description: 'macOS .dmg URL path'
        required: true
        type: string
        default: 'https://delta.jan.ai/nightly/Jan-nightly_0.6.4-728_universal.dmg'
      is_nightly:
        description: 'Is the app a nightly build?'
        required: true
        type: boolean
        default: true
      reliability_phase:
        description: 'Reliability phase'
        required: true
        type: choice
        options: [development, deployment]
        default: development
      reliability_runs:
        description: 'Custom runs (0 uses phase default)'
        required: true
        type: number
        default: 0
      reliability_test_path:
        description: 'Test file path (relative to autoqa working directory)'
        required: true
        type: string
        default: 'tests/base/settings/app-data.txt'

jobs:
  reliability-windows:
    runs-on: windows-11-nvidia-gpu
    timeout-minutes: 60
    env:
      DEFAULT_JAN_APP_URL: 'https://catalog.jan.ai/windows/Jan_0.6.8_x64-setup.exe'
      DEFAULT_IS_NIGHTLY: 'false'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Python 3.13
        uses: actions/setup-python@v4
        with:
          python-version: '3.13'

      - name: Clean existing Jan installations
        shell: powershell
        run: |
          .\autoqa\scripts\windows_cleanup.ps1 -IsNightly "${{ inputs.is_nightly }}"

      - name: Download/Prepare Jan app
        shell: powershell
        run: |
          .\autoqa\scripts\windows_download.ps1 `
            -WorkflowInputUrl "${{ inputs.jan_app_windows_source }}" `
            -WorkflowInputIsNightly "${{ inputs.is_nightly }}" `
            -RepoVariableUrl "${{ vars.JAN_APP_URL }}" `
            -RepoVariableIsNightly "${{ vars.IS_NIGHTLY }}" `
            -DefaultUrl "$env:DEFAULT_JAN_APP_URL" `
            -DefaultIsNightly "$env:DEFAULT_IS_NIGHTLY"

      - name: Install Jan app
        shell: powershell
        run: |
          .\autoqa\scripts\windows_install.ps1 -IsNightly "$env:IS_NIGHTLY"

      - name: Install Python dependencies
        working-directory: autoqa
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Run reliability tests
        working-directory: autoqa
        shell: powershell
        run: |
          $runs = "${{ inputs.reliability_runs }}"
          $runsArg = ""
          if ([int]$runs -gt 0) { $runsArg = "--reliability-runs $runs" }
          python main.py --enable-reliability-test --reliability-phase "${{ inputs.reliability_phase }}" --reliability-test-path "${{ inputs.reliability_test_path }}" $runsArg

      - name: Upload screen recordings
        if: always()
        uses: actions/upload-artifact@v4
        continue-on-error: true
        with:
          name: reliability-recordings-${{ github.run_number }}-${{ runner.os }}
          path: autoqa/recordings/

      - name: Upload trajectories
        if: always()
        uses: actions/upload-artifact@v4
        continue-on-error: true
        with:
          name: reliability-trajectories-${{ github.run_number }}-${{ runner.os }}
          path: autoqa/trajectories/

      - name: Cleanup after tests
        if: always()
        shell: powershell
        run: |
          .\autoqa\scripts\windows_post_cleanup.ps1 -IsNightly "${{ inputs.is_nightly }}"
autoqa-template .github/workflows/autoqa-template.yml
Triggers
workflow_call
Runs on
windows-11-nvidia-gpu, ubuntu-22-04-nvidia-gpu, macos-selfhosted-15-arm64-cua
Jobs
windows, ubuntu, macos
Commands
  • .\autoqa\scripts\windows_cleanup.ps1 -IsNightly "${{ inputs.is_nightly }}"
  • if ("${{ inputs.source_type }}" -eq "local") { # Find the exe file in the artifact $exeFile = Get-ChildItem -Path "${{ runner.temp }}/windows-artifact" -Recurse -Filter "*.exe" | Select-Object -First 1 if ($exeFile) { Write-Host "[SUCCESS] Found local installer: $($exeFile.FullName)" Copy-Item -Path $exeFile.FullName -Destination "$env:TEMP\jan-installer.exe" -Force Write-Host "[SUCCESS] Installer copied to: $env:TEMP\jan-installer.exe" # Don't set JAN_APP_PATH here - let the install script set it to the correct installed app path echo "IS_NIGHTLY=${{ inputs.is_nightly }}" >> $env:GITHUB_ENV } else { Write-Error "[FAILED] No .exe file found in artifact" exit 1 } } else { # Use the existing download script for URLs .\autoqa\scripts\windows_download.ps1 ` -WorkflowInputUrl "${{ inputs.jan_app_windows_source }}" ` -WorkflowInputIsNightly "${{ inputs.is_nightly }}" ` -RepoVariableUrl "${{ vars.JAN_APP_URL }}" ` -RepoVariableIsNightly "${{ vars.IS_NIGHTLY }}" ` -DefaultUrl "$env:DEFAULT_JAN_APP_URL" ` -DefaultIsNightly "$env:DEFAULT_IS_NIGHTLY" }
  • .\autoqa\scripts\windows_install.ps1 -IsNightly "$env:IS_NIGHTLY"
  • python -m pip install --upgrade pip pip install -r requirements.txt
  • .\scripts\run_tests.ps1 -JanAppPath "$env:JAN_APP_PATH" -ProcessName "$env:JAN_PROCESS_NAME" -RpToken "$env:RP_TOKEN"
  • $logDirs = @( "$env:APPDATA\Jan-nightly\data\logs", "$env:APPDATA\Jan\data\logs" ) $dest = "autoqa\jan-logs" mkdir $dest -Force | Out-Null foreach ($dir in $logDirs) { if (Test-Path $dir) { Copy-Item "$dir\*.log" $dest -Force -ErrorAction SilentlyContinue } }
  • .\autoqa\scripts\windows_post_cleanup.ps1 -IsNightly "${{ inputs.is_nightly }}"
  • sudo apt-get update sudo apt-get install -y \ x11-utils \ python3-tk \ python3-dev \ wmctrl \ xdotool \ libnss3-dev \ libgconf-2-4 \ libxss1 \ libasound2 \ libxtst6 \ libgtk-3-0 \ libgbm-dev \ libxshmfence1 \ libxrandr2 \ libpangocairo-1.0-0 \ libatk1.0-0 \ libcairo-gobject2 \ libgdk-pixbuf2.0-0 \ gnome-screenshot
View raw YAML
name: Auto QA Test Runner Template

on:
  workflow_call:
    inputs:
      jan_app_windows_source:
        description: 'Windows app source - can be URL or local path'
        required: true
        type: string
      jan_app_ubuntu_source:
        description: 'Ubuntu app source - can be URL or local path'
        required: true
        type: string
      jan_app_macos_source:
        description: 'macOS app source - can be URL or local path'
        required: true
        type: string
      is_nightly:
        description: 'Is this a nightly build?'
        required: true
        type: boolean
        default: true
      source_type:
        description: 'Source type: url or local'
        required: true
        type: string
        default: 'url'
      artifact_name_windows:
        description: 'Windows artifact name (only needed for local)'
        required: false
        type: string
        default: ''
      artifact_name_ubuntu:
        description: 'Ubuntu artifact name (only needed for local)'
        required: false
        type: string
        default: ''
      artifact_name_macos:
        description: 'macOS artifact name (only needed for local)'
        required: false
        type: string
        default: ''
    secrets:
      RP_TOKEN:
        description: 'ReportPortal API token'
        required: true

jobs:
  windows:
    runs-on: windows-11-nvidia-gpu
    timeout-minutes: 60

    env:
      DEFAULT_JAN_APP_URL: 'https://catalog.jan.ai/windows/Jan-nightly_0.6.5-758_x64-setup.exe'
      DEFAULT_IS_NIGHTLY: 'true'

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Python 3.13
        uses: actions/setup-python@v4
        with:
          python-version: '3.13'

      - name: Download artifact (if source_type is local)
        if: inputs.source_type == 'local'
        uses: actions/download-artifact@v4
        with:
          name: ${{ inputs.artifact_name_windows }}
          path: ${{ runner.temp }}/windows-artifact

      - name: Clean existing Jan installations
        shell: powershell
        run: |
          .\autoqa\scripts\windows_cleanup.ps1 -IsNightly "${{ inputs.is_nightly }}"

      - name: Download/Prepare Jan app
        shell: powershell
        run: |
          if ("${{ inputs.source_type }}" -eq "local") {
            # Find the exe file in the artifact
            $exeFile = Get-ChildItem -Path "${{ runner.temp }}/windows-artifact" -Recurse -Filter "*.exe" | Select-Object -First 1
            if ($exeFile) {
              Write-Host "[SUCCESS] Found local installer: $($exeFile.FullName)"
              Copy-Item -Path $exeFile.FullName -Destination "$env:TEMP\jan-installer.exe" -Force
              Write-Host "[SUCCESS] Installer copied to: $env:TEMP\jan-installer.exe"
              # Don't set JAN_APP_PATH here - let the install script set it to the correct installed app path
              echo "IS_NIGHTLY=${{ inputs.is_nightly }}" >> $env:GITHUB_ENV
            } else {
              Write-Error "[FAILED] No .exe file found in artifact"
              exit 1
            }
          } else {
            # Use the existing download script for URLs
            .\autoqa\scripts\windows_download.ps1 `
              -WorkflowInputUrl "${{ inputs.jan_app_windows_source }}" `
              -WorkflowInputIsNightly "${{ inputs.is_nightly }}" `
              -RepoVariableUrl "${{ vars.JAN_APP_URL }}" `
              -RepoVariableIsNightly "${{ vars.IS_NIGHTLY }}" `
              -DefaultUrl "$env:DEFAULT_JAN_APP_URL" `
              -DefaultIsNightly "$env:DEFAULT_IS_NIGHTLY"
          }

      - name: Install Jan app
        shell: powershell
        run: |
          .\autoqa\scripts\windows_install.ps1 -IsNightly "$env:IS_NIGHTLY"

      - name: Install Python dependencies
        working-directory: autoqa
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Run Auto QA Tests
        working-directory: autoqa
        shell: powershell
        env:
          RP_TOKEN: ${{ secrets.RP_TOKEN }}
          ENABLE_REPORTPORTAL: 'true'
          RP_ENDPOINT: 'https://reportportal.menlo.ai'
          RP_PROJECT: 'default_personal'
          MAX_TURNS: '50'
          DELAY_BETWEEN_TESTS: '3'
          LAUNCH_NAME: 'CI AutoQA Run Windows - ${{ github.run_number }} - ${{ github.ref_name }}'
        run: |
          .\scripts\run_tests.ps1 -JanAppPath "$env:JAN_APP_PATH" -ProcessName "$env:JAN_PROCESS_NAME" -RpToken "$env:RP_TOKEN"

      - name: Collect Jan logs for artifact upload
        if: always()
        shell: powershell
        run: |
          $logDirs = @(
            "$env:APPDATA\Jan-nightly\data\logs",
            "$env:APPDATA\Jan\data\logs"
          )
          $dest = "autoqa\jan-logs"
          mkdir $dest -Force | Out-Null
          foreach ($dir in $logDirs) {
            if (Test-Path $dir) {
              Copy-Item "$dir\*.log" $dest -Force -ErrorAction SilentlyContinue
            }
          }

      - name: Upload screen recordings
        if: always()
        uses: actions/upload-artifact@v4
        continue-on-error: true
        with:
          name: ${{ inputs.is_nightly && 'jan-nightly' || 'jan' }}-recordings-${{ github.run_number }}-${{ runner.os }}
          path: autoqa/recordings/

      - name: Upload Jan logs
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: ${{ inputs.is_nightly && 'jan-nightly' || 'jan' }}-logs-${{ github.run_number }}-${{ runner.os }}
          path: autoqa/jan-logs/

      - name: Cleanup after tests
        if: always()
        shell: powershell
        run: |
          .\autoqa\scripts\windows_post_cleanup.ps1 -IsNightly "${{ inputs.is_nightly }}"

  ubuntu:
    runs-on: ubuntu-22-04-nvidia-gpu
    timeout-minutes: 60

    env:
      DEFAULT_JAN_APP_URL: 'https://delta.jan.ai/nightly/Jan-nightly_0.6.4-728_amd64.deb'
      DEFAULT_IS_NIGHTLY: 'true'

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Python 3.13
        uses: actions/setup-python@v4
        with:
          python-version: '3.13'

      - name: Download artifact (if source_type is local)
        if: inputs.source_type == 'local'
        uses: actions/download-artifact@v4
        with:
          name: ${{ inputs.artifact_name_ubuntu }}
          path: ${{ runner.temp }}/ubuntu-artifact

      - name: Install system dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y \
            x11-utils \
            python3-tk \
            python3-dev \
            wmctrl \
            xdotool \
            libnss3-dev \
            libgconf-2-4 \
            libxss1 \
            libasound2 \
            libxtst6 \
            libgtk-3-0 \
            libgbm-dev \
            libxshmfence1 \
            libxrandr2 \
            libpangocairo-1.0-0 \
            libatk1.0-0 \
            libcairo-gobject2 \
            libgdk-pixbuf2.0-0 \
            gnome-screenshot

      - name: Setup script permissions
        run: |
          chmod +x autoqa/scripts/setup_permissions.sh
          ./autoqa/scripts/setup_permissions.sh

      - name: Clean existing Jan installations
        run: |
          ./autoqa/scripts/ubuntu_cleanup.sh

      - name: Download/Prepare Jan app
        run: |
          if [ "${{ inputs.source_type }}" = "local" ]; then
            # Find the deb file in the artifact
            DEB_FILE=$(find "${{ runner.temp }}/ubuntu-artifact" -name "*.deb" -type f | head -1)
            if [ -n "$DEB_FILE" ]; then
              echo "[SUCCESS] Found local installer: $DEB_FILE"
              cp "$DEB_FILE" "/tmp/jan-installer.deb"
              echo "[SUCCESS] Installer copied to: /tmp/jan-installer.deb"
              echo "JAN_APP_PATH=/tmp/jan-installer.deb" >> $GITHUB_ENV
              echo "IS_NIGHTLY=${{ inputs.is_nightly }}" >> $GITHUB_ENV
              if [ "${{ inputs.is_nightly }}" = "true" ]; then
                echo "JAN_PROCESS_NAME=Jan-nightly" >> $GITHUB_ENV
              else
                echo "JAN_PROCESS_NAME=Jan" >> $GITHUB_ENV
              fi
            else
              echo "[FAILED] No .deb file found in artifact"
              exit 1
            fi
          else
            # Use the existing download script for URLs
            ./autoqa/scripts/ubuntu_download.sh \
              "${{ inputs.jan_app_ubuntu_source }}" \
              "${{ inputs.is_nightly }}" \
              "${{ vars.JAN_APP_URL_LINUX }}" \
              "${{ vars.IS_NIGHTLY }}" \
              "$DEFAULT_JAN_APP_URL" \
              "$DEFAULT_IS_NIGHTLY"
            
            # Set the correct environment variables for the test runner
            echo "JAN_APP_PATH=/tmp/jan-installer.deb" >> $GITHUB_ENV
            if [ "${{ inputs.is_nightly }}" = "true" ]; then
              echo "JAN_PROCESS_NAME=Jan-nightly" >> $GITHUB_ENV
            else
              echo "JAN_PROCESS_NAME=Jan" >> $GITHUB_ENV
            fi
          fi

      - name: Install Jan app
        run: |
          ./autoqa/scripts/ubuntu_install.sh "$IS_NIGHTLY"

      - name: Install Python dependencies
        working-directory: autoqa
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Run Auto QA Tests
        working-directory: autoqa
        env:
          RP_TOKEN: ${{ secrets.RP_TOKEN }}
          ENABLE_REPORTPORTAL: 'true'
          RP_ENDPOINT: 'https://reportportal.menlo.ai'
          RP_PROJECT: 'default_personal'
          MAX_TURNS: '50'
          DELAY_BETWEEN_TESTS: '3'
          LAUNCH_NAME: 'CI AutoQA Run Ubuntu - ${{ github.run_number }} - ${{ github.ref_name }}'
        run: |
          ./scripts/run_tests.sh "$JAN_APP_PATH" "$JAN_PROCESS_NAME" "$RP_TOKEN" "ubuntu"

      - name: Collect Jan logs for artifact upload
        if: always()
        run: |
          mkdir -p autoqa/jan-logs
          cp ~/.local/share/Jan-nightly/data/logs/*.log autoqa/jan-logs/ 2>/dev/null || true
          cp ~/.local/share/Jan/data/logs/*.log autoqa/jan-logs/ 2>/dev/null || true

      - name: Upload screen recordings
        if: always()
        uses: actions/upload-artifact@v4
        continue-on-error: true
        with:
          name: ${{ inputs.is_nightly && 'jan-nightly' || 'jan' }}-recordings-${{ github.run_number }}-${{ runner.os }}
          path: autoqa/recordings/

      - name: Upload Jan logs
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: ${{ inputs.is_nightly && 'jan-nightly' || 'jan' }}-logs-${{ github.run_number }}-${{ runner.os }}
          path: autoqa/jan-logs/

      - name: Cleanup after tests
        if: always()
        run: |
          ./autoqa/scripts/ubuntu_post_cleanup.sh "$IS_NIGHTLY"

  macos:
    runs-on: macos-selfhosted-15-arm64-cua
    timeout-minutes: 60

    env:
      DEFAULT_JAN_APP_URL: 'https://delta.jan.ai/nightly/Jan-nightly_0.6.4-728_universal.dmg'
      DEFAULT_IS_NIGHTLY: 'true'

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Python 3.13
        uses: actions/setup-python@v4
        with:
          python-version: '3.13'

      - name: Download artifact (if source_type is local)
        if: inputs.source_type == 'local'
        uses: actions/download-artifact@v4
        with:
          name: ${{ inputs.artifact_name_macos }}
          path: ${{ runner.temp }}/macos-artifact

      - name: Setup script permissions
        run: |
          chmod +x autoqa/scripts/setup_permissions.sh
          ./autoqa/scripts/setup_permissions.sh

      - name: Clean existing Jan installations
        run: |
          ./autoqa/scripts/macos_cleanup.sh

      - name: Download/Prepare Jan app
        run: |
          if [ "${{ inputs.source_type }}" = "local" ]; then
            # Find the dmg file in the artifact
            DMG_FILE=$(find "${{ runner.temp }}/macos-artifact" -name "*.dmg" -type f | head -1)
            if [ -n "$DMG_FILE" ]; then
              echo "[SUCCESS] Found local installer: $DMG_FILE"
              cp "$DMG_FILE" "/tmp/jan-installer.dmg"
              echo "[SUCCESS] Installer copied to: /tmp/jan-installer.dmg"
              echo "JAN_APP_PATH=/tmp/jan-installer.dmg" >> $GITHUB_ENV
              echo "IS_NIGHTLY=${{ inputs.is_nightly }}" >> $GITHUB_ENV
              if [ "${{ inputs.is_nightly }}" = "true" ]; then
                echo "PROCESS_NAME=Jan-nightly" >> $GITHUB_ENV
              else
                echo "PROCESS_NAME=Jan" >> $GITHUB_ENV
              fi
            else
              echo "[FAILED] No .dmg file found in artifact"
              exit 1
            fi
          else
            # Use the existing download script for URLs
            ./autoqa/scripts/macos_download.sh \
              "${{ inputs.jan_app_macos_source }}" \
              "${{ inputs.is_nightly }}" \
              "${{ vars.JAN_APP_URL }}" \
              "${{ vars.IS_NIGHTLY }}" \
              "$DEFAULT_JAN_APP_URL" \
              "$DEFAULT_IS_NIGHTLY"
            
            # Set the correct environment variables for the test runner
            echo "JAN_APP_PATH=/tmp/jan-installer.dmg" >> $GITHUB_ENV
            if [ "${{ inputs.is_nightly }}" = "true" ]; then
              echo "PROCESS_NAME=Jan-nightly" >> $GITHUB_ENV
            else
              echo "PROCESS_NAME=Jan" >> $GITHUB_ENV
            fi
          fi

      - name: Install Jan app
        run: |
          ./autoqa/scripts/macos_install.sh

      - name: Install system dependencies
        run: |
          echo "Installing system dependencies for macOS..."

          # Check if Homebrew is available
          if command -v brew >/dev/null 2>&1; then
            echo "Homebrew is available"
            
            # Install python-tk if not available
            python3 -c "import tkinter" 2>/dev/null || {
              echo "Installing python-tk via Homebrew..."
              brew install python-tk || true
            }
          else
            echo "Homebrew not available, checking if tkinter works..."
            python3 -c "import tkinter" || {
              echo "[WARNING] tkinter not available and Homebrew not found"
              echo "This may cause issues with mouse control"
            }
          fi

          echo "System dependencies check completed"

      - name: Install Python dependencies
        run: |
          cd autoqa
          echo "Installing Python dependencies..."
          pip install --upgrade pip
          pip install -r requirements.txt
          echo "[SUCCESS] Python dependencies installed"

      - name: Setup ReportPortal environment
        run: |
          echo "Setting up ReportPortal environment..."
          echo "RP_TOKEN=${{ secrets.RP_TOKEN }}" >> $GITHUB_ENV
          echo "ReportPortal environment configured"

      - name: Run E2E tests
        env:
          RP_TOKEN: ${{ secrets.RP_TOKEN }}
          ENABLE_REPORTPORTAL: 'true'
          RP_ENDPOINT: 'https://reportportal.menlo.ai'
          RP_PROJECT: 'default_personal'
          MAX_TURNS: '50'
          DELAY_BETWEEN_TESTS: '3'
          LAUNCH_NAME: 'CI AutoQA Run Macos - ${{ github.run_number }} - ${{ github.ref_name }}'
        run: |
          cd autoqa
          echo "Starting E2E test execution..."

          echo "Environment variables:"
          echo "JAN_APP_PATH: $JAN_APP_PATH"
          echo "PROCESS_NAME: $PROCESS_NAME"
          echo "IS_NIGHTLY: $IS_NIGHTLY"

          ./scripts/run_tests.sh "$JAN_APP_PATH" "$PROCESS_NAME" "$RP_TOKEN" "macos"

      - name: Collect Jan logs for artifact upload
        if: always()
        run: |
          mkdir -p autoqa/jan-logs
          cp ~/Library/Application\ Support/Jan-nightly/data/logs/*.log autoqa/jan-logs/ 2>/dev/null || true
          cp ~/Library/Application\ Support/Jan/data/logs/*.log autoqa/jan-logs/ 2>/dev/null || true

      - name: Upload screen recordings
        if: always()
        uses: actions/upload-artifact@v4
        continue-on-error: true
        with:
          name: ${{ inputs.is_nightly && 'jan-nightly' || 'jan' }}-recordings-${{ github.run_number }}-${{ runner.os }}
          path: autoqa/recordings/

      - name: Upload Jan logs
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: ${{ inputs.is_nightly && 'jan-nightly' || 'jan' }}-logs-${{ github.run_number }}-${{ runner.os }}
          path: autoqa/jan-logs/

      - name: Cleanup after tests
        if: always()
        run: |
          ./autoqa/scripts/macos_post_cleanup.sh
clean-cloudflare-page-preview-url-and-r2 matrix .github/workflows/clean-cloudflare-page-preview-url-and-r2.yml
Triggers
schedule, workflow_dispatch
Runs on
ubuntu-latest
Jobs
clean-cloudflare-pages-preview-urls
Matrix
project→ docs, nitro
Actions
jannekem/run-python-script-action
Commands
  • python3 -m pip install requests pytz tqdm
View raw YAML
name: "Clean old cloudflare pages preview urls and nightly build"
on:
  schedule:
    - cron: "0 0 * * *" # every day at 00:00
  workflow_dispatch:

jobs:
  clean-cloudflare-pages-preview-urls:
    strategy:
      matrix:
        project: ["nitro", "docs"]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-python@v4
        with:
          python-version: '3.x'
      - name: install requests
        run: |
          python3 -m pip install requests pytz tqdm
      - name: Python Inline script
        uses: jannekem/run-python-script-action@v1
        with: 
          script: |
            import requests
            from datetime import datetime, UTC
            from pytz import timezone
            from tqdm import tqdm
            
            # Configuration
            endpoint = "https://api.cloudflare.com/client/v4/accounts/${{ secrets.CLOUDFLARE_ACCOUNT_ID }}/pages/projects/${{ matrix.project }}/deployments"
            expiration_days = 3
            headers = {
                "Content-Type": "application/json;charset=UTF-8",
                "Authorization": "Bearer ${{ secrets.CLOUDFLARE_API_TOKEN }}"
            }
            utc_tz = timezone('UTC')

            # Fetch the list of deployments
            response = requests.get(endpoint, headers=headers)
            deployments = response.json()

            for deployment in tqdm(deployments['result']):
                # Calculate the age of the deployment
                created_on = datetime.strptime(deployment['created_on'], "%Y-%m-%dT%H:%M:%S.%fZ").replace(tzinfo=utc_tz)
                if (datetime.now(UTC) - created_on).days > expiration_days:
                    # Delete the deployment
                    delete_response = requests.delete(f"{endpoint}/{deployment['id']}", headers=headers)
                    if delete_response.status_code == 200:
                        print(f"Deleted deployment: {deployment['id']}")
                    else:
                        print(f"Failed to delete deployment: {deployment['id']}")

issues .github/workflows/issues.yaml
Triggers
issues
Runs on
ubuntu-latest
Jobs
add-to-project
Actions
actions/add-to-project
View raw YAML
name: Adds all issues to project board

on:
  issues:
    types:
      - opened

jobs:
  add-to-project:
    name: Add issue to project
    runs-on: ubuntu-latest
    steps:
      - uses: actions/add-to-project@v1.0.2
        with:
          project-url: https://github.com/orgs/${{ vars.ORG_NAME }}/projects/${{ vars.JAN_PROJECT_NUMBER }}
          github-token: ${{ secrets.AUTO_ADD_TICKET_PAT }}
jan-docs .github/workflows/jan-docs.yml
Triggers
push, pull_request, workflow_dispatch
Runs on
ubuntu-latest
Jobs
deploy
Actions
dcarbone/install-jq-action, cloudflare/pages-action, mshick/add-pr-comment, cloudflare/pages-action
Commands
  • corepack enable corepack prepare yarn@4.5.3 --activate yarn --version yarn config set -H enableImmutableInstalls false
  • env_example_file=".env.example" touch .env while IFS= read -r line || [[ -n "$line" ]]; do if [[ "$line" == *"="* ]]; then var_name=$(echo $line | cut -d '=' -f 1) echo $var_name var_value="$(jq -r --arg key "$var_name" '.[$key]' <<< "$SECRETS")" echo "$var_name=$var_value" >> .env fi done < "$env_example_file"
  • yarn install
  • rm -rf out/* .next/*
  • export NODE_ENV=production && yarn build && cp _redirects out/_redirects && cp _headers out/_headers
View raw YAML
name: Jan Docs

on:
  push:
    branches:
      - main
    paths:
      - 'docs/**'
      - '.github/workflows/jan-docs.yml'
  pull_request:
    paths:
      - 'docs/**'
      - '.github/workflows/jan-docs.yml'
    # Review gh actions docs if you want to further define triggers, paths, etc
    # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
  workflow_dispatch:

jobs:
  deploy:
    name: Deploy to CloudFlare Pages
    env:
      CLOUDFLARE_PROJECT_NAME: docs
    runs-on: ubuntu-latest
    permissions:
      contents: write
      deployments: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: Install jq      
        uses: dcarbone/install-jq-action@v2.0.1

      - name: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Fill env vars
        working-directory: docs
        run: |
          env_example_file=".env.example"
          touch .env
          while IFS= read -r line || [[ -n "$line" ]]; do
            if [[ "$line" == *"="* ]]; then
              var_name=$(echo $line | cut -d '=' -f 1)
              echo $var_name
              var_value="$(jq -r --arg key "$var_name" '.[$key]' <<< "$SECRETS")"
              echo "$var_name=$var_value" >> .env
            fi
          done < "$env_example_file"
        env:
          SECRETS: '${{ toJson(secrets) }}'

      - name: Install dependencies
        working-directory: docs
        run: yarn install
      - name: Clean output directory
        working-directory: docs
        run: rm -rf out/* .next/*
      - name: Build website
        working-directory: docs
        run: export NODE_ENV=production && yarn build && cp _redirects out/_redirects && cp _headers out/_headers

      - name: Publish to Cloudflare Pages PR Preview and Staging
        if: github.event_name == 'pull_request'
        uses: cloudflare/pages-action@v1
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          projectName: ${{ env.CLOUDFLARE_PROJECT_NAME }}
          directory: ./docs/out
          # Optional: Enable this if you want to have GitHub Deployments triggered
          gitHubToken: ${{ secrets.GITHUB_TOKEN }}
        id: deployCloudflarePages

      - uses: mshick/add-pr-comment@v2
        if: github.event_name == 'pull_request'
        with:
          message: |
              Preview URL: ${{ steps.deployCloudflarePages.outputs.url }}

      - name: Publish to Cloudflare Pages Production
        if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') || (github.event_name == 'workflow_dispatch' && startsWith(github.ref, 'refs/heads/release/'))
        uses: cloudflare/pages-action@v1
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          projectName: ${{ env.CLOUDFLARE_PROJECT_NAME }}
          directory: ./docs/out
          branch: main
          # Optional: Enable this if you want to have GitHub Deployments triggered
          gitHubToken: ${{ secrets.GITHUB_TOKEN }}
jan-linter-and-test matrix .github/workflows/jan-linter-and-test.yml
Triggers
workflow_dispatch, push, pull_request
Runs on
ubuntu-latest, macos-latest, windows-desktop-${{ matrix.antivirus-tools }}, windows-latest, ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) && 'ubuntu-latest' || 'ubuntu-latest' }}, ubuntu-latest
Jobs
base_branch_cov, test-on-macos, test-on-windows, test-on-windows-pr, test-on-ubuntu, coverage-check
Matrix
antivirus-tools→ bit-defender, mcafee
Actions
jlumbroso/free-disk-space, barecheck/code-coverage-action
Commands
  • rm -rf ~/jan make clean
  • corepack enable corepack prepare yarn@4.5.3 --activate yarn --version yarn config set -H enableImmutableInstalls false
  • make lint
  • yarn test:coverage
  • rm -rf ~/jan make clean
  • corepack enable corepack prepare yarn@4.5.3 --activate yarn --version yarn config set -H enableImmutableInstalls false
  • sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer
  • make test
View raw YAML
name: Linter & Test
on:
  workflow_dispatch:
  push:
    branches:
      - main
    paths:
      - .github/workflows/jan-linter-and-test.yml
      - 'web/**'
      - 'joi/**'
      - 'package.json'
      - 'node_modules/**'
      - 'yarn.lock'
      - 'core/**'
      - 'extensions/**'
      - '!README.md'
      - 'Makefile'

  pull_request:
    branches:
      - main
      - release/**
    paths:
      - .github/workflows/jan-linter-and-test.yml
      - 'web/**'
      - 'joi/**'
      - 'package.json'
      - 'node_modules/**'
      - 'yarn.lock'
      - 'Makefile'
      - 'extensions/**'
      - 'core/**'
      - 'src-tauri/**'
      - 'web-app/**'
      - '!README.md'

jobs:
  base_branch_cov:
    if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
    runs-on: ubuntu-latest
    continue-on-error: true
    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ github.base_ref }}
      - name: Use Node.js 20.x
        uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: 'Cleanup cache'
        continue-on-error: true
        run: |
          rm -rf ~/jan
          make clean

      - name: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Install dependencies
        run: |
          make lint

      - name: Run test coverage
        run: |
          yarn test:coverage

      - name: Upload code coverage for ref branch
        uses: actions/upload-artifact@v4
        with:
          name: ref-lcov.info
          path: coverage/lcov.info

  test-on-macos:
    runs-on: 'macos-latest'
    if: github.event_name == 'pull_request' || github.event_name == 'push' || github.event_name == 'workflow_dispatch'
    steps:
      - name: Getting the repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Installing node
        uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: 'Cleanup cache'
        continue-on-error: true
        run: |
          rm -rf ~/jan
          make clean

      - name: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Set up Xcode version
        run: sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer

      - name: Linter and test
        run: |
          make test
        env:
          CSC_IDENTITY_AUTO_DISCOVERY: 'false'

  test-on-windows:
    if: github.event_name == 'push'
    strategy:
      fail-fast: false
      matrix:
        antivirus-tools: ['mcafee', 'bit-defender']
    runs-on: windows-desktop-${{ matrix.antivirus-tools }}
    steps:
      - name: Getting the repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Installing node
        uses: actions/setup-node@v3
        with:
          node-version: 20

      # Clean cache, continue on error
      - name: 'Cleanup cache'
        shell: powershell
        continue-on-error: true
        run: |
          $path = "$Env:APPDATA\jan"
          if (Test-Path $path) {
              Remove-Item "\\?\$path" -Recurse -Force
          } else {
              Write-Output "Folder does not exist."
          }
          make clean

      - name: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Linter and test
        shell: powershell
        run: |
          make test

  test-on-windows-pr:
    if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
    runs-on: 'windows-latest'
    steps:
      - name: Getting the repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: install dependencies
        run: |
          choco install --yes --no-progress make

      - name: Installing node
        uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: 'Cleanup cache'
        shell: powershell
        continue-on-error: true
        run: |
          $path = "$Env:APPDATA\jan"
          if (Test-Path $path) {
              Remove-Item "\\?\$path" -Recurse -Force
          } else {
              Write-Output "Folder does not exist."
          }
          make clean

      - name: Install WebView2 Runtime (Bootstrapper)
        shell: powershell
        run: |
          Invoke-WebRequest -Uri 'https://go.microsoft.com/fwlink/p/?LinkId=2124703' -OutFile 'setup.exe'
          Start-Process -FilePath setup.exe -Verb RunAs -Wait

      - name: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Linter and test
        shell: powershell
        run: |
          make test
        env:
          NODE_OPTIONS: '--max-old-space-size=2048'

  test-on-ubuntu:
    runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) && 'ubuntu-latest' || 'ubuntu-latest' }}
    if: github.event_name == 'pull_request' || github.event_name == 'push' || github.event_name == 'workflow_dispatch'
    steps:
      - name: Getting the repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Free Disk Space (Ubuntu)
        uses: jlumbroso/free-disk-space@v1.3.1
        with:
          tool-cache: false
          android: true
          dotnet: true
          haskell: true
          large-packages: true
          docker-images: true
          swap-storage: true

      - name: Installing node
        uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: Install Tauri dependencies
        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 webkit2gtk-driver

      - name: 'Cleanup cache'
        continue-on-error: true
        run: |
          rm -rf ~/jan
          make clean

      - name: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Linter and test
        run: |
          export DISPLAY=$(w -h | awk 'NR==1 {print $2}')
          echo -e "Display ID: $DISPLAY"
          make test

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: electron/playwright-report/
          retention-days: 2

  coverage-check:
    if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
    runs-on: ubuntu-latest
    needs: base_branch_cov
    continue-on-error: true
    steps:
      - name: Getting the repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Installing node
        uses: actions/setup-node@v3
        with:
          node-version: 20
      - name: 'Cleanup cache'
        continue-on-error: true
        run: |
          rm -rf ~/jan
          make clean

      - name: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Install dependencies
        run: |
          make lint

      - name: Run test coverage
        run: |
          yarn test:coverage

      - name: Download code coverage report from base branch
        uses: actions/download-artifact@v4
        with:
          name: ref-lcov.info
      - name: Generate Code Coverage report
        id: code-coverage
        uses: barecheck/code-coverage-action@v1
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          lcov-file: './coverage/lcov.info'
          base-lcov-file: './lcov.info'
          send-summary-comment: true
          show-annotations: 'warning'
jan-tauri-build .github/workflows/jan-tauri-build.yaml
Triggers
push
Runs on
ubuntu-latest, ubuntu-latest
Jobs
get-update-version, create-draft-release, build-macos, build-windows-x64, build-linux-x64, sync-temp-to-latest
Actions
softprops/action-gh-release, actions/upload-release-asset
Commands
  • echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV && echo "::set-output name=version::${GITHUB_REF#refs/tags/v}"
  • 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/janhq/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/janhq/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/janhq/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
View raw YAML
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
          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
      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/janhq/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/janhq/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/janhq/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
jan-tauri-build-flatpak .github/workflows/jan-tauri-build-flatpak.yaml
Triggers
workflow_dispatch
Runs on
Jobs
build-linux-x64-flatpak
View raw YAML
name: Tauri Builder Flatpak

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to build. For example: 0.6.8'
        required: false
      public_provider:
        type: choice
        description: 'Public Provider'
        options:
          - none
          - aws-s3
        default: none

jobs:
  build-linux-x64-flatpak:
    uses: ./.github/workflows/template-tauri-build-linux-x64-flatpak.yml
    secrets: inherit
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
    with:
      ref: ${{ github.ref }}
      public_provider: ${{ inputs.public_provider }}
      new_version: ${{ inputs.version }}
      channel: stable
      disable_updater: true
jan-tauri-build-nightly .github/workflows/jan-tauri-build-nightly.yaml
Triggers
schedule, workflow_dispatch, pull_request
Runs on
ubuntu-latest, ubuntu-22.04, ubuntu-latest
Jobs
set-public-provider, get-update-version, build-macos, build-windows-x64, build-linux-x64, sync-temp-to-latest, comment-pr-build-url
Actions
dcarbone/install-jq-action
Commands
  • 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/main" 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
  • 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
  • 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/
  • 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/
  • 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"
View raw YAML
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
      disable_updater:
        type: boolean
        description: 'If true, builds both .deb and .appimage but disables auto-updater'
        default: false
  pull_request:
    branches:
      - release/**
      - main
    paths:
      - '.github/workflows/jan-tauri-build-nightly.yaml'
      - '.github/workflows/template-get-update-version.yml'
      - '.github/workflows/template-tauri-build-macos.yml'
      - '.github/workflows/template-tauri-build-windows-x64.yml'
      - '.github/workflows/template-tauri-build-linux-x64.yml'
      - '.github/workflows/template-noti-discord-and-update-url-readme.yml'
      - 'src-tauri/**'
      - 'core/**'
      - 'web-app/**'
      - 'extensions/**'
      - 'scripts/**'
      - 'pre-install/**'
      - 'Makefile'
      - 'package.json'


jobs:
  set-public-provider:
    runs-on: ubuntu-latest
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
    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/main"
            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:
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
    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]
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
    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]
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
    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]
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
    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'
      disable_updater: ${{ github.event.inputs.disable_updater == 'true' }}

  sync-temp-to-latest:
    needs:
      [
        get-update-version,
        set-public-provider,
        build-windows-x64,
        build-linux-x64,
        build-macos,
      ]
    runs-on: ubuntu-22.04
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
    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"
jan-tauri-build-nightly-external .github/workflows/jan-tauri-build-nightly-external.yaml
Triggers
pull_request
Runs on
Jobs
get-update-version, build-macos, build-windows-x64, build-linux-x64
View raw YAML
name: Tauri Builder - Nightly / External PRs

on:
  pull_request:
    branches:
      - main
    paths:
      - '.github/workflows/jan-tauri-build-nightly-external.yaml'
      - '.github/workflows/template-tauri-build-*-external.yml'
      - 'src-tauri/**'
      - 'core/**'
      - 'web-app/**'
      - 'extensions/**'
      - 'scripts/**'
      - 'pre-install/**'
      - 'Makefile'
      - 'package.json'

jobs:
  get-update-version:
    if: github.event.pull_request.head.repo.full_name != github.repository
    uses: ./.github/workflows/template-get-update-version.yml

  build-macos:
    if: github.event.pull_request.head.repo.full_name != github.repository
    uses: ./.github/workflows/template-tauri-build-macos-external.yml
    needs: [get-update-version]
    with:
      ref: ${{ github.ref }}
      new_version: ${{ needs.get-update-version.outputs.new_version }}
      channel: nightly

  build-windows-x64:
    if: github.event.pull_request.head.repo.full_name != github.repository
    uses: ./.github/workflows/template-tauri-build-windows-x64-external.yml
    needs: [get-update-version]
    with:
      ref: ${{ github.ref }}
      new_version: ${{ needs.get-update-version.outputs.new_version }}
      channel: nightly

  build-linux-x64:
    if: github.event.pull_request.head.repo.full_name != github.repository
    uses: ./.github/workflows/template-tauri-build-linux-x64-external.yml
    needs: [get-update-version]
    with:
      ref: ${{ github.ref }}
      new_version: ${{ needs.get-update-version.outputs.new_version }}
      channel: nightly
      disable_updater: false
manual-build-portable .github/workflows/manual-build-portable.yml
Triggers
workflow_dispatch
Runs on
Jobs
build-windows-portable
View raw YAML
name: Manual build portable (windows)

on:
  workflow_dispatch:
    inputs:
      build_ref:
        description: "Code ref to build (e.g. refs/tags/v0.7.5 or refs/heads/release/v0.7.5)"
        required: true
        default: "refs/tags/v0.7.5"
      version:
        description: "Version to stamp into the app"
        required: true
        default: "0.7.5"
      channel:
        description: "stable/beta/nightly"
        required: true
        default: "stable"

jobs:
  build-windows-portable:
    uses: janhq/jan/.github/workflows/template-tauri-build-windows-x64.yml@main
    secrets: inherit
    with:
      ref: ${{ inputs.build_ref }}
      public_provider: "none"
      channel: ${{ inputs.channel }}
      new_version: ${{ inputs.version }}
      upload_url: ""
publish-npm-core .github/workflows/publish-npm-core.yml
Triggers
push, workflow_dispatch
Runs on
ubuntu-latest
Jobs
build-and-publish-plugins
Actions
dcarbone/install-jq-action
Commands
  • echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV && echo "::set-output name=version::${GITHUB_REF#refs/tags/v}"
  • # Get the tag from the event tag=${GITHUB_REF#refs/tags/v} # remove the -core suffix new_version=$(echo $tag | sed -n 's/-core//p') echo $new_version # Replace the old version with the new version in package.json jq --arg version "$new_version" '.version = $version' core/package.json > /tmp/package.json && mv /tmp/package.json core/package.json # Print the new version echo "Updated package.json version to: $new_version" cat core/package.json
  • cd core && corepack enable && corepack prepare yarn@4.5.3 --activate && yarn --version && yarn config set -H enableImmutableInstalls false && yarn install && yarn build
  • cd core && yarn publish --access public
View raw YAML
name: Publish core Package to npmjs
on:
  push:
    tags: ['v[0-9]+.[0-9]+.[0-9]+-core']
    paths: ['core/**', '.github/workflows/publish-npm-core.yml']
  workflow_dispatch:
jobs:
  build-and-publish-plugins:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: '0'
          token: ${{ secrets.PAT_SERVICE_ACCOUNT }}

      - name: Install jq
        uses: dcarbone/install-jq-action@v2.0.1

      - 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: 'Get Semantic Version from tag'
        if: github.event_name == 'push'
        run: |
          # Get the tag from the event
          tag=${GITHUB_REF#refs/tags/v}
          # remove the -core suffix
          new_version=$(echo $tag | sed -n 's/-core//p')
          echo $new_version
          # Replace the old version with the new version in package.json
          jq --arg version "$new_version" '.version = $version' core/package.json > /tmp/package.json && mv /tmp/package.json core/package.json

          # Print the new version
          echo "Updated package.json version to: $new_version"
          cat core/package.json

      # Setup .npmrc file to publish to npm
      - uses: actions/setup-node@v3
        with:
          node-version: '20.x'
          registry-url: 'https://registry.npmjs.org'

      - run: cd core && corepack enable && corepack prepare yarn@4.5.3 --activate && yarn --version && yarn config set -H enableImmutableInstalls false && yarn install && yarn build

      - run: cd core && yarn publish --access public
        if: github.event_name == 'push'
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
template-get-update-version .github/workflows/template-get-update-version.yml
Triggers
workflow_call
Runs on
ubuntu-latest
Jobs
get-update-version
Actions
dcarbone/install-jq-action, dawidd6/action-get-tag
Commands
  • # Function to get the latest release tag get_latest_tag() { local retries=0 local max_retries=3 local tag while [ $retries -lt $max_retries ]; do tag=$(curl -H "Authorization: token ${GITHUB_TOKEN}" -s https://api.github.com/repos/janhq/jan/releases/latest | jq -r .tag_name) if [ -n "$tag" ] && [ "$tag" != "null" ]; then echo $tag return else let retries++ echo "Retrying... ($retries/$max_retries)" sleep 2 fi done echo "Failed to fetch latest tag after $max_retries attempts." exit 1 } if ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}; then echo "Tag detected, set output follow 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) # Remove the 'v' and append the build number to the version new_version="${LATEST_TAG#v}-${GITHUB_RUN_NUMBER}" echo "New version: $new_version" echo "::set-output name=new_version::$new_version" fi
View raw YAML
name: get-update-version
on:
  workflow_call:
    outputs:
      new_version:
        description: 'The new version of the app'
        value: ${{ jobs.get-update-version.outputs.new_version }}

jobs:
  get-update-version:
    runs-on: ubuntu-latest
    outputs:
      new_version: ${{ steps.version_update.outputs.new_version }}
    steps:
      - name: Install jq
        uses: dcarbone/install-jq-action@v2.0.1

      - name: Get tag
        if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
        id: tag
        uses: dawidd6/action-get-tag@v1

      - name: Update app version based on latest release tag with build number
        id: version_update
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          # Function to get the latest release tag
          get_latest_tag() {
            local retries=0
            local max_retries=3
            local tag
            while [ $retries -lt $max_retries ]; do
              tag=$(curl -H "Authorization: token ${GITHUB_TOKEN}" -s https://api.github.com/repos/janhq/jan/releases/latest | jq -r .tag_name)
              if [ -n "$tag" ] && [ "$tag" != "null" ]; then
                echo $tag
                return
              else
                let retries++
                echo "Retrying... ($retries/$max_retries)"
                sleep 2
              fi
            done
            echo "Failed to fetch latest tag after $max_retries attempts."
            exit 1
          }

            if ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}; then
            echo "Tag detected, set output follow 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)
            
            # Remove the 'v' and append the build number to the version
            new_version="${LATEST_TAG#v}-${GITHUB_RUN_NUMBER}"
            echo "New version: $new_version"
            echo "::set-output name=new_version::$new_version"
          fi
template-noti-discord-and-update-url-readme .github/workflows/template-noti-discord-and-update-url-readme.yml
Triggers
workflow_call
Runs on
ubuntu-latest
Jobs
noti-discord-and-update-url-readme
Actions
Ilshidur/action-discord
Commands
  • echo "VERSION=${{ inputs.new_version }}" >> $GITHUB_ENV
View raw YAML
name: noti-discord-and-update-url-readme
on:
  workflow_call:
    inputs:
      ref:
        required: true
        type: string
        default: 'refs/heads/main'
      build_reason:
        required: true
        type: string
        default: 'Nightly'
      push_to_branch:
        required: true
        type: string
        default: 'main'
      new_version:
        required: true
        type: string
        default: ''
    # secrets:
    #   PAT_SERVICE_ACCOUNT:
    #     required: false
    #   DISCORD_WEBHOOK:
    #     required: false

jobs:
  noti-discord-and-update-url-readme:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          fetch-depth: '0'
          token: ${{ secrets.PAT_SERVICE_ACCOUNT }}
          ref: ${{ inputs.ref }}

      - name: Set version to environment variable
        run: |
          echo "VERSION=${{ inputs.new_version }}" >> $GITHUB_ENV

      - name: Notify Discord
        uses: Ilshidur/action-discord@master
        with:
          args: |
            Jan App ${{ inputs.build_reason }} build artifact version {{ VERSION }}:
            - 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/janhq/jan/actions/runs/{{ GITHUB_RUN_ID }}
        env:
          DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
template-tauri-build-linux-x64 .github/workflows/template-tauri-build-linux-x64.yml
Triggers
workflow_call
Runs on
ubuntu-22.04
Jobs
build-linux-x64
Actions
dcarbone/install-jq-action, actions/upload-release-asset, actions/upload-release-asset
Commands
  • 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
  • cp .github/scripts/icon-${{ inputs.channel }}.png src-tauri/icons/icon.png
  • cargo install ctoml
  • 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 libappindicator3-dev
  • 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 if [ "${{ inputs.channel }}" != "stable" ]; then jq '.bundle.linux.deb.files = {"usr/bin/bun": "resources/bin/bun"}' ./src-tauri/tauri.linux.conf.json > /tmp/tauri.linux.conf.json mv /tmp/tauri.linux.conf.json ./src-tauri/tauri.linux.conf.json fi jq --arg version "${{ inputs.new_version }}" '.version = $version' web-app/package.json > /tmp/package.json mv /tmp/package.json web-app/package.json # Update tauri plugin versions jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------" cat ./src-tauri/plugins/tauri-plugin-hardware/package.json jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/Cargo.toml---------" cat ./src-tauri/Cargo.toml # Temporarily enable devtool on prod build ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" cat ./src-tauri/Cargo.toml # Change app name for beta and nightly builds if [ "${{ inputs.channel }}" != "stable" ]; then if [[ "${{ inputs.channel }}" == "nightly" ]]; then jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json else jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json fi 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 }}" ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}" ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" 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
  • corepack enable corepack prepare yarn@4.5.3 --activate yarn --version yarn config set -H enableImmutableInstalls false
  • make build APP_IMAGE=./src-tauri/target/release/bundle/appimage/$(ls ./src-tauri/target/release/bundle/appimage/ | grep AppImage | head -1) yarn tauri signer sign \ --private-key "$TAURI_SIGNING_PRIVATE_KEY" \ --password "$TAURI_SIGNING_PRIVATE_KEY_PASSWORD" \ "$APP_IMAGE"
  • 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
View raw YAML
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'
      disable_updater:
        required: false
        type: boolean
        default: false
        description: 'If true, builds both .deb and .appimage but disables auto-updater'
    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
      JAN_SIGNING_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 }}
    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 dependencies
        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 libappindicator3-dev

      - 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' ./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"}' ./src-tauri/tauri.linux.conf.json > /tmp/tauri.linux.conf.json
            mv /tmp/tauri.linux.conf.json ./src-tauri/tauri.linux.conf.json
          fi
          jq --arg version "${{ inputs.new_version }}" '.version = $version' web-app/package.json > /tmp/package.json
          mv /tmp/package.json web-app/package.json

          # Update tauri plugin versions

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/package.json

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml

          ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml

          ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/Cargo.toml---------"
          cat ./src-tauri/Cargo.toml

          # Temporarily enable devtool on prod build
          ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"
          cat ./src-tauri/Cargo.toml

          # Change app name for beta and nightly builds
          if [ "${{ inputs.channel }}" != "stable" ]; then
            if [[ "${{ inputs.channel }}" == "nightly" ]]; then
              jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            else
              jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            fi
            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 }}"
            ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}"
            ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"
            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: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Build app
        run: |
          make build

          APP_IMAGE=./src-tauri/target/release/bundle/appimage/$(ls ./src-tauri/target/release/bundle/appimage/ | grep AppImage | head -1)
          yarn tauri signer sign \
          --private-key "$TAURI_SIGNING_PRIVATE_KEY" \
          --password "$TAURI_SIGNING_PRIVATE_KEY_PASSWORD" \
          "$APP_IMAGE"

        env:
          RELEASE_CHANNEL: '${{ inputs.channel }}'
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
          POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }}
          TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
          TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
          AUTO_UPDATER_DISABLED: ${{ inputs.disable_updater && 'true' || 'false' }}
          JAN_SIGNING_KEY: ${{ secrets.JAN_SIGNING_KEY }}
          TAURI_TRAY: libappindicator3
      # 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

      ## Set output filename for linux
      - name: Set output filename for linux
        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'
        run: |
          cd ./src-tauri/target/release/bundle

          # 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
          aws s3 cp ./appimage/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage.sig s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage.sig
          aws s3 cp ./deb/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb.sig s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb.sig
        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
        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
template-tauri-build-linux-x64-external .github/workflows/template-tauri-build-linux-x64-external.yml
Triggers
workflow_call
Runs on
ubuntu-22.04
Jobs
build-linux-x64-external
Actions
dcarbone/install-jq-action
Commands
  • 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
  • cp .github/scripts/icon-${{ inputs.channel }}.png src-tauri/icons/icon.png
  • cargo install ctoml
  • 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 libappindicator3-dev
  • echo "Version: ${{ inputs.new_version }}" jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = false' ./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"}' ./src-tauri/tauri.linux.conf.json > /tmp/tauri.linux.conf.json mv /tmp/tauri.linux.conf.json ./src-tauri/tauri.linux.conf.json fi jq --arg version "${{ inputs.new_version }}" '.version = $version' web-app/package.json > /tmp/package.json mv /tmp/package.json web-app/package.json # Update tauri plugin versions jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------" cat ./src-tauri/plugins/tauri-plugin-hardware/package.json jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/Cargo.toml---------" cat ./src-tauri/Cargo.toml ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" if [ "${{ inputs.channel }}" != "stable" ]; then if [[ "${{ inputs.channel }}" == "nightly" ]]; then jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json else jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json fi 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 }} ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}" ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}" ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" chmod +x .github/scripts/rename-workspace.sh .github/scripts/rename-workspace.sh ./package.json ${{ inputs.channel }} fi
  • corepack enable corepack prepare yarn@4.5.3 --activate yarn --version yarn config set -H enableImmutableInstalls false
  • make build
View raw YAML
name: tauri-build-linux-x64-external
on:
  workflow_call:
    inputs:
      ref:
        required: true
        type: string
        default: 'refs/heads/main'
      new_version:
        required: true
        type: string
        default: ''
      channel:
        required: true
        type: string
        default: 'nightly'
        description: 'The channel to use for this job'
      disable_updater:
        required: false
        type: boolean
        default: false
        description: 'If true, builds both .deb and .appimage but disables auto-updater'
jobs:
  build-linux-x64-external:
    runs-on: ubuntu-22.04
    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 dependencies
        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 libappindicator3-dev

      - name: Update app version
        run: |
          echo "Version: ${{ inputs.new_version }}"
          jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = false' ./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"}' ./src-tauri/tauri.linux.conf.json > /tmp/tauri.linux.conf.json
            mv /tmp/tauri.linux.conf.json ./src-tauri/tauri.linux.conf.json
          fi
          jq --arg version "${{ inputs.new_version }}" '.version = $version' web-app/package.json > /tmp/package.json
          mv /tmp/package.json web-app/package.json

          # Update tauri plugin versions

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/package.json

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml

          ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml

          ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/Cargo.toml---------"
          cat ./src-tauri/Cargo.toml

          ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"

          if [ "${{ inputs.channel }}" != "stable" ]; then
            if [[ "${{ inputs.channel }}" == "nightly" ]]; then
              jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            else
              jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            fi
            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 }}
            ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}"
            ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}"
            ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"
            chmod +x .github/scripts/rename-workspace.sh
            .github/scripts/rename-workspace.sh ./package.json ${{ inputs.channel }}
          fi

      - name: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Build app
        run: |
          make build

        env:
          RELEASE_CHANNEL: '${{ inputs.channel }}'
          AUTO_UPDATER_DISABLED: ${{ inputs.disable_updater && 'true' || 'false' }}
          TAURI_TRAY: libappindicator3

      - name: Upload Artifact
        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
        uses: actions/upload-artifact@v4
        with:
          name: jan-linux-amd64-${{ inputs.new_version }}-AppImage
          path: ./src-tauri/target/release/bundle/appimage/*.AppImage
template-tauri-build-linux-x64-flatpak .github/workflows/template-tauri-build-linux-x64-flatpak.yml
Triggers
workflow_call
Runs on
ubuntu-22.04
Jobs
build-linux-x64
Actions
dcarbone/install-jq-action
Commands
  • 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
  • cargo install ctoml
  • 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 libappindicator3-dev
  • 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 if [ "${{ inputs.channel }}" != "stable" ]; then jq '.bundle.linux.deb.files = {"usr/bin/bun": "resources/bin/bun"}' ./src-tauri/tauri.linux.conf.json > /tmp/tauri.linux.conf.json mv /tmp/tauri.linux.conf.json ./src-tauri/tauri.linux.conf.json fi jq --arg version "${{ inputs.new_version }}" '.version = $version' web-app/package.json > /tmp/package.json mv /tmp/package.json web-app/package.json # Update tauri plugin versions jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------" cat ./src-tauri/plugins/tauri-plugin-hardware/package.json jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/Cargo.toml---------" cat ./src-tauri/Cargo.toml # Temporarily enable devtool on prod build ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" cat ./src-tauri/Cargo.toml # Change app name for beta and nightly builds if [ "${{ inputs.channel }}" != "stable" ]; then if [[ "${{ inputs.channel }}" == "nightly" ]]; then jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json else jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json fi 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 }}" ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}" ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" 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
  • corepack enable corepack prepare yarn@4.5.3 --activate yarn --version yarn config set -H enableImmutableInstalls false
  • make build
  • cd ./src-tauri/target/release/bundle DEB_FILE_NAME=Jan_${{ inputs.new_version }}_amd64.deb DEB_SIG=$(cat deb/Jan_${{ inputs.new_version }}_amd64.deb.sig) echo "DEB_SIG=$DEB_SIG" >> $GITHUB_OUTPUT echo "DEB_FILE_NAME=$DEB_FILE_NAME" >> $GITHUB_OUTPUT
  • cd ./src-tauri/target/release/bundle # Upload for tauri updater aws s3 cp ./deb/${{ steps.packageinfo.outputs.DEB_FILE_NAME }} s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/flatpak/${{ steps.packageinfo.outputs.DEB_FILE_NAME }} aws s3 cp ./deb/${{ steps.packageinfo.outputs.DEB_FILE_NAME }}.sig s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/flatpak/${{ steps.packageinfo.outputs.DEB_FILE_NAME }}.sig
View raw YAML
name: tauri-build-linux-x64-flatpak
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: ''
      upload_url:
        required: false
        type: string
        default: ''
      channel:
        required: true
        type: string
        default: 'nightly'
        description: 'The channel to use for this job'
      disable_updater:
        required: false
        type: boolean
        default: false
        description: 'If true, builds both .deb and .appimage but disables auto-updater'
    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
      JAN_SIGNING_KEY:
        required: false
jobs:
  build-linux-x64:
    runs-on: ubuntu-22.04
    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: 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 dependencies
        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 libappindicator3-dev

      - 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' ./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"}' ./src-tauri/tauri.linux.conf.json > /tmp/tauri.linux.conf.json
            mv /tmp/tauri.linux.conf.json ./src-tauri/tauri.linux.conf.json
          fi
          jq --arg version "${{ inputs.new_version }}" '.version = $version' web-app/package.json > /tmp/package.json
          mv /tmp/package.json web-app/package.json

          # Update tauri plugin versions

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/package.json

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml

          ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml

          ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/Cargo.toml---------"
          cat ./src-tauri/Cargo.toml

          # Temporarily enable devtool on prod build
          ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"
          cat ./src-tauri/Cargo.toml

          # Change app name for beta and nightly builds
          if [ "${{ inputs.channel }}" != "stable" ]; then
            if [[ "${{ inputs.channel }}" == "nightly" ]]; then
              jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            else
              jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            fi
            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 }}"
            ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}"
            ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"
            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: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Build app
        run: |
          make build

        env:
          RELEASE_CHANNEL: '${{ inputs.channel }}'
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
          POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }}
          TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
          TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
          AUTO_UPDATER_DISABLED: ${{ inputs.disable_updater && 'true' || 'false' }}
          JAN_SIGNING_KEY: ${{ secrets.JAN_SIGNING_KEY }}
          TAURI_TRAY: libappindicator3
      # 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-flatpak-${{ inputs.new_version }}-deb
          path: ./src-tauri/target/release/bundle/deb/*.deb

      ## Set output filename for linux
      - name: Set output filename for linux
        id: packageinfo
        run: |
          cd ./src-tauri/target/release/bundle
          DEB_FILE_NAME=Jan_${{ inputs.new_version }}_amd64.deb
          DEB_SIG=$(cat deb/Jan_${{ inputs.new_version }}_amd64.deb.sig)

          echo "DEB_SIG=$DEB_SIG" >> $GITHUB_OUTPUT
          echo "DEB_FILE_NAME=$DEB_FILE_NAME" >> $GITHUB_OUTPUT

      - name: upload to aws s3 if public provider is aws
        if: inputs.public_provider == 'aws-s3'
        run: |
          cd ./src-tauri/target/release/bundle
          # Upload for tauri updater
          aws s3 cp ./deb/${{ steps.packageinfo.outputs.DEB_FILE_NAME }} s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/flatpak/${{ steps.packageinfo.outputs.DEB_FILE_NAME }}
          aws s3 cp ./deb/${{ steps.packageinfo.outputs.DEB_FILE_NAME }}.sig s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/flatpak/${{ steps.packageinfo.outputs.DEB_FILE_NAME }}.sig

        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'
template-tauri-build-macos .github/workflows/template-tauri-build-macos.yml
Triggers
workflow_call
Runs on
macos-latest
Jobs
build-macos
Actions
dcarbone/install-jq-action, apple-actions/import-codesign-certs, actions/upload-release-asset, actions/upload-release-asset, actions/upload-release-asset
Commands
  • cp .github/scripts/icon-${{ inputs.channel }}.png src-tauri/icons/icon.png
  • cargo install ctoml
  • sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer
  • 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-app/package.json > /tmp/package.json mv /tmp/package.json web-app/package.json # Update tauri plugin versions jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------" cat ./src-tauri/plugins/tauri-plugin-hardware/package.json jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/Cargo.toml---------" cat ./src-tauri/Cargo.toml # Temporarily enable devtool on prod build ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" cat ./src-tauri/Cargo.toml # Change app name for beta and nightly builds if [ "${{ inputs.channel }}" != "stable" ]; then if [[ "${{ inputs.channel }}" == "nightly" ]]; then jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json else jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json fi 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 }}" ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}" ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" 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
  • base64 -d <<< "$NOTARIZE_P8_BASE64" > /tmp/notary-key.p8
  • corepack enable corepack prepare yarn@4.5.3 --activate yarn --version yarn config set -H enableImmutableInstalls false
  • make build
  • 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"
View raw YAML
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
      JAN_SIGNING_KEY:
        required: false
    outputs:
      MAC_UNIVERSAL_SIG:
        value: ${{ jobs.build-macos.outputs.MAC_UNIVERSAL_SIG }}
      FILE_NAME:
        value: ${{ jobs.build-macos.outputs.FILE_NAME }}
      DMG_NAME:
        value: ${{ jobs.build-macos.outputs.DMG_NAME }}
      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 }}
      FILE_NAME: ${{ steps.metadata.outputs.FILE_NAME }}
      DMG_NAME: ${{ steps.metadata.outputs.DMG_NAME }}
      TAR_NAME: ${{ steps.metadata.outputs.TAR_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: Set up Xcode version
        run: sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer

      - 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-app/package.json > /tmp/package.json
          mv /tmp/package.json web-app/package.json

          # Update tauri plugin versions

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/package.json

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml

          ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml

          ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/Cargo.toml---------"
          cat ./src-tauri/Cargo.toml

          # Temporarily enable devtool on prod build
          ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"
          cat ./src-tauri/Cargo.toml

          # Change app name for beta and nightly builds
          if [ "${{ inputs.channel }}" != "stable" ]; then
            if [[ "${{ inputs.channel }}" == "nightly" ]]; then
              jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            else
              jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            fi
            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 }}"
            ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}"
            ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"
            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: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Build app
        run: |
          make build
        env:
          NODE_OPTIONS: "--max-old-space-size=4196"
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          APP_PATH: '.'
          POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
          POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }}
          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 }}
          JAN_SIGNING_KEY: ${{ secrets.JAN_SIGNING_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

      ## Set output filename for mac
      - name: Set output filename for mac
        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'
        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.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
          aws s3 cp ./macos/Jan-${{ inputs.channel }}.app.tar.gz.sig s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}.app.tar.gz.sig
        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
        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
template-tauri-build-macos-external .github/workflows/template-tauri-build-macos-external.yml
Triggers
workflow_call
Runs on
macos-latest
Jobs
build-macos-external
Actions
dcarbone/install-jq-action
Commands
  • cp .github/scripts/icon-${{ inputs.channel }}.png src-tauri/icons/icon.png
  • cargo install ctoml
  • sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer
  • echo "Version: ${{ inputs.new_version }}" jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = false' ./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-app/package.json > /tmp/package.json mv /tmp/package.json web-app/package.json # Update tauri plugin versions jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------" cat ./src-tauri/plugins/tauri-plugin-hardware/package.json jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/Cargo.toml---------" cat ./src-tauri/Cargo.toml ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" if [ "${{ inputs.channel }}" != "stable" ]; then if [[ "${{ inputs.channel }}" == "nightly" ]]; then jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json else jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json fi 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 }} ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}" ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}" ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" chmod +x .github/scripts/rename-workspace.sh .github/scripts/rename-workspace.sh ./package.json ${{ inputs.channel }} fi
  • corepack enable corepack prepare yarn@4.5.3 --activate yarn --version yarn config set -H enableImmutableInstalls false
  • make build
View raw YAML
name: tauri-build-macos-external
on:
  workflow_call:
    inputs:
      ref:
        required: true
        type: string
        default: 'refs/heads/main'
      new_version:
        required: true
        type: string
        default: ''
      channel:
        required: true
        type: string
        default: 'nightly'
        description: 'The channel to use for this job'
jobs:
  build-macos-external:
    runs-on: macos-latest
    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: Set up Xcode version
        run: sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer

      - name: Update app version
        run: |
          echo "Version: ${{ inputs.new_version }}"
          jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = false' ./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-app/package.json > /tmp/package.json
          mv /tmp/package.json web-app/package.json

          # Update tauri plugin versions

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/package.json

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml

          ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml

          ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/Cargo.toml---------"
          cat ./src-tauri/Cargo.toml

          ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"

          if [ "${{ inputs.channel }}" != "stable" ]; then
            if [[ "${{ inputs.channel }}" == "nightly" ]]; then
              jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            else
              jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            fi
            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 }}
            ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}"
            ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}"
            ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"
            chmod +x .github/scripts/rename-workspace.sh
            .github/scripts/rename-workspace.sh ./package.json ${{ inputs.channel }}
          fi

      - name: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Build app
        run: |
          make build
        env:
          NODE_OPTIONS: "--max-old-space-size=4196"
          APP_PATH: '.'

      - name: Upload Artifact
        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
template-tauri-build-windows-x64 .github/workflows/template-tauri-build-windows-x64.yml
Triggers
workflow_call
Runs on
windows-latest
Jobs
build-windows-x64
Actions
dcarbone/install-jq-action, actions/upload-release-asset
Commands
  • cp .github/scripts/icon-${{ inputs.channel }}.png src-tauri/icons/icon.png
  • cargo install ctoml
  • 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 '.bundle.windows.nsis.template = "tauri.bundle.windows.nsis.template"' ./src-tauri/tauri.windows.conf.json > /tmp/tauri.windows.conf.json mv /tmp/tauri.windows.conf.json ./src-tauri/tauri.windows.conf.json jq --arg version "${{ inputs.new_version }}" '.version = $version' web-app/package.json > /tmp/package.json mv /tmp/package.json web-app/package.json # Add sign commands to tauri.windows.conf.json jq '.bundle.windows.signCommand = "powershell -ExecutionPolicy Bypass -File ./sign.ps1 %1"' ./src-tauri/tauri.windows.conf.json > /tmp/tauri.windows.conf.json mv /tmp/tauri.windows.conf.json ./src-tauri/tauri.windows.conf.json # Update tauri plugin versions jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------" cat ./src-tauri/plugins/tauri-plugin-hardware/package.json jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/Cargo.toml---------" cat ./src-tauri/Cargo.toml generate_build_version() { ### Example ### 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 "---------tauri.windows.conf.json---------" cat ./src-tauri/tauri.windows.conf.json # Temporarily enable devtool on prod build ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" cat ./src-tauri/Cargo.toml # Change app name for beta and nightly builds if [ "${{ inputs.channel }}" != "stable" ]; then if [[ "${{ inputs.channel }}" == "nightly" ]]; then jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json else jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json fi mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json # Update product name jq --arg name "Jan-${{ inputs.channel }}" '.productName = $name' ./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 }} echo "---------tauri.conf.json---------" cat ./src-tauri/tauri.conf.json # Update Cargo.toml ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}" ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}" ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" 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 else sed -i "s/jan_productname/Jan/g" ./src-tauri/tauri.bundle.windows.nsis.template sed -i "s/jan_mainbinaryname/jan/g" ./src-tauri/tauri.bundle.windows.nsis.template fi echo "---------nsis.template---------" cat ./src-tauri/tauri.bundle.windows.nsis.template
  • dotnet tool install --global --version 6.0.0 AzureSignTool
  • corepack enable corepack prepare yarn@4.5.3 --activate yarn --version yarn config set -H enableImmutableInstalls false
  • make build
  • 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) MSI_FILE="Jan-${{ inputs.channel }}_${{ inputs.new_version }}_x64_en-US.msi" # PORTABLE_FILE_NAME="Jan-${{ inputs.channel }}_${{ inputs.new_version }}_x64-portable.exe" else FILE_NAME=Jan_${{ inputs.new_version }}_x64-setup.exe WIN_SIG=$(cat Jan_${{ inputs.new_version }}_x64-setup.exe.sig) MSI_FILE="Jan_${{ inputs.new_version }}_x64_en-US.msi" # PORTABLE_FILE_NAME="Jan_${{ inputs.new_version }}_x64-portable.exe" fi echo "::set-output name=WIN_SIG::$WIN_SIG" echo "::set-output name=FILE_NAME::$FILE_NAME" echo "::set-output name=MSI_FILE_NAME::$MSI_FILE" # echo "::set-output name=PORTABLE_FILE_NAME::$PORTABLE_FILE_NAME"
  • cd ./src-tauri/target/release/bundle/nsis # 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 }} aws s3 cp ./${{ steps.metadata.outputs.FILE_NAME }}.sig s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/${{ steps.metadata.outputs.FILE_NAME }}.sig
View raw YAML
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
      JAN_SIGNING_KEY:
        required: false
    outputs:
      WIN_SIG:
        value: ${{ jobs.build-windows-x64.outputs.WIN_SIG }}
      FILE_NAME:
        value: ${{ jobs.build-windows-x64.outputs.FILE_NAME }}
      MSI_FILE_NAME:
        value: ${{ jobs.build-windows-x64.outputs.MSI_FILE_NAME }}
      # PORTABLE_FILE_NAME:
      #   value: ${{ jobs.build-windows-x64.outputs.PORTABLE_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 }}
      MSI_FILE_NAME: ${{ steps.metadata.outputs.MSI_FILE_NAME }}
      # PORTABLE_FILE_NAME: ${{ steps.metadata.outputs.PORTABLE_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 '.bundle.windows.nsis.template = "tauri.bundle.windows.nsis.template"' ./src-tauri/tauri.windows.conf.json > /tmp/tauri.windows.conf.json
          mv /tmp/tauri.windows.conf.json ./src-tauri/tauri.windows.conf.json
          jq --arg version "${{ inputs.new_version }}" '.version = $version' web-app/package.json > /tmp/package.json
          mv /tmp/package.json web-app/package.json

          # Add sign commands to tauri.windows.conf.json
          jq '.bundle.windows.signCommand = "powershell -ExecutionPolicy Bypass -File ./sign.ps1 %1"' ./src-tauri/tauri.windows.conf.json > /tmp/tauri.windows.conf.json
          mv /tmp/tauri.windows.conf.json ./src-tauri/tauri.windows.conf.json

          # Update tauri plugin versions

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/package.json

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml

          ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml

          ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/Cargo.toml---------"
          cat ./src-tauri/Cargo.toml

          generate_build_version() {
              ### Example
              ### 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 "---------tauri.windows.conf.json---------"
          cat ./src-tauri/tauri.windows.conf.json

          # Temporarily enable devtool on prod build
          ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"
          cat ./src-tauri/Cargo.toml

          # Change app name for beta and nightly builds
          if [ "${{ inputs.channel }}" != "stable" ]; then
            if [[ "${{ inputs.channel }}" == "nightly" ]]; then
              jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            else
              jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            fi
            mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json

            # Update product name
            jq --arg name "Jan-${{ inputs.channel }}" '.productName = $name' ./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 }}

            echo "---------tauri.conf.json---------"
            cat ./src-tauri/tauri.conf.json

            # Update Cargo.toml
            ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}"
            ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}"
            ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"
            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
          else
            sed -i "s/jan_productname/Jan/g" ./src-tauri/tauri.bundle.windows.nsis.template
            sed -i "s/jan_mainbinaryname/jan/g" ./src-tauri/tauri.bundle.windows.nsis.template
          fi
          echo "---------nsis.template---------"
          cat ./src-tauri/tauri.bundle.windows.nsis.template

      - name: Install AzureSignTool
        run: |
          dotnet tool install --global --version 6.0.0 AzureSignTool

      - name: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Build app
        shell: bash
        run: |
          make build
        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 }}
          TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
          TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
          JAN_SIGNING_KEY: ${{ secrets.JAN_SIGNING_KEY }}

      - name: Upload NSIS Installer Artifact
        uses: actions/upload-artifact@v4
        with:
          name: jan-windows-exe-${{ inputs.new_version }}
          path: |
            ./src-tauri/target/release/bundle/nsis/*.exe
      - name: Upload MSI Installer Artifact
        uses: actions/upload-artifact@v4
        with:
          name: jan-windows-msi-${{ inputs.new_version }}
          path: |
            ./src-tauri/target/release/bundle/msi/*.msi

      # - name: Upload Portable Artifact
      #   uses: actions/upload-artifact@v4
      #   with:
      #     name: jan-windows-portable-${{ inputs.new_version }}
      #     path: |
      #       ./src-tauri/target/release/Jan*.exe

      ## Set output filename for windows
      - name: Set output filename for windows
        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)

            MSI_FILE="Jan-${{ inputs.channel }}_${{ inputs.new_version }}_x64_en-US.msi"
            # PORTABLE_FILE_NAME="Jan-${{ inputs.channel }}_${{ inputs.new_version }}_x64-portable.exe"
          else
            FILE_NAME=Jan_${{ inputs.new_version }}_x64-setup.exe
            WIN_SIG=$(cat Jan_${{ inputs.new_version }}_x64-setup.exe.sig)

            MSI_FILE="Jan_${{ inputs.new_version }}_x64_en-US.msi"
            # PORTABLE_FILE_NAME="Jan_${{ inputs.new_version }}_x64-portable.exe"
          fi

          echo "::set-output name=WIN_SIG::$WIN_SIG"
          echo "::set-output name=FILE_NAME::$FILE_NAME"
          echo "::set-output name=MSI_FILE_NAME::$MSI_FILE"
          # echo "::set-output name=PORTABLE_FILE_NAME::$PORTABLE_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 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 }}
          aws s3 cp ./${{ steps.metadata.outputs.FILE_NAME }}.sig s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/${{ steps.metadata.outputs.FILE_NAME }}.sig
        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
        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

      # - name: Upload portable exe to release (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/${{ steps.metadata.outputs.PORTABLE_FILE_NAME }}
      #     asset_name: ${{ steps.metadata.outputs.PORTABLE_FILE_NAME }}
      #     asset_content_type: application/octet-stream
template-tauri-build-windows-x64-external .github/workflows/template-tauri-build-windows-x64-external.yml
Triggers
workflow_call
Runs on
windows-latest
Jobs
build-windows-x64-external
Actions
dcarbone/install-jq-action
Commands
  • cp .github/scripts/icon-${{ inputs.channel }}.png src-tauri/icons/icon.png
  • cargo install ctoml
  • echo "Version: ${{ inputs.new_version }}" # Update tauri.conf.json jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = false' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json jq '.bundle.windows.nsis.template = "tauri.bundle.windows.nsis.template"' ./src-tauri/tauri.windows.conf.json > /tmp/tauri.windows.conf.json mv /tmp/tauri.windows.conf.json ./src-tauri/tauri.windows.conf.json jq '.bundle.windows.signCommand = "echo External build - skipping signature: %1"' ./src-tauri/tauri.windows.conf.json > /tmp/tauri.windows.conf.json mv /tmp/tauri.windows.conf.json ./src-tauri/tauri.windows.conf.json jq --arg version "${{ inputs.new_version }}" '.version = $version' web-app/package.json > /tmp/package.json mv /tmp/package.json web-app/package.json # Update tauri plugin versions jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------" cat ./src-tauri/plugins/tauri-plugin-hardware/package.json jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------" cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}" echo "---------./src-tauri/Cargo.toml---------" 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 if [ "${{ inputs.channel }}" != "stable" ]; then if [[ "${{ inputs.channel }}" == "nightly" ]]; then jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json else jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json fi mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json # Update product name jq --arg name "Jan-${{ inputs.channel }}" '.productName = $name' ./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 }} echo "---------tauri.conf.json---------" cat ./src-tauri/tauri.conf.json # Update Cargo.toml ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}" ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}" ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" 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 else sed -i "s/jan_productname/Jan/g" ./src-tauri/tauri.bundle.windows.nsis.template sed -i "s/jan_mainbinaryname/jan/g" ./src-tauri/tauri.bundle.windows.nsis.template fi echo "---------nsis.template---------" cat ./src-tauri/tauri.bundle.windows.nsis.template
  • corepack enable corepack prepare yarn@4.5.3 --activate yarn --version yarn config set -H enableImmutableInstalls false
  • make build
View raw YAML
name: tauri-build-windows-x64-external
on:
  workflow_call:
    inputs:
      ref:
        required: true
        type: string
        default: 'refs/heads/main'
      new_version:
        required: true
        type: string
        default: ''
      channel:
        required: true
        type: string
        default: 'nightly'
        description: 'The channel to use for this job'
jobs:
  build-windows-x64-external:
    runs-on: windows-latest
    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
        shell: bash
        run: |
          echo "Version: ${{ inputs.new_version }}"
          # Update tauri.conf.json
          jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = false' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
          mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json
          jq '.bundle.windows.nsis.template = "tauri.bundle.windows.nsis.template"' ./src-tauri/tauri.windows.conf.json > /tmp/tauri.windows.conf.json
          mv /tmp/tauri.windows.conf.json ./src-tauri/tauri.windows.conf.json
          jq '.bundle.windows.signCommand = "echo External build - skipping signature: %1"' ./src-tauri/tauri.windows.conf.json > /tmp/tauri.windows.conf.json
          mv /tmp/tauri.windows.conf.json ./src-tauri/tauri.windows.conf.json
          jq --arg version "${{ inputs.new_version }}" '.version = $version' web-app/package.json > /tmp/package.json
          mv /tmp/package.json web-app/package.json

          # Update tauri plugin versions

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-hardware/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-hardware/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-hardware/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/package.json

          jq --arg version "${{ inputs.new_version }}" '.version = $version' ./src-tauri/plugins/tauri-plugin-llamacpp/package.json > /tmp/package.json
          mv /tmp/package.json ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/package.json---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/package.json

          ctoml ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-hardware/Cargo.toml

          ctoml ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml---------"
          cat ./src-tauri/plugins/tauri-plugin-llamacpp/Cargo.toml

          ctoml ./src-tauri/Cargo.toml package.version "${{ inputs.new_version }}"
          echo "---------./src-tauri/Cargo.toml---------"
          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

          if [ "${{ inputs.channel }}" != "stable" ]; then
            if [[ "${{ inputs.channel }}" == "nightly" ]]; then
              jq '.plugins.updater.endpoints = ["https://apps-nightly.jan.ai/update-check", "https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            else
              jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json
            fi
            mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json

            # Update product name
            jq --arg name "Jan-${{ inputs.channel }}" '.productName = $name' ./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 }}

            echo "---------tauri.conf.json---------"
            cat ./src-tauri/tauri.conf.json

            # Update Cargo.toml
            ctoml ./src-tauri/Cargo.toml package.name "Jan-${{ inputs.channel }}"
            ctoml ./src-tauri/Cargo.toml package.default-run "Jan-${{ inputs.channel }}"
            ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools"
            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
          else
            sed -i "s/jan_productname/Jan/g" ./src-tauri/tauri.bundle.windows.nsis.template
            sed -i "s/jan_mainbinaryname/jan/g" ./src-tauri/tauri.bundle.windows.nsis.template
          fi
          echo "---------nsis.template---------"
          cat ./src-tauri/tauri.bundle.windows.nsis.template

      - name: Config Yarn
        run: |
          corepack enable
          corepack prepare yarn@4.5.3 --activate
          yarn --version
          yarn config set -H enableImmutableInstalls false

      - name: Build app
        shell: bash
        run: |
          make build

      - name: Upload Artifact
        uses: actions/upload-artifact@v4
        with:
          name: jan-windows-${{ inputs.new_version }}
          path: |
            ./src-tauri/target/release/bundle/nsis/*.exe