{"id":19561366,"url":"https://github.com/m-mizutani/ghnotify","last_synced_at":"2025-04-27T00:31:12.480Z","repository":{"id":64308010,"uuid":"464011719","full_name":"m-mizutani/ghnotify","owner":"m-mizutani","description":"General GitHub event notification tool to Slack with Open Policy Agent and Rego","archived":false,"fork":false,"pushed_at":"2025-04-16T21:43:27.000Z","size":200,"stargazers_count":21,"open_issues_count":7,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-26T07:08:35.360Z","etag":null,"topics":["github-actions","go","slack"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/m-mizutani.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-27T01:48:45.000Z","updated_at":"2024-12-14T01:21:23.000Z","dependencies_parsed_at":"2024-06-20T14:46:17.809Z","dependency_job_id":"b3f9263c-ea42-4b4f-9232-82f3c03afb4b","html_url":"https://github.com/m-mizutani/ghnotify","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-mizutani%2Fghnotify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-mizutani%2Fghnotify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-mizutani%2Fghnotify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-mizutani%2Fghnotify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m-mizutani","download_url":"https://codeload.github.com/m-mizutani/ghnotify/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251072279,"owners_count":21532004,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["github-actions","go","slack"],"created_at":"2024-11-11T05:11:13.084Z","updated_at":"2025-04-27T00:31:12.217Z","avatar_url":"https://github.com/m-mizutani.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ghnotify\n\n`ghnotify` is a general GitHub event notification tool to Slack with [Open Policy Agent](https://github.com/open-policy-agent/opa) and [Rego](https://www.openpolicyagent.org/docs/latest/policy-language/). There are a lot of notification tools from GitHub to Slack. However, in most case, notification rules are deeply integrated with source code implementation and customization of notification rule by end-user is limited.\n\n`ghnotify` uses generic policy language Rego and OPA as runtime to separate implementation and policy completely. Therefore, `ghnotify` can handle and notify **all type of GitHub event**, not only issue/PR comments but also such as following events according to your Rego policy.\n\n- GitHub Actions success/failure\n- deploy key creation\n- push to specified branch\n- add/remove a label\n- repository creation, archived, transferred\n- team modification\n- a new GitHub App installation\n\n## Setup\n\n### 1) Retrieve Bot User OAuth Token of Slack\n\nCreate your Slack bot and keep *OAuth Tokens for Your Workspace* in *OAuth \u0026 Permissions* page.\n\n### 2) Creating Rego policy\n\n`ghnotify` evaluates received GitHub event one by one. If `notify` variable exists in evaluation results, `ghnotify` notifies a message to Slack according to the results.\n\nPolicy rules are following.\n\n**Input**: What data will be provided\n- `input.name`: Event name. It comes from `X-GitHub-Event` header.\n- `input.event`: Webhook events. See [docs](https://docs.github.com/en/developers/webhooks-and-events/webhooks) for more detail and schema.\n\n**Result**: What data should be returned\n- `notify`: Set of notification messages\n    - `notify[_].channel`: Destination channel of Slack. It can be used by only API token\n    - `notify[_].text`: Custom message of slack notification\n    - `notify[_].body`: Custom message body\n    - `notify[_].color`: Message bar color\n    - `notify[_].fields`: Set of custom message fields.\n        - `notify[_].fields[_].name`: Field name\n        - `notify[_].fields[_].value`: Field value\n        - `notify[_].fields[_].url`: Link assigned to the field\n\n#### Example 1) Notification of \"call me\" in issue comment\n\n```rego\npackage github.notify\n\nnotify[msg] {\n    input.name == \"issue_comment\"\n    contains(input.event.comment.body, \"mizutani\")\n    msg := {\n        \"channel\": \"#notify-mizutani\",\n        \"text\": \"Hello, mizutani\",\n        \"body\": input.event.comment.body,\n    }\n}\n```\n\nThen, you shall get a message like following.\n\n![](https://user-images.githubusercontent.com/605953/155864886-c9c8ccbb-809c-44df-8925-fe69a0d820f4.png)\n\n\n#### Example 2) Notification of workflow (actions) failed\n\n```rego\npackage github.notify\n\nnotify[msg] {\n    input.name == \"workflow_run\"\n    input.event.action == \"completed\"\n    input.event.conclusion == \"failure\"\n\n    msg := {\n        \"channel\": \"#notify-failure\",\n        \"text\": \"workflow failed\",\n        \"color\": \"#E01E5A\", # red\n    }\n}\n```\n\n#### Example 3) Assigned \"breaking-change\" label to PR\n\n```rego\npackage github.notify\n\nnotify[msg] {\n    input.name == \"pull_request\"\n    input.event.action == \"labeled\"\n    input.event.label.name == \"breaking-change\"\n    labels := { name | name := input.event.pull_request.labels[_].name }\n\n    msg := {\n        \"channel\": \"#notify-mizutani\",\n        \"text\": \"breaking change assigned\",\n        \"fields\": [\n            {\n                \"name\": \"All labels\",\n                \"value\": concat(\", \", labels),\n            },\n        ],\n    }\n}\n```\n\n## Run\n\n### Use Case 1: As GitHub Actions\n\n- Pros: Easy to install\n- Cons: GitHub Actions can receive events from only the repository\n\nCreate GitHub Actions workflow as following.\n\n```yaml\nname: Build and publish container image\n\non:\n  push:\n  issue:\n  issue_comment:\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    env:\n      GHNOTIFY_SLACK_API_TOKEN: ${{ secrets.GHNOTIFY_SLACK_API_TOKEN }}\n    steps:\n      - name: checkout\n        uses: actions/checkout@v2\n      - name: dump event\n        run: echo '${{ toJSON(github.event) }}' \u003e /tmp/event.json\n      - uses: docker://ghcr.io/m-mizutani/ghnotify:latest\n        with:\n          args: \"emit -f /tmp/event.json -t ${{ github.event_name }} --local-policy ./policy\"\n```\n\n### Use Case 2: As GitHub App server\n\n- Pros: Easy to install\n- Cons: GitHub Actions can receive event on each repository, can not watch organization wide\n\n#### Deploy `ghnotify`\n\nDeploy `ghnotify` to your environment and prepare URL that can be accessed from public internet. I recommend [Cloud Run](https://cloud.google.com/run) of Google Cloud in the use case.\n\nWhen deploying `ghnotify`, I recommend to generate and use *Webhook secret* value. Please prepare random token and provide it to `--webhook-secret`.\n\nCallback endpoint will be `http://{hostname}:4080/webhook/github`. You can change port number by `--addr` option.\n\n#### Create a new GitHub App\n\n1. Go to https://github.com/settings/apps and click `New GitHub App`\n2. Grant permissions and check events you want to subscribe in `Subscribe to events`.\n3. Check `Active` in `Webhook` section\n4. Set URL of deployed `ghnotify` to `Webhook URL`\n5. Set *Webhook secret* to `Webhook secret` if you configured\n6. Then click `Create GitHub App`\n\n#### Example\n\n## Options\n\n- Server\n    - `--addr`: Server address and port to listen webhook. e.g. `0.0.0.0:8080`\n    - `--webhook-secret`: Webhook secret\n- Policy (either one of `--local-policy` and `--remote-url` is required)\n    - `--local-policy`: Policy files or directory.\n    - `--local-package`: Package name of policy file\n    - `--remote-url`: URL of OPA server\n    - `--remote-header`: HTTP header to query OPA server\n- Notification (either one of following is required)\n    - `--slack-api-token`: API token retrieved in Step 1 (Recommended)\n    - `--slack-webhook`: Incoming webhook URL of Slack\n\n## License\n\nApache License 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm-mizutani%2Fghnotify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm-mizutani%2Fghnotify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm-mizutani%2Fghnotify/lists"}