dev-tooling #103
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: dev-tooling | |
| # Shape+flow analyzer gate (pyright + semgrep) — ADVISORY in CI, matching the testbed's | |
| # "all test workflows advisory; informative red without gating merges" philosophy. The | |
| # hard zero-FP gate lives in pre-commit (agent-work/dev-tooling/.pre-commit-config.experiment.yaml), | |
| # which runs locally on your own commits. CodeQL is a separate, disabled job (NOTES_codeql.md): | |
| # add it only once the in-editor tools are tuned and a residual flow class remains. | |
| # | |
| # Cross-repo: these analyzers target the gramps SOURCE, not the testbed. We check out the | |
| # sibling gramps fork at ../gramps so the include paths resolve, mirroring the local | |
| # four-sibling workspace layout. Repo/ref resolution matches the other test workflows: | |
| # workflow_dispatch input -> repository variable -> same-owner default. | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| schedule: | |
| - cron: "0 5 * * 1" # weekly, Monday 05:00 UTC — matches the cron cadence of the suite | |
| workflow_dispatch: | |
| inputs: | |
| gramps_repo: | |
| description: "owner/repo of the gramps fork to analyze" | |
| required: false | |
| gramps_ref: | |
| description: "branch/tag/SHA of the gramps fork to analyze" | |
| required: false | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
| jobs: | |
| shape-and-flow: | |
| runs-on: ubuntu-24.04 | |
| # Cap a hung analyzer (pyright/semgrep can spin on a pathological input). | |
| # The analyzers normally finish in a few minutes; 15 is generous. | |
| timeout-minutes: 15 | |
| # ADVISORY at the JOB level — same pattern as unit-tests.yml / addon-unit-tests.yml. | |
| # `continue-on-error` here makes the WORKFLOW conclusion stay green even when the | |
| # JOB is red, so findings don't gate merges. The check-run / job conclusion still | |
| # accurately reflects findings — pyright exits non-zero on type errors, semgrep is | |
| # invoked with --error below so it exits non-zero on rule matches. | |
| # | |
| # Putting `continue-on-error` at the STEP level (as this workflow originally did) | |
| # was wrong: it made the step "succeed" regardless of findings, so the check-run | |
| # went green even when 39 None-flow errors were live in gramps. Findings were | |
| # silently invisible. The job-level placement matches the convention the testbed | |
| # already uses elsewhere. | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout testbed | |
| uses: actions/checkout@v4 | |
| with: | |
| path: gramps-testbed | |
| # Resolve gramps repo/ref: input -> repository variable -> same-owner default. | |
| - name: Resolve gramps source | |
| id: src | |
| run: | | |
| repo="${{ github.event.inputs.gramps_repo }}" | |
| ref="${{ github.event.inputs.gramps_ref }}" | |
| repo="${repo:-${{ vars.GRAMPS_REPO }}}" | |
| ref="${ref:-${{ vars.GRAMPS_REF }}}" | |
| repo="${repo:-${{ github.repository_owner }}/gramps}" | |
| # gramps61: this job is core-defect analysis (pyright/semgrep over | |
| # gramps core source); its findings become CORE PRs, which target | |
| # maintenance/gramps61. So it analyzes the branch core fixes land | |
| # on — distinct from the addon-conformance jobs (which pair gramps60 | |
| # addons against gramps61 core). Analyzing gramps60 here would flag | |
| # against code the fixes won't be written on. | |
| ref="${ref:-maintenance/gramps61}" | |
| echo "repo=$repo" >> "$GITHUB_OUTPUT" | |
| echo "ref=$ref" >> "$GITHUB_OUTPUT" | |
| echo "Analyzing $repo @ $ref" | |
| - name: Checkout gramps fork (sibling) | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: ${{ steps.src.outputs.repo }} | |
| ref: ${{ steps.src.outputs.ref }} | |
| path: gramps | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| - name: Install analyzers | |
| run: pip install --break-system-packages pyright semgrep | |
| # Both analyzers exit non-zero on findings — pyright by default, semgrep via | |
| # --error (without it, semgrep exits 0 regardless of matches). The job-level | |
| # continue-on-error: true above keeps the workflow green; the job/check-run | |
| # accurately reflects whether findings exist. Hard zero-FP blocking lives in | |
| # pre-commit (.pre-commit-config.experiment.yaml), local. | |
| - name: pyright (scoped None-flow) | |
| id: pyright | |
| working-directory: gramps-testbed | |
| run: pyright --project agent-work/dev-tooling/pyright/pyrightconfig.experiment.json | |
| - name: semgrep (gramps shape patterns) | |
| id: semgrep | |
| working-directory: gramps-testbed | |
| run: semgrep --error --config agent-work/dev-tooling/semgrep/rules/ ../gramps/gramps/gui/ | |
| # Rule self-test is NOT advisory: a rule that no longer pairs with its labeled | |
| # fixtures is a tooling regression, not an informative finding about gramps. Fail. | |
| - name: semgrep rule self-test | |
| working-directory: gramps-testbed/agent-work/dev-tooling/semgrep | |
| run: semgrep --test --config rules/ tests/ | |
| - name: Advisory summary | |
| if: always() | |
| run: | | |
| { | |
| echo "## dev-tooling analyzers (advisory)" | |
| echo "" | |
| echo "Source: \`${{ steps.src.outputs.repo }}\` @ \`${{ steps.src.outputs.ref }}\`" | |
| echo "" | |
| echo "| Analyzer | Result |" | |
| echo "| --- | --- |" | |
| echo "| pyright (None-flow) | ${{ steps.pyright.outcome }} |" | |
| echo "| semgrep (shape) | ${{ steps.semgrep.outcome }} |" | |
| echo "" | |
| echo "_Advisory: findings do not gate merges. The hard zero-FP gate is pre-commit, local._" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| # --------------------------------------------------------------------------- | |
| # CodeQL — DISABLED until the residual flow class is reached (see NOTES_codeql.md). | |
| # Owns ONLY path-sensitive flow pyright misses (e.g. 14177 init-order). Do not | |
| # re-implement generic None-deref here. Uncomment + flip `if` when ready. | |
| # --------------------------------------------------------------------------- | |
| # codeql-residual-flow: | |
| # if: false | |
| # runs-on: ubuntu-24.04 | |
| # permissions: | |
| # security-events: write | |
| # steps: | |
| # - uses: actions/checkout@v4 | |
| # with: | |
| # repository: ${{ github.repository_owner }}/gramps | |
| # ref: maintenance/gramps61 # core-analysis branch; see Resolve step | |
| # - uses: github/codeql-action/init@v3 | |
| # with: | |
| # languages: python | |
| # # queries: ./agent-work/dev-tooling/codeql/queries # custom init-order query | |
| # - uses: github/codeql-action/analyze@v3 |