Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,15 @@ Prove the refund use case with working platform integrations.
| [WooCommerce Plugin](examples/ecommerce/woocommerce/) | WordPress plugin for order/refund verification | 🚧 In Progress | Community |
| [Stripe Connect Verification](examples/ecommerce/stripe/) | Webhook handler for Stripe Connect payouts | 📋 Planned | Community |

### 🔌 **Platform Integrations**
Bring APort verification into platforms that already govern developer workflows.

| Integration | Description | Status | Maintainer |
|-------------|-------------|--------|------------|
| [GitHub PR Verifier](examples/platform-integrations/github-app/) | GitHub App for APort-backed PR checks | ✅ Active | Community |
| Zapier App | Custom Zapier app for APort verification | 🚧 In Progress | Community |
| Discord Bot | Team verification workflows | 📋 Planned | Community |

### 🔧 **Developer Experience Tools**
Reduce APort integration time from hours to minutes.

Expand Down
86 changes: 86 additions & 0 deletions examples/platform-integrations/github-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# APort GitHub PR Verifier

GitHub App example that blocks or approves pull requests with an APort policy check.

The app receives `pull_request` webhooks, sends repository and pull request context to APort, then writes a GitHub Check Run named `APort policy verification` on the pull request head commit.

## What It Does

- Verifies pull requests against a configurable APort policy pack.
- Supports different policies through `APORT_POLICY_PACK`.
- Passes PR context such as base branch, head SHA, author, labels, file counts, and configured allowed base branches.
- Creates a GitHub Check Run with `success`, `failure`, or `neutral`.
- Handles webhook signature verification, installation authentication, API failures, and missing configuration.

## Quick Start

```bash
npm install
cp env.example .env
npm start
```

Expose the local server to GitHub with a tunnel such as `ngrok` and set the GitHub App webhook URL to:

```text
https://your-public-url.example/webhooks/github
```

## GitHub App Setup

Create a GitHub App with:

- Webhook event: `Pull request`
- Repository permission: `Checks: Read and write`
- Repository permission: `Pull requests: Read-only`
- Webhook secret matching `GITHUB_WEBHOOK_SECRET`

Install the app on the repositories you want to protect.

## Configuration

| Variable | Required | Description |
| --- | --- | --- |
| `GITHUB_APP_ID` | Yes | GitHub App numeric ID. |
| `GITHUB_PRIVATE_KEY` | Yes | GitHub App private key. Newlines may be escaped as `\n`. |
| `GITHUB_WEBHOOK_SECRET` | Yes | Secret used to verify GitHub webhook signatures. |
| `APORT_API_KEY` | Yes | API key used to call APort. |
| `APORT_AGENT_ID` | Yes | APort passport/agent identity for this GitHub App. |
| `APORT_BASE_URL` | No | Defaults to `https://aport.io`. |
| `APORT_POLICY_PACK` | No | Defaults to `code.repository.merge.v1`. |
| `APORT_ALLOWED_BASE_BRANCHES` | No | Comma-separated branch list included in policy context. |
| `APORT_FAIL_ON_ERROR` | No | Defaults to `true`; set `false` to make API errors neutral. |

## Policy Context

The app sends this shape to APort:

```json
{
"event": "pull_request",
"action": "opened",
"repository": {
"full_name": "aporthq/example",
"default_branch": "main"
},
"pull_request": {
"number": 42,
"author": "contributor",
"base": { "ref": "main" },
"head": { "sha": "abc123" },
"changed_files": 3,
"labels": ["security"]
},
"policy_config": {
"allowed_base_branches": ["main", "develop"]
}
}
```

## Running Tests

```bash
npm test
```

The test suite mocks both APort and GitHub, so it does not need a live GitHub App, webhook secret, or APort key.
16 changes: 16 additions & 0 deletions examples/platform-integrations/github-app/env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
PORT=3000

# GitHub App settings
GITHUB_APP_ID=123456
GITHUB_WEBHOOK_SECRET=replace-with-webhook-secret
GITHUB_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"

# APort settings
APORT_BASE_URL=https://aport.io
APORT_API_KEY=replace-with-aport-api-key
APORT_AGENT_ID=agt_inst_github_pr_verifier
APORT_POLICY_PACK=code.repository.merge.v1

# Optional policy configuration
APORT_ALLOWED_BASE_BRANCHES=main,develop
APORT_FAIL_ON_ERROR=true
Loading