diff --git a/.github/actions/deploy/action.yml b/.github/actions/deploy/action.yml index a5c62b247..afa60601a 100644 --- a/.github/actions/deploy/action.yml +++ b/.github/actions/deploy/action.yml @@ -1,9 +1,6 @@ name: 'Deploy to Cluster' description: 'Deploy AFFiNE Cloud to cluster' inputs: - build-type: - description: 'Align with App build type, canary|beta|stable|internal' - default: 'canary' gcp-project-number: description: 'GCP project number' required: true @@ -36,5 +33,3 @@ runs: - name: Deploy shell: bash run: node ./.github/actions/deploy/deploy.mjs - env: - BUILD_TYPE: '${{ inputs.build-type }}' diff --git a/.github/actions/prepare-release/action.yml b/.github/actions/prepare-release/action.yml new file mode 100644 index 000000000..f49b6e949 --- /dev/null +++ b/.github/actions/prepare-release/action.yml @@ -0,0 +1,42 @@ +name: Prepare Release +description: 'Prepare Release' +outputs: + APP_VERSION: + description: 'App Version' + value: ${{ steps.get-version.outputs.APP_VERSION }} + GIT_SHORT_HASH: + description: 'Git Short Hash' + value: ${{ steps.get-version.outputs.GIT_SHORT_HASH }} + BUILD_TYPE: + description: 'Build Type' + value: ${{ steps.get-version.outputs.BUILD_TYPE }} +runs: + using: 'composite' + steps: + - name: Get Version + id: get-version + shell: bash + run: | + GIT_SHORT_HASH=$(git rev-parse --short HEAD) + if [ "${{ github.ref_type }}" == "tag" ]; then + APP_VERSION=$(echo "${{ github.ref_name }}" | sed 's/^v//') + else + PACKAGE_VERSION=$(node -p "require('./package.json').version") + APP_VERSION=$PACKAGE_VERSION-canary.$GIT_SHORT_HASH + fi + if [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + BUILD_TYPE=stable + elif [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+-beta\.[0-9]+$ ]]; then + BUILD_TYPE=beta + elif [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+-canary\.[0-9a-f]+$ ]]; then + BUILD_TYPE=canary + else + echo "Error: unsupported version string: $APP_VERSION" >&2 + exit 1 + fi + echo $APP_VERSION + echo $GIT_SHORT_HASH + echo $BUILD_TYPE + echo "APP_VERSION=$APP_VERSION" >> "$GITHUB_OUTPUT" + echo "GIT_SHORT_HASH=$GIT_SHORT_HASH" >> "$GITHUB_OUTPUT" + echo "BUILD_TYPE=$BUILD_TYPE" >> "$GITHUB_OUTPUT" diff --git a/.github/actions/setup-version/action.yml b/.github/actions/setup-version/action.yml index 385c7cb1b..ba0622184 100644 --- a/.github/actions/setup-version/action.yml +++ b/.github/actions/setup-version/action.yml @@ -1,24 +1,12 @@ name: Setup Version description: 'Setup Version' -outputs: - APP_VERSION: +inputs: + app-version: description: 'App Version' - value: ${{ steps.version.outputs.APP_VERSION }} + required: true runs: using: 'composite' steps: - name: 'Write Version' - id: version shell: bash - run: | - if [ "${{ github.ref_type }}" == "tag" ]; then - APP_VERSION=$(echo "${{ github.ref_name }}" | sed 's/^v//') - else - PACKAGE_VERSION=$(node -p "require('./package.json').version") - TIME_VERSION=$(date +%Y%m%d%H%M) - GIT_SHORT_HASH=$(git rev-parse --short HEAD) - APP_VERSION=$PACKAGE_VERSION-nightly-$GIT_SHORT_HASH - fi - echo $APP_VERSION - echo "APP_VERSION=$APP_VERSION" >> "$GITHUB_OUTPUT" - ./scripts/set-version.sh $APP_VERSION + run: ./scripts/set-version.sh ${{ inputs.app-version }} diff --git a/.github/workflows/build-images.yml b/.github/workflows/build-images.yml index 7371945a3..1ff7622a9 100644 --- a/.github/workflows/build-images.yml +++ b/.github/workflows/build-images.yml @@ -3,7 +3,13 @@ name: Build Images on: workflow_call: inputs: - flavor: + build-type: + type: string + required: true + app-version: + type: string + required: true + git-short-hash: type: string required: true @@ -16,12 +22,13 @@ jobs: build-web: name: Build @affine/web runs-on: ubuntu-latest - environment: ${{ github.event.inputs.flavor }} + environment: ${{ inputs.build-type }} steps: - uses: actions/checkout@v4 - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Setup Node.js uses: ./.github/actions/setup-node - name: Build Core @@ -30,11 +37,11 @@ jobs: R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }} R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} - BUILD_TYPE: ${{ github.event.inputs.flavor }} + BUILD_TYPE: ${{ inputs.build-type }} CAPTCHA_SITE_KEY: ${{ secrets.CAPTCHA_SITE_KEY }} SENTRY_ORG: ${{ secrets.SENTRY_ORG }} SENTRY_PROJECT: 'affine-web' - SENTRY_RELEASE: ${{ steps.version.outputs.APP_VERSION }} + SENTRY_RELEASE: ${{ inputs.app-version }} SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }} PERFSEE_TOKEN: ${{ secrets.PERFSEE_TOKEN }} @@ -49,12 +56,13 @@ jobs: build-admin: name: Build @affine/admin runs-on: ubuntu-latest - environment: ${{ github.event.inputs.flavor }} + environment: ${{ inputs.build-type }} steps: - uses: actions/checkout@v4 - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Setup Node.js uses: ./.github/actions/setup-node - name: Build Admin @@ -63,7 +71,7 @@ jobs: R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }} R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} - BUILD_TYPE: ${{ github.event.inputs.flavor }} + BUILD_TYPE: ${{ inputs.build-type }} CAPTCHA_SITE_KEY: ${{ secrets.CAPTCHA_SITE_KEY }} SENTRY_ORG: ${{ secrets.SENTRY_ORG }} SENTRY_PROJECT: 'affine-admin' @@ -81,12 +89,13 @@ jobs: build-mobile: name: Build @affine/mobile runs-on: ubuntu-latest - environment: ${{ github.event.inputs.flavor }} + environment: ${{ inputs.build-type }} steps: - uses: actions/checkout@v4 - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Setup Node.js uses: ./.github/actions/setup-node - name: Build Mobile @@ -95,7 +104,7 @@ jobs: R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }} R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} - BUILD_TYPE: ${{ github.event.inputs.flavor }} + BUILD_TYPE: ${{ inputs.build-type }} CAPTCHA_SITE_KEY: ${{ secrets.CAPTCHA_SITE_KEY }} SENTRY_ORG: ${{ secrets.SENTRY_ORG }} SENTRY_PROJECT: 'affine-mobile' @@ -113,7 +122,7 @@ jobs: build-server-native: name: Build Server native - ${{ matrix.targets.name }} runs-on: ubuntu-latest - environment: ${{ github.event.inputs.flavor }} + environment: ${{ inputs.build-type }} strategy: fail-fast: false matrix: @@ -128,8 +137,9 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -161,8 +171,9 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -202,16 +213,6 @@ jobs: with: name: server-dist path: ./packages/backend/server/dist - - name: Setup env - run: | - echo "GIT_SHORT_HASH=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV" - if [ -z "${{ inputs.flavor }}" ] - then - echo "RELEASE_FLAVOR=canary" >> "$GITHUB_ENV" - else - echo "RELEASE_FLAVOR=${{ inputs.flavor }}" >> "$GITHUB_ENV" - fi - - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: @@ -263,8 +264,9 @@ jobs: run: mv ./node_modules ./packages/backend/server - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Build front Dockerfile uses: docker/build-push-action@v6 @@ -275,7 +277,7 @@ jobs: platforms: linux/amd64,linux/arm64 provenance: true file: .github/deployment/front/Dockerfile - tags: ghcr.io/toeverything/affine-front:${{env.RELEASE_FLAVOR}}-${{ env.GIT_SHORT_HASH }},ghcr.io/toeverything/affine-front:${{env.RELEASE_FLAVOR}} + tags: ghcr.io/toeverything/affine-front:${{inputs.build-type}}-${{ inputs.git-short-hash }} - name: Build graphql Dockerfile uses: docker/build-push-action@v6 @@ -286,4 +288,4 @@ jobs: platforms: linux/amd64,linux/arm64,linux/arm/v7 provenance: true file: .github/deployment/node/Dockerfile - tags: ghcr.io/toeverything/affine-graphql:${{env.RELEASE_FLAVOR}}-${{ env.GIT_SHORT_HASH }},ghcr.io/toeverything/affine-graphql:${{env.RELEASE_FLAVOR}} + tags: ghcr.io/toeverything/affine:${{inputs.build-type}}-${{ inputs.git-short-hash }} diff --git a/.github/workflows/build-selfhost-image.yml b/.github/workflows/build-selfhost-image.yml deleted file mode 100644 index c11ed4127..000000000 --- a/.github/workflows/build-selfhost-image.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Build Selfhost Image - -on: - workflow_dispatch: - inputs: - flavor: - description: 'Select distribution to build' - type: choice - default: canary - options: - - canary - - beta - - stable - -permissions: - contents: 'write' - id-token: 'write' - packages: 'write' - -jobs: - build-image: - name: Build Image - uses: ./.github/workflows/build-images.yml - with: - flavor: ${{ github.event.inputs.flavor }} diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 3d96c55ee..04a07805a 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -1359,15 +1359,6 @@ jobs: run: | yarn affine @affine/electron node ./scripts/macos-arm64-output-check.ts - test-build-mobile-app: - uses: ./.github/workflows/release-mobile.yml - with: - build-type: canary - build-target: development - secrets: inherit - permissions: - id-token: 'write' - test-done: needs: - analyze @@ -1398,7 +1389,6 @@ jobs: - desktop-test - desktop-bundle-check - cloud-e2e-test - - test-build-mobile-app if: always() runs-on: ubuntu-latest name: 3, 2, 1 Launch diff --git a/.github/workflows/deploy-automatically.yml b/.github/workflows/deploy-automatically.yml deleted file mode 100644 index f335ff2b1..000000000 --- a/.github/workflows/deploy-automatically.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Deploy Automatically - -on: - push: - tags: - - 'v[0-9]+.[0-9]+.[0-9]+-canary.[0-9]+' - schedule: - - cron: '0 9 * * *' - -permissions: - contents: write - pull-requests: write - actions: write - -jobs: - dispatch-deploy: - runs-on: ubuntu-latest - name: Setup Deploy - steps: - - name: dispatch deploy by tag - if: ${{ github.event_name == 'push' }} - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: deploy.yml - inputs: '{ "flavor": "canary" }' - - name: dispatch deploy by schedule - if: ${{ github.event_name == 'schedule' }} - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: deploy.yml - inputs: '{ "flavor": "canary" }' - ref: canary diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index e956e067a..000000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,189 +0,0 @@ -name: Deploy - -on: - workflow_dispatch: - inputs: - flavor: - description: 'Select what enverionment to deploy to' - type: choice - default: canary - options: - - canary - - beta - - stable - - internal - -permissions: - contents: 'write' - id-token: 'write' - packages: 'write' - -jobs: - output-prev-version: - name: Output previous version - runs-on: ubuntu-latest - environment: ${{ github.event.inputs.flavor }} - outputs: - prev: ${{ steps.print.outputs.version }} - namespace: ${{ steps.print.outputs.namespace }} - steps: - - uses: actions/checkout@v4 - - name: Auth to Cluster - uses: './.github/actions/cluster-auth' - with: - gcp-project-number: ${{ secrets.GCP_PROJECT_NUMBER }} - gcp-project-id: ${{ secrets.GCP_PROJECT_ID }} - service-account: ${{ secrets.GCP_HELM_DEPLOY_SERVICE_ACCOUNT }} - cluster-name: ${{ secrets.GCP_CLUSTER_NAME }} - cluster-location: ${{ secrets.GCP_CLUSTER_LOCATION }} - - name: Output previous version - id: print - run: | - namespace="" - if [ "${{ github.event.inputs.flavor }}" = "canary" ]; then - namespace="dev" - elif [ "${{ github.event.inputs.flavor }}" = "beta" ]; then - namespace="beta" - elif [ "${{ github.event.inputs.flavor }}" = "stable" ]; then - namespace="production" - else - echo "Invalid flavor: ${{ github.event.inputs.flavor }}" - exit 1 - fi - - echo "Namespace set to: $namespace" - - # Get the previous version from the deployment - prev_version=$(kubectl get deployment -n $namespace affine-graphql -o=jsonpath='{.spec.template.spec.containers[0].image}' | awk -F '-' '{print $3}') - - echo "Previous version: $prev_version" - echo "version=$prev_version" >> $GITHUB_OUTPUT - echo "namesapce=$namespace" >> $GITHUB_OUTPUT - - build-images: - name: Build Images - uses: ./.github/workflows/build-images.yml - secrets: inherit - with: - flavor: ${{ github.event.inputs.flavor }} - - deploy: - name: Deploy to cluster - if: ${{ github.event_name == 'workflow_dispatch' }} - environment: ${{ github.event.inputs.flavor }} - needs: - - build-images - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Setup Version - id: version - uses: ./.github/actions/setup-version - - name: Deploy to ${{ github.event.inputs.flavor }} - uses: ./.github/actions/deploy - with: - build-type: ${{ github.event.inputs.flavor }} - gcp-project-number: ${{ secrets.GCP_PROJECT_NUMBER }} - gcp-project-id: ${{ secrets.GCP_PROJECT_ID }} - service-account: ${{ secrets.GCP_HELM_DEPLOY_SERVICE_ACCOUNT }} - cluster-name: ${{ secrets.GCP_CLUSTER_NAME }} - cluster-location: ${{ secrets.GCP_CLUSTER_LOCATION }} - env: - APP_VERSION: ${{ steps.version.outputs.APP_VERSION }} - DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} - CANARY_DEPLOY_HOST: ${{ secrets.CANARY_DEPLOY_HOST }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - DATABASE_URL: ${{ secrets.DATABASE_URL }} - DATABASE_USERNAME: ${{ secrets.DATABASE_USERNAME }} - DATABASE_PASSWORD: ${{ secrets.DATABASE_PASSWORD }} - DATABASE_NAME: ${{ secrets.DATABASE_NAME }} - GCLOUD_CONNECTION_NAME: ${{ secrets.GCLOUD_CONNECTION_NAME }} - REDIS_SERVER_HOST: ${{ secrets.REDIS_SERVER_HOST }} - REDIS_SERVER_PASSWORD: ${{ secrets.REDIS_SERVER_PASSWORD }} - CLOUD_SQL_IAM_ACCOUNT: ${{ secrets.CLOUD_SQL_IAM_ACCOUNT }} - APP_IAM_ACCOUNT: ${{ secrets.APP_IAM_ACCOUNT }} - STATIC_IP_NAME: ${{ secrets.STATIC_IP_NAME }} - AFFINE_INDEXER_SEARCH_PROVIDER: ${{ secrets.AFFINE_INDEXER_SEARCH_PROVIDER }} - AFFINE_INDEXER_SEARCH_ENDPOINT: ${{ secrets.AFFINE_INDEXER_SEARCH_ENDPOINT }} - AFFINE_INDEXER_SEARCH_API_KEY: ${{ secrets.AFFINE_INDEXER_SEARCH_API_KEY }} - - deploy-done: - needs: - - output-prev-version - - build-images - - deploy - if: always() - runs-on: ubuntu-latest - name: Post deploy message - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: actions/checkout@v4 - with: - repository: toeverything/blocksuite - path: blocksuite - fetch-depth: 0 - fetch-tags: true - - name: Setup Node.js - uses: ./.github/actions/setup-node - with: - extra-flags: 'workspaces focus @affine/changelog' - electron-install: false - - name: Output deployed info - if: ${{ always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }} - id: set_info - run: | - if [ "${{ github.event.inputs.flavor }}" = "canary" ]; then - echo "deployed_url=https://affine.fail" >> $GITHUB_OUTPUT - elif [ "${{ github.event.inputs.flavor }}" = "beta" ]; then - echo "deployed_url=https://insider.affine.pro" >> $GITHUB_OUTPUT - elif [ "${{ github.event.inputs.flavor }}" = "stable" ]; then - echo "deployed_url=https://app.affine.pro" >> $GITHUB_OUTPUT - else - exit 1 - fi - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - name: Post Success event to a Slack channel - if: ${{ always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }} - run: node ./tools/changelog/index.js - env: - CHANNEL_ID: ${{ secrets.RELEASE_SLACK_CHNNEL_ID }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - DEPLOYED_URL: ${{ steps.set_info.outputs.deployed_url }} - PREV_VERSION: ${{ needs.output-prev-version.outputs.prev }} - NAMESPACE: ${{ needs.output-prev-version.outputs.namespace }} - DEPLOYMENT: 'SERVER' - FLAVOR: ${{ github.event.inputs.flavor }} - BLOCKSUITE_REPO_PATH: ${{ github.workspace }}/blocksuite - - name: Post Failed event to a Slack channel - id: failed-slack - uses: slackapi/slack-github-action@v2.1.0 - if: ${{ always() && contains(needs.*.result, 'failure') }} - with: - method: chat.postMessage - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - channel: ${{ secrets.RELEASE_SLACK_CHNNEL_ID }} - text: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Backend deploy failed `${{ github.event.inputs.flavor }}`>" - blocks: - - type: section - text: - type: mrkdwn - text: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Backend deploy failed `${{ github.event.inputs.flavor }}`>" - - name: Post Cancel event to a Slack channel - id: cancel-slack - uses: slackapi/slack-github-action@v2.1.0 - if: ${{ always() && contains(needs.*.result, 'cancelled') && !contains(needs.*.result, 'failure') }} - with: - token: ${{ secrets.SLACK_BOT_TOKEN }} - method: chat.postMessage - payload: | - channel: ${{ secrets.RELEASE_SLACK_CHNNEL_ID }} - text: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Backend deploy cancelled `${{ github.event.inputs.flavor }}`>" - blocks: - - type: section - text: - type: mrkdwn - text: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Backend deploy cancelled `${{ github.event.inputs.flavor }}`>" diff --git a/.github/workflows/helm-releaser.yml b/.github/workflows/helm-releaser.yml deleted file mode 100644 index 8047ae2e3..000000000 --- a/.github/workflows/helm-releaser.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: Release Charts - -on: - push: - branches: [canary] - paths: - - '.github/helm/**/Chart.yml' - -jobs: - release: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Checkout Helm chart repo - uses: actions/checkout@v4 - with: - repository: toeverything/helm-charts - path: .helm-chart-repo - ref: gh-pages - token: ${{ secrets.HELM_RELEASER_TOKEN }} - - - name: Install Helm - uses: azure/setup-helm@v4 - - - name: Install chart releaser - run: | - set -e - arch="$(dpkg --print-architecture)" - curl -s https://api.github.com/repos/helm/chart-releaser/releases/latest \ - | yq --indent 0 --no-colors --input-format json --unwrapScalar \ - ".assets[] | select(.name | test("\""^chart-releaser_.+_linux_${arch}\.tar\.gz$"\"")) | .browser_download_url" \ - | xargs curl -SsL \ - | tar zxf - -C /usr/local/bin - - - name: Package charts - working-directory: .helm-chart-repo - run: | - mkdir -p .cr-index - helm repo add bitnami https://charts.bitnami.com/bitnami - helm repo update - - helm dependencies build ../.github/helm/affine - helm dependencies build ../.github/helm/affine-cloud - cr package ../.github/helm/affine - cr package ../.github/helm/affine-cloud - - - name: Publish charts - working-directory: .helm-chart-repo - run: | - set -ex - git config --local user.name "$GITHUB_ACTOR" - git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" - owner=$(cut -d '/' -f 1 <<< '${{ github.repository }}') - repo=helm-charts - git_hash=$(git rev-parse HEAD) - cr upload --commit "$git_hash" \ - --git-repo "$repo" --owner "$owner" \ - --token '${{ secrets.HELM_RELEASER_TOKEN }}' \ - --skip-existing - cr index --git-repo "$repo" --owner "$owner" \ - --token '${{ secrets.HELM_RELEASER_TOKEN }}' \ - --index-path .cr-index --push diff --git a/.github/workflows/label-checker.yml b/.github/workflows/label-checker.yml deleted file mode 100644 index 8138ccdce..000000000 --- a/.github/workflows/label-checker.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Label Checker -on: - pull_request: - types: - - opened - - labeled - - unlabeled - branches: - - canary - -jobs: - check_labels: - name: PR should not have a blocked label - runs-on: ubuntu-latest - steps: - - uses: docker://agilepathway/pull-request-label-checker:latest - with: - none_of: blocked - repo_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pr-auto-assign.yml b/.github/workflows/pr-auto-assign.yml deleted file mode 100644 index 9b2bdb3b2..000000000 --- a/.github/workflows/pr-auto-assign.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: Pull request auto assign - -# on: pull_request -on: - pull_request: - types: [opened, ready_for_review] - -jobs: - add-reviews: - runs-on: ubuntu-latest - steps: - - uses: kentaro-m/auto-assign-action@v2.0.0 diff --git a/.github/workflows/release-automatically.yml b/.github/workflows/release-automatically.yml deleted file mode 100644 index f791eef68..000000000 --- a/.github/workflows/release-automatically.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Release Desktop/Mobile Automatically - -on: - push: - tags: - - 'v[0-9]+.[0-9]+.[0-9]+-canary.[0-9]+' - schedule: - - cron: '0 9 * * *' - -permissions: - contents: write - pull-requests: write - actions: write - -jobs: - dispatch-release-desktop: - runs-on: ubuntu-latest - name: Setup Release Desktop - steps: - - name: dispatch desktop release by tag - if: ${{ github.event_name == 'push' }} - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: release-desktop.yml - inputs: '{ "build-type": "canary", "is-draft": false, "is-pre-release": true }' - - - name: dispatch desktop release by schedule - if: ${{ github.event_name == 'schedule' }} - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: release-desktop.yml - inputs: '{ "build-type": "canary", "is-draft": false, "is-pre-release": true }' - ref: canary - - name: dispatch desktop release by tag - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: release-mobile.yml - inputs: '{ "build-type": "canary", "build-target": "distribution" }' diff --git a/.github/workflows/release-cloud.yml b/.github/workflows/release-cloud.yml new file mode 100644 index 000000000..18b046e71 --- /dev/null +++ b/.github/workflows/release-cloud.yml @@ -0,0 +1,66 @@ +name: Release Cloud + +on: + workflow_call: + inputs: + build-type: + required: true + type: string + app-version: + required: true + type: string + git-short-hash: + required: true + type: string + +permissions: + contents: 'write' + id-token: 'write' + packages: 'write' + +jobs: + build-images: + name: Build Images + uses: ./.github/workflows/build-images.yml + secrets: inherit + with: + build-type: ${{ inputs.build-type }} + app-version: ${{ inputs.app-version }} + git-short-hash: ${{ inputs.git-short-hash }} + + deploy: + name: Deploy to cluster + environment: ${{ inputs.build-type }} + needs: + - build-images + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Deploy to ${{ inputs.build-type }} + uses: ./.github/actions/deploy + with: + gcp-project-number: ${{ secrets.GCP_PROJECT_NUMBER }} + gcp-project-id: ${{ secrets.GCP_PROJECT_ID }} + service-account: ${{ secrets.GCP_HELM_DEPLOY_SERVICE_ACCOUNT }} + cluster-name: ${{ secrets.GCP_CLUSTER_NAME }} + cluster-location: ${{ secrets.GCP_CLUSTER_LOCATION }} + env: + BUILD_TYPE: ${{ inputs.build-type }} + APP_VERSION: ${{ inputs.app-version }} + GIT_SHORT_HASH: ${{ inputs.git-short-hash }} + DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} + CANARY_DEPLOY_HOST: ${{ secrets.CANARY_DEPLOY_HOST }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DATABASE_URL: ${{ secrets.DATABASE_URL }} + DATABASE_USERNAME: ${{ secrets.DATABASE_USERNAME }} + DATABASE_PASSWORD: ${{ secrets.DATABASE_PASSWORD }} + DATABASE_NAME: ${{ secrets.DATABASE_NAME }} + GCLOUD_CONNECTION_NAME: ${{ secrets.GCLOUD_CONNECTION_NAME }} + REDIS_SERVER_HOST: ${{ secrets.REDIS_SERVER_HOST }} + REDIS_SERVER_PASSWORD: ${{ secrets.REDIS_SERVER_PASSWORD }} + CLOUD_SQL_IAM_ACCOUNT: ${{ secrets.CLOUD_SQL_IAM_ACCOUNT }} + APP_IAM_ACCOUNT: ${{ secrets.APP_IAM_ACCOUNT }} + STATIC_IP_NAME: ${{ secrets.STATIC_IP_NAME }} + AFFINE_INDEXER_SEARCH_PROVIDER: ${{ secrets.AFFINE_INDEXER_SEARCH_PROVIDER }} + AFFINE_INDEXER_SEARCH_ENDPOINT: ${{ secrets.AFFINE_INDEXER_SEARCH_ENDPOINT }} + AFFINE_INDEXER_SEARCH_API_KEY: ${{ secrets.AFFINE_INDEXER_SEARCH_API_KEY }} diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index 91ecffd15..2266f257f 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -1,27 +1,17 @@ -name: Release Desktop App +name: Release Desktop on: - workflow_dispatch: + workflow_call: inputs: build-type: - description: 'Build Type' - type: choice required: true - default: canary - options: - - canary - - beta - - stable - is-draft: - description: 'Draft Release?' - type: boolean + type: string + app-version: required: true - default: true - is-pre-release: - description: 'Pre Release? (labeled as "PreRelease")' - type: boolean + type: string + git-short-hash: required: true - default: true + type: string permissions: actions: write @@ -31,7 +21,8 @@ permissions: attestations: write env: - BUILD_TYPE: ${{ github.event.inputs.build-type }} + BUILD_TYPE: ${{ inputs.build-type }} + RELEASE_VERSION: ${{ inputs.app-version }} DEBUG: 'affine:*,napi:*' APP_NAME: affine MACOSX_DEPLOYMENT_TARGET: '10.13' @@ -39,14 +30,13 @@ env: jobs: before-make: runs-on: ubuntu-latest - environment: ${{ github.event.inputs.build-type }} - outputs: - RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }} + environment: ${{ inputs.build-type }} steps: - uses: actions/checkout@v4 - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Setup Node.js uses: ./.github/actions/setup-node - name: Setup @sentry/cli @@ -58,8 +48,8 @@ jobs: SENTRY_PROJECT: 'affine' SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - SENTRY_RELEASE: ${{ steps.version.outputs.APP_VERSION }} - RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }} + SENTRY_RELEASE: ${{ inputs.app-version }} + RELEASE_VERSION: ${{ inputs.app-version }} MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }} - name: Upload web artifact @@ -87,7 +77,7 @@ jobs: target: x86_64-unknown-linux-gnu runs-on: ${{ matrix.spec.runner }} needs: before-make - environment: ${{ github.event.inputs.build-type }} + environment: ${{ inputs.build-type }} env: APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} @@ -97,13 +87,14 @@ jobs: SENTRY_PROJECT: 'affine' SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - SENTRY_RELEASE: ${{ needs.before-make.outputs.RELEASE_VERSION }} + SENTRY_RELEASE: ${{ inputs.app-version }} MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }} steps: - uses: actions/checkout@v4 - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Setup Node.js timeout-minutes: 10 uses: ./.github/actions/setup-node @@ -165,31 +156,31 @@ jobs: if: ${{ matrix.spec.platform == 'darwin' }} run: | mkdir -p builds - mv packages/frontend/apps/electron/out/*/make/*.dmg ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.dmg - mv packages/frontend/apps/electron/out/*/make/zip/darwin/${{ matrix.spec.arch }}/*.zip ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.zip + mv packages/frontend/apps/electron/out/*/make/*.dmg ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.dmg + mv packages/frontend/apps/electron/out/*/make/zip/darwin/${{ matrix.spec.arch }}/*.zip ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.zip - name: Save artifacts (linux) if: ${{ matrix.spec.platform == 'linux' }} run: | mkdir -p builds - mv packages/frontend/apps/electron/out/*/make/zip/linux/${{ matrix.spec.arch }}/*.zip ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.zip - mv packages/frontend/apps/electron/out/*/make/*.AppImage ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.appimage - mv packages/frontend/apps/electron/out/*/make/deb/${{ matrix.spec.arch }}/*.deb ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.deb - mv packages/frontend/apps/electron/out/*/make/flatpak/*/*.flatpak ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.flatpak + mv packages/frontend/apps/electron/out/*/make/zip/linux/${{ matrix.spec.arch }}/*.zip ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.zip + mv packages/frontend/apps/electron/out/*/make/*.AppImage ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.appimage + mv packages/frontend/apps/electron/out/*/make/deb/${{ matrix.spec.arch }}/*.deb ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.deb + mv packages/frontend/apps/electron/out/*/make/flatpak/*/*.flatpak ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.flatpak - uses: actions/attest-build-provenance@v2 if: ${{ matrix.spec.platform == 'darwin' }} with: subject-path: | - ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.zip - ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.dmg + ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.zip + ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.dmg - uses: actions/attest-build-provenance@v2 if: ${{ matrix.spec.platform == 'linux' }} with: subject-path: | - ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.zip - ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.appimage - ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.deb + ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.zip + ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.appimage + ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.deb - name: Upload Artifact uses: actions/upload-artifact@v4 with: @@ -197,7 +188,7 @@ jobs: path: builds package-distribution-windows: - environment: ${{ github.event.inputs.build-type }} + environment: ${{ inputs.build-type }} strategy: fail-fast: false matrix: @@ -221,13 +212,14 @@ jobs: SENTRY_PROJECT: 'affine' SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - SENTRY_RELEASE: ${{ needs.before-make.outputs.RELEASE_VERSION }} + SENTRY_RELEASE: ${{ inputs.app-version }} MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }} steps: - uses: actions/checkout@v4 - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Setup Node.js timeout-minutes: 10 uses: ./.github/actions/setup-node @@ -314,8 +306,9 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Setup Node.js timeout-minutes: 10 uses: ./.github/actions/setup-node @@ -399,16 +392,16 @@ jobs: - name: Save artifacts run: | mkdir -p builds - mv packages/frontend/apps/electron/out/*/make/zip/win32/${{ matrix.spec.arch }}/AFFiNE*-win32-${{ matrix.spec.arch }}-*.zip ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.zip - mv packages/frontend/apps/electron/out/*/make/squirrel.windows/${{ matrix.spec.arch }}/*.exe ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.exe - mv packages/frontend/apps/electron/out/*/make/nsis.windows/${{ matrix.spec.arch }}/*.exe ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.nsis.exe + mv packages/frontend/apps/electron/out/*/make/zip/win32/${{ matrix.spec.arch }}/AFFiNE*-win32-${{ matrix.spec.arch }}-*.zip ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.zip + mv packages/frontend/apps/electron/out/*/make/squirrel.windows/${{ matrix.spec.arch }}/*.exe ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.exe + mv packages/frontend/apps/electron/out/*/make/nsis.windows/${{ matrix.spec.arch }}/*.exe ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.nsis.exe - uses: actions/attest-build-provenance@v2 with: subject-path: | - ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.zip - ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.exe - ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.nsis.exe + ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.zip + ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.exe + ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.nsis.exe - name: Upload Artifact uses: actions/upload-artifact@v4 @@ -465,32 +458,13 @@ jobs: run: | node ./scripts/generate-release-yml.mjs env: - RELEASE_VERSION: ${{ needs.before-make.outputs.RELEASE_VERSION }} - - name: Create Release Draft - if: ${{ github.ref_type == 'tag' }} + RELEASE_VERSION: ${{ env.RELEASE_VERSION }} + - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: - name: ${{ needs.before-make.outputs.RELEASE_VERSION }} - body: '' - draft: ${{ github.event.inputs.is-draft }} - prerelease: ${{ github.event.inputs.is-pre-release }} - files: | - ./release/* - ./release/.env.example - - name: Create Nightly Release Draft - if: ${{ github.ref_type == 'branch' }} - uses: softprops/action-gh-release@v2 - env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} - with: - # Temporarily, treat release from branch as nightly release, artifact saved to AFFiNE-Releases. - # Need to improve internal build and nightly release logic. - repository: 'toeverything/AFFiNE-Releases' - name: ${{ needs.before-make.outputs.RELEASE_VERSION }} - tag_name: ${{ needs.before-make.outputs.RELEASE_VERSION }} - body: '' - draft: false - prerelease: true + name: ${{ env.RELEASE_VERSION }} + draft: ${{ inputs.build-type == 'stable' }} + prerelease: ${{ inputs.build-type != 'stable' }} files: | ./release/* ./release/.env.example diff --git a/.github/workflows/release-mobile.yml b/.github/workflows/release-mobile.yml index b65c35aef..89d5ef7ed 100644 --- a/.github/workflows/release-mobile.yml +++ b/.github/workflows/release-mobile.yml @@ -1,68 +1,33 @@ -name: Release Mobile App +name: Release Mobile on: workflow_call: inputs: - build-target: - description: 'Build Target' + app-version: + type: string + required: true + git-short-hash: type: string required: true build-type: - description: 'Build Type' type: string required: true - workflow_dispatch: - inputs: - build-target: - description: 'Build Target' - type: choice - required: true - default: distribution - options: - - development - - distribution - build-type: - description: 'Build Type' - type: choice - required: true - default: canary - options: - - canary - - beta - - stable + env: - BUILD_TYPE: ${{ inputs.build-type || github.event.inputs.build-type }} - BUILD_TARGET: ${{ inputs.build-target || github.event.inputs.build-target }} + BUILD_TYPE: ${{ inputs.build-type }} DEBUG: napi:* KEYCHAIN_NAME: ${{ github.workspace }}/signing_temp jobs: - output-env: - runs-on: ubuntu-latest - outputs: - ENVIRONMENT: ${{ steps.env.outputs.ENVIRONMENT }} - steps: - - name: Output Environment - id: env - run: | - if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then - echo "ENVIRONMENT=${{ github.event.inputs.build-type }}" >> $GITHUB_OUTPUT - else - echo "ENVIRONMENT=" >> $GITHUB_OUTPUT - fi - build-ios-web: - needs: - - output-env - runs-on: ubuntu-24.04-arm - environment: ${{ needs.output-env.outputs.ENVIRONMENT }} - outputs: - RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }} + runs-on: ubuntu-latest + environment: ${{ inputs.build-type }} steps: - uses: actions/checkout@v4 - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Setup Node.js uses: ./.github/actions/setup-node - name: Setup @sentry/cli @@ -76,8 +41,8 @@ jobs: SENTRY_PROJECT: 'affine' SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - SENTRY_RELEASE: ${{ steps.version.outputs.APP_VERSION }} - RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }} + SENTRY_RELEASE: ${{ inputs.app-version }} + RELEASE_VERSION: ${{ inputs.app-version }} - name: Upload ios artifact uses: actions/upload-artifact@v4 with: @@ -85,17 +50,13 @@ jobs: path: packages/frontend/apps/ios/dist build-android-web: - runs-on: ubuntu-24.04-arm - needs: - - output-env - environment: ${{ needs.output-env.outputs.ENVIRONMENT }} - outputs: - RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }} + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Setup Node.js uses: ./.github/actions/setup-node - name: Setup @sentry/cli @@ -109,8 +70,7 @@ jobs: SENTRY_PROJECT: 'affine' SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - SENTRY_RELEASE: ${{ steps.version.outputs.APP_VERSION }} - RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }} + SENTRY_RELEASE: ${{ inputs.app-version }} - name: Upload android artifact uses: actions/upload-artifact@v4 with: @@ -157,7 +117,7 @@ jobs: package: 'affine_mobile_native' no-build: 'true' - name: Testflight - if: ${{ env.BUILD_TYPE != 'stable' }} + if: ${{ env.BUILD_TYPE == 'beta' }} working-directory: packages/frontend/apps/ios/App run: | echo -n "${{ env.BUILD_PROVISION_PROFILE }}" | base64 --decode -o $PP_PATH @@ -180,8 +140,9 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup Version - id: version uses: ./.github/actions/setup-version + with: + app-version: ${{ inputs.app-version }} - name: Download mobile artifact uses: actions/download-artifact@v4 with: @@ -214,7 +175,7 @@ jobs: - name: Auth gcloud id: auth uses: google-github-actions/auth@v2 - if: ${{ env.BUILD_TARGET == 'distribution' }} + if: ${{ env.BUILD_TYPE != 'canary' }} with: workload_identity_provider: 'projects/${{ secrets.GCP_PROJECT_NUMBER }}/locations/global/workloadIdentityPools/github-actions/providers/github-actions-helm-deploy' service_account: '${{ secrets.GCP_HELM_DEPLOY_SERVICE_ACCOUNT }}' @@ -228,7 +189,7 @@ jobs: cache: 'gradle' - name: Auto increment version code id: bump - if: ${{ env.BUILD_TARGET == 'distribution' }} + if: ${{ env.BUILD_TYPE != 'canary' }} run: yarn affine @affine/playstore-auto-bump bump env: GOOGLE_APPLICATION_CREDENTIALS: ${{ steps.auth.outputs.credentials_file_path }} @@ -240,14 +201,14 @@ jobs: AFFINE_ANDROID_KEYSTORE_PASSWORD: ${{ secrets.AFFINE_ANDROID_KEYSTORE_PASSWORD }} AFFINE_ANDROID_KEYSTORE_ALIAS_PASSWORD: ${{ secrets.AFFINE_ANDROID_KEYSTORE_ALIAS_PASSWORD }} AFFINE_ANDROID_SIGN_KEYSTORE: ${{ secrets.AFFINE_ANDROID_SIGN_KEYSTORE }} - VERSION_NAME: ${{ steps.version.outputs.APP_VERSION }} + VERSION_NAME: ${{ inputs.app-version }} - name: Upload to Google Play uses: r0adkll/upload-google-play@v1 - if: ${{ env.BUILD_TARGET == 'distribution' }} + if: ${{ env.BUILD_TYPE != 'canary' }} with: serviceAccountJson: ${{ steps.auth.outputs.credentials_file_path }} packageName: app.affine.pro - releaseName: ${{ steps.version.outputs.APP_VERSION }} + releaseName: ${{ inputs.app-version }} releaseFiles: packages/frontend/apps/android/App/app/build/outputs/bundle/${{ env.BUILD_TYPE }}Release/app-${{ env.BUILD_TYPE }}-release-signed.aab track: internal status: draft diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..2a973ee09 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,128 @@ +name: Release + +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+-canary.*' + + schedule: + - cron: '0 9 * * *' + + workflow_dispatch: + inputs: + web: + description: 'Release Web?' + required: true + type: boolean + default: false + desktop: + description: 'Release Desktop?' + required: true + type: boolean + default: false + mobile: + description: 'Release Mobile?' + required: true + type: boolean + default: false + +permissions: + contents: write + pull-requests: write + actions: write + +jobs: + prepare: + name: Prepare + runs-on: ubuntu-latest + outputs: + APP_VERSION: ${{ steps.prepare.outputs.APP_VERSION }} + GIT_SHORT_HASH: ${{ steps.prepare.outputs.GIT_SHORT_HASH }} + BUILD_TYPE: ${{ steps.prepare.outputs.BUILD_TYPE }} + steps: + - uses: actions/checkout@v4 + - name: Prepare Release + id: prepare + uses: ./.github/actions/prepare-release + + cloud: + name: Release Cloud + if: ${{ inputs.web || github.event_name != 'workflow_dispatch' }} + runs-on: ubuntu-latest + needs: + - prepare + steps: + - uses: actions/checkout@v4 + - name: Release Cloud + uses: ./.github/workflows/release-cloud.yml + with: + build-type: ${{ needs.prepare.outputs.BUILD_TYPE }} + app-version: ${{ needs.prepare.outputs.APP_VERSION }} + git-short-hash: ${{ needs.prepare.outputs.GIT_SHORT_HASH }} + + release-image: + name: Release Image + runs-on: ubuntu-latest + needs: + - prepare + - cloud + steps: + - uses: trstringer/manual-approval@v1 + if: ${{ needs.prepare.outputs.BUILD_TYPE == 'stable' }} + name: Wait for approval + with: + secret: ${{ secrets.GITHUB_TOKEN }} + approvers: forehalo,fengmk2 + fail-on-denial: true + issue-title: Please confirm to release docker image + issue-body: | + Env: ${{ needs.prepare.outputs.BUILD_TYPE }} + Candidate: ghcr.io/toeverything/affine:${{ needs.prepare.outputs.BUILD_TYPE }}-${{ needs.prepare.outputs.GIT_SHORT_HASH }} + Tag: ghcr.io/toeverything/affine:${{ needs.prepare.outputs.BUILD_TYPE }} + + > comment with "approve", "approved", "lgtm", "yes" to approve + > comment with "deny", "deny", "no" to deny + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + logout: false + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Tag Image + run: | + docker tag ghcr.io/toeverything/affine:${{needs.prepare.outputs.BUILD_TYPE}}-${{needs.prepare.outputs.GIT_SHORT_HASH}} ghcr.io/toeverything/affine:${{needs.prepare.outputs.BUILD_TYPE}} + docker push ghcr.io/toeverything/affine:${{needs.prepare.outputs.BUILD_TYPE}} + + desktop: + name: Release Desktop + if: ${{ inputs.desktop || github.event_name != 'workflow_dispatch' }} + runs-on: ubuntu-latest + needs: + - prepare + steps: + - uses: actions/checkout@v4 + - name: Release Desktop + uses: ./.github/workflows/release-desktop.yml + with: + build-type: ${{ needs.prepare.outputs.BUILD_TYPE }} + app-version: ${{ needs.prepare.outputs.APP_VERSION }} + git-short-hash: ${{ needs.prepare.outputs.GIT_SHORT_HASH }} + + mobile: + name: Release Mobile + if: ${{ inputs.mobile }} + runs-on: ubuntu-latest + needs: + - prepare + steps: + - uses: actions/checkout@v4 + - name: Release Mobile + uses: ./.github/workflows/release-mobile.yml + with: + build-type: ${{ needs.prepare.outputs.BUILD_TYPE }} + app-version: ${{ needs.prepare.outputs.APP_VERSION }} + git-short-hash: ${{ needs.prepare.outputs.GIT_SHORT_HASH }}