Dependency Update and Visual Regression Testing #4
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: Auto update deps + Percy Web (single job) | |
| on: | |
| workflow_dispatch: | |
| schedule: | |
| - cron: "0 6 * * 1" # Mondays 11:30 IST | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| env: | |
| PYTHON_VERSION: "3.11" | |
| NODE_VERSION: "20" | |
| UPDATE_BRANCH: "chore/dep-bumps-${{ github.run_id }}" | |
| jobs: | |
| update-pr-and-percy: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout (base) | |
| uses: actions/checkout@v4 | |
| - name: Set up Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: npm | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| cache: "pip" | |
| - name: Install Node deps | |
| run: | | |
| npm ci || npm install | |
| - name: Create venv & install Python deps | |
| run: | | |
| python -m venv .venv | |
| source .venv/bin/activate | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| - name: Bump Node deps to latest stable (incl. @percy/cli) | |
| run: | | |
| npx --yes npm-check-updates@latest -u --target latest | |
| npm install --save-dev @percy/cli@latest | |
| npm install | |
| - name: Bump Python deps & repin requirements.txt | |
| run: | | |
| set -e | |
| source .venv/bin/activate | |
| pip install --upgrade -r requirements.txt | |
| pip freeze > requirements.txt | |
| - name: Verify percy CLI | |
| run: npx percy --version | |
| - name: Create Pull Request (if changes) | |
| id: cpr | |
| uses: peter-evans/create-pull-request@v6 | |
| with: | |
| branch: ${{ env.UPDATE_BRANCH }} | |
| commit-message: "chore: bump Node & Python deps (incl. @percy/cli) to latest stable" | |
| title: "chore: bump deps to latest stable" | |
| body: | | |
| Automated dependency update: | |
| - Node deps via npm-check-updates (stable) + npm install | |
| - Python deps upgraded and re-pinned via pip freeze | |
| - Ensures latest stable @percy/cli | |
| labels: dependencies, percy | |
| - name: Stop if no PR was created | |
| if: ${{ steps.cpr.outputs.pull-request-number == '' }} | |
| run: | | |
| echo "No changes detected; no PR opened. Skipping Percy run." | |
| echo "pr_created=0" >> $GITHUB_OUTPUT | |
| id: nopr | |
| # === Run Percy Web on the PR branch === | |
| - name: Checkout PR branch | |
| if: ${{ steps.cpr.outputs.pull-request-number != '' }} | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ env.UPDATE_BRANCH }} | |
| - name: Install Node deps (PR branch) | |
| if: ${{ steps.cpr.outputs.pull-request-number != '' }} | |
| run: | | |
| npm ci || npm install | |
| - name: Re-create venv & install Python deps (PR branch) | |
| if: ${{ steps.cpr.outputs.pull-request-number != '' }} | |
| run: | | |
| python -m venv .venv | |
| source .venv/bin/activate | |
| python -m pip install --upgrade pip setuptools wheel | |
| pip install -r requirements.txt | |
| - name: Upgrade Playwright (python) and install browsers + OS deps | |
| if: ${{ steps.cpr.outputs.pull-request-number != '' }} | |
| env: | |
| DEBIAN_FRONTEND: noninteractive | |
| run: | | |
| set -e | |
| source .venv/bin/activate | |
| python -m pip install --upgrade playwright | |
| python -m playwright install --with-deps | |
| - name: Percy Web run | |
| if: ${{ steps.cpr.outputs.pull-request-number != '' }} | |
| id: percy_web | |
| env: | |
| PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_WEB }} | |
| run: | | |
| set -o pipefail | |
| if [ -z "$PERCY_TOKEN" ]; then | |
| echo "Missing PERCY_TOKEN_WEB secret; cannot run Percy Web." | |
| echo "skipped=1" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| ( source .venv/bin/activate && npx percy exec -- .venv/bin/python tests/web/test.py ) 2>&1 | tee percy_web.log | |
| URL=$(grep -Eo 'https://percy.io[^ ]+' percy_web.log | tail -n1 || true) | |
| ID=$(grep -Eo 'Finalized build #[0-9]+' percy_web.log | grep -Eo '[0-9]+' | tail -n1 || true) | |
| STATUS=$? | |
| # If command returned non-zero, mark failure | |
| if [ $STATUS -ne 0 ]; then | |
| echo "success=0" >> $GITHUB_OUTPUT | |
| else | |
| # Percy may still finalize with errors; treat URL presence as success signal | |
| if [ -n "$URL" ]; then echo "success=1" >> $GITHUB_OUTPUT; else echo "success=0" >> $GITHUB_OUTPUT; fi | |
| fi | |
| echo "url=${URL}" >> $GITHUB_OUTPUT | |
| echo "id=${ID}" >> $GITHUB_OUTPUT | |
| - name: Comment on PR with Percy result | |
| if: ${{ steps.cpr.outputs.pull-request-number != '' }} | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const prNumber = Number('${{ steps.cpr.outputs.pull-request-number }}'); | |
| const url = '${{ steps.percy_web.outputs.url }}'; | |
| const id = '${{ steps.percy_web.outputs.id }}'; | |
| const skipped = '${{ steps.percy_web.outputs.skipped }}' === '1'; | |
| const success = '${{ steps.percy_web.outputs.success }}' === '1'; | |
| let body; | |
| if (skipped) { | |
| body = `## Percy Web\nSkipped (missing \`PERCY_TOKEN_WEB\`).`; | |
| } else if (success && url) { | |
| body = `## Percy Web\n✅ Build #${id}\n${url}`; | |
| } else { | |
| body = `## Percy Web\n❌ Build failed (see logs in workflow artifacts).`; | |
| if (url) body += `\nFinalized build URL (may contain error details):\n${url}`; | |
| } | |
| const { context, getOctokit } = require('@actions/github'); | |
| const octokit = getOctokit(process.env.GITHUB_TOKEN); | |
| await octokit.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| body, | |
| }); | |
| - name: Upload Percy logs | |
| if: always() && ${{ steps.cpr.outputs.pull-request-number != '' }} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: percy-web-log | |
| path: percy_web.log | |
| if-no-files-found: ignore |