diff --git a/.github/actions/pnpm-cache/action.yml b/.github/actions/pnpm-cache/action.yml deleted file mode 100644 index 0af26d52f..000000000 --- a/.github/actions/pnpm-cache/action.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: 'pnpm Cache' -description: 'Restore or save pnpm store cache' - -inputs: - mode: - description: 'Whether to restore or save the cache' - required: true - path: - description: 'Custom cache path (defaults to pnpm store path)' - required: false - key-prefix: - description: 'Cache key prefix (defaults to {runner.os}-pnpm-store)' - required: false - cache-hit: - description: 'Whether cache was hit (required for save mode)' - required: false - cache-key: - description: 'Cache key to use for saving (required for save mode)' - required: false - -outputs: - cache-hit: - description: 'Whether cache was restored' - value: ${{ steps.cache-restore.outputs.cache-hit }} - cache-key: - description: 'Cache key for use in save step' - value: ${{ steps.cache-restore.outputs.cache-primary-key }} - -runs: - using: 'composite' - steps: - # Restore mode steps - - name: Get pnpm store directory - if: inputs.mode == 'restore' && inputs.path == '' - id: pnpm-store - shell: bash - run: echo "path=$(pnpm store path)" >> $GITHUB_OUTPUT - - - name: Compute cache key prefix - if: inputs.mode == 'restore' - id: key-prefix - shell: bash - run: | - if [ -n "${{ inputs.key-prefix }}" ]; then - echo "value=${{ inputs.key-prefix }}" >> $GITHUB_OUTPUT - else - echo "value=${{ runner.os }}-pnpm-store" >> $GITHUB_OUTPUT - fi - - - name: Restore pnpm cache - if: inputs.mode == 'restore' - id: cache-restore - uses: actions/cache/restore@v4 - with: - path: ${{ inputs.path || steps.pnpm-store.outputs.path }} - key: ${{ steps.key-prefix.outputs.value }}-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ steps.key-prefix.outputs.value }}- - - # Save mode steps - - name: Get pnpm store directory for save - if: inputs.mode == 'save' && inputs.cache-hit != 'true' && inputs.path == '' - id: pnpm-store-save - shell: bash - run: echo "path=$(pnpm store path)" >> $GITHUB_OUTPUT - - - name: Save pnpm cache - if: inputs.mode == 'save' && inputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - path: ${{ inputs.path || steps.pnpm-store-save.outputs.path }} - key: ${{ inputs.cache-key }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7fc5adc77..feec74f3b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,140 +11,24 @@ on: - '*' jobs: - lint: + check: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - name: Lint + command: pnpm lint + - name: Type check + command: pnpm typecheck + - name: Unit tests + command: pnpm test:unit + - name: Knip + command: pnpm knip + name: ${{ matrix.name }} steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Setup + uses: complexdatacollective/github-actions/setup-pnpm@v1 - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' - - - name: Install pnpm - uses: pnpm/action-setup@v4 - - - name: Restore pnpm cache - id: cache - uses: ./.github/actions/pnpm-cache - with: - mode: restore - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Lint - run: pnpm lint - - - name: Save pnpm cache - if: always() - uses: ./.github/actions/pnpm-cache - with: - mode: save - cache-hit: ${{ steps.cache.outputs.cache-hit }} - cache-key: ${{ steps.cache.outputs.cache-key }} - - typecheck: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' - - - name: Install pnpm - uses: pnpm/action-setup@v4 - - - name: Restore pnpm cache - id: cache - uses: ./.github/actions/pnpm-cache - with: - mode: restore - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Type check - run: pnpm typecheck - - - name: Save pnpm cache - if: always() - uses: ./.github/actions/pnpm-cache - with: - mode: save - cache-hit: ${{ steps.cache.outputs.cache-hit }} - cache-key: ${{ steps.cache.outputs.cache-key }} - - test: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' - - - name: Install pnpm - uses: pnpm/action-setup@v4 - - - name: Restore pnpm cache - id: cache - uses: ./.github/actions/pnpm-cache - with: - mode: restore - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Run unit tests - run: pnpm test:unit - - - name: Save pnpm cache - if: always() - uses: ./.github/actions/pnpm-cache - with: - mode: save - cache-hit: ${{ steps.cache.outputs.cache-hit }} - cache-key: ${{ steps.cache.outputs.cache-key }} - - knip: - env: - SKIP_ENV_VALIDATION: true - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' - - - name: Install pnpm - uses: pnpm/action-setup@v4 - - - name: Restore pnpm cache - id: cache - uses: ./.github/actions/pnpm-cache - with: - mode: restore - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Run knip - run: pnpm knip - - - name: Save pnpm cache - if: always() - uses: ./.github/actions/pnpm-cache - with: - mode: save - cache-hit: ${{ steps.cache.outputs.cache-hit }} - cache-key: ${{ steps.cache.outputs.cache-key }} + - name: ${{ matrix.name }} + run: ${{ matrix.command }} diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index cb9cbba11..65620191c 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -10,17 +10,11 @@ jobs: name: Run Chromatic runs-on: ubuntu-latest steps: - - name: Checkout code - uses: actions/checkout@v4 + - name: Setup + uses: complexdatacollective/github-actions/setup-pnpm@v1 with: - fetch-depth: 0 - - name: Install pnpm - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 - with: - cache: 'pnpm' - - name: Install dependencies - run: pnpm install --frozen-lockfile + fetch-depth: '0' + - name: Run Chromatic uses: chromaui/action@latest with: diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 9dcbf280c..c0620b71e 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -7,9 +7,9 @@ permissions: pull-requests: write on: + workflow_dispatch: push: branches: [main, next] - pull_request: jobs: e2e: @@ -19,24 +19,13 @@ jobs: test-result: ${{ steps.test.outcome }} steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 + - name: Setup + id: setup + uses: complexdatacollective/github-actions/setup-pnpm@v1 with: - node-version-file: '.nvmrc' - - - name: Install pnpm - uses: pnpm/action-setup@v4 - - - name: Restore pnpm cache - id: cache - uses: ./.github/actions/pnpm-cache - with: - mode: restore - path: .pnpm-docker-store - key-prefix: pnpm-docker-store + install: 'false' + cache-path: .pnpm-docker-store + cache-key-prefix: pnpm-docker-store - name: Run E2E tests id: test @@ -63,18 +52,44 @@ jobs: retention-days: 7 - name: Save pnpm cache - if: always() - uses: ./.github/actions/pnpm-cache + if: always() && steps.setup.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 with: - mode: save path: .pnpm-docker-store - cache-hit: ${{ steps.cache.outputs.cache-hit }} - cache-key: ${{ steps.cache.outputs.cache-key }} + key: ${{ steps.setup.outputs.cache-key }} + + # Resolve PR context for both pull_request and workflow_dispatch events + resolve-pr: + if: failure() && needs.e2e.outputs.test-result == 'failure' + needs: e2e + runs-on: ubuntu-latest + outputs: + pr-number: ${{ steps.pr.outputs.number }} + head-sha: ${{ steps.pr.outputs.head_sha }} + branch: ${{ steps.pr.outputs.branch }} + steps: + - name: Resolve PR context + id: pr + env: + GH_TOKEN: ${{ github.token }} + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + echo "number=${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT" + echo "head_sha=${{ github.event.pull_request.head.sha }}" >> "$GITHUB_OUTPUT" + echo "branch=${{ github.head_ref }}" >> "$GITHUB_OUTPUT" + else + PR_NUMBER=$(gh pr list --repo "${{ github.repository }}" --head "${{ github.ref_name }}" --json number --jq '.[0].number') + if [ -n "$PR_NUMBER" ] && [ "$PR_NUMBER" != "null" ]; then + echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT" + fi + echo "head_sha=${{ github.sha }}" >> "$GITHUB_OUTPUT" + echo "branch=${{ github.ref_name }}" >> "$GITHUB_OUTPUT" + fi # Deploy report to GitHub Pages on test failure (PR-specific subdirectory) deploy-report: - if: failure() && github.event_name == 'pull_request' && needs.e2e.outputs.test-result == 'failure' - needs: e2e + if: failure() && needs.resolve-pr.outputs.pr-number != '' + needs: [e2e, resolve-pr] runs-on: ubuntu-latest # Single concurrency group for all Pages deployments to prevent race conditions concurrency: @@ -82,7 +97,7 @@ jobs: cancel-in-progress: false environment: name: github-pages - url: https://complexdatacollective.github.io/Fresco/pr-${{ github.event.pull_request.number }}/ + url: https://complexdatacollective.github.io/Fresco/pr-${{ needs.resolve-pr.outputs.pr-number }}/ steps: - name: Download playwright report @@ -110,8 +125,8 @@ jobs: fi # Create PR-specific subdirectory with new report - mkdir -p merged/pr-${{ github.event.pull_request.number }} - cp -r new-report/playwright-report/* merged/pr-${{ github.event.pull_request.number }}/ + mkdir -p merged/pr-${{ needs.resolve-pr.outputs.pr-number }} + cp -r new-report/playwright-report/* merged/pr-${{ needs.resolve-pr.outputs.pr-number }}/ # Generate index page listing all reports echo "