GHA Overhaul #16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: PR Validation | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| paths-ignore: | |
| - 'docs/**' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| # Inline setup - required for fork PR compatibility | |
| # Cannot use ./.github/actions/setup-pnpm as it won't work from forks | |
| - uses: pnpm/action-setup@v4 | |
| - name: Setup Node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version-file: '.nvmrc' | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile --prefer-offline | |
| - name: Cache Manifest | |
| uses: actions/cache@v4 | |
| with: | |
| path: manifest-cache | |
| key: destiny-manifest-${{ github.run_number }} | |
| restore-keys: | | |
| destiny-manifest- | |
| - name: Run tests | |
| run: pnpm test | |
| env: | |
| CLEAN_MANIFEST_CACHE: true | |
| - name: Upload test results | |
| uses: actions/upload-artifact@v4 | |
| if: success() || failure() | |
| with: | |
| name: test-results | |
| path: junit.xml | |
| retention-days: 7 | |
| lint: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| # Inline setup - required for fork PR compatibility | |
| - uses: pnpm/action-setup@v4 | |
| - name: Setup Node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version-file: '.nvmrc' | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile --prefer-offline | |
| # Optimized cache key: Only invalidate on config changes, not all dependencies | |
| - name: Cache ESLint | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| .eslintcache | |
| node_modules/.cache | |
| key: ${{ runner.os }}-eslint-${{ hashFiles('eslint.config.js', 'tsconfig.json') }}-${{ hashFiles('src/**/*.ts', 'src/**/*.tsx', 'src/**/*.js', 'src/**/*.jsx') }} | |
| restore-keys: | | |
| ${{ runner.os }}-eslint-${{ hashFiles('eslint.config.js', 'tsconfig.json') }}- | |
| ${{ runner.os }}-eslint- | |
| - name: Prettier | |
| run: pnpm lint:prettier | |
| - name: StyleLint | |
| run: pnpm lint:stylelint | |
| - name: ESLint | |
| id: eslint | |
| run: pnpm lint-report:cached | |
| continue-on-error: true | |
| - name: Upload ESLint results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: eslint-results | |
| path: eslint.results.json | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| # Annotation happens in separate workflow (pr-reports.yml) | |
| # This allows annotations to work for fork PRs too | |
| - name: Show ESLint errors in console | |
| if: steps.eslint.outcome == 'failure' | |
| run: pnpm lintcached | |
| - name: Fail if ESLint has errors | |
| if: steps.eslint.outcome == 'failure' | |
| run: | | |
| echo "::error::ESLint found errors - check output above or download artifact for details" | |
| exit 1 | |
| build: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| environment: | |
| name: pr | |
| url: ${{ steps.deploy-url.outputs.url }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| # Inline setup - required for fork PR compatibility | |
| - uses: pnpm/action-setup@v4 | |
| - name: Setup Node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version-file: '.nvmrc' | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile --prefer-offline | |
| - name: Get package version | |
| id: package-version | |
| uses: martinbeentjes/[email protected] | |
| - name: Set version | |
| run: | | |
| echo "VERSION=${{ steps.package-version.outputs.current-version }}.${{ github.run_number }}" >> $GITHUB_ENV | |
| - name: Build PR version | |
| run: pnpm build:pr | |
| env: | |
| NODE_OPTIONS: "--max_old_space_size=8192" | |
| WEB_API_KEY: ${{ secrets.BUNGIE_API_KEY }} | |
| WEB_OAUTH_CLIENT_ID: ${{ secrets.OAUTH_CLIENT_ID }} | |
| WEB_OAUTH_CLIENT_SECRET: ${{ secrets.OAUTH_SECRET }} | |
| DIM_API_KEY: ${{ secrets.DIM_API_KEY }} | |
| PUBLIC_PATH: /${{ github.event.number }}/ | |
| - name: Check for build pipeline updates | |
| id: filter | |
| uses: dorny/paths-filter@v3 | |
| with: | |
| filters: | | |
| build-pipeline: | |
| - package.json | |
| - pnpm-lock.yaml | |
| - config/webpack.ts | |
| - babel.config.cjs | |
| - name: Upload webpack stats | |
| if: steps.filter.outputs.build-pipeline == 'true' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: webpack-stats | |
| path: webpack-stats.json | |
| retention-days: 1 | |
| - name: Install SSH key | |
| if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' }} | |
| uses: benoitchantre/[email protected] | |
| with: | |
| private-key: ${{ secrets.SSH_KEY }} | |
| private-key-name: dim.rsa | |
| known-hosts: ${{ secrets.REMOTE_HOST }} | |
| - name: Check Syntax | |
| if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' }} | |
| run: pnpm syntax | |
| - name: Deploy to preview | |
| if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' }} | |
| run: ./build/rsync-deploy.sh | |
| env: | |
| SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY }} | |
| SOURCE: "dist/" | |
| REMOTE_USER: ${{ secrets.REMOTE_USER }} | |
| REMOTE_HOST: ${{ secrets.REMOTE_HOST }} | |
| REMOTE_PATH: pr.destinyitemmanager.com/${{ github.event.number }} | |
| - name: Purge CloudFlare cache | |
| if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' }} | |
| run: ./build/purge-cloudflare.sh | |
| env: | |
| CLOUDFLARE_KEY: ${{ secrets.CLOUDFLARE_KEY }} | |
| CLOUDFLARE_EMAIL: ${{ secrets.CLOUDFLARE_EMAIL }} | |
| APP_DOMAIN: pr.destinyitemmanager.com/${{ github.event.number }} | |
| - name: Set preview URL | |
| if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' }} | |
| id: deploy-url | |
| run: | | |
| echo "url=https://pr.dim.gg/${{ github.event.number }}/" >> $GITHUB_OUTPUT |