A GitHub app that syncs GitHub issue and PR progress blocks.
Find a file
2026-06-30 18:30:44 +08:00
config chore: rename progress bot 2026-06-30 11:37:19 +08:00
docs chore: rename progress bot 2026-06-30 11:37:19 +08:00
drizzle chore: add antfu eslint config 2026-06-30 10:18:25 +08:00
src fix: use repo installation for writes 2026-06-30 18:30:44 +08:00
test fix: use repo installation for writes 2026-06-30 18:30:44 +08:00
.env.example chore: add local dev env setup 2026-06-29 11:55:08 +08:00
.gitignore chore: add local dev env setup 2026-06-29 11:55:08 +08:00
AGENTS.md chore: add local dev env setup 2026-06-29 11:55:08 +08:00
Dockerfile docs: fix webhook endpoint 2026-06-30 14:19:19 +08:00
drizzle.config.ts chore: add antfu eslint config 2026-06-30 10:18:25 +08:00
eslint.config.mjs chore: add antfu eslint config 2026-06-30 10:18:25 +08:00
package-lock.json chore: rename progress bot 2026-06-30 11:37:19 +08:00
package.json chore: rename progress bot 2026-06-30 11:37:19 +08:00
README.md docs: fix webhook endpoint 2026-06-30 14:19:19 +08:00
tsconfig.json chore: add antfu eslint config 2026-06-30 10:18:25 +08:00
vitest.config.ts chore: add antfu eslint config 2026-06-30 10:18:25 +08:00

progress-bot

progress-bot - Probot app that syncs GitHub issue and PR progress blocks from static YAML config.

Build Docker Image

docker buildx build --load -t github-progress-bot:latest .

Environment variables

Required:

  • APP_ID - GitHub App ID.
  • PRIVATE_KEY or PRIVATE_KEY_PATH - GitHub App private key value or mounted PEM path.
  • WEBHOOK_SECRET - GitHub App webhook secret.
  • DATABASE_URL - PostgreSQL connection string.

Optional:

  • PROJECT_CONFIG_PATH - config path, defaults to config/projects.yaml in local dev and should usually be /app/config/projects.yaml in Docker.
  • PORT - HTTP port, default 3000.
  • HOST - bind host, default 0.0.0.0 in Docker.
  • LOG_LEVEL - log level, default info.
  • OBJECT_CACHE_TTL_SECONDS - GitHub object cache TTL, default 300.
  • WEBHOOK_PATH - webhook route, default /api/github/webhooks.
  • RUN_MIGRATIONS - run Drizzle migrations before startup when set to true; default false.
  • DRIZZLE_MIGRATIONS_DIR - migration directory, default /app/drizzle in Docker.

Configuration

Mount the YAML project config into the container:

-v "$PWD/config/projects.yaml:/app/config/projects.yaml:ro"

For file-based GitHub App keys, mount the PEM and point PRIVATE_KEY_PATH at it:

-v "$PWD/config/private-key.pem:/run/secrets/github-app.pem:ro" \
-e PRIVATE_KEY_PATH=/run/secrets/github-app.pem

GitHub App

Permissions:

  • Issues - read/write.
  • Pull requests - read/write.
  • Metadata - read-only.
  • Contents - read-only.

Webhook events:

  • Issue comments.
  • Issues.
  • Pull requests.

Subscribe the app webhook URL to the container endpoint:

http(s)://HOST/api/github/webhooks

/probot is Probot's status/setup UI route, not the webhook receiver.

Database Migrations

Run migrations explicitly:

docker run --rm \
  -e DATABASE_URL="$DATABASE_URL" \
  -e RUN_MIGRATIONS=true \
  -v "$PWD/config/projects.yaml:/app/config/projects.yaml:ro" \
  github-progress-bot:latest \
  true

Or run the migration CLI directly:

docker run --rm \
  --entrypoint node \
  -e DATABASE_URL="$DATABASE_URL" \
  github-progress-bot:latest \
  ./dist/migrate.js

Run

docker run -d \
  --name github-progress-bot \
  -p 3000:3000 \
  -e APP_ID="$APP_ID" \
  -e PRIVATE_KEY_PATH=/run/secrets/github-app.pem \
  -e WEBHOOK_SECRET="$WEBHOOK_SECRET" \
  -e DATABASE_URL="$DATABASE_URL" \
  -e PROJECT_CONFIG_PATH=/app/config/projects.yaml \
  -v "$PWD/config/projects.yaml:/app/config/projects.yaml:ro" \
  -v "$PWD/config/private-key.pem:/run/secrets/github-app.pem:ro" \
  github-progress-bot:latest

Bot Commands

Commands are GitHub issue or PR comments. Only the first non-empty line is parsed.

Reference forms:

  • #123 - same repository.
  • owner/repo#123 - another configured repository.
  • https://github.com/owner/repo/issues/123 - issue URL.
  • https://github.com/owner/repo/pull/123 - pull request URL.

Command synopsis:

/sync
/sync --fresh
/link REF
/unlink REF
/subissue REF
/unsubissue REF
/branch NAME
/unbranch

Command description:

  • /sync - update the progress block from body references, native GitHub relations, and stored links.
  • /sync --fresh - bypass the object cache while syncing.
  • /link REF - add a tracked relation from the commented object to REF.
  • /unlink REF - remove that tracked relation and strip stale progress from REF.
  • /subissue REF - add issue REF as a sub-issue and update GitHub's native sub-issue relation.
  • /unsubissue REF - remove issue REF from sub-issues.
  • /branch NAME - set the branch group for the commented object. NAME may contain letters, numbers, _, ., /, and -.
  • /unbranch - clear the branch group.

Local Development

npm install
cp .env.example .env
cp config/projects.example.yaml config/projects.yaml
npm run db:migrate
npm run dev