From 7124da22e325c20704026a3cf32679a957a0ed1e Mon Sep 17 00:00:00 2001 From: Service Account Date: Thu, 18 Jan 2024 20:20:55 +0000 Subject: [PATCH 01/18] janhq/jan: Update README.md with nightly build artifact URL --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fee40a1b3..703171090 100644 --- a/README.md +++ b/README.md @@ -76,31 +76,31 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute Experimental (Nightly Build) - + jan.exe - + Intel - + M1/M2 - + jan.deb - + jan.AppImage From 42a86e9cb71a195a58d4050b6f8649d080155382 Mon Sep 17 00:00:00 2001 From: hiento09 <136591877+hiento09@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:06:17 +0700 Subject: [PATCH 02/18] Cherrypick cicd to main branch to apply new gitflow (#1665) * Update CI follow git flow (#1625) * Update CI follow git flow --------- Co-authored-by: Hien To * Feature add schedule clean cloudflare page and r2 (#1653) * Add notify for manual build if publish to R2 * Add CI clean cloudflare cache * Update jan-docs CI * Add job clean cloudflare r2 --------- Co-authored-by: Hien To --------- Co-authored-by: Hien To --- ...ean-cloudflare-page-preview-url-and-r2.yml | 75 +++ .github/workflows/codeQL-analysis.yml | 2 + .github/workflows/jan-docs.yml | 25 +- .../workflows/jan-electron-build-nightly.yml | 431 +++--------------- .../jan-electron-build-pre-release.yml | 52 +++ .github/workflows/jan-electron-build.yml | 234 +--------- .../jan-electron-linter-and-test.yml | 2 + .../workflows/template-build-linux-x64.yml | 116 +++++ .github/workflows/template-build-macos.yml | 156 +++++++ .../workflows/template-build-windows-x64.yml | 144 ++++++ .../workflows/template-get-update-version.yml | 58 +++ ...ate-noti-discord-and-update-url-readme.yml | 73 +++ electron/package.json | 6 +- 13 files changed, 787 insertions(+), 587 deletions(-) create mode 100644 .github/workflows/clean-cloudflare-page-preview-url-and-r2.yml create mode 100644 .github/workflows/jan-electron-build-pre-release.yml create mode 100644 .github/workflows/template-build-linux-x64.yml create mode 100644 .github/workflows/template-build-macos.yml create mode 100644 .github/workflows/template-build-windows-x64.yml create mode 100644 .github/workflows/template-get-update-version.yml create mode 100644 .github/workflows/template-noti-discord-and-update-url-readme.yml diff --git a/.github/workflows/clean-cloudflare-page-preview-url-and-r2.yml b/.github/workflows/clean-cloudflare-page-preview-url-and-r2.yml new file mode 100644 index 000000000..620f74714 --- /dev/null +++ b/.github/workflows/clean-cloudflare-page-preview-url-and-r2.yml @@ -0,0 +1,75 @@ +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: ["jan", "nitro"] + 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']}") + clean-cloudflare-r2: + runs-on: ubuntu-latest + environment: production + steps: + - name: install-aws-cli-action + uses: unfor19/install-aws-cli-action@v1 + - name: Delete object older than 7 days + run: | + # Get the list of objects in the 'latest' folder + OBJECTS=$(aws s3api list-objects --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --query 'Contents[?LastModified<`'$(date -d "$current_date -30 days" -u +"%Y-%m-%dT%H:%M:%SZ")'`].{Key: Key}' --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com | jq -c .) + + # Create a JSON file for the delete operation + echo "{\"Objects\": $OBJECTS, \"Quiet\": false}" > delete.json + + # Delete the objects + echo q | aws s3api delete-objects --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --delete file://delete.json --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com + + # Remove the JSON file + rm delete.json + env: + AWS_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: auto + AWS_EC2_METADATA_DISABLED: "true" diff --git a/.github/workflows/codeQL-analysis.yml b/.github/workflows/codeQL-analysis.yml index 94411c4d2..00301b840 100644 --- a/.github/workflows/codeQL-analysis.yml +++ b/.github/workflows/codeQL-analysis.yml @@ -15,6 +15,7 @@ on: push: branches: - main + - dev paths: - "electron/**" - .github/workflows/jan-electron-linter-and-test.yml @@ -31,6 +32,7 @@ on: pull_request: branches: - main + - dev paths: - "electron/**" - .github/workflows/jan-electron-linter-and-test.yml diff --git a/.github/workflows/jan-docs.yml b/.github/workflows/jan-docs.yml index bc8473687..8ce4e91ed 100644 --- a/.github/workflows/jan-docs.yml +++ b/.github/workflows/jan-docs.yml @@ -4,12 +4,14 @@ on: push: branches: - main + - dev paths: - 'docs/**' - '.github/workflows/jan-docs.yml' pull_request: branches: - main + - dev paths: - 'docs/**' - '.github/workflows/jan-docs.yml' @@ -20,7 +22,6 @@ jobs: deploy: name: Deploy to GitHub Pages env: - CLOUDFLARE_ACCOUNT_ID: 9707100ef42a1a25bd70e3ee2137bd0e CLOUDFLARE_PROJECT_NAME: jan runs-on: ubuntu-latest permissions: @@ -60,11 +61,23 @@ jobs: working-directory: docs - name: Publish to Cloudflare Pages PR Preview and Staging - if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main') + if: github.event_name == 'push' && github.ref == 'refs/heads/dev' uses: cloudflare/pages-action@v1 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ env.CLOUDFLARE_ACCOUNT_ID }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + projectName: ${{ env.CLOUDFLARE_PROJECT_NAME }} + directory: ./docs/build + branch: main + # Optional: Enable this if you want to have GitHub Deployments triggered + gitHubToken: ${{ secrets.GITHUB_TOKEN }} + + - 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/build # Optional: Enable this if you want to have GitHub Deployments triggered @@ -72,19 +85,19 @@ jobs: id: deployCloudflarePages - uses: mshick/add-pr-comment@v2 - if: github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main' + if: github.event_name == 'pull_request' with: message: | Preview URL: ${{ steps.deployCloudflarePages.outputs.url }} - name: Add Custome Domain file - if: github.event_name == 'push' && github.event.pull_request.head.repo.full_name != github.repository + if: github.event_name == 'push' && github.ref == 'refs/heads/main' && github.event.pull_request.head.repo.full_name != github.repository run: echo "${{ vars.DOCUSAURUS_DOMAIN }}" > ./docs/build/CNAME # Popular action to deploy to GitHub Pages: # Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus - name: Deploy to GitHub Pages - if: github.event_name == 'push' && github.event.pull_request.head.repo.full_name != github.repository + if: github.event_name == 'push' && github.ref == 'refs/heads/main' && github.event.pull_request.head.repo.full_name != github.repository uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/jan-electron-build-nightly.yml b/.github/workflows/jan-electron-build-nightly.yml index 40948407d..60a8a951c 100644 --- a/.github/workflows/jan-electron-build-nightly.yml +++ b/.github/workflows/jan-electron-build-nightly.yml @@ -2,392 +2,85 @@ name: Jan Build Electron App Nightly or Manual on: schedule: - - cron: '0 20 * * *' # At 8 PM UTC, which is 3 AM UTC+7 - + - cron: '0 20 * * 2,3,4' # At 8 PM UTC on Tuesday, Wednesday, and Thursday, which is 3 AM UTC+7 workflow_dispatch: + inputs: + public_provider: + type: choice + description: 'Public Provider' + options: + - none + - cloudflare-r2 + default: none jobs: - delete-cloudflare-r2-folder: + set-public-provider: runs-on: ubuntu-latest - environment: production + if: github.event_name == 'workflow_dispatch' + outputs: + public_provider: ${{ steps.set-public-provider.outputs.public_provider }} + ref: ${{ steps.set-public-provider.outputs.ref }} steps: - - name: install-aws-cli-action - uses: unfor19/install-aws-cli-action@v1 - - - name: Delete cloudflare-r2 folder using awscli s3api - if: github.ref == 'refs/heads/main' - continue-on-error: true + - name: Set public provider + id: set-public-provider run: | - # Get the list of objects in the 'latest' folder - OBJECTS=$(aws s3api list-objects --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --prefix "latest/" --query 'Contents[].{Key: Key}' --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com | jq -c .) - - # Create a JSON file for the delete operation - echo "{\"Objects\": $OBJECTS, \"Quiet\": false}" > delete.json - - # Delete the objects - echo q | aws s3api delete-objects --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --delete file://delete.json --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com - - # Remove the JSON file - rm delete.json - env: - AWS_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} - AWS_DEFAULT_REGION: auto - AWS_EC2_METADATA_DISABLED: "true" - + if [ ${{ github.event == 'workflow_dispatch' }} ]; then + echo "::set-output name=public_provider::${{ github.event.inputs.public_provider }}" + echo "::set-output name=ref::${{ github.ref }}" + else + echo "::set-output name=public_provider::cloudflare-r2" + echo "::set-output name=ref::refs/heads/dev" + fi # Job create Update app version based on latest release tag with build number and save to output get-update-version: - runs-on: ubuntu-latest - needs: delete-cloudflare-r2-folder - environment: production - outputs: - new_version: ${{ steps.version_update.outputs.new_version }} - steps: + uses: ./.github/workflows/template-get-update-version.yml - - name: Install jq - uses: dcarbone/install-jq-action@v2.0.1 - - - name: Update app version based on latest release tag with build number - id: version_update - 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 -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 - } - - # 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" build-macos: - runs-on: macos-latest - needs: [delete-cloudflare-r2-folder, get-update-version] - environment: production - permissions: - contents: write - steps: - - name: Getting the repo - uses: actions/checkout@v3 - - - name: Installing node - uses: actions/setup-node@v1 - with: - node-version: 20 - - - name: Install jq - uses: dcarbone/install-jq-action@v2.0.1 - - - - name: Update app version based on latest release tag with build number - id: version_update - run: | - # Update the version in electron/package.json - jq --arg version "${{ needs.get-update-version.outputs.new_version }}" '.version = $version' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - - jq --arg version "${{ needs.get-update-version.outputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json - mv /tmp/package.json web/package.json - - jq '.build.publish = [{"provider": "generic", "url": "${{ secrets.CLOUDFLARE_R2_PUBLIC_URL }}", "channel": "latest"}]' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - - - name: Get Cer for code signing - run: base64 -d <<< "$CODE_SIGN_P12_BASE64" > /tmp/codesign.p12 - shell: bash - env: - CODE_SIGN_P12_BASE64: ${{ secrets.CODE_SIGN_P12_BASE64 }} - - - uses: apple-actions/import-codesign-certs@v2 - continue-on-error: true - with: - p12-file-base64: ${{ secrets.CODE_SIGN_P12_BASE64 }} - p12-password: ${{ secrets.CODE_SIGN_P12_PASSWORD }} - - - name: Build and publish app - run: | - make build - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CSC_LINK: "/tmp/codesign.p12" - CSC_KEY_PASSWORD: ${{ secrets.CODE_SIGN_P12_PASSWORD }} - CSC_IDENTITY_AUTO_DISCOVERY: "true" - APPLE_ID: ${{ secrets.APPLE_ID }} - APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} - APP_PATH: "." - DEVELOPER_ID: ${{ secrets.DEVELOPER_ID }} - - - name: Upload Artifact - uses: actions/upload-artifact@v2 - with: - name: jan-mac-x64-${{ needs.get-update-version.outputs.new_version }} - path: ./electron/dist/jan-mac-x64-${{ needs.get-update-version.outputs.new_version }}.dmg - - - name: Upload Artifact - uses: actions/upload-artifact@v2 - with: - name: jan-mac-arm64-${{ needs.get-update-version.outputs.new_version }} - path: ./electron/dist/jan-mac-arm64-${{ needs.get-update-version.outputs.new_version }}.dmg - - - name: put-object using awscli s3api - if: github.ref == 'refs/heads/main' - continue-on-error: true - run: | - ls -al ./electron/dist - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "latest/jan-mac-x64-${{ needs.get-update-version.outputs.new_version }}.dmg" --body "./electron/dist/jan-mac-x64-${{ needs.get-update-version.outputs.new_version }}.dmg" --content-type "application/octet-stream" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "latest/jan-mac-arm64-${{ needs.get-update-version.outputs.new_version }}.dmg" --body "./electron/dist/jan-mac-arm64-${{ needs.get-update-version.outputs.new_version }}.dmg" --content-type "application/octet-stream" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "latest/jan-mac-x64-${{ needs.get-update-version.outputs.new_version }}.zip" --body "./electron/dist/jan-mac-x64-${{ needs.get-update-version.outputs.new_version }}.zip" --content-type "application/zip" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "latest/jan-mac-arm64-${{ needs.get-update-version.outputs.new_version }}.zip" --body "./electron/dist/jan-mac-arm64-${{ needs.get-update-version.outputs.new_version }}.zip" --content-type "application/zip" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "${{ needs.get-update-version.outputs.new_version }}/jan-mac-x64-${{ needs.get-update-version.outputs.new_version }}.dmg" --body "./electron/dist/jan-mac-x64-${{ needs.get-update-version.outputs.new_version }}.dmg" --content-type "application/octet-stream" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "${{ needs.get-update-version.outputs.new_version }}/jan-mac-arm64-${{ needs.get-update-version.outputs.new_version }}.dmg" --body "./electron/dist/jan-mac-arm64-${{ needs.get-update-version.outputs.new_version }}.dmg" --content-type "application/octet-stream" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "${{ needs.get-update-version.outputs.new_version }}/latest-mac.yml" --body "./electron/dist/latest-mac.yml" --content-type "text/yaml" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "latest/latest-mac.yml" --body "./electron/dist/latest-mac.yml" --content-type "text/yaml" - env: - AWS_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} - AWS_DEFAULT_REGION: auto - AWS_EC2_METADATA_DISABLED: "true" + uses: ./.github/workflows/template-build-macos.yml + needs: [get-update-version, set-public-provider] + secrets: inherit + with: + ref: ${{ needs.set-public-provider.outputs.ref }} + public_provider: ${{ needs.set-public-provider.outputs.public_provider }} + new_version: ${{ needs.get-update-version.outputs.new_version }} build-windows-x64: - runs-on: windows-latest - needs: [delete-cloudflare-r2-folder, get-update-version] - permissions: - contents: write - steps: - - name: Getting the repo - uses: actions/checkout@v3 + uses: ./.github/workflows/template-build-windows-x64.yml + secrets: inherit + needs: [get-update-version, set-public-provider] + with: + ref: ${{ needs.set-public-provider.outputs.ref }} + public_provider: ${{ needs.set-public-provider.outputs.public_provider }} + new_version: ${{ needs.get-update-version.outputs.new_version }} - - name: Installing node - uses: actions/setup-node@v1 - with: - node-version: 20 - - - name: Install jq - uses: dcarbone/install-jq-action@v2.0.1 - - - name: Update app version base on tag - id: version_update - shell: bash - run: | - # Update the version in electron/package.json - jq --arg version "${{ needs.get-update-version.outputs.new_version }}" '.version = $version' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - - jq --arg version "${{ needs.get-update-version.outputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json - mv /tmp/package.json web/package.json - - jq '.build.publish = [{"provider": "generic", "url": "${{ secrets.CLOUDFLARE_R2_PUBLIC_URL }}", "channel": "latest"}]' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - - jq '.build.win.sign = "./sign.js"' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - - - name: Install AzureSignTool - run: | - dotnet tool install --global AzureSignTool - - - name: Build app - 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 }} - - - name: Upload Artifact - uses: actions/upload-artifact@v2 - with: - name: jan-win-x64-${{ needs.get-update-version.outputs.new_version }} - path: ./electron/dist/*.exe - - - name: put-object using awscli s3api - if: github.ref == 'refs/heads/main' - shell: bash - run: | - ls -al ./electron/dist - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "latest/jan-win-x64-${{ needs.get-update-version.outputs.new_version }}.exe" --body "./electron/dist/jan-win-x64-${{ needs.get-update-version.outputs.new_version }}.exe" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "latest/jan-win-x64-${{ needs.get-update-version.outputs.new_version }}.exe.blockmap" --body "./electron/dist/jan-win-x64-${{ needs.get-update-version.outputs.new_version }}.exe.blockmap" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "${{ needs.get-update-version.outputs.new_version }}/jan-win-x64-${{ needs.get-update-version.outputs.new_version }}.exe" --body "./electron/dist/jan-win-x64-${{ needs.get-update-version.outputs.new_version }}.exe" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "latest/latest.yml" --body "./electron/dist/latest.yml" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "${{ needs.get-update-version.outputs.new_version }}/latest.yml" --body "./electron/dist/latest.yml" - env: - AWS_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} - AWS_DEFAULT_REGION: auto - AWS_EC2_METADATA_DISABLED: "true" build-linux-x64: - runs-on: ubuntu-latest - needs: [delete-cloudflare-r2-folder, get-update-version] - environment: production - env: - SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }} - permissions: - contents: write - steps: - - name: Getting the repo - uses: actions/checkout@v3 - - - name: Installing node - uses: actions/setup-node@v1 - with: - node-version: 20 - - - name: Install jq - uses: dcarbone/install-jq-action@v2.0.1 - - - name: Update app version base on tag - id: version_update - run: | - # Update the version in electron/package.json - jq --arg version "${{ needs.get-update-version.outputs.new_version }}" '.version = $version' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - jq --arg version "${{ needs.get-update-version.outputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json - mv /tmp/package.json web/package.json - jq '.build.publish = [{"provider": "generic", "url": "${{ secrets.CLOUDFLARE_R2_PUBLIC_URL }}", "channel": "latest"}]' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - - - name: Build and publish app - run: | - make build - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Upload Artifact - uses: actions/upload-artifact@v2 - with: - name: jan-linux-amd64-${{ needs.get-update-version.outputs.new_version }}-deb - path: ./electron/dist/*.deb - - - name: Upload Artifact - uses: actions/upload-artifact@v2 - with: - name: jan-linux-amd64-${{ needs.get-update-version.outputs.new_version }}-AppImage - path: ./electron/dist/*.AppImage - - - name: put-object using awscli s3api - if: github.ref == 'refs/heads/main' - run: | - ls -al ./electron/dist - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "latest/jan-linux-amd64-${{ needs.get-update-version.outputs.new_version }}.deb" --body "./electron/dist/jan-linux-amd64-${{ needs.get-update-version.outputs.new_version }}.deb" --content-type "application/octet-stream" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "${{ needs.get-update-version.outputs.new_version }}/jan-linux-amd64-${{ needs.get-update-version.outputs.new_version }}.deb" --body "./electron/dist/jan-linux-amd64-${{ needs.get-update-version.outputs.new_version }}.deb" --content-type "application/octet-stream" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "latest/jan-linux-x86_64-${{ needs.get-update-version.outputs.new_version }}.AppImage" --body "./electron/dist/jan-linux-x86_64-${{ needs.get-update-version.outputs.new_version }}.AppImage" --content-type "application/octet-stream" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "${{ needs.get-update-version.outputs.new_version }}/jan-linux-x86_64-${{ needs.get-update-version.outputs.new_version }}.AppImage" --body "./electron/dist/jan-linux-x86_64-${{ needs.get-update-version.outputs.new_version }}.AppImage" --content-type "application/octet-stream" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "latest/latest-linux.yml" --body "./electron/dist/latest-linux.yml" --content-type "text/yaml" - aws s3api put-object --endpoint-url https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com --bucket ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }} --key "${{ needs.get-update-version.outputs.new_version }}/latest-linux.yml" --body "./electron/dist/latest-linux.yml" --content-type "text/yaml" - env: - AWS_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} - AWS_DEFAULT_REGION: auto - AWS_EC2_METADATA_DISABLED: "true" + uses: ./.github/workflows/template-build-linux-x64.yml + secrets: inherit + needs: [get-update-version, set-public-provider] + with: + ref: ${{ needs.set-public-provider.outputs.ref }} + public_provider: ${{ needs.set-public-provider.outputs.public_provider }} + new_version: ${{ needs.get-update-version.outputs.new_version }} noti-discord-nightly-and-update-url-readme: - needs: [build-macos, build-windows-x64, build-linux-x64, delete-cloudflare-r2-folder, get-update-version] - environment: production + needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider] + secrets: inherit if: github.event_name == 'schedule' - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - fetch-depth: "0" - token: ${{ secrets.PAT_SERVICE_ACCOUNT }} - - - name: Set version to environment variable - run: | - echo "VERSION=${{ needs.get-update-version.outputs.new_version }}" >> $GITHUB_ENV - - - name: Notify Discord - uses: Ilshidur/action-discord@master - with: - args: | - Jan App Nightly build artifact version {{ VERSION }}: - - Windows: https://delta.jan.ai/{{ VERSION }}/jan-win-x64-{{ VERSION }}.exe - - macOS Intel: https://delta.jan.ai/{{ VERSION }}/jan-mac-x64-{{ VERSION }}.dmg - - macOS Apple Silicon: https://delta.jan.ai/{{ VERSION }}/jan-mac-arm64-{{ VERSION }}.dmg - - Linux Deb: https://delta.jan.ai/{{ VERSION }}/jan-linux-amd64-{{ VERSION }}.deb - - Linux AppImage: https://delta.jan.ai/{{ VERSION }}/jan-linux-x86_64-{{ VERSION }}.AppImage - - Github action run: https://github.com/janhq/jan/actions/runs/{{ GITHUB_RUN_ID }} - env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} - - - name: Update README.md with artifact URL - run: | - sed -i "s|||" README.md - sed -i "s|||" README.md - sed -i "s|||" README.md - sed -i "s|||" README.md - sed -i "s|||" README.md - git config --global user.email "service@jan.ai" - git config --global user.name "Service Account" - git add README.md - git commit -m "${GITHUB_REPOSITORY}: Update README.md with nightly build artifact URL" - git -c http.extraheader="AUTHORIZATION: bearer ${{ secrets.PAT_SERVICE_ACCOUNT }}" push origin HEAD:main - env: - GITHUB_RUN_ID: ${{ github.run_id }} + uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml + with: + ref: ${{ needs.set-public-provider.outputs.ref }} + build_reason: Nightly + push_to_branch: main + 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, delete-cloudflare-r2-folder, get-update-version] - environment: production - if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - fetch-depth: "0" - token: ${{ secrets.PAT_SERVICE_ACCOUNT }} - - - name: Set version to environment variable - run: | - echo "VERSION=${{ needs.get-update-version.outputs.new_version }}" >> $GITHUB_ENV - - - name: Notify Discord - uses: Ilshidur/action-discord@master - with: - args: | - Jan App Manual build artifact version {{ VERSION }}: - - Windows: https://delta.jan.ai/{{ VERSION }}/jan-win-x64-{{ VERSION }}.exe - - macOS Intel: https://delta.jan.ai/{{ VERSION }}/jan-mac-x64-{{ VERSION }}.dmg - - macOS Apple Silicon: https://delta.jan.ai/{{ VERSION }}/jan-mac-arm64-{{ VERSION }}.dmg - - Linux: https://delta.jan.ai/{{ VERSION }}/jan-linux-amd64-{{ VERSION }}.deb - - Linux AppImage: https://delta.jan.ai/{{ VERSION }}/jan-linux-x86_64-{{ VERSION }}.AppImage - - Github action run: https://github.com/janhq/jan/actions/runs/{{ GITHUB_RUN_ID }} - env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} - - # Update README.md with artifact URL if manual build from main branch - - name: Update README.md with artifact URL - if: github.ref == 'refs/heads/main' - run: | - sed -i "s|||" README.md - sed -i "s|||" README.md - sed -i "s|||" README.md - sed -i "s|||" README.md - sed -i "s|||" README.md - git config --global user.email "service@jan.ai" - git config --global user.name "Service Account" - git add README.md - git commit -m "${GITHUB_REPOSITORY}: Update README.md with nightly build artifact URL" - git -c http.extraheader="AUTHORIZATION: bearer ${{ secrets.PAT_SERVICE_ACCOUNT }}" push origin HEAD:main - env: - GITHUB_RUN_ID: ${{ github.run_id }} \ No newline at end of file + needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version, set-public-provider] + secrets: inherit + if: github.event_name == 'workflow_dispatch' && github.event.inputs.public_provider == 'cloudflare-r2' + uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml + with: + ref: ${{ needs.set-public-provider.outputs.ref }} + build_reason: Manual + push_to_branch: main + new_version: ${{ needs.get-update-version.outputs.new_version }} diff --git a/.github/workflows/jan-electron-build-pre-release.yml b/.github/workflows/jan-electron-build-pre-release.yml new file mode 100644 index 000000000..c3580105b --- /dev/null +++ b/.github/workflows/jan-electron-build-pre-release.yml @@ -0,0 +1,52 @@ +name: Jan Build Electron Pre Release + +on: + push: + branches: + - main + paths: + - "!README.md" + +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 + + build-macos: + uses: ./.github/workflows/template-build-macos.yml + secrets: inherit + needs: [get-update-version] + with: + ref: ${{ github.ref }} + public_provider: cloudflare-r2 + new_version: ${{ needs.get-update-version.outputs.new_version }} + + build-windows-x64: + uses: ./.github/workflows/template-build-windows-x64.yml + secrets: inherit + needs: [get-update-version] + with: + ref: ${{ github.ref }} + public_provider: cloudflare-r2 + new_version: ${{ needs.get-update-version.outputs.new_version }} + + build-linux-x64: + uses: ./.github/workflows/template-build-linux-x64.yml + secrets: inherit + needs: [get-update-version] + with: + ref: ${{ github.ref }} + public_provider: cloudflare-r2 + new_version: ${{ needs.get-update-version.outputs.new_version }} + + noti-discord-nightly-and-update-url-readme: + needs: [build-macos, build-windows-x64, build-linux-x64, get-update-version] + secrets: inherit + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml + with: + ref: refs/heads/main + build_reason: Nightly + push_to_branch: main + new_version: ${{ needs.get-update-version.outputs.new_version }} diff --git a/.github/workflows/jan-electron-build.yml b/.github/workflows/jan-electron-build.yml index abd0aaeda..20102447b 100644 --- a/.github/workflows/jan-electron-build.yml +++ b/.github/workflows/jan-electron-build.yml @@ -5,223 +5,39 @@ on: tags: ["v[0-9]+.[0-9]+.[0-9]+"] jobs: - 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: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref_name }} - release_name: "${{ env.VERSION }}" - draft: true - prerelease: false + # Job create Update app version based on latest release tag with build number and save to output + get-update-version: + uses: ./.github/workflows/template-get-update-version.yml build-macos: - runs-on: macos-latest - needs: create-draft-release - environment: production - permissions: - contents: write - steps: - - name: Getting the repo - uses: actions/checkout@v3 - - - name: Installing node - uses: actions/setup-node@v1 - with: - node-version: 20 - - - name: Install jq - uses: dcarbone/install-jq-action@v2.0.1 - - - name: Get tag - id: tag - uses: dawidd6/action-get-tag@v1 - - - name: Update app version base on tag - run: | - if [[ ! "${VERSION_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Error: Tag is not valid!" - exit 1 - fi - jq --arg version "${VERSION_TAG#v}" '.version = $version' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - jq --arg version "${VERSION_TAG#v}" '.version = $version' web/package.json > /tmp/package.json - mv /tmp/package.json web/package.json - env: - VERSION_TAG: ${{ steps.tag.outputs.tag }} - - - name: Get Cer for code signing - run: base64 -d <<< "$CODE_SIGN_P12_BASE64" > /tmp/codesign.p12 - shell: bash - env: - CODE_SIGN_P12_BASE64: ${{ secrets.CODE_SIGN_P12_BASE64 }} - - - uses: apple-actions/import-codesign-certs@v2 - continue-on-error: true - with: - p12-file-base64: ${{ secrets.CODE_SIGN_P12_BASE64 }} - p12-password: ${{ secrets.CODE_SIGN_P12_PASSWORD }} - - - name: Build and publish app - run: | - make build-and-publish - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CSC_LINK: "/tmp/codesign.p12" - CSC_KEY_PASSWORD: ${{ secrets.CODE_SIGN_P12_PASSWORD }} - CSC_IDENTITY_AUTO_DISCOVERY: "true" - APPLE_ID: ${{ secrets.APPLE_ID }} - APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} - APP_PATH: "." - DEVELOPER_ID: ${{ secrets.DEVELOPER_ID }} - ANALYTICS_ID: ${{ secrets.JAN_APP_POSTHOG_PROJECT_API_KEY }} - ANALYTICS_HOST: ${{ secrets.JAN_APP_POSTHOG_URL }} + uses: ./.github/workflows/template-build-macos.yml + secrets: inherit + needs: [get-update-version] + with: + ref: ${{ github.ref }} + public_provider: github + new_version: ${{ needs.get-update-version.outputs.new_version }} build-windows-x64: - runs-on: windows-latest - needs: create-draft-release - permissions: - contents: write - steps: - - name: Getting the repo - uses: actions/checkout@v3 - - - name: Installing node - uses: actions/setup-node@v1 - with: - node-version: 20 - - - name: Install jq - uses: dcarbone/install-jq-action@v2.0.1 - - - name: Get tag - id: tag - uses: dawidd6/action-get-tag@v1 - - - name: Update app version base on tag - shell: bash - run: | - if [[ ! "${VERSION_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Error: Tag is not valid!" - exit 1 - fi - jq --arg version "${VERSION_TAG#v}" '.version = $version' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - jq --arg version "${VERSION_TAG#v}" '.version = $version' web/package.json > /tmp/package.json - mv /tmp/package.json web/package.json - jq '.build.win.sign = "./sign.js"' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - env: - VERSION_TAG: ${{ steps.tag.outputs.tag }} - - - name: Install AzureSignTool - run: | - dotnet tool install --global AzureSignTool - - - name: Build app - run: | - make build - env: - ANALYTICS_ID: ${{ secrets.JAN_APP_POSTHOG_PROJECT_API_KEY }} - ANALYTICS_HOST: ${{ secrets.JAN_APP_POSTHOG_URL }} - 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 }} - - - uses: actions/upload-release-asset@v1.0.1 - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.create-draft-release.outputs.upload_url }} - asset_path: ./electron/dist/jan-win-x64-${{ needs.create-draft-release.outputs.version }}.exe - asset_name: jan-win-x64-${{ needs.create-draft-release.outputs.version }}.exe - asset_content_type: application/octet-stream - - - uses: actions/upload-release-asset@v1.0.1 - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.create-draft-release.outputs.upload_url }} - asset_path: ./electron/dist/jan-win-x64-${{ needs.create-draft-release.outputs.version }}.exe.blockmap - asset_name: jan-win-x64-${{ needs.create-draft-release.outputs.version }}.exe.blockmap - asset_content_type: application/octet-stream - - - uses: actions/upload-release-asset@v1.0.1 - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.create-draft-release.outputs.upload_url }} - asset_path: ./electron/dist/latest.yml - asset_name: latest.yml - asset_content_type: text/yaml + uses: ./.github/workflows/template-build-windows-x64.yml + secrets: inherit + needs: [get-update-version] + with: + ref: ${{ github.ref }} + public_provider: github + new_version: ${{ needs.get-update-version.outputs.new_version }} build-linux-x64: - runs-on: ubuntu-latest - needs: create-draft-release - environment: production - env: - SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }} - permissions: - contents: write - steps: - - name: Getting the repo - uses: actions/checkout@v3 - - - name: Installing node - uses: actions/setup-node@v1 - with: - node-version: 20 - - - name: Install jq - uses: dcarbone/install-jq-action@v2.0.1 - - - name: Get tag - id: tag - uses: dawidd6/action-get-tag@v1 - - - name: Update app version base on tag - run: | - if [[ ! "${VERSION_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Error: Tag is not valid!" - exit 1 - fi - jq --arg version "${VERSION_TAG#v}" '.version = $version' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json - jq --arg version "${VERSION_TAG#v}" '.version = $version' web/package.json > /tmp/package.json - mv /tmp/package.json web/package.json - env: - VERSION_TAG: ${{ steps.tag.outputs.tag }} - - - name: Build and publish app - run: | - make build-and-publish - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ANALYTICS_ID: ${{ secrets.JAN_APP_POSTHOG_PROJECT_API_KEY }} - ANALYTICS_HOST: ${{ secrets.JAN_APP_POSTHOG_URL }} + uses: ./.github/workflows/template-build-linux-x64.yml + secrets: inherit + needs: [get-update-version] + with: + ref: ${{ github.ref }} + public_provider: github + new_version: ${{ needs.get-update-version.outputs.new_version }} update_release_draft: - needs: [build-macos, build-windows-x64, build-linux-x64, create-draft-release] + needs: [build-macos, build-windows-x64, build-linux-x64] permissions: # write permission is required to create a github release contents: write diff --git a/.github/workflows/jan-electron-linter-and-test.yml b/.github/workflows/jan-electron-linter-and-test.yml index 1157f8166..6d5aaf150 100644 --- a/.github/workflows/jan-electron-linter-and-test.yml +++ b/.github/workflows/jan-electron-linter-and-test.yml @@ -3,6 +3,7 @@ on: push: branches: - main + - dev paths: - "electron/**" - .github/workflows/jan-electron-linter-and-test.yml @@ -19,6 +20,7 @@ on: pull_request: branches: - main + - dev paths: - "electron/**" - .github/workflows/jan-electron-linter-and-test.yml diff --git a/.github/workflows/template-build-linux-x64.yml b/.github/workflows/template-build-linux-x64.yml new file mode 100644 index 000000000..f39f2302e --- /dev/null +++ b/.github/workflows/template-build-linux-x64.yml @@ -0,0 +1,116 @@ +name: 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, cloudflare: build and publish to cloudflare' + new_version: + required: true + type: string + default: '' + cloudflare_r2_path: + required: false + type: string + default: '/latest/' + secrets: + CLOUDFLARE_R2_BUCKET_NAME: + required: false + CLOUDFLARE_R2_ACCESS_KEY_ID: + required: false + CLOUDFLARE_R2_SECRET_ACCESS_KEY: + required: false + CLOUDFLARE_ACCOUNT_ID: + required: false + +jobs: + build-linux-x64: + runs-on: ubuntu-latest + environment: production + permissions: + contents: write + steps: + - name: Getting the repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + + - name: Installing node + uses: actions/setup-node@v1 + with: + node-version: 20 + + - name: Install jq + uses: dcarbone/install-jq-action@v2.0.1 + + - name: Update app version base public_provider + if: inputs.public_provider != 'github' + run: | + echo "Version: ${{ inputs.new_version }}" + # Update the version in electron/package.json + jq --arg version "${{ inputs.new_version }}" '.version = $version' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + jq --arg version "${{ inputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json + mv /tmp/package.json web/package.json + jq '.build.publish = [{"provider": "s3", "bucket": "${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }}", "region": "auto", "endpoint": "https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com", "path": "${{ inputs.cloudflare_r2_path }}", "channel": "latest"}]' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + cat electron/package.json + + - name: Update app version base on tag + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && inputs.public_provider == 'github' + run: | + if [[ ! "${VERSION_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Error: Tag is not valid!" + exit 1 + fi + jq --arg version "${VERSION_TAG#v}" '.version = $version' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + jq --arg version "${VERSION_TAG#v}" '.version = $version' web/package.json > /tmp/package.json + mv /tmp/package.json web/package.json + env: + VERSION_TAG: ${{ inputs.new_version }} + + - name: Build and publish app to cloudflare r2 or github artifactory + if: inputs.public_provider != 'github' + run: | + # check public_provider is true or not + echo "public_provider is ${{ inputs.public_provider }}" + if [ "${{ inputs.public_provider }}" == "none" ]; then + make build + else + make build-and-publish + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} + AWS_EC2_METADATA_DISABLED: "true" + + - name: Build and publish app to github + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && inputs.public_provider == 'github' + run: | + make build-and-publish + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ANALYTICS_ID: ${{ secrets.JAN_APP_POSTHOG_PROJECT_API_KEY }} + ANALYTICS_HOST: ${{ secrets.JAN_APP_POSTHOG_URL }} + + - name: Upload Artifact .deb file + if: inputs.public_provider != 'github' + uses: actions/upload-artifact@v2 + with: + name: jan-linux-amd64-${{ inputs.new_version }}-deb + path: ./electron/dist/*.deb + + - name: Upload Artifact .AppImage file + if: inputs.public_provider != 'github' + uses: actions/upload-artifact@v2 + with: + name: jan-linux-amd64-${{ inputs.new_version }}-AppImage + path: ./electron/dist/*.AppImage diff --git a/.github/workflows/template-build-macos.yml b/.github/workflows/template-build-macos.yml new file mode 100644 index 000000000..8295947af --- /dev/null +++ b/.github/workflows/template-build-macos.yml @@ -0,0 +1,156 @@ +name: 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, cloudflare: build and publish to cloudflare' + new_version: + required: true + type: string + default: '' + cloudflare_r2_path: + required: false + type: string + default: '/latest/' + secrets: + CLOUDFLARE_R2_BUCKET_NAME: + required: false + CLOUDFLARE_R2_ACCESS_KEY_ID: + required: false + CLOUDFLARE_R2_SECRET_ACCESS_KEY: + required: false + CLOUDFLARE_ACCOUNT_ID: + 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 + +jobs: + build-macos: + runs-on: macos-latest + environment: production + permissions: + contents: write + steps: + - name: Getting the repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + + - name: Installing node + uses: actions/setup-node@v1 + with: + node-version: 20 + + - name: Install jq + uses: dcarbone/install-jq-action@v2.0.1 + + - name: Update app version based on latest release tag with build number + if: inputs.public_provider != 'github' + run: | + echo "Version: ${{ inputs.new_version }}" + # Update the version in electron/package.json + jq --arg version "${{ inputs.new_version }}" '.version = $version' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + + jq --arg version "${{ inputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json + mv /tmp/package.json web/package.json + + jq '.build.publish = [{"provider": "s3", "bucket": "${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }}", "region": "auto", "endpoint": "https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com", "path": "${{ inputs.cloudflare_r2_path }}", "channel": "latest"}]' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + cat electron/package.json + + - name: Update app version base on tag + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && inputs.public_provider == 'github' + run: | + if [[ ! "${VERSION_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Error: Tag is not valid!" + exit 1 + fi + jq --arg version "${VERSION_TAG#v}" '.version = $version' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + jq --arg version "${VERSION_TAG#v}" '.version = $version' web/package.json > /tmp/package.json + mv /tmp/package.json web/package.json + env: + VERSION_TAG: ${{ inputs.new_version }} + + - name: Get Cer for code signing + run: base64 -d <<< "$CODE_SIGN_P12_BASE64" > /tmp/codesign.p12 + shell: bash + env: + CODE_SIGN_P12_BASE64: ${{ secrets.CODE_SIGN_P12_BASE64 }} + + - uses: apple-actions/import-codesign-certs@v2 + continue-on-error: true + with: + p12-file-base64: ${{ secrets.CODE_SIGN_P12_BASE64 }} + p12-password: ${{ secrets.CODE_SIGN_P12_PASSWORD }} + + - name: Build and publish app to cloudflare r2 or github artifactory + if: inputs.public_provider != 'github' + run: | + # check public_provider is true or not + echo "public_provider is ${{ inputs.public_provider }}" + if [ "${{ inputs.public_provider }}" == "none" ]; then + make build + else + make build-and-publish + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CSC_LINK: "/tmp/codesign.p12" + CSC_KEY_PASSWORD: ${{ secrets.CODE_SIGN_P12_PASSWORD }} + CSC_IDENTITY_AUTO_DISCOVERY: "true" + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} + APP_PATH: "." + DEVELOPER_ID: ${{ secrets.DEVELOPER_ID }} + AWS_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: auto + AWS_EC2_METADATA_DISABLED: "true" + + - name: Build and publish app to github + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && inputs.public_provider == 'github' + run: | + make build-and-publish + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CSC_LINK: "/tmp/codesign.p12" + CSC_KEY_PASSWORD: ${{ secrets.CODE_SIGN_P12_PASSWORD }} + CSC_IDENTITY_AUTO_DISCOVERY: "true" + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} + APP_PATH: "." + DEVELOPER_ID: ${{ secrets.DEVELOPER_ID }} + ANALYTICS_ID: ${{ secrets.JAN_APP_POSTHOG_PROJECT_API_KEY }} + ANALYTICS_HOST: ${{ secrets.JAN_APP_POSTHOG_URL }} + + - name: Upload Artifact + if: inputs.public_provider != 'github' + uses: actions/upload-artifact@v2 + with: + name: jan-mac-x64-${{ inputs.new_version }} + path: ./electron/dist/jan-mac-x64-${{ inputs.new_version }}.dmg + + - name: Upload Artifact + if: inputs.public_provider != 'github' + uses: actions/upload-artifact@v2 + with: + name: jan-mac-arm64-${{ inputs.new_version }} + path: ./electron/dist/jan-mac-arm64-${{ inputs.new_version }}.dmg + diff --git a/.github/workflows/template-build-windows-x64.yml b/.github/workflows/template-build-windows-x64.yml new file mode 100644 index 000000000..83ca10e95 --- /dev/null +++ b/.github/workflows/template-build-windows-x64.yml @@ -0,0 +1,144 @@ +name: 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, cloudflare: build and publish to cloudflare' + new_version: + required: true + type: string + default: '' + cloudflare_r2_path: + required: false + type: string + default: '/latest/' + secrets: + CLOUDFLARE_R2_BUCKET_NAME: + required: false + CLOUDFLARE_R2_ACCESS_KEY_ID: + required: false + CLOUDFLARE_R2_SECRET_ACCESS_KEY: + required: false + CLOUDFLARE_ACCOUNT_ID: + 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 + +jobs: + build-windows-x64: + runs-on: windows-latest + permissions: + contents: write + steps: + - name: Getting the repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + + - name: Installing node + uses: actions/setup-node@v1 + with: + node-version: 20 + + - name: Install jq + uses: dcarbone/install-jq-action@v2.0.1 + + - name: Update app version base on tag + if: inputs.public_provider != 'github' + id: version_update + shell: bash + run: | + echo "Version: ${{ inputs.new_version }}" + # Update the version in electron/package.json + jq --arg version "${{ inputs.new_version }}" '.version = $version' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + + jq --arg version "${{ inputs.new_version }}" '.version = $version' web/package.json > /tmp/package.json + mv /tmp/package.json web/package.json + + jq '.build.publish = [{"provider": "s3", "bucket": "${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }}", "region": "auto", "endpoint": "https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com", "path": "${{ inputs.cloudflare_r2_path }}", "channel": "latest"}]' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + + jq '.build.win.sign = "./sign.js"' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + cat electron/package.json + + - name: Update app version base on tag + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && inputs.public_provider == 'github' + shell: bash + run: | + if [[ ! "${VERSION_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Error: Tag is not valid!" + exit 1 + fi + jq --arg version "${VERSION_TAG#v}" '.version = $version' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + jq --arg version "${VERSION_TAG#v}" '.version = $version' web/package.json > /tmp/package.json + mv /tmp/package.json web/package.json + jq '.build.win.sign = "./sign.js"' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + env: + VERSION_TAG: ${{ inputs.new_version }} + + - name: Install AzureSignTool + run: | + dotnet tool install --global AzureSignTool + + - name: Build and publish app to cloudflare r2 or github artifactory + shell: bash + if: inputs.public_provider != 'github' + run: | + # check public_provider is true or not + echo "public_provider is ${{ inputs.public_provider }}" + if [ "${{ inputs.public_provider }}" == "none" ]; then + make build + else + make build-and-publish + fi + 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.CLOUDFLARE_R2_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: auto + AWS_EC2_METADATA_DISABLED: "true" + + - name: Build app and publish app to github + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && inputs.public_provider == 'github' + run: | + make build-and-publish + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ANALYTICS_ID: ${{ secrets.JAN_APP_POSTHOG_PROJECT_API_KEY }} + ANALYTICS_HOST: ${{ secrets.JAN_APP_POSTHOG_URL }} + 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 }} + + - name: Upload Artifact + if: inputs.public_provider != 'github' + uses: actions/upload-artifact@v2 + with: + name: jan-win-x64-${{ inputs.new_version }} + path: ./electron/dist/*.exe + diff --git a/.github/workflows/template-get-update-version.yml b/.github/workflows/template-get-update-version.yml new file mode 100644 index 000000000..24cfe4a03 --- /dev/null +++ b/.github/workflows/template-get-update-version.yml @@ -0,0 +1,58 @@ +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 + environment: production + 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 + 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 -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" + echo "::set-output name=new_version::${{ steps.tag.outputs.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 \ No newline at end of file diff --git a/.github/workflows/template-noti-discord-and-update-url-readme.yml b/.github/workflows/template-noti-discord-and-update-url-readme.yml new file mode 100644 index 000000000..c13e79dd7 --- /dev/null +++ b/.github/workflows/template-noti-discord-and-update-url-readme.yml @@ -0,0 +1,73 @@ +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: + environment: production + 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/latest/jan-win-x64-{{ VERSION }}.exe + - macOS Intel: https://delta.jan.ai/latest/jan-mac-x64-{{ VERSION }}.dmg + - macOS Apple Silicon: https://delta.jan.ai/latest/jan-mac-arm64-{{ VERSION }}.dmg + - Linux Deb: https://delta.jan.ai/latest/jan-linux-amd64-{{ VERSION }}.deb + - Linux AppImage: https://delta.jan.ai/latest/jan-linux-x86_64-{{ VERSION }}.AppImage + - Github action run: https://github.com/janhq/jan/actions/runs/{{ GITHUB_RUN_ID }} + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + + - name: Update README.md with artifact URL + run: | + sed -i "s|||" README.md + sed -i "s|||" README.md + sed -i "s|||" README.md + sed -i "s|||" README.md + sed -i "s|||" README.md + cat README.md + git config --global user.email "service@jan.ai" + git config --global user.name "Service Account" + git add README.md + git commit -m "${GITHUB_REPOSITORY}: Update README.md with nightly build artifact URL" + git -c http.extraheader="AUTHORIZATION: bearer ${{ secrets.PAT_SERVICE_ACCOUNT }}" push origin HEAD:${{ inputs.push_to_branch }} + env: + GITHUB_RUN_ID: ${{ github.run_id }} diff --git a/electron/package.json b/electron/package.json index 82b569495..173e54f2b 100644 --- a/electron/package.json +++ b/electron/package.json @@ -67,9 +67,9 @@ "build:win32": "tsc -p . && electron-builder -p never -w", "build:linux": "tsc -p . && electron-builder -p never -l deb -l AppImage", "build:publish": "run-script-os", - "build:publish:darwin": "tsc -p . && electron-builder -p onTagOrDraft -m --x64 --arm64", - "build:publish:win32": "tsc -p . && electron-builder -p onTagOrDraft -w", - "build:publish:linux": "tsc -p . && electron-builder -p onTagOrDraft -l deb -l AppImage" + "build:publish:darwin": "tsc -p . && electron-builder -p always -m --x64 --arm64", + "build:publish:win32": "tsc -p . && electron-builder -p always -w", + "build:publish:linux": "tsc -p . && electron-builder -p always -l deb -l AppImage" }, "dependencies": { "@alumna/reflect": "^1.1.3", From e7f82c678c1b44a318e6d8d1f2cac6546aaa6557 Mon Sep 17 00:00:00 2001 From: hiento09 <136591877+hiento09@users.noreply.github.com> Date: Wed, 24 Jan 2024 10:58:04 +0700 Subject: [PATCH 03/18] Remove error condition trigger jobs (#1736) Co-authored-by: Hien To --- .github/workflows/jan-electron-build-nightly.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/jan-electron-build-nightly.yml b/.github/workflows/jan-electron-build-nightly.yml index 15390b752..f961ccd6f 100644 --- a/.github/workflows/jan-electron-build-nightly.yml +++ b/.github/workflows/jan-electron-build-nightly.yml @@ -16,7 +16,6 @@ on: jobs: set-public-provider: runs-on: ubuntu-latest - if: github.event_name == 'workflow_dispatch' outputs: public_provider: ${{ steps.set-public-provider.outputs.public_provider }} ref: ${{ steps.set-public-provider.outputs.ref }} From 7401f3d798ef57f82a5d364db114e3cb1a5aa7d5 Mon Sep 17 00:00:00 2001 From: Service Account Date: Wed, 24 Jan 2024 05:58:20 +0000 Subject: [PATCH 04/18] janhq/jan: Update README.md with nightly build artifact URL --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dc933eb9a..5b43692ab 100644 --- a/README.md +++ b/README.md @@ -76,31 +76,31 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute Experimental (Nightly Build) - + jan.exe - + Intel - + M1/M2 - + jan.deb - + jan.AppImage From 1b794b5337d0b47313ebf5e6ff169698325088da Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Wed, 24 Jan 2024 21:33:45 +0700 Subject: [PATCH 05/18] fix: input port have range validation (#1741) * fix port cannot be empty and have range validation * fix: do not allow user to start server with blank port config (after navigating back) * fix: thread disable button color --------- Co-authored-by: Louis --- web/containers/Layout/Ribbon/index.tsx | 7 ++++-- web/screens/LocalServer/index.tsx | 34 +++++++++++++++++++++----- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/web/containers/Layout/Ribbon/index.tsx b/web/containers/Layout/Ribbon/index.tsx index 6c63ade33..83ed2725a 100644 --- a/web/containers/Layout/Ribbon/index.tsx +++ b/web/containers/Layout/Ribbon/index.tsx @@ -41,7 +41,10 @@ export default function RibbonNav() { icon: ( ), state: MainViewState.Thread, @@ -60,7 +63,7 @@ export default function RibbonNav() { const secondaryMenus = [ { - name: 'Local Server', + name: 'Local API Server', icon: ( { + const [errorRangePort, setErrorRangePort] = useState(false) const [serverEnabled, setServerEnabled] = useAtom(serverEnabledAtom) const showing = useAtomValue(showRightSideBarAtom) const activeModelParams = useAtomValue(getActiveThreadModelParamsAtom) const modelEngineParams = toSettingParams(activeModelParams) - const componentDataEngineSetting = getConfigurationsData(modelEngineParams) const { openServerLog, clearServerLog } = useServerLog() - const { activeModel, startModel, stateModel } = useActiveModel() + const { startModel, stateModel } = useActiveModel() const [selectedModel] = useAtom(selectedModelAtom) const [isCorsEnabled, setIsCorsEnabled] = useAtom(corsEnabledAtom) @@ -77,6 +78,15 @@ const LocalServerScreen = () => { const [firstTimeVisitAPIServer, setFirstTimeVisitAPIServer] = useState(false) + const handleChangePort = (value: any) => { + if (Number(value) <= 0 || Number(value) >= 65536) { + setErrorRangePort(true) + } else { + setErrorRangePort(false) + } + setPort(value) + } + useEffect(() => { if ( localStorage.getItem(FIRST_TIME_VISIT_API_SERVER) === null || @@ -87,6 +97,10 @@ const LocalServerScreen = () => { } }, [firstTimeVisitAPIServer]) + useEffect(() => { + handleChangePort(port) + }, []) + return (
{/* Left SideBar */} @@ -102,7 +116,7 @@ const LocalServerScreen = () => {
+ {errorRangePort && ( +

{`The port range should be from 0 to 65536`}

+ )}