From 87f621129ebeacad2850385845e414bbb8c7ee0e Mon Sep 17 00:00:00 2001 From: hiento09 <136591877+hiento09@users.noreply.github.com> Date: Wed, 17 Jan 2024 19:10:00 +0700 Subject: [PATCH] Update CI follow git flow (#1625) * Update CI follow git flow --------- Co-authored-by: Hien To --- .github/workflows/codeQL-analysis.yml | 2 + .github/workflows/jan-docs.yml | 11 +- .../workflows/jan-electron-build-nightly.yml | 421 +++--------------- .../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 +- 12 files changed, 688 insertions(+), 587 deletions(-) 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/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..12d5992dd 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' @@ -60,31 +62,32 @@ 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/main') || (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main') || (github.event_name == 'push' && github.ref == 'refs/heads/dev') || (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'dev') uses: cloudflare/pages-action@v1 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ env.CLOUDFLARE_ACCOUNT_ID }} projectName: ${{ env.CLOUDFLARE_PROJECT_NAME }} directory: ./docs/build + branch: dev # Optional: Enable this if you want to have GitHub Deployments triggered gitHubToken: ${{ secrets.GITHUB_TOKEN }} id: deployCloudflarePages - uses: mshick/add-pr-comment@v2 - if: github.event_name == 'pull_request' && 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..ae7fac45f 100644 --- a/.github/workflows/jan-electron-build-nightly.yml +++ b/.github/workflows/jan-electron-build-nightly.yml @@ -2,392 +2,71 @@ 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 }} 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 }}" + else + echo "::set-output name=public_provider::cloudflare-r2" + 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: refs/heads/dev + 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: refs/heads/dev + 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: refs/heads/dev + 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] + 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 }} - - 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 + uses: ./.github/workflows/template-noti-discord-and-update-url-readme.yml + with: + ref: refs/heads/dev + build_reason: Nightly + 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 dc6585da9..513e83f52 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",