kedgeway

Docs / Integrations / GitHub Action

GitHub Action

Run kedgeway on every pull request and fail the build when a finding meets your threshold, or run it on a schedule and let it open the migration pull request.

Quick start

Terminal
kedgeway init

This writes .github/workflows/kedgeway.yml, pinned to the installed version. Then add the secret: run kedgeway login --export and save its output as a repository secret named KEDGEWAY_AUTH. Use --print to preview the YAML and --force to overwrite an existing file. See Commands.

Use it

Terminal
- uses: actions/checkout@v4
- uses: Klorenn/kedgeway@v0.1.0
  with:
    path: .
    fail-on: warning
    auth: ${{ secrets.KEDGEWAY_AUTH }}   # live Raven data; or use fixture: for offline

Pin a release tag as above. @main is unpinned and can change under you.

Inputs and outputs

InputDefaultMeaning
modediagnosediagnose reports findings. pr opens or updates a pull request with the migration edits. See Open a migration PR.
path.Directory to scan.
repononeRepository URL or owner/repo to scan instead of path. It is shallow-cloned and deleted afterwards. Annotations are not emitted for it, because its paths are not in the checkout.
fail-onwarningFail on any finding at or above this severity. Empty disables.
fixturenoneEcosystem snapshot JSON (offline). Set this or auth.
authnoneRaven credentials from kedgeway login --export, as a secret. Set this or fixture.
jsonfalsePrint JSON instead of text.
sariffalseAlso write SARIF 2.1.0 to $RUNNER_TEMP/kedgeway.sarif.
versionthe pinned tagkedgeway version to run. Accepts a semver such as 1.2.3, or source to force the source build.
annotationson in ActionsEmit a GitHub annotation, with file and line, for each finding. Set "false" to disable.
pr-basenonemode: pr only. Branch the pull request targets. Empty uses the repository's default branch.
pr-branchnonemode: pr only. Head branch to push. Empty uses kedgeway/migrate-<major>. Force-pushed with a lease; must start with kedgeway/.
pr-draftfalsemode: pr only. Open the pull request as a draft.
refresh-lockfilesfalsemode: pr only. Also refresh the lockfiles the plan touched, when the tool is installed on the runner.
token${{ github.token }}mode: pr only. GitHub token used to push and to call the API. Defaults to the workflow token.

Outputs: summary (for example critical=0 warning=1 info=2), report-json (the path of the JSON report under RUNNER_TEMP) and sarif (the SARIF file path, only when sarif is on). With mode: pr, also pr-url and pr-action.

Auth or a fixture is required

The action needs one of two inputs, and names both if neither is set.

  • auth: your KEDGEWAY_AUTH secret, for live Raven data. Export it with kedgeway login --export.
  • fixture: a committed snapshot (see Fixtures). Offline and deterministic; you refresh it.

Annotations

With annotations on, which is the default when the action runs on GitHub, each finding becomes a workflow command pointing at the dependency's line in its manifest. Critical is ::error, warning is ::warning, info is ::notice. On a pull request they show on the changed files in the diff. No extra permission or step is needed.

  • GitHub caps annotations at 10 per type (error, warning, notice) per step and 50 per job. A large repo shows only the first ones; the full report is still printed in the log.
  • Findings that are not about a file, such as DATA_DEGRADED and NO_SDK_FOUND, have no file and show on the run instead.
  • The line comes from a plain scan of the manifest (the first matching key), so it is best effort. Paths are relative to the directory the action runs from.
  • Finding text is sanitised before it is printed, so a manifest cannot inject workflow commands.

Outside Actions, use kedgeway diagnose --format annotations or --annotations <file>. See Commands. SARIF below is separate and stays: it feeds code scanning, annotations feed the diff.

Open a migration PR

With mode: pr the action runs kedgeway pr: when your SDK versions are behind, it pushes the branch kedgeway/migrate-<major> and opens one pull request with the edits, the findings, the manual steps as a checklist and the migration guide. Later runs update the same pull request. When there is nothing to edit, the run is skipped. The repo input is not supported here, because a pull request needs the local checkout. See Commands for the full flow.

Terminal
kedgeway init --mode pr
Terminal
name: kedgeway-pr

on:
  schedule:
    - cron: "0 9 * * 1"
  workflow_dispatch:

permissions:
  contents: write
  pull-requests: write

concurrency:
  group: kedgeway-pr
  cancel-in-progress: false

jobs:
  kedgeway-pr:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          persist-credentials: false
      - uses: Klorenn/kedgeway@v0.3.0
        with:
          mode: pr
          auth: ${{ secrets.KEDGEWAY_AUTH }}

kedgeway init --mode pr writes this file as .github/workflows/kedgeway-pr.yml, pinned to the installed version. It runs every Monday at 09:00 UTC and on demand. Add the KEDGEWAY_AUTH secret as for diagnose.

It needs:

  • permissions: contents: write and pull-requests: write on the workflow or job. The generated file sets them.
  • actions/checkout with fetch-depth: 0, so the base branch history is available to branch from.
  • persist-credentials: false on the checkout, so no token is left in .git/config. The generated workflow sets it.
  • A concurrency group, kedgeway-pr, so two runs never overlap. The generated workflow sets it.
  • A push host of github.com, or the host of GITHUB_API_URL on GitHub Enterprise Server. Otherwise the run exits 2 and the token is never sent.
  • With refresh-lockfiles, Yarn 1 is skipped and Yarn 2+ runs with scripts disabled.
  • The repository setting "Allow GitHub Actions to create and approve pull requests" (Settings, Actions, General, Workflow permissions). An organization must allow it first at the organization level. Without it GitHub answers 403; kedgeway prints GitHub's message with a hint pointing at this setting and exits 1.

In mode: pr the action also sets pr-url (the pull request that was created or updated, empty when skipped) and pr-action (create, update or skip).

SARIF and code scanning

Terminal
permissions:
  contents: read
  security-events: write
steps:
  - uses: actions/checkout@v4
  - id: kedgeway
    uses: Klorenn/kedgeway@v0.1.0
    with:
      auth: ${{ secrets.KEDGEWAY_AUTH }}
      sarif: "true"
      fail-on: ""            # let the upload step report instead of failing here
  - uses: github/codeql-action/upload-sarif@v3
    if: always()
    with:
      sarif_file: ${{ steps.kedgeway.outputs.sarif }}

The log has one run for the tool kedgeway, a rule per finding code (18), and one result per finding with the repo-relative manifest path. Critical is an error, warning is a warning, info is a note. Findings that are not about a file, such as DATA_DEGRADED and NO_SDK_FOUND, have no location.

Exit codes and speed

The action runs diagnose once, always writes its outputs, then exits with the CLI's code: 0 when nothing met the threshold, 2 when a finding did, 1 on a tool error. Pinning a release tag (uses: Klorenn/kedgeway@v1.2.3) installs exactly that version from npm with no build step, and fails with a clear error if the version is not published. Any other ref (@main, a commit SHA, a branch) builds the checked-out source with npm ci && npm run build, which is slower, and @main is unpinned. The npm install path applies to tags cut after this change; v0.1.0 still builds from source.

With mode: pr it runs kedgeway pr instead: 0 when the pull request was created or updated, or the run was skipped; 1 on a git or API failure; 2 on a usage error.