GHA Overhaul #14
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 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| # Inline setup (works with fork PRs) | |
| - 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 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| # Inline setup (works with fork PRs) | |
| - 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 ESLint | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| .eslintcache | |
| node_modules/.cache | |
| key: ${{ runner.os }}-eslint-${{ hashFiles('**/pnpm-lock.yaml', 'eslint.config.js', 'tsconfig.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-eslint-${{ hashFiles('**/pnpm-lock.yaml') }}- | |
| ${{ 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 (eslint-annotate.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 | |
| environment: | |
| name: pr | |
| url: ${{ steps.deploy-url.outputs.url }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| # Inline setup (works with fork PRs) | |
| - 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 | |
| validation-complete: | |
| needs: [test, lint, build] | |
| runs-on: ubuntu-latest | |
| if: always() | |
| steps: | |
| - name: Check validation results | |
| run: | | |
| if [[ "${{ needs.test.result }}" == "failure" ]] || [[ "${{ needs.lint.result }}" == "failure" ]] || [[ "${{ needs.build.result }}" == "failure" ]]; then | |
| echo "::error::PR validation failed" | |
| exit 1 | |
| fi | |
| echo "::notice::✅ All PR validations passed successfully!" |