Skip to content

Repository files navigation

Code Review GitHub Action

AI-powered code review by Single Origin. Reviews pull request files and posts inline comments. Supports reply threading for follow-up conversations.

Setup

Add this workflow to your repository at .github/workflows/review.yml:

name: Code Review
on:
  pull_request:
    types: [opened, synchronize, reopened]
  pull_request_review_comment:
    types: [created]

concurrency:
  group: >-
    ${{ github.event_name == 'pull_request'
        && format('review-{0}', github.event.pull_request.number)
        || format('reply-{0}-{1}', github.event.pull_request.number,
    github.event.comment.id) }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      contents: read
    steps:
      - uses: single-origin/code-review-action@v1
        with:
          backend-url: ${{ secrets.SO_BACKEND_URL }}
          api-key: ${{ secrets.SO_API_KEY }}

Configuring secrets

Add secrets in Github UI.  Navigate to YourRepo → Settings → Secrets and Variables → Actions.

SO_BACKEND_URL

Set SO_BACKEND_URL to https://{yourcompanyname}-api.singleorigin.tech

SO_API_KEY

You can create an API key with these steps:

  • Login to the Single Origin UI, click on the user icon on the top right of the page, navigate to the Account page
  • Choose "Access Tokens"
  • Create an Access Token. This will give you an {id} and {secret}. Save these in a secure place.
  • To derive the string for SO_API_KEY, base64 encode the id and secret with the command echo -n '{id}:{secret}' | base64. Make sure to pass the -n option to avoid a newline in the string.

Inputs

Input Required Default Description
backend-url Yes Backend API base URL
api-key Yes API key (id:secret, base64-encoded)
github-token No github.token GitHub token for API calls
timeout-seconds No 300 Backend request timeout in seconds
file-filter No **/*.sql Glob inclusion filter for file paths (only matching files are reviewed)
upload-artifact No false Upload raw result JSON as artifact for debugging

How It Works

PR Review (pull_request event)

  1. Determines review scope:
    • opened/reopened (or a synchronize with no prior review) → full: all files changed between the base branch and the PR head.
    • synchronize with a prior review → incremental: only files changed since the last review, via the compare API (GET /compare/{lastReviewedSha}...{head}). Falls back to a full review if the branch was force-pushed/rebased (compare status is not ahead).
  2. Filters out binary, deleted, and generated files
  3. Fetches full file content for each reviewable file
  4. Sends files to backend (POST /api/v1/code-review/review) with the scope
  5. Posts a review on the PR (inline comments, or "No new issues found" when there are none), skipping any comment on a line the bot has already commented on

The last-reviewed commit is read back from GitHub itself: every review the action posts is stamped with its head commit, so a review is always posted (even with no comments) to leave that marker for the next incremental run. No server-side state is needed.

Reply Threading (pull_request_review_comment event)

  1. Detects when a user replies to a bot-generated comment
  2. Fetches the full conversation thread and file content
  3. Sends context to backend (POST /api/v1/code-review/reply)
  4. Posts a threaded reply

File Filtering

Only files matching the file-filter glob pattern are reviewed (default: **/*.sql). Examples:

  • **/*.sql — all SQL files
  • **/*.{sql,py} — SQL and Python files
  • src/**/*.sql — SQL files under src/
  • **/{db,migrations}/**/*.sql — SQL files in db/ or migrations/ directories

Set to empty string to match nothing.

Additionally, these are always skipped:

  • Binary files
  • Deleted files
  • Generated/vendor files (node_modules/, vendor/, dist/, *.min.js, lock files, *.pb.go, etc.)

Security

  • Uses pull_request trigger only (safe from fork injection attacks)
  • API key is masked in logs via core.setSecret()
  • GITHUB_TOKEN scoped to minimum permissions (pull-requests: write, contents: read)

Concurrency

  • PR reviews: cancel-in-progress (rapid pushes cancel stale reviews)
  • Reply threads: independent runs per comment

Fork PRs

Fork PRs do not receive reviews. The pull_request trigger provides a read-only GITHUB_TOKEN and no access to repo secrets for fork PRs.

Development

npm install
npm run test         # jest unit tests
npm run package      # rollup bundle to dist/
npm run lint         # eslint
npm run format:write # prettier --write
npm run format:check # prettier --check
npm run all          # format + lint + test + package

The dist/index.js file is committed. After making changes, run npm run package and commit the updated dist/.

Local Testing with local-action

Test against your local backend using @github/local-action:

  1. Copy .env.example to .env and fill in your values
  2. Run: npm run local-action

About

Code review to assess data processing efficiency

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages