396 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			YAML
		
	
	
	
	
	
			
		
		
	
	
			396 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			YAML
		
	
	
	
	
	
name: E2E Tests
 | 
						|
on:
 | 
						|
  push:
 | 
						|
    branches:
 | 
						|
      - main
 | 
						|
      - all-e2e # this bypasses `fixme()` using `orRunWhenFullSuiteEnabled()`
 | 
						|
  pull_request:
 | 
						|
  schedule:
 | 
						|
    - cron: 0 * * * *  # hourly
 | 
						|
 | 
						|
concurrency:
 | 
						|
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
 | 
						|
  cancel-in-progress: true
 | 
						|
 | 
						|
permissions:
 | 
						|
  contents: write
 | 
						|
  pull-requests: write
 | 
						|
  actions: read
 | 
						|
 | 
						|
jobs:
 | 
						|
 | 
						|
  conditions:
 | 
						|
    runs-on: ubuntu-latest
 | 
						|
    outputs:
 | 
						|
      significant: ${{ steps.path-changes.outputs.significant }}
 | 
						|
      should-run: ${{ steps.should-run.outputs.should-run }}
 | 
						|
 | 
						|
    steps:
 | 
						|
      - uses: actions/checkout@v4
 | 
						|
 | 
						|
      - name: Fetch the base branch
 | 
						|
        if: ${{ github.event_name == 'pull_request' }}
 | 
						|
        run: git fetch origin ${{ github.base_ref }} --depth=1
 | 
						|
 | 
						|
      - name: Check for path changes
 | 
						|
        id: path-changes
 | 
						|
        shell: bash
 | 
						|
        run: |
 | 
						|
          set -euo pipefail
 | 
						|
 | 
						|
          # Manual runs or push should run all tests.
 | 
						|
          if [[ ${{ github.event_name }} != 'pull_request' ]]; then
 | 
						|
            echo "significant=true" >> $GITHUB_OUTPUT
 | 
						|
            exit 0
 | 
						|
          fi
 | 
						|
 | 
						|
          changed_files=$(git diff --name-only origin/${{ github.base_ref }})
 | 
						|
          echo "$changed_files"
 | 
						|
          if grep -Evq '^README.md|^public/kcl-samples/|^rust/kcl-lib/tests/kcl_samples/' <<< "$changed_files" ; then
 | 
						|
            echo "significant=true" >> $GITHUB_OUTPUT
 | 
						|
          else
 | 
						|
            echo "significant=false" >> $GITHUB_OUTPUT
 | 
						|
          fi
 | 
						|
 | 
						|
      - name: Should run
 | 
						|
        id: should-run
 | 
						|
        shell: bash
 | 
						|
        run: |
 | 
						|
          set -euo pipefail
 | 
						|
          # We should run when this is a scheduled run or if there are
 | 
						|
          # significant changes in the diff.
 | 
						|
          if [[ ${{ github.event_name }} == 'schedule' || ${{ steps.path-changes.outputs.significant }} == 'true' ]]; then
 | 
						|
            echo "should-run=true" >> $GITHUB_OUTPUT
 | 
						|
          else
 | 
						|
            echo "should-run=false" >> $GITHUB_OUTPUT
 | 
						|
          fi
 | 
						|
 | 
						|
      - name: Display conditions
 | 
						|
        shell: bash
 | 
						|
        run: |
 | 
						|
          # For debugging purposes
 | 
						|
          set -euo pipefail
 | 
						|
          echo "GITHUB_REF: $GITHUB_REF"
 | 
						|
          echo "GITHUB_HEAD_REF: $GITHUB_HEAD_REF"
 | 
						|
          echo "GITHUB_BASE_REF: $GITHUB_BASE_REF"
 | 
						|
          echo "significant: ${{ steps.path-changes.outputs.significant }}"
 | 
						|
          echo "should-run: ${{ steps.should-run.outputs.should-run }}"
 | 
						|
 | 
						|
  prepare-wasm:
 | 
						|
    # separate job on Ubuntu to build or fetch the wasm blob once on the fastest runner
 | 
						|
    runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
 | 
						|
    needs: conditions
 | 
						|
    steps:
 | 
						|
      - uses: actions/checkout@v4
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
 | 
						|
      - id: filter
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        name: Check for Rust changes
 | 
						|
        uses: dorny/paths-filter@v3
 | 
						|
        with:
 | 
						|
          filters: |
 | 
						|
            rust:
 | 
						|
              - 'rust/**'
 | 
						|
 | 
						|
      - uses: actions/setup-node@v4
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        with:
 | 
						|
          node-version-file: '.nvmrc'
 | 
						|
          cache: 'yarn'
 | 
						|
 | 
						|
      - name: Install dependencies
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        run: yarn
 | 
						|
 | 
						|
      - name: Download Wasm Cache
 | 
						|
        id: download-wasm
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && github.event_name != 'schedule' && steps.filter.outputs.rust == 'false' }}
 | 
						|
        uses: dawidd6/action-download-artifact@v7
 | 
						|
        continue-on-error: true
 | 
						|
        with:
 | 
						|
          github_token: ${{secrets.GITHUB_TOKEN}}
 | 
						|
          name: wasm-bundle
 | 
						|
          workflow: build-and-store-wasm.yml
 | 
						|
          branch: main
 | 
						|
          path: rust/kcl-wasm-lib/pkg
 | 
						|
 | 
						|
      - name: Build WASM condition
 | 
						|
        id: wasm
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        run: |
 | 
						|
          set -euox pipefail
 | 
						|
          # Build wasm if this is a scheduled run, there are Rust changes, or
 | 
						|
          # downloading from the wasm cache failed.
 | 
						|
          if [[ ${{github.event_name}} == 'schedule' || ${{steps.filter.outputs.rust}} == 'true' || ${{steps.download-wasm.outcome}} == 'failure' ]]; then
 | 
						|
            echo "should-build-wasm=true" >> $GITHUB_OUTPUT
 | 
						|
          else
 | 
						|
            echo "should-build-wasm=false" >> $GITHUB_OUTPUT
 | 
						|
          fi
 | 
						|
 | 
						|
      - name: Use correct Rust toolchain
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
 | 
						|
        shell: bash
 | 
						|
        run: |
 | 
						|
          [ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
 | 
						|
 | 
						|
      - name: Install rust
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
 | 
						|
        uses: actions-rust-lang/setup-rust-toolchain@v1
 | 
						|
        with:
 | 
						|
          cache: false # Configured below.
 | 
						|
 | 
						|
      - uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
 | 
						|
        with:
 | 
						|
          tool: wasm-pack
 | 
						|
 | 
						|
      - name: Rust Cache
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
 | 
						|
        uses: Swatinem/rust-cache@v2
 | 
						|
        with:
 | 
						|
          workspaces: './rust'
 | 
						|
 | 
						|
      - name: Build Wasm
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
 | 
						|
        shell: bash
 | 
						|
        run: yarn build:wasm
 | 
						|
 | 
						|
      - uses: actions/upload-artifact@v4
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        with:
 | 
						|
          name: prepared-wasm
 | 
						|
          path: |
 | 
						|
            rust/kcl-wasm-lib/pkg/kcl_wasm_lib*
 | 
						|
 | 
						|
  snapshots:
 | 
						|
    name: playwright:snapshots:ubuntu
 | 
						|
    runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
 | 
						|
    needs: [conditions, prepare-wasm]
 | 
						|
    steps:
 | 
						|
      - uses: actions/create-github-app-token@v1
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        id: app-token
 | 
						|
        with:
 | 
						|
          app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
 | 
						|
          private-key: ${{ secrets.MODELING_APP_GH_APP_PRIVATE_KEY }}
 | 
						|
          owner: ${{ github.repository_owner }}
 | 
						|
 | 
						|
      - uses: actions/checkout@v4
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        with:
 | 
						|
          token: ${{ steps.app-token.outputs.token }}
 | 
						|
 | 
						|
      - uses: actions/download-artifact@v4
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        name: prepared-wasm
 | 
						|
 | 
						|
      - name: Copy prepared wasm
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        run: |
 | 
						|
          ls -R prepared-wasm
 | 
						|
          cp prepared-wasm/kcl_wasm_lib_bg.wasm public
 | 
						|
          mkdir rust/kcl-wasm-lib/pkg
 | 
						|
          cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
 | 
						|
 | 
						|
      - uses: actions/setup-node@v4
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        with:
 | 
						|
          node-version-file: '.nvmrc'
 | 
						|
          cache: 'yarn'
 | 
						|
 | 
						|
      - name: Install dependencies
 | 
						|
        id: deps-install
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        run: yarn
 | 
						|
 | 
						|
      - name: Cache Playwright Browsers
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        uses: actions/cache@v4
 | 
						|
        with:
 | 
						|
          path: |
 | 
						|
            ~/.cache/ms-playwright/
 | 
						|
          key: ${{ runner.os }}-playwright-${{ hashFiles('yarn.lock') }}
 | 
						|
 | 
						|
      - name: Install Playwright Browsers
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        run: yarn playwright install --with-deps
 | 
						|
 | 
						|
      - name: build web
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        run: yarn tronb:vite:dev
 | 
						|
 | 
						|
      - name: Run ubuntu/chrome snapshots
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        uses: nick-fields/retry@v3.0.2
 | 
						|
        with:
 | 
						|
          shell: bash
 | 
						|
          command: yarn test:snapshots
 | 
						|
          timeout_minutes: 30
 | 
						|
          max_attempts: 3
 | 
						|
        env:
 | 
						|
          token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
 | 
						|
          snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }}
 | 
						|
 | 
						|
      - uses: actions/upload-artifact@v4
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
 | 
						|
        with:
 | 
						|
          name: playwright-report-ubuntu-snapshot-${{ github.sha }}
 | 
						|
          path: playwright-report/
 | 
						|
          include-hidden-files: true
 | 
						|
          retention-days: 30
 | 
						|
          overwrite: true
 | 
						|
 | 
						|
      - name: Check for changes
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && github.ref != 'refs/heads/main' }}
 | 
						|
        shell: bash
 | 
						|
        id: git-check
 | 
						|
        run: |
 | 
						|
            git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
 | 
						|
            if git status | grep -q "Changes to be committed"
 | 
						|
            then echo "modified=true" >> $GITHUB_OUTPUT
 | 
						|
            else echo "modified=false" >> $GITHUB_OUTPUT
 | 
						|
            fi
 | 
						|
 | 
						|
      - name: Commit changes, if any
 | 
						|
        # TODO: find a more reliable way to detect visual changes
 | 
						|
        if: ${{ false && needs.conditions.outputs.should-run == 'true' && steps.git-check.outputs.modified == 'true' }}
 | 
						|
        shell: bash
 | 
						|
        run: |
 | 
						|
          git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
 | 
						|
          git config --local user.email "github-actions[bot]@users.noreply.github.com"
 | 
						|
          git config --local user.name "github-actions[bot]"
 | 
						|
          git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
 | 
						|
          git fetch origin
 | 
						|
          echo ${{ github.head_ref }}
 | 
						|
          git checkout ${{ github.head_ref }}
 | 
						|
          git commit -m "A snapshot a day keeps the bugs away! 📷🐛" || true
 | 
						|
          git push
 | 
						|
          git push origin ${{ github.head_ref }}
 | 
						|
 | 
						|
  electron:
 | 
						|
    needs: [conditions, prepare-wasm]
 | 
						|
    timeout-minutes: 60
 | 
						|
    env:
 | 
						|
      OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}
 | 
						|
    name: playwright:electron:${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}:${{ matrix.shardIndex }}:${{ matrix.shardTotal }}
 | 
						|
    strategy:
 | 
						|
      fail-fast: false
 | 
						|
      matrix:
 | 
						|
        # TODO: enable namespace-profile-windows-latest once available
 | 
						|
        os:
 | 
						|
          - "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
 | 
						|
          - namespace-profile-macos-8-cores
 | 
						|
          - windows-latest-8-cores
 | 
						|
        shardIndex: [1, 2, 3, 4]
 | 
						|
        shardTotal: [4]
 | 
						|
        # Disable macos and windows tests on hourly e2e tests since we only care
 | 
						|
        # about server side changes.
 | 
						|
        # Technique from https://github.com/joaomcteixeira/python-project-skeleton/pull/31/files
 | 
						|
        isScheduled:
 | 
						|
          - ${{ github.event_name == 'schedule' }}
 | 
						|
        exclude:
 | 
						|
          - os: namespace-profile-macos-8-cores
 | 
						|
            isScheduled: true
 | 
						|
          - os: windows-latest-8-cores
 | 
						|
            isScheduled: true
 | 
						|
        # TODO: add ref here for main and latest release tag
 | 
						|
    runs-on: ${{ matrix.os }}
 | 
						|
    steps:
 | 
						|
      - uses: actions/checkout@v4
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
 | 
						|
      - uses: actions/download-artifact@v4
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        name: prepared-wasm
 | 
						|
 | 
						|
      - name: Copy prepared wasm
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        run: |
 | 
						|
          ls -R prepared-wasm
 | 
						|
          cp prepared-wasm/kcl_wasm_lib_bg.wasm public
 | 
						|
          mkdir rust/kcl-wasm-lib/pkg
 | 
						|
          cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
 | 
						|
 | 
						|
      - uses: actions/setup-node@v4
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        with:
 | 
						|
          node-version-file: '.nvmrc'
 | 
						|
          cache: 'yarn'
 | 
						|
 | 
						|
      - name: Install dependencies
 | 
						|
        id: deps-install
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        run: yarn
 | 
						|
 | 
						|
      - name: Cache Playwright Browsers
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        uses: actions/cache@v4
 | 
						|
        with:
 | 
						|
          path: |
 | 
						|
            ~/.cache/ms-playwright/
 | 
						|
          key: ${{ runner.os }}-playwright-${{ hashFiles('yarn.lock') }}
 | 
						|
 | 
						|
      - name: Install Playwright Browsers
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        run: yarn playwright install --with-deps
 | 
						|
 | 
						|
      - name: Build web
 | 
						|
        if: needs.conditions.outputs.should-run == 'true'
 | 
						|
        run: yarn tronb:vite:dev
 | 
						|
 | 
						|
      - name: Install vector
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && contains(matrix.os, 'ubuntu') }}
 | 
						|
        shell: bash
 | 
						|
        run: |
 | 
						|
          curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
 | 
						|
          chmod +x /tmp/vector.sh
 | 
						|
          /tmp/vector.sh -y -no-modify-path
 | 
						|
          mkdir -p /tmp/vector
 | 
						|
          cp .github/workflows/vector.toml /tmp/vector.toml
 | 
						|
          sed -i "s#GITHUB_WORKFLOW#${GITHUB_WORKFLOW}#g" /tmp/vector.toml
 | 
						|
          sed -i "s#GITHUB_REPOSITORY#${GITHUB_REPOSITORY}#g" /tmp/vector.toml
 | 
						|
          sed -i "s#GITHUB_SHA#${GITHUB_SHA}#g" /tmp/vector.toml
 | 
						|
          sed -i "s#GITHUB_REF_NAME#${GITHUB_REF_NAME}#g" /tmp/vector.toml
 | 
						|
          sed -i "s#GH_ACTIONS_AXIOM_TOKEN#${{secrets.GH_ACTIONS_AXIOM_TOKEN}}#g" /tmp/vector.toml
 | 
						|
          cat /tmp/vector.toml
 | 
						|
          ${HOME}/.vector/bin/vector --config /tmp/vector.toml &
 | 
						|
 | 
						|
      - uses: actions/download-artifact@v4
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
 | 
						|
        continue-on-error: true
 | 
						|
        with:
 | 
						|
          name: test-results-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
 | 
						|
          path: test-results/
 | 
						|
 | 
						|
      - name: Run playwright/electron flow (with retries)
 | 
						|
        id: retry
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && steps.deps-install.outcome == 'success' }}
 | 
						|
        uses: nick-fields/retry@v3.0.2
 | 
						|
        with:
 | 
						|
          shell: bash
 | 
						|
          command: .github/ci-cd-scripts/playwright-electron.sh ${{matrix.shardIndex}} ${{matrix.shardTotal}} ${{ env.OS_NAME }}
 | 
						|
          timeout_minutes: 30
 | 
						|
          max_attempts: 9
 | 
						|
        env:
 | 
						|
          FAIL_ON_CONSOLE_ERRORS: true
 | 
						|
          token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
 | 
						|
 | 
						|
      - uses: actions/upload-artifact@v4
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && always() }}
 | 
						|
        with:
 | 
						|
          name: test-results-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
 | 
						|
          path: test-results/
 | 
						|
          include-hidden-files: true
 | 
						|
          retention-days: 30
 | 
						|
          overwrite: true
 | 
						|
 | 
						|
      - uses: actions/upload-artifact@v4
 | 
						|
        if: ${{ needs.conditions.outputs.should-run == 'true' && always() }}
 | 
						|
        with:
 | 
						|
          name: playwright-report-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
 | 
						|
          path: playwright-report/
 | 
						|
          include-hidden-files: true
 | 
						|
          retention-days: 30
 | 
						|
          overwrite: true
 |