name: Build & Test on: push: branches: - master - v[0-9]+.[0-9]+.x-staging - v[0-9]+.[0-9]+.x paths-ignore: - README.md - .github/** - '!.github/workflows/build.yml' - '!.github/actions/build-rust/action.yml' - '!.github/actions/setup-node/action.yml' pull_request: merge_group: branches: - master - v[0-9]+.[0-9]+.x-staging - v[0-9]+.[0-9]+.x paths-ignore: - README.md - .github/** - '!.github/workflows/build.yml' - '!.github/actions/build-rust/action.yml' - '!.github/actions/setup-node/action.yml' env: DEBUG: napi:* APP_NAME: affine COVERAGE: true MACOSX_DEPLOYMENT_TARGET: '10.13' NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} jobs: lint: name: Lint runs-on: ubuntu-latest environment: development steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: ./.github/actions/setup-node - name: Run checks run: | yarn i18n-codegen gen yarn typecheck yarn lint --max-warnings=0 yarn circular build-docs: name: Build Docs runs-on: ubuntu-latest environment: development steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: ./.github/actions/setup-node - run: yarn nx build @affine/docs env: NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} build-storybook: name: Build Storybook runs-on: ubuntu-latest environment: development steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: ./.github/actions/setup-node - run: yarn nx build @affine/storybook env: NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} - name: Upload storybook artifact uses: actions/upload-artifact@v3 with: name: storybook path: ./apps/storybook/storybook-static if-no-files-found: error build-web: name: Build @affine/web runs-on: ubuntu-latest environment: development env: RELEASE_VERSION: canary steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: ./.github/actions/setup-node - name: Build Web run: yarn nx build @affine/web - name: Upload artifact uses: actions/upload-artifact@v3 with: name: next-js path: ./apps/web/.next if-no-files-found: error build-web-desktop: name: Build @affine/web (Desktop) runs-on: ubuntu-latest environment: development env: ENABLE_BOOKMARK_OPERATION: true RELEASE_VERSION: canary steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: ./.github/actions/setup-node - name: Export static resources run: yarn nx export @affine/web - name: Upload static resources artifact uses: actions/upload-artifact@v3 with: name: next-js-static path: ./apps/web/out if-no-files-found: error server-test: name: Server Test runs-on: ubuntu-latest environment: development services: postgres: image: postgres env: POSTGRES_PASSWORD: affine options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: ./.github/actions/setup-node - name: Initialize database run: | psql -h localhost -U postgres -c "CREATE DATABASE affine;" psql -h localhost -U postgres -c "CREATE USER affine WITH PASSWORD 'affine';" psql -h localhost -U postgres -c "ALTER USER affine WITH SUPERUSER;" env: PGPASSWORD: affine - name: Generate prisma client run: | yarn exec prisma generate yarn exec prisma db push working-directory: apps/server env: DATABASE_URL: postgresql://affine:affine@localhost:5432/affine - name: Run init-db script run: yarn exec ts-node-esm ./scripts/init-db.ts working-directory: apps/server env: DATABASE_URL: postgresql://affine:affine@localhost:5432/affine - name: Run server tests run: yarn nx test:coverage @affine/server env: DATABASE_URL: postgresql://affine:affine@localhost:5432/affine - name: Upload server test coverage results uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} files: ./apps/server/.coverage/lcov.info flags: server-test name: affine fail_ci_if_error: true storybook-test: name: Storybook Test runs-on: ubuntu-latest environment: development needs: [build-storybook] steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: ./.github/actions/setup-node with: playwright-install: true - name: Download storybook artifact uses: actions/download-artifact@v3 with: name: storybook path: ./apps/storybook/storybook-static - name: Run storybook tests working-directory: ./apps/storybook run: | yarn exec concurrently -k -s first -n "SB,TEST" -c "magenta,blue" "yarn exec serve ./storybook-static -l 6006" "yarn exec wait-on tcp:6006 && yarn test" e2e-test: name: E2E Test runs-on: ubuntu-latest strategy: fail-fast: false matrix: shard: [1, 2, 3, 4] environment: development needs: [build-web, build-storybook] services: octobase: image: ghcr.io/toeverything/cloud-self-hosted:nightly-latest ports: - 3000:3000 env: SIGN_KEY: 'test123' RUST_LOG: 'debug' JWST_DEV: '1' steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: ./.github/actions/setup-node with: playwright-install: true - name: Download artifact uses: actions/download-artifact@v3 with: name: next-js path: ./apps/web/.next - name: Download storybook artifact uses: actions/download-artifact@v3 with: name: storybook path: ./apps/storybook/storybook-static - name: Wait for Octobase Ready run: | node ./scripts/wait-3000-healthz.mjs - name: Run playwright tests run: yarn e2e --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }} env: COVERAGE: true - name: Collect code coverage report run: yarn exec nyc report -t .nyc_output --report-dir .coverage --reporter=lcov - name: Upload e2e test coverage results uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} files: ./.coverage/lcov.info flags: e2etest name: affine fail_ci_if_error: true - name: Upload test results if: ${{ failure() }} uses: actions/upload-artifact@v3 with: name: test-results-e2e-${{ matrix.shard }} path: ./test-results if-no-files-found: ignore e2e-migration-test: name: E2E Migration Test runs-on: ubuntu-latest environment: development steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: ./.github/actions/setup-node with: playwright-install: true - name: Unzip run: yarn unzip working-directory: ./tests/affine-legacy/0.7.0-canary.18 - name: Run legacy playwright tests run: yarn e2e --forbid-only working-directory: ./tests/affine-legacy/0.7.0-canary.18 desktop-test: name: Desktop Test runs-on: ${{ matrix.spec.os }} environment: development strategy: fail-fast: false # all combinations: macos-latest x64, macos-latest arm64, windows-latest x64, ubuntu-latest x64 matrix: spec: - { os: macos-latest, platform: macos, arch: x64, target: x86_64-apple-darwin, test: true, } - { os: macos-latest, platform: macos, arch: arm64, target: aarch64-apple-darwin, test: false, } - { os: ubuntu-latest, platform: linux, arch: x64, target: x86_64-unknown-linux-gnu, test: true, } - { os: windows-latest, platform: windows, arch: x64, target: x86_64-pc-windows-msvc, test: true, } needs: [build-web-desktop] steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: ./.github/actions/setup-node with: playwright-install: true - name: Build AFFiNE native uses: ./.github/actions/build-rust with: target: ${{ matrix.spec.target }} nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} - name: Run unit tests if: ${{ matrix.spec.test }} shell: bash run: yarn nx test @affine/monorepo env: NATIVE_TEST: 'true' - name: Build layers run: yarn workspace @affine/electron build - name: Download static resource artifact uses: actions/download-artifact@v3 with: name: next-js-static path: ./apps/electron/resources/web-static - name: Run desktop tests if: ${{ matrix.spec.test && matrix.spec.os == 'ubuntu-latest' }} run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn workspace @affine/electron test env: COVERAGE: true - name: Run desktop tests if: ${{ matrix.spec.test && matrix.spec.os != 'ubuntu-latest' }} run: yarn workspace @affine/electron test env: COVERAGE: true - name: Collect code coverage report if: ${{ matrix.spec.test }} run: yarn exec nyc report -t .nyc_output --report-dir .coverage --reporter=lcov - name: Upload e2e test coverage results if: ${{ matrix.spec.test }} uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} files: ./.coverage/lcov.info flags: e2etest-${{ matrix.spec.os }}-${{ matrix.spec.arch }} name: affine fail_ci_if_error: true - name: Upload test results if: ${{ failure() }} uses: actions/upload-artifact@v3 with: name: test-results-e2e-${{ matrix.spec.os }}-${{ matrix.spec.arch }} path: ./test-results if-no-files-found: ignore unit-test: name: Unit Test runs-on: ubuntu-latest environment: development services: octobase: image: ghcr.io/toeverything/cloud-self-hosted:nightly-latest ports: - 3000:3000 env: SIGN_KEY: 'test123' RUST_LOG: 'debug' JWST_DEV: '1' steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: ./.github/actions/setup-node - name: Unit Test run: yarn nx test:coverage @affine/monorepo - name: Upload unit test coverage results uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} files: ./.coverage/store/lcov.info flags: unittest name: affine fail_ci_if_error: true build-docker: if: github.ref == 'refs/heads/master' name: Build Docker needs: - build-web-desktop runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Download next static uses: actions/download-artifact@v3 with: name: next-js-static path: ./apps/web/out - name: Setup Git short hash run: | echo "GIT_SHORT_HASH=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV" - name: Login to GitHub Container Registry uses: docker/login-action@v2 with: registry: ghcr.io logout: false username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Build front Dockerfile uses: docker/build-push-action@v4 with: context: . push: true pull: true platforms: linux/amd64,linux/arm64 provenance: true file: .github/deployment/front/Dockerfile tags: ghcr.io/toeverything/affine-front:${{ env.GIT_SHORT_HASH }},ghcr.io/toeverything/affine-front:latest - name: Setup Node.js uses: ./.github/actions/setup-node with: package-install: false - name: Install Node.js dependencies run: yarn workspaces focus @affine/server --production - name: Build graphql Dockerfile uses: docker/build-push-action@v4 with: context: . push: true pull: true platforms: linux/amd64,linux/arm64 provenance: true file: .github/deployment/node/Dockerfile tags: ghcr.io/toeverything/affine-graphql:${{ env.GIT_SHORT_HASH }},ghcr.io/toeverything/affine-graphql:latest