fix: exit edit mode when navigating between tabs in Agreement details #25249
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: Continuous Integration | |
| on: | |
| pull_request: | |
| branches: | |
| - main | |
| push: | |
| branches: [main, development, staging] | |
| paths-ignore: | |
| - ".github/**" # We don't want to trigger when we update the workflows. | |
| - "docs/**" # We don't want to trigger when we update the docs. | |
| - "*.md" | |
| - "terraform/**" | |
| jobs: | |
| secret-scanning: | |
| name: Trufflehog Secret Scanning | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: TruffleHog OSS | |
| id: trufflehog | |
| uses: trufflesecurity/trufflehog@17456f8c7d042d8c82c9a8ca9e937231f9f42e26 # v3.95.2 | |
| env: | |
| GITHUB_HEAD_REF_SAFE: ${{ github.head_ref }} | |
| continue-on-error: true | |
| with: | |
| path: ./ | |
| base: "${{ github.event.repository.default_branch }}" | |
| head: "$GITHUB_HEAD_REF_SAFE" | |
| extra_args: --debug --only-verified | |
| # - name: Setup Trufflehog [Docker] | |
| # env: | |
| # GITHUB_HEAD_REF_SAFE: ${{ github.head_ref }} | |
| # run: docker run --rm -v "$PWD:/pwd" trufflesecurity/trufflehog:3.67.1 git file://. --since-commit main --branch "$GITHUB_HEAD_REF_SAFE" --only-verified --fail | |
| unit-tests: | |
| name: Unit Tests | |
| secrets: inherit # https://docs.github.com/en/actions/using-workflows/reusing-workflows#passing-inputs-and-secrets-to-a-reusable-workflow | |
| uses: ./.github/workflows/unit_test_reusable.yml | |
| e2e-tests: | |
| name: End-to-End Tests | |
| secrets: inherit # https://docs.github.com/en/actions/using-workflows/reusing-workflows#passing-inputs-and-secrets-to-a-reusable-workflow | |
| uses: ./.github/workflows/e2e_test_reusable.yml | |
| a11y-regression: | |
| name: A11y Regression Gate | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: ./.github/actions/setup-javascript | |
| - name: Cache Cypress binary | |
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| path: ~/.cache/Cypress | |
| key: cypress-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('frontend/bun.lock') }} | |
| - name: Install Cypress binary | |
| working-directory: ./frontend | |
| run: | | |
| bunx cypress install | |
| bunx cypress verify | |
| - name: Launch Stack | |
| uses: ./.github/actions/run-full-stack | |
| env: | |
| JWT_PRIVATE_KEY: ${{ secrets.JWT_PRIVATE_KEY }} | |
| JWT_PUBLIC_KEY: ${{ secrets.JWT_PUBLIC_KEY }} | |
| - name: Validate a11y suppression metadata | |
| working-directory: ./frontend | |
| run: bun run a11y:validate-suppressions | |
| - name: Install minimal runtime deps for headless browser | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends dbus-x11 xvfb libgtk-3-0 libnss3 libxss1 libasound2t64 libgbm1 | |
| - name: Run critical accessibility regression specs | |
| working-directory: ./frontend | |
| env: | |
| TERM: xterm | |
| A11Y_REGRESSION_GATE: "true" | |
| JWT_PRIVATE_KEY: ${{ secrets.JWT_PRIVATE_KEY }} | |
| JWT_PUBLIC_KEY: ${{ secrets.JWT_PUBLIC_KEY }} | |
| run: | | |
| dbus-run-session -- npx cypress run \ | |
| --config-file ./cypress.config.ci.js \ | |
| --headless \ | |
| --spec "cypress/e2e/agreementList.cy.js,cypress/e2e/agreementsPagination.cy.js,cypress/e2e/agreementDetails.cy.js,cypress/e2e/portfolioList.cy.js,cypress/e2e/portfolioDetail.cy.js,cypress/e2e/budgetLineItemsList.cy.js,cypress/e2e/createAgreement.cy.js,cypress/e2e/createAgreementWithValidations.cy.js,cypress/e2e/uploadDocument.cy.js,cypress/e2e/notificationCenter.cy.js" | |
| codeql-analysis: | |
| permissions: | |
| actions: read | |
| contents: read | |
| security-events: write | |
| name: CodeQL Scan | |
| uses: ./.github/workflows/security_codeql.yml | |
| semgrep-analysis: | |
| permissions: | |
| security-events: write | |
| name: Semgrep Scan | |
| uses: ./.github/workflows/security_semgrep.yml | |
| lint: | |
| name: Linting | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - name: Check out PR head commit | |
| if: github.event_name == 'pull_request' | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.ref }} | |
| repository: ${{ github.event.pull_request.head.repo.full_name }} | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Check out push commit | |
| if: github.event_name != 'pull_request' | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Detect commit source | |
| id: detect | |
| run: | | |
| COMMITTER_NAME=$(git log -1 --pretty=format:'%cn') | |
| COMMITTER_EMAIL=$(git log -1 --pretty=format:'%ce') | |
| AUTHOR_NAME=$(git log -1 --pretty=format:'%an') | |
| echo "Last committer: $COMMITTER_NAME <$COMMITTER_EMAIL>" | |
| echo "Last author: $AUTHOR_NAME" | |
| if [[ "$AUTHOR_NAME" == *"[bot]"* ]]; then | |
| echo "source=bot" >> $GITHUB_OUTPUT | |
| echo "Bot commit detected — will check formatting (no auto-fix)" | |
| elif [[ "$COMMITTER_NAME" == "GitHub" && "$COMMITTER_EMAIL" == *"noreply@github.com"* ]]; then | |
| echo "source=web-ui" >> $GITHUB_OUTPUT | |
| echo "Web UI commit detected — will auto-format if needed" | |
| else | |
| echo "source=local" >> $GITHUB_OUTPUT | |
| echo "Local commit detected — will check formatting" | |
| fi | |
| - name: Determine formatting strategy | |
| id: strategy | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name || '' }} | |
| CURRENT_REPO: ${{ github.repository }} | |
| SOURCE: ${{ steps.detect.outputs.source }} | |
| run: | | |
| if [[ "$EVENT_NAME" == "pull_request" && "$SOURCE" == "web-ui" && "$HEAD_REPO" == "$CURRENT_REPO" ]]; then | |
| echo "mode=auto-fix" >> $GITHUB_OUTPUT | |
| echo "Same-repo web UI PR detected — will auto-format and push fixes" | |
| else | |
| echo "mode=check" >> $GITHUB_OUTPUT | |
| echo "Formatting will run in check mode" | |
| fi | |
| - uses: ./.github/actions/setup-python | |
| - name: Lint backend | |
| working-directory: ./backend/ops_api | |
| run: pipenv run nox -s lint | |
| # --- For local commits: check formatting (fail build if wrong) --- | |
| - name: Check backend formatting (Black) | |
| if: steps.strategy.outputs.mode == 'check' | |
| working-directory: ./backend/ops_api | |
| run: pipenv run black --config ./pyproject.toml --check ops tests ./noxfile.py ../../performance_tests/locustfile.py | |
| - name: Check backend import sorting (isort) | |
| if: steps.strategy.outputs.mode == 'check' | |
| working-directory: ./backend/ops_api | |
| run: pipenv run isort --settings-file ./pyproject.toml --check-only --filter-files ops tests ./noxfile.py ../../performance_tests/locustfile.py | |
| - name: Install data_tools dependencies | |
| working-directory: ./backend/data_tools | |
| run: pipenv install --dev | |
| - name: Check data_tools formatting (Black) | |
| if: steps.strategy.outputs.mode == 'check' | |
| working-directory: ./backend/data_tools | |
| run: pipenv run black --config ./pyproject.toml --check . | |
| - name: Check data_tools import sorting (isort) | |
| if: steps.strategy.outputs.mode == 'check' | |
| working-directory: ./backend/data_tools | |
| run: pipenv run isort --settings-file ./pyproject.toml --check-only --filter-files . | |
| - uses: ./.github/actions/setup-javascript | |
| - name: Lint frontend | |
| working-directory: ./frontend | |
| run: bun lint | |
| - name: Check frontend formatting | |
| if: steps.strategy.outputs.mode == 'check' | |
| working-directory: ./frontend | |
| run: bun run prettier --check --ignore-unknown 'src/**/*' '!src/uswds/**' | |
| # --- For web UI commits: auto-fix formatting instead of failing --- | |
| - name: Auto-fix backend formatting (Black) | |
| if: steps.strategy.outputs.mode == 'auto-fix' | |
| working-directory: ./backend/ops_api | |
| run: pipenv run black --config ./pyproject.toml ops tests ./noxfile.py ../../performance_tests/locustfile.py | |
| - name: Auto-fix backend import sorting (isort) | |
| if: steps.strategy.outputs.mode == 'auto-fix' | |
| working-directory: ./backend/ops_api | |
| run: pipenv run isort --settings-file ./pyproject.toml --filter-files ops tests ./noxfile.py ../../performance_tests/locustfile.py | |
| - name: Auto-fix data_tools formatting (Black) | |
| if: steps.strategy.outputs.mode == 'auto-fix' | |
| working-directory: ./backend/data_tools | |
| run: pipenv run black --config ./pyproject.toml . | |
| - name: Auto-fix data_tools import sorting (isort) | |
| if: steps.strategy.outputs.mode == 'auto-fix' | |
| working-directory: ./backend/data_tools | |
| run: pipenv run isort --settings-file ./pyproject.toml --filter-files . | |
| - name: Auto-fix frontend formatting (Prettier) | |
| if: steps.strategy.outputs.mode == 'auto-fix' | |
| working-directory: ./frontend | |
| run: bun run prettier --write --ignore-unknown 'src/**/*' '!src/uswds/**' | |
| - name: Commit and push formatting fixes | |
| id: auto-commit | |
| if: steps.strategy.outputs.mode == 'auto-fix' | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add -A | |
| if git diff --staged --quiet; then | |
| echo "committed=none" >> $GITHUB_OUTPUT | |
| echo "No formatting changes needed" | |
| else | |
| git commit -m "style: auto-format code (web UI commit)" | |
| git push | |
| echo "committed=true" >> $GITHUB_OUTPUT | |
| echo "Formatting fixes committed and pushed" | |
| fi | |
| - name: Comment on PR — formatting auto-fixed | |
| if: | | |
| steps.detect.outputs.source == 'web-ui' && | |
| steps.auto-commit.outputs.committed == 'true' && | |
| github.event_name == 'pull_request' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| CONTRIBUTING_URL: ${{ github.server_url }}/${{ github.repository }}/blob/${{ github.event.pull_request.head.sha }}/CONTRIBUTING.md | |
| run: | | |
| BODY=$(cat <<EOF | |
| 🤖 **Auto-formatting applied!** | |
| I detected that this PR was edited via the GitHub web UI and had some formatting issues. I automatically applied fixes using: | |
| - **Prettier** (frontend) | |
| - **Black** + **isort** (backend) | |
| The fixes have been committed to this branch. For future contributions, consider setting up the [local development environment]($CONTRIBUTING_URL) to run formatters before pushing - it avoids this extra round-trip. | |
| EOF | |
| ) | |
| gh pr comment "$PR_NUMBER" --body "$BODY" |