diff --git a/.github/workflows/jan-electron-build-nightly.yml b/.github/workflows/jan-electron-build-nightly.yml index 1db805d4e..b5ffa9a3b 100644 --- a/.github/workflows/jan-electron-build-nightly.yml +++ b/.github/workflows/jan-electron-build-nightly.yml @@ -15,6 +15,7 @@ jobs: 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 run: | # Get the list of objects in the 'latest' folder @@ -34,25 +35,18 @@ jobs: AWS_DEFAULT_REGION: auto AWS_EC2_METADATA_DISABLED: "true" - build-macos: - runs-on: macos-latest + # 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 - permissions: - contents: write + outputs: + new_version: ${{ steps.version_update.outputs.new_version }} 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: | @@ -82,11 +76,35 @@ jobs: # Remove the 'v' and append the build number to the version NEW_VERSION="${LATEST_TAG#v}-${GITHUB_RUN_NUMBER}" echo "New version: $NEW_VERSION" - - # Update the version in electron/package.json - jq --arg version "$NEW_VERSION" '.version = $version' electron/package.json > /tmp/package.json - mv /tmp/package.json electron/package.json 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 @@ -119,26 +137,27 @@ jobs: - name: Upload Artifact uses: actions/upload-artifact@v2 with: - name: jan-mac-x64-${{ steps.version_update.outputs.new_version }} - path: ./electron/dist/jan-mac-x64-${{ steps.version_update.outputs.new_version }}.dmg + 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-${{ steps.version_update.outputs.new_version }} - path: ./electron/dist/jan-mac-arm64-${{ steps.version_update.outputs.new_version }}.dmg + 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-${{ steps.version_update.outputs.new_version }}.dmg" --body "./electron/dist/jan-mac-x64-${{ steps.version_update.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-${{ steps.version_update.outputs.new_version }}.dmg" --body "./electron/dist/jan-mac-arm64-${{ steps.version_update.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-${{ steps.version_update.outputs.new_version }}.zip" --body "./electron/dist/jan-mac-x64-${{ steps.version_update.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-${{ steps.version_update.outputs.new_version }}.zip" --body "./electron/dist/jan-mac-arm64-${{ steps.version_update.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 "${{ steps.version_update.outputs.new_version }}/jan-mac-x64-${{ steps.version_update.outputs.new_version }}.dmg" --body "./electron/dist/jan-mac-x64-${{ steps.version_update.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 "${{ steps.version_update.outputs.new_version }}/jan-mac-arm64-${{ steps.version_update.outputs.new_version }}.dmg" --body "./electron/dist/jan-mac-arm64-${{ steps.version_update.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 "${{ steps.version_update.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/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 }} @@ -148,7 +167,7 @@ jobs: build-windows-x64: runs-on: windows-latest - needs: delete-cloudflare-r2-folder + needs: [delete-cloudflare-r2-folder, get-update-version] permissions: contents: write steps: @@ -167,38 +186,12 @@ jobs: id: version_update shell: bash 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" - # Update the version in electron/package.json - jq --arg version "$NEW_VERSION" '.version = $version' electron/package.json > /tmp/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 - echo "::set-output name=new_version::$NEW_VERSION" + 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 @@ -223,18 +216,19 @@ jobs: - name: Upload Artifact uses: actions/upload-artifact@v2 with: - name: jan-win-x64-${{ steps.version_update.outputs.new_version }} + 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-${{ steps.version_update.outputs.new_version }}.exe" --body "./electron/dist/jan-win-x64-${{ steps.version_update.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-${{ steps.version_update.outputs.new_version }}.exe.blockmap" --body "./electron/dist/jan-win-x64-${{ steps.version_update.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 "${{ steps.version_update.outputs.new_version }}/jan-win-x64-${{ steps.version_update.outputs.new_version }}.exe" --body "./electron/dist/jan-win-x64-${{ steps.version_update.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" --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 "${{ steps.version_update.outputs.new_version }}/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 }} @@ -243,7 +237,7 @@ jobs: build-linux-x64: runs-on: ubuntu-latest - needs: delete-cloudflare-r2-folder + needs: [delete-cloudflare-r2-folder, get-update-version] environment: production env: SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }} @@ -264,37 +258,11 @@ jobs: - name: Update app version base on tag 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" - # Update the version in electron/package.json - jq --arg version "$NEW_VERSION" '.version = $version' electron/package.json > /tmp/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 - echo "::set-output name=new_version::$NEW_VERSION" + 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 @@ -307,16 +275,17 @@ jobs: - name: Upload Artifact uses: actions/upload-artifact@v2 with: - name: jan-linux-amd64-${{ steps.version_update.outputs.new_version }} + name: jan-linux-amd64-${{ needs.get-update-version.outputs.new_version }} path: ./electron/dist/*.deb - 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-${{ steps.version_update.outputs.new_version }}.deb" --body "./electron/dist/jan-linux-amd64-${{ steps.version_update.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 "${{ steps.version_update.outputs.new_version }}/jan-linux-amd64-${{ steps.version_update.outputs.new_version }}.deb" --body "./electron/dist/jan-linux-amd64-${{ steps.version_update.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-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/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 "${{ steps.version_update.outputs.new_version }}/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 }} @@ -324,7 +293,7 @@ jobs: AWS_EC2_METADATA_DISABLED: "true" noti-discord-nightly-and-update-url-readme: - needs: [build-macos, build-windows-x64, build-linux-x64, delete-cloudflare-r2-folder] + needs: [build-macos, build-windows-x64, build-linux-x64, delete-cloudflare-r2-folder, get-update-version] environment: production if: github.event_name == 'schedule' runs-on: ubuntu-latest @@ -335,16 +304,29 @@ jobs: 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: "Nightly build artifact: https://github.com/janhq/jan/actions/runs/{{ GITHUB_RUN_ID }}" + 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: https://delta.jan.ai/{{ VERSION }}/jan-linux-amd64-{{ VERSION }}.deb + - 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 @@ -354,9 +336,9 @@ jobs: GITHUB_RUN_ID: ${{ github.run_id }} noti-discord-manual-and-update-url-readme: - needs: [build-macos, build-windows-x64, build-linux-x64, delete-cloudflare-r2-folder] + needs: [build-macos, build-windows-x64, build-linux-x64, delete-cloudflare-r2-folder, get-update-version] environment: production - if: github.event_name == 'workflow_dispatch' + if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - name: Checkout code @@ -364,11 +346,21 @@ jobs: 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: "Manual build artifact: https://github.com/janhq/jan/actions/runs/{{ GITHUB_RUN_ID }}" + 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 + - Github action run: https://github.com/janhq/jan/actions/runs/{{ GITHUB_RUN_ID }} env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} @@ -376,7 +368,10 @@ jobs: - 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 diff --git a/.github/workflows/jan-electron-build.yml b/.github/workflows/jan-electron-build.yml index eba68fea1..abd0aaeda 100644 --- a/.github/workflows/jan-electron-build.yml +++ b/.github/workflows/jan-electron-build.yml @@ -60,6 +60,8 @@ jobs: 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 }} @@ -120,6 +122,8 @@ jobs: 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: @@ -203,6 +207,8 @@ jobs: 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 }} diff --git a/Makefile b/Makefile index a61ae92bb..65e21897d 100644 --- a/Makefile +++ b/Makefile @@ -52,21 +52,17 @@ build: check-file-counts clean: ifeq ($(OS),Windows_NT) powershell -Command "Get-ChildItem -Path . -Include node_modules, .next, dist -Recurse -Directory | Remove-Item -Recurse -Force" - rmdir /s /q "%USERPROFILE%\AppData\Roaming\jan" - rmdir /s /q "%USERPROFILE%\AppData\Roaming\jan-electron" - rmdir /s /q "%USERPROFILE%\AppData\Local\jan*" + rmdir /s /q "%USERPROFILE%\jan\extensions" else ifeq ($(shell uname -s),Linux) find . -name "node_modules" -type d -prune -exec rm -rf '{}' + find . -name ".next" -type d -exec rm -rf '{}' + find . -name "dist" -type d -exec rm -rf '{}' + - rm -rf "~/.config/jan" - rm -rf "~/.config/jan-electron" + rm -rf "~/jan/extensions" rm -rf "~/.cache/jan*" else find . -name "node_modules" -type d -prune -exec rm -rf '{}' + find . -name ".next" -type d -exec rm -rf '{}' + find . -name "dist" -type d -exec rm -rf '{}' + - rm -rf ~/Library/Application\ Support/jan - rm -rf ~/Library/Application\ Support/jan-electron + rm -rf ~/jan/extensions rm -rf ~/Library/Caches/jan* endif diff --git a/README.md b/README.md index f17a131e0..7d8cd7802 100644 --- a/README.md +++ b/README.md @@ -34,13 +34,13 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute ## Download - + - + - + - + + + @@ -111,18 +130,7 @@ As Jan is in development mode, you might get stuck on a broken build. To reset your installation: -1. **Remove Jan from your Applications folder and Cache folder** - - ```bash - make clean - ``` - - This will remove all build artifacts and cached files: - - - Delete Jan from your `/Applications` folder - - Clear Application cache in `/Users/$(whoami)/Library/Caches/jan` - -2. Use the following commands to remove any dangling backend processes: +1. Use the following commands to remove any dangling backend processes: ```sh ps aux | grep nitro @@ -134,6 +142,18 @@ To reset your installation: kill -9 ``` +2. **Remove Jan from your Applications folder and Cache folder** + + ```bash + make clean + ``` + + This will remove all build artifacts and cached files: + + - Delete Jan extension from your `~/jan/extensions` folder + - Delete all `node_modules` in current folder + - Clear Application cache in `~/Library/Caches/jan` + ## Contributing Contributions are welcome! Please read the [CONTRIBUTING.md](CONTRIBUTING.md) file @@ -172,25 +192,6 @@ make build This will build the app MacOS m1/m2 for production (with code signing already done) and put the result in `dist` folder. -## Nightly Build - -Our nightly build process for this project is defined in [`.github/workflows/jan-electron-build-nightly.yml`](.github/workflows/jan-electron-build-nightly.yml) - -The nightly build is triggered at 2:00 AM UTC every day. - -Getting on Nightly: - -1. Join our Discord server [here](https://discord.gg/FTk2MvZwJH) and go to channel [github-jan](https://discordapp.com/channels/1107178041848909847/1148534730359308298). -2. Download the build artifacts from the channel. -3. Subsequently, to get the latest nightly, just quit and restart the app. -4. Upon app restart, you will be automatically prompted to update to the latest nightly build. - -## Manual Build - -Stable releases are triggered by manual builds. This is usually done for new features or a bug fixes. - -The process for this project is defined in [`.github/workflows/jan-electron-build-nightly.yml`](.github/workflows/jan-electron-build-nightly.yml) - ## Acknowledgements Jan builds on top of other open-source projects: diff --git a/core/src/node/module.ts b/core/src/node/module.ts index 2201fb400..0919667df 100644 --- a/core/src/node/module.ts +++ b/core/src/node/module.ts @@ -3,6 +3,7 @@ */ export class ModuleManager { public requiredModules: Record = {} + public cleaningResource = false public static instance: ModuleManager = new ModuleManager() diff --git a/electron/main.ts b/electron/main.ts index 6eaa0acfe..4ddf4df56 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -19,6 +19,7 @@ import { handleAppIPCs } from './handlers/app' import { handleAppUpdates } from './handlers/update' import { handleFsIPCs } from './handlers/fs' import { migrateExtensions } from './utils/migration' +import { dispose } from './utils/disposable' app .whenReady() @@ -37,14 +38,12 @@ app }) }) -app.on('window-all-closed', () => { - ModuleManager.instance.clearImportedModules() - app.quit() +app.once('window-all-closed', () => { + cleanUpAndQuit() }) -app.on('quit', () => { - ModuleManager.instance.clearImportedModules() - app.quit() +app.once('quit', () => { + cleanUpAndQuit() }) function createMainWindow() { @@ -83,3 +82,13 @@ function handleIPCs() { handleAppIPCs() handleFileMangerIPCs() } + +function cleanUpAndQuit() { + if (!ModuleManager.instance.cleaningResource) { + ModuleManager.instance.cleaningResource = true + WindowManager.instance.currentWindow?.destroy() + dispose(ModuleManager.instance.requiredModules) + ModuleManager.instance.clearImportedModules() + app.quit() + } +} diff --git a/server/index.ts b/server/index.ts index 3d6ede634..6a03c06fd 100644 --- a/server/index.ts +++ b/server/index.ts @@ -45,7 +45,7 @@ export const startServer = async (schemaPath?: string, baseDir?: string) => { }); await server.register(require("@fastify/swagger-ui"), { - routePrefix: "/docs", + routePrefix: "/", baseDir: baseDir ?? path.join(__dirname, "../..", "./docs/openapi"), uiConfig: { docExpansion: "full", diff --git a/web/containers/DropdownListSidebar/index.tsx b/web/containers/DropdownListSidebar/index.tsx index e40599344..0295f5512 100644 --- a/web/containers/DropdownListSidebar/index.tsx +++ b/web/containers/DropdownListSidebar/index.tsx @@ -26,7 +26,7 @@ import { useMainViewState } from '@/hooks/useMainViewState' import useRecommendedModel from '@/hooks/useRecommendedModel' -import { toGigabytes } from '@/utils/converter' +import { toGibibytes } from '@/utils/converter' import { activeThreadAtom, @@ -130,7 +130,7 @@ export default function DropdownListSidebar() {
{x.name} - {toGigabytes(x.metadata.size)} + {toGibibytes(x.metadata.size)}
diff --git a/web/screens/ExploreModels/ExploreModelItemHeader/index.tsx b/web/screens/ExploreModels/ExploreModelItemHeader/index.tsx index b5798206b..ceab733bd 100644 --- a/web/screens/ExploreModels/ExploreModelItemHeader/index.tsx +++ b/web/screens/ExploreModels/ExploreModelItemHeader/index.tsx @@ -21,7 +21,7 @@ import { getAssistants } from '@/hooks/useGetAssistants' import { useGetDownloadedModels } from '@/hooks/useGetDownloadedModels' import { useMainViewState } from '@/hooks/useMainViewState' -import { toGigabytes } from '@/utils/converter' +import { toGibibytes } from '@/utils/converter' type Props = { model: Model @@ -99,7 +99,7 @@ const ExploreModelItemHeader: React.FC = ({ model, onClick, open }) => {
- {toGigabytes(model.metadata.size)} + {toGibibytes(model.metadata.size)} {downloadButton} {props.data.metadata.size - ? toGigabytes(props.data.metadata.size) + ? toGibibytes(props.data.metadata.size) : '-'} diff --git a/web/screens/SystemMonitor/index.tsx b/web/screens/SystemMonitor/index.tsx index 525f1e7c9..a621c611f 100644 --- a/web/screens/SystemMonitor/index.tsx +++ b/web/screens/SystemMonitor/index.tsx @@ -4,7 +4,7 @@ import { useAtomValue } from 'jotai' import { useActiveModel } from '@/hooks/useActiveModel' -import { toGigabytes } from '@/utils/converter' +import { toGibibytes } from '@/utils/converter' import { cpuUsageAtom, @@ -31,7 +31,7 @@ export default function SystemMonitorScreen() { ram ({Math.round((usedRam / totalRam) * 100)}%) - {toGigabytes(usedRam)} of {toGigabytes(totalRam)} used + {toGibibytes(usedRam)} of {toGibibytes(totalRam)} used
@@ -87,7 +87,7 @@ export default function SystemMonitorScreen() {
Version Type Windows MacOS Linux
Stable (Recommended) @@ -67,11 +67,30 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute
Experimental (Nightly Build) - - Github action artifactory + + + + jan.exe + + + + + Intel + + + + + M1/M2 + + + + + jan.deb
{activeModel.id} - {toGigabytes(activeModel.metadata.size)} + {toGibibytes(activeModel.metadata.size)} diff --git a/web/utils/converter.ts b/web/utils/converter.ts index ed8a61d65..3e8cf21cd 100644 --- a/web/utils/converter.ts +++ b/web/utils/converter.ts @@ -1,11 +1,11 @@ -export const toGigabytes = (input: number) => { +export const toGibibytes = (input: number) => { if (!input) return '' if (input > 1024 ** 3) { - return (input / 1000 ** 3).toFixed(2) + 'GB' + return (input / 1024 ** 3).toFixed(2) + 'GB' } else if (input > 1024 ** 2) { - return (input / 1000 ** 2).toFixed(2) + 'MB' + return (input / 1024 ** 2).toFixed(2) + 'MB' } else if (input > 1024) { - return (input / 1000).toFixed(2) + 'KB' + return (input / 1024).toFixed(2) + 'KB' } else { return input + 'B' } @@ -21,7 +21,7 @@ export const formatDownloadPercentage = ( export const formatDownloadSpeed = (input: number | undefined) => { if (!input) return '0B/s' - return toGigabytes(input) + '/s' + return toGibibytes(input) + '/s' } export const formatTwoDigits = (input: number) => {