Pull-request check

Check the direct dependencies a pull request adds: the repogates-checkup deps command and a GitHub Actions workflow to copy.

What it checks

The pull-request check is a command of the check-up CLI, repogates-checkup deps. It checks the direct dependencies a pull request adds. It compares the manifests between the pull request and the branch it goes into: package.json (dependencies, devDependencies, optionalDependencies, peerDependencies), requirements*.txt, pyproject.toml ([project] dependencies and optional dependencies, dependency groups, Poetry's dependencies, [tool.uv.sources] and the package indexes it names), and go.mod (require lines, // indirect ones too, and replace directives). Manifests are read at any depth, but never under node_modules/ or vendor/. For every dependency that is new, or whose version changed, it writes the install line (npm install name@spec, pip install 'name<spec>', go get module@version; a URL is sent as the URL, without a user name or password) and asks RepoGates about that line, as the Claude Code plugin's hook does. A dependency named twice with two versions is checked twice. The answer is your policy profile's action:

  • Block: the run exits 1 and the pull request's check fails.
  • Warn: REVIEW, not assessable, a repository the parser cannot resolve, another registry. So is what the manifest shows and RepoGates does not assess: a manifest that names another package index, a pip option this check does not read, an address different tools read differently, a local path, a go.mod replace that points at one. The dependency is listed as a warning, and the check does not fail.
  • Allow: listed as a note.

The limits. Direct dependencies named in the manifest changes only: lockfiles and transitive dependencies are not resolved, and an outage never fails the check. With no token, a token the service refuses, no paid plan, a rate limit or the service out of reach, each dependency is listed as "not assessed" with the reason, and the run exits 0. A dependency that is already on the base branch is not checked again. A pull request that adds more than 100 dependencies fails the check: the dependencies past the hundredth are not checked, and one blocked row says so.

What leaves the runner

One install line per new or changed dependency is sent to POST /v1/preflight, with your API token, and nothing else: never a file's contents. The token is sent only to a RepoGates address, and it is never printed. git runs read-only, with the same flags as repogates-checkup secrets (no external diff, textconv, fsmonitor, ssh or transport). A partial clone, or a repository another user owns, is refused.

The workflow to copy

Save this as .github/workflows/repogates-deps.yml in your repository. The checkout needs the whole history (fetch-depth: 0) to find the merge-base. Each action is pinned to a full commit SHA.

name: RepoGates dependencies
on: pull_request
permissions:
  contents: read
jobs:
  deps:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
        with:
          fetch-depth: 0
      - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
      - name: Check the dependencies this pull request adds
        env:
          REPOGATES_TOKEN: ${{ secrets.REPOGATES_TOKEN }}
        run: >-
          uvx --from https://repogates.com/cli/repogates_checkup-0.3.0-py3-none-any.whl
          repogates-checkup deps --base "origin/${{ github.base_ref }}"
          --summary "$GITHUB_STEP_SUMMARY" --sarif repogates.sarif

The table of dependencies appears on the run's summary page. To also see blocked and warned dependencies as code-scanning alerts on the manifest lines, add security-events: write under permissions and this step at the end:

      - uses: github/codeql-action/upload-sarif@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
        if: always()
        with:
          sarif_file: repogates.sarif

The wheel's SHA-256 is published beside it at /cli/repogates_checkup-0.3.0-py3-none-any.whl.sha256 and on /cli/.

Storing the token

Create a personal API token on your account page (a paid plan is needed for an answer). In the repository's settings, go to Secrets and variables → Actions → New repository secret and save the token under the name REPOGATES_TOKEN. GitHub does not give secrets to a pull request opened from a fork. That run has no token: it lists the dependencies as not assessed and passes.

On your machine

uvx --from https://repogates.com/cli/repogates_checkup-0.3.0-py3-none-any.whl repogates-checkup deps --base origin/main

The token is read from ~/.config/repogates/token or REPOGATES_TOKEN. If both are set to different tokens, nothing is sent. --json prints a stable document (repogates-deps/v1), and --head REF compares another commit than HEAD. Exit codes: 0 nothing blocked, 1 a dependency your policy blocks or more than 100 dependencies to check, 2 a usage error or a git failure.

What it does not see

This check does not see a dependency that is not written in a manifest, such as one installed by a build script, a Dockerfile or a CI step, and it does not see what a dependency brings in. It does not see a lockfile change on its own, or a manifest under node_modules/ or vendor/. It runs only where your workflow runs it.

What it does not see. RepoGates gates downloads made through the browser. It does not see git clone, package managers or curl — outside Claude Code with the RepoGates plugin, whose hook refuses a clone or install that names a blocked repository on the command line, before it runs. The hook sees Bash tool calls in that one client and nothing else. Edit and Write are read for one thing only — an API key about to be saved — checked on the machine and never sent; that guard asks, it never denies. VS Code and Docker Desktop extensions and agent skills are answered through the MCP server and the plugin, not in the browser.

What each answer means: How a decision is made.