Ctrl K
ComunidadGuías…

action.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
name: Repowise CI gates
description: >-
  Gate a pull request on patch coverage, documentation drift, new security
  findings, new code-health findings and change risk, and select the tests it needs. The gates need git
  and nothing else (no index, no API key); test selection reads a cached index.
author: repowise-dev
branding:
  icon: check-circle
  color: blue

inputs:
  checks:
    description: >-
      Comma-separated gates to run: coverage, doc-drift, security, health,
      risk. Coverage needs a report, so it is not on by default. Doc drift
      checks the whole tree; on a repository that already has drift, commit a
      baseline first. Health is opt-in: it fails on code-shape findings the
      change introduces. Risk is opt-in too, and gates only when
      risk-fail-above-percentile is set.
    default: doc-drift,security
  version:
    description: Repowise version to install from PyPI. Empty installs the latest.
    default: ""
  python-version:
    description: Python used to install and run Repowise (3.11 or newer).
    default: "3.12"
  working-directory:
    description: Path inside the repository to run from.
    default: "."
  base:
    description: >-
      Revision range for coverage, security, health and risk, e.g. origin/main...HEAD.
      Empty reads the pull request's target branch, else the default branch.
    default: ""
  coverage-report:
    description: >-
      Coverage reports, one per line. Each line is a path or a glob such as
      artifacts/**/lcov.info (Repowise expands it), optionally path=prefix to
      prepend a directory to that report's paths. Empty uses coverage.paths
      from .repowise/config.yaml, else discovery.
    default: ""
  coverage-fail-under:
    description: >-
      Minimum patch coverage percent. Empty uses coverage.fail_under from
      .repowise/config.yaml, else reports without gating.
    default: ""
  coverage-min-coverable-lines:
    description: >-
      Small-change tolerance: a change with fewer changed executable lines
      than this is reported but never fails the coverage gate. Empty uses
      coverage.min_coverable_lines from .repowise/config.yaml.
    default: ""
  coverage-fail-under-risky:
    description: >-
      Minimum patch coverage percent over risky files only: hotspots or bug
      magnets from the index; on git alone, the top quartile of files with
      bug-fix history. A change with no risky file is not gated. Empty uses
      coverage.fail_under_risky from .repowise/config.yaml, else no risky gate.
    default: ""
  coverage-fail-under-branches:
    description: >-
      Minimum percent of branches taken on changed lines, judged beside patch
      coverage and never blended into it. A change with no branching line is
      not gated; a report without per-line branch data fails the step as
      cannot evaluate (exit 2). Empty uses coverage.fail_under_branches from
      .repowise/config.yaml (where missing branch data is only a note), else
      no branch gate.
    default: ""
  coverage-base-report:
    description: >-
      Coverage reports measured at the change's base commit (the merge-base
      with the target branch), one per line, read like coverage-report. Adds
      project coverage at the base against the head, and the files whose
      coverage changed outside the change.
    default: ""
  coverage-max-drop:
    description: >-
      Most project coverage may fall from the change's base, in percentage
      points. Needs coverage-base-report (or an index that stored coverage at
      the base). Empty uses coverage.max_drop from .repowise/config.yaml, else
      reports without gating.
    default: ""
  doc-drift-baseline:
    description: Committed doc-drift baseline file; only findings it does not list fail.
    default: ""
  security-fail-on:
    description: Lowest severity that fails the security gate (high, med or low).
    default: high
  security-baseline:
    description: Committed security baseline file; only findings it does not list fail.
    default: ""
  fail-on-baseline-growth:
    description: >-
      "true" fails doc-drift and security when their baseline lists a finding
      the same file at the change's base does not, so a change cannot hide new
      findings by re-saving the baseline. A baseline new in the change passes.
    default: "false"
  health-fail-on:
    description: >-
      What fails the health gate: introduced (findings the change wrote) or
      worsened (those, plus findings it made worse). Below it they warn.
    default: introduced
  health-fail-at:
    description: >-
      Lowest severity that fails the health gate (medium, high or critical);
      findings below it warn.
    default: high
  risk-fail-above-percentile:
    description: >-
      Fail when the change ranks above this percentile of the repository's
      recent commits by size and spread: a size gate, not a bug predictor.
      Empty reports the rank without gating.
    default: ""
  comment:
    description: >-
      "true" posts one pull-request comment summarizing every gate and updates
      it in place on each run. The workflow needs the pull-requests write
      permission; on a fork's pull request the comment is skipped with a warning.
    default: "false"
  github-token:
    description: >-
      Token the summary comment is posted with; a later run edits only the
      comment this token's own account posted.
    default: ${{ github.token }}
  upload-sarif:
    description: >-
      "true" uploads doc-drift, security and health findings to GitHub code scanning.
      The workflow needs the security-events write permission.
    default: "false"
  impacted-tests:
    description: >-
      "true" selects the tests the change needs (repowise impacted-tests
      --format args) and sets the impacted-tests and run-all-tests outputs. It
      requires a cached Repowise index: restore .repowise into the working
      directory first, and the step brings it up to date with repowise update
      --index-only. Without one every answer is run-all-tests, with the reason.
    default: "false"
  impacted-tests-runner:
    description: Runner the tests output is written for (auto, pytest, go, jest or files).
    default: auto

outputs:
  coverage:
    description: Exit code of the coverage gate (0 passed, 1 failed, 2 could not evaluate), empty when not run.
    value: ${{ steps.gates.outputs.coverage }}
  doc-drift:
    description: Exit code of the doc-drift gate, empty when not run.
    value: ${{ steps.gates.outputs.doc-drift }}
  security:
    description: Exit code of the security gate, empty when not run.
    value: ${{ steps.gates.outputs.security }}
  health:
    description: Exit code of the health gate, empty when not run.
    value: ${{ steps.gates.outputs.health }}
  risk:
    description: Exit code of the change-risk gate, empty when not run.
    value: ${{ steps.gates.outputs.risk }}
  verdict:
    description: >-
      All gates combined: "fail" when any gate failed or could not evaluate,
      "warn" when any passed with warnings or exited 0 without a result (an
      older Repowise), else "pass". Empty when no gate ran.
    value: ${{ steps.summary.outputs.verdict }}
  sarif-dir:
    description: Directory holding the SARIF files, when upload-sarif is on.
    value: ${{ steps.gates.outputs.sarif-dir }}
  impacted-tests:
    description: With impacted-tests, the runner arguments for the selected tests, or ":all" to run every test.
    value: ${{ steps.impacted.outputs.impacted-tests }}
  run-all-tests:
    description: >-
      With impacted-tests, "false" only when the subset is safe to run alone;
      "true" when every test must run, also when selection could not run.
      Branch on != 'false' so a skipped step runs everything.
    value: ${{ steps.impacted.outputs.run-all-tests }}

runs:
  using: composite
  steps:
    - uses: actions/setup-python@v5
      with:
        python-version: ${{ inputs.python-version }}

    - name: Install Repowise
      shell: bash
      env:
        REPOWISE_VERSION: ${{ inputs.version }}
      run: python -m pip install --quiet "repowise${REPOWISE_VERSION:+==$REPOWISE_VERSION}"

    - name: Select impacted tests
      id: impacted
      if: inputs.impacted-tests == 'true'
      shell: bash
      working-directory: ${{ inputs.working-directory }}
      env:
        BASE: ${{ inputs.base }}
        RUNNER: ${{ inputs.impacted-tests-runner }}
        PYTHONUTF8: "1"
      run: bash "$GITHUB_ACTION_PATH/ci/github/impacted-tests.sh"

    - name: Run gates
      id: gates
      # Test selection alone runs no gate.
      if: inputs.checks != '' || inputs.impacted-tests != 'true'
      shell: bash
      working-directory: ${{ inputs.working-directory }}
      env:
        CHECKS: ${{ inputs.checks }}
        BASE: ${{ inputs.base }}
        COVERAGE_REPORT: ${{ inputs.coverage-report }}
        COVERAGE_FAIL_UNDER: ${{ inputs.coverage-fail-under }}
        COVERAGE_MIN_COVERABLE_LINES: ${{ inputs.coverage-min-coverable-lines }}
        COVERAGE_FAIL_UNDER_RISKY: ${{ inputs.coverage-fail-under-risky }}
        COVERAGE_FAIL_UNDER_BRANCHES: ${{ inputs.coverage-fail-under-branches }}
        COVERAGE_BASE_REPORT: ${{ inputs.coverage-base-report }}
        COVERAGE_MAX_DROP: ${{ inputs.coverage-max-drop }}
        DOC_DRIFT_BASELINE: ${{ inputs.doc-drift-baseline }}
        SECURITY_FAIL_ON: ${{ inputs.security-fail-on }}
        SECURITY_BASELINE: ${{ inputs.security-baseline }}
        FAIL_ON_BASELINE_GROWTH: ${{ inputs.fail-on-baseline-growth }}
        HEALTH_FAIL_ON: ${{ inputs.health-fail-on }}
        HEALTH_FAIL_AT: ${{ inputs.health-fail-at }}
        RISK_FAIL_ABOVE_PERCENTILE: ${{ inputs.risk-fail-above-percentile }}
        SARIF: ${{ inputs.upload-sarif }}
        SARIF_DIR: ${{ runner.temp }}/repowise-sarif
        REPOWISE_GATE_SUMMARY_DIR: ${{ runner.temp }}/repowise-gates
        PYTHONUTF8: "1"
      run: bash "$GITHUB_ACTION_PATH/ci/github/run-gates.sh"

    - name: Summarize gates
      id: summary
      if: ${{ !cancelled() && steps.gates.outcome != 'skipped' }}
      shell: bash
      working-directory: ${{ inputs.working-directory }}
      env:
        EXIT_CODES: >-
          coverage=${{ steps.gates.outputs.coverage }}
          doc-drift=${{ steps.gates.outputs.doc-drift }}
          security=${{ steps.gates.outputs.security }}
          health=${{ steps.gates.outputs.health }}
          risk=${{ steps.gates.outputs.risk }}
        SUMMARY_DIR: ${{ runner.temp }}/repowise-gates
        WORKING_DIRECTORY: ${{ inputs.working-directory }}
        COMMENT: ${{ inputs.comment }}
        GH_TOKEN: ${{ inputs.github-token }}
        PYTHONUTF8: "1"
      run: bash "$GITHUB_ACTION_PATH/ci/github/summary.sh"

    - name: Upload SARIF
      if: always() && inputs.upload-sarif == 'true' && steps.gates.outputs.sarif-dir != ''
      # A fork's pull request has a read-only token; the gates decide the check.
      continue-on-error: true
      uses: github/codeql-action/upload-sarif@v3
      with:
        sarif_file: ${{ steps.gates.outputs.sarif-dir }}