notifycat

module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2026 License: MIT

README

notifycat

notifycat listens for GitHub pull request webhooks and keeps Slack up to date.

One pull request gets one Slack message. As the PR opens, moves to draft, gets reviewed, merges, or closes, notifycat updates that message and adds the configured reactions. The result is a quieter channel: reviewers can follow the state of a PR without digging through repeated notifications.

It is intentionally small: one HTTP endpoint, a SQLite database (for Slack message timestamps), and a declarative mappings.yaml that decides which PRs route to which Slack channels.

What It Handles

  • pull_request webhooks for opened, closed, and converted-to-draft PRs.
  • pull_request_review webhooks for approved, commented, and changes-requested reviews.
  • pull_request_review_comment webhooks for line-specific PR comments.
  • GitHub HMAC-SHA256 verification through X-Hub-Signature-256.
  • Repository routing from a declarative mappings.yaml — explicit lists or repositories: "*" for a whole org. See mappings.example.yaml.
  • Slack message updates instead of repeated new messages for the same PR.

Binaries

Binary Purpose
notifycat-server HTTP server for GitHub webhooks
notifycat-mapping CLI for listing and validating the mappings file
notifycat-migrate Applies embedded SQLite migrations

Documentation

Quickstart

Create a local env file and the mappings file from the bundled examples:

cp .env.example .env
cp mappings.example.yaml mappings.yaml

Edit mappings.yaml to point your repos at real Slack channels, then migrate, validate, and start the server:

go run ./cmd/notifycat-migrate up
go run ./cmd/notifycat-mapping validate
go run ./cmd/notifycat-server

Health check:

curl -i http://localhost:8080/healthz

See Getting started for the full local setup.

Development

The project includes a justfile for common development commands. Install just (brew install just on macOS), then run:

just
just check
just serve

just is a developer tool only. It is not part of the Go module, the Docker runtime image, or production dependencies.

The underlying checks are:

go vet ./...
golangci-lint run ./...
govulncheck ./...
go test -race ./...
go build ./...

See CONTRIBUTING.md for contributor setup, pull request expectations, and issue reporting guidance.

Release Process

Releases are automated by release-please and follow Semantic Versioning driven by Conventional Commits.

  1. Merge a PR into main with a Conventional Commits title (feat:, fix:, …). The PR-title lint workflow blocks non-conforming titles.
  2. release-please opens — and keeps up-to-date — a single "release PR" that bumps the version in .release-please-manifest.json and writes the new section of CHANGELOG.md.
  3. Merging the release PR creates a Git tag (e.g. v0.2.0) and publishes a GitHub Release with release notes.
  4. The release event triggers the Docker workflow, which builds the Dockerfile and pushes ghcr.io/mptooling/notifycat:<semver>, :<major>.<minor>, :<major>, and :latest to GHCR.
  5. Documentation under docs/ and mkdocs.yml is published to GitHub Pages on every push to main that changes those paths.

Pre-1.0 caveat: while the project is on 0.x, a breaking change bumps the minor version (0.1.00.2.0). Major bumps begin after 1.0.0.

Community

License

MIT. See LICENSE.

Directories

Path Synopsis
cmd
notifycat-mapping command
Command notifycat-mapping is the CLI for the declarative mappings.yaml workflow: `list` prints the file, `validate` runs the cache-aware validation pipeline.
Command notifycat-mapping is the CLI for the declarative mappings.yaml workflow: `list` prints the file, `validate` runs the cache-aware validation pipeline.
notifycat-migrate command
Command notifycat-migrate applies the embedded database migrations.
Command notifycat-migrate applies the embedded database migrations.
notifycat-server command
Command notifycat-server starts the HTTP server that receives GitHub webhooks and posts to Slack.
Command notifycat-server starts the HTTP server that receives GitHub webhooks and posts to Slack.
internal
app
Package app is the composition root for notifycat.
Package app is the composition root for notifycat.
cleanup
Package cleanup runs the scheduled, in-process pruning of stale rows from the slack_messages table.
Package cleanup runs the scheduled, in-process pruning of stale rows from the slack_messages table.
config
Package config loads runtime configuration from environment variables (and optionally from a .env file in development).
Package config loads runtime configuration from environment variables (and optionally from a .env file in development).
github
Package github is a minimal GitHub API client covering only the endpoints notifycat needs for validation.
Package github is a minimal GitHub API client covering only the endpoints notifycat needs for validation.
githubhook
Package githubhook authenticates and parses inbound GitHub webhook requests.
Package githubhook authenticates and parses inbound GitHub webhook requests.
mappings
Package mappings owns the declarative repository → Slack-channel configuration: parsing mappings.yaml, the in-memory Provider used at runtime, and the mappings.lock cache that records which entries have been validated.
Package mappings owns the declarative repository → Slack-channel configuration: parsing mappings.yaml, the in-memory Provider used at runtime, and the mappings.lock cache that records which entries have been validated.
pullrequest
Package pullrequest holds the domain model for GitHub pull-request events and the handlers that update Slack in response.
Package pullrequest holds the domain model for GitHub pull-request events and the handlers that update Slack in response.
slack
Package slack talks to the Slack Web API for the PR notifier: posting, updating, and deleting messages, adding emoji reactions, and composing the text of the notification.
Package slack talks to the Slack Web API for the PR notifier: posting, updating, and deleting messages, adding emoji reactions, and composing the text of the notification.
store
Package store owns the database schema, GORM models, repositories, and the goose-driven migration runner.
Package store owns the database schema, GORM models, repositories, and the goose-driven migration runner.
validate
Package validate verifies that a repository → Slack-channel mapping is usable end-to-end before GitHub fires a real PR event: the mapping row exists, the channel ID is well-formed, the Slack bot has the right scopes and is a member of the channel, and (when GitHub credentials are available) the webhook is subscribed to the events notifycat needs.
Package validate verifies that a repository → Slack-channel mapping is usable end-to-end before GitHub fires a real PR event: the mapping row exists, the channel ID is well-formed, the Slack bot has the right scopes and is a member of the channel, and (when GitHub credentials are available) the webhook is subscribed to the events notifycat needs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL