├── .anvil.lock
├── .editorconfig
├── .github
├── FUNDING.yml
├── auto_assign.yml
├── issue_template.md
├── pull_request_template.md
├── renovate.json
├── settings.yml
└── workflows
│ ├── autoassign.yml
│ ├── automerge.yml
│ ├── go.yaml
│ ├── notify.yml
│ ├── stale.yml
│ └── tag.yml
├── .gitignore
├── .go-version
├── .golangci.yml
├── .img
├── callbacks.png
├── callbacks.xml
└── gopher.png
├── CODEOWNERS
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── examples
├── README.md
├── simple-http-server-funcs
│ ├── go.mod
│ ├── go.sum
│ └── main.go
├── simple-http-server-packages
│ ├── go.mod
│ ├── go.sum
│ ├── main.go
│ └── plugins
│ │ └── responder.go
└── simple-http-server
│ ├── go.mod
│ ├── go.sum
│ └── main.go
├── gen
├── format.go
├── generate.go
├── template_markdown.go.tmpl
├── template_params.go
├── template_webhook_event.go.tmpl
├── template_webhook_event_tests.go.tmpl
└── template_webhook_event_types.go.tmpl
├── githubevents
├── events.go
├── events_branch_protection_rule.go
├── events_branch_protection_rule_test.go
├── events_check_run.go
├── events_check_run_test.go
├── events_check_suite.go
├── events_check_suite_test.go
├── events_commit_comment.go
├── events_commit_comment_test.go
├── events_create.go
├── events_create_test.go
├── events_custom_property.go
├── events_custom_property_test.go
├── events_custom_property_values.go
├── events_custom_property_values_test.go
├── events_delete.go
├── events_delete_test.go
├── events_deploy_key.go
├── events_deploy_key_test.go
├── events_deployment.go
├── events_deployment_status.go
├── events_deployment_status_test.go
├── events_deployment_test.go
├── events_discussion.go
├── events_discussion_test.go
├── events_fork.go
├── events_fork_test.go
├── events_github_app_authorization.go
├── events_github_app_authorization_test.go
├── events_gollum.go
├── events_gollum_test.go
├── events_installation.go
├── events_installation_repositories.go
├── events_installation_repositories_test.go
├── events_installation_test.go
├── events_issue_comment.go
├── events_issue_comment_test.go
├── events_issues.go
├── events_issues_test.go
├── events_label.go
├── events_label_test.go
├── events_marketplace_purchase.go
├── events_marketplace_purchase_test.go
├── events_member.go
├── events_member_test.go
├── events_membership.go
├── events_membership_test.go
├── events_merge_group_event.go
├── events_merge_group_event_test.go
├── events_meta.go
├── events_meta_test.go
├── events_milestone.go
├── events_milestone_test.go
├── events_org_block.go
├── events_org_block_test.go
├── events_organization.go
├── events_organization_test.go
├── events_package.go
├── events_package_test.go
├── events_page_build.go
├── events_page_build_test.go
├── events_ping.go
├── events_ping_test.go
├── events_project_v2.go
├── events_project_v2_item.go
├── events_project_v2_item_test.go
├── events_project_v2_test.go
├── events_public.go
├── events_public_test.go
├── events_pull_request.go
├── events_pull_request_review.go
├── events_pull_request_review_comment.go
├── events_pull_request_review_comment_test.go
├── events_pull_request_review_test.go
├── events_pull_request_test.go
├── events_push.go
├── events_push_test.go
├── events_release.go
├── events_release_test.go
├── events_repository.go
├── events_repository_dispatch.go
├── events_repository_dispatch_test.go
├── events_repository_ruleset.go
├── events_repository_ruleset_test.go
├── events_repository_test.go
├── events_repository_vulnerability_alert.go
├── events_repository_vulnerability_alert_test.go
├── events_star.go
├── events_star_test.go
├── events_status.go
├── events_status_test.go
├── events_team.go
├── events_team_add.go
├── events_team_add_test.go
├── events_team_test.go
├── events_watch.go
├── events_watch_test.go
├── events_workflow_dispatch.go
├── events_workflow_dispatch_test.go
├── events_workflow_job.go
├── events_workflow_job_test.go
├── events_workflow_run.go
└── events_workflow_run_test.go
├── go.mod
└── go.sum
/.anvil.lock:
--------------------------------------------------------------------------------
1 | {
2 | "generated_at": "2025-05-15T20:52:16.267888961Z",
3 | "version": "1.2.29",
4 | "files": [
5 | {
6 | "path": ".editorconfig"
7 | },
8 | {
9 | "path": ".github/FUNDING.yml"
10 | },
11 | {
12 | "path": ".github/auto_assign.yml"
13 | },
14 | {
15 | "path": ".github/issue_template.md"
16 | },
17 | {
18 | "path": ".github/pull_request_template.md"
19 | },
20 | {
21 | "path": ".github/renovate.json"
22 | },
23 | {
24 | "path": ".github/settings.yml"
25 | },
26 | {
27 | "path": ".github/workflows/autoassign.yml"
28 | },
29 | {
30 | "path": ".github/workflows/automerge.yml"
31 | },
32 | {
33 | "path": ".github/workflows/notify.yml"
34 | },
35 | {
36 | "path": ".github/workflows/stale.yml"
37 | },
38 | {
39 | "path": ".github/workflows/tag.yml"
40 | },
41 | {
42 | "path": "CODEOWNERS"
43 | },
44 | {
45 | "path": "CONTRIBUTING.md"
46 | },
47 | {
48 | "path": "LICENSE"
49 | }
50 | ]
51 | }
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | charset = utf-8
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 |
10 | [Makefile]
11 | indent_style = tab
12 | indent_size = 4
13 |
14 | [*.go]
15 | indent_style = tab
16 | indent_size = 4
17 |
18 | [*.md]
19 | trim_trailing_whitespace = true
20 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | ko_fi: chrisbargmann
4 |
5 |
--------------------------------------------------------------------------------
/.github/auto_assign.yml:
--------------------------------------------------------------------------------
1 | # Set to true to add reviewers to pull requests
2 | addReviewers: true
3 |
4 | # Set to true to add assignees to pull requests
5 | addAssignees: false
6 |
7 | # A list of reviewers to be added to pull requests (GitHub user name)
8 | reviewers:
9 | - cbrgm
10 |
11 | # A number of reviewers added to the pull request
12 | # Set 0 to add all the reviewers (default: 0)
13 | numberOfReviewers: 1
14 |
--------------------------------------------------------------------------------
/.github/issue_template.md:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/.github/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "github>cbrgm/cbrgm//renovate/preset"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.github/settings.yml:
--------------------------------------------------------------------------------
1 | ---
2 | repository:
3 | name: githubevents
4 | description: GitHub webhook events toolset for Go 🚀
5 | homepage: https://cbrgm.net
6 | topics: github, go, golang, webhooks, events, module, webhook, codegen, go-library
7 |
8 | private: false
9 | has_issues: true
10 | has_wiki: false
11 | has_downloads: false
12 |
13 | default_branch: main
14 |
15 | allow_squash_merge: true
16 | allow_merge_commit: true
17 | allow_rebase_merge: true
18 |
19 | allow_update_branch: true
20 | allow_auto_merge: true
21 | delete_branch_on_merge: true
22 | enable_automated_security_fixes: true
23 | enable_vulnerability_alerts: true
24 |
25 | branches:
26 | - name: main
27 | protection:
28 | required_pull_request_reviews: null
29 | required_status_checks:
30 | strict: true
31 | contexts:
32 | - testing
33 | enforce_admins: true
34 | ...
35 |
--------------------------------------------------------------------------------
/.github/workflows/autoassign.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: add-reviews
3 |
4 | on:
5 | pull_request_target:
6 | types: [opened, ready_for_review]
7 |
8 | permissions:
9 | pull-requests: write
10 |
11 | jobs:
12 | add-reviews:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: kentaro-m/auto-assign-action@f4648c0a9fdb753479e9e75fc251f507ce17bb7e # v2.0.0
16 | ...
17 |
--------------------------------------------------------------------------------
/.github/workflows/automerge.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: automerge
3 |
4 | on: pull_request
5 |
6 | permissions:
7 | contents: write
8 | pull-requests: write
9 |
10 | jobs:
11 | dependabot:
12 | runs-on: ubuntu-latest
13 | if: github.actor == 'dependabot[bot]'
14 |
15 | steps:
16 |
17 | - name: Fetch metadata
18 | id: metadata
19 | uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # v2.4.0
20 | with:
21 | github-token: ${{ secrets.BOT_PAT_TOKEN }}
22 |
23 | - name: Approve request
24 | id: approve
25 | run: gh pr review --approve ${{ github.event.pull_request.html_url }}
26 | env:
27 | GH_TOKEN: ${{ secrets.BOT_PAT_TOKEN }}
28 |
29 | - name: Enable automerge
30 | id: automerge
31 | run: gh pr merge --rebase --auto ${{ github.event.pull_request.html_url }}
32 | env:
33 | GH_TOKEN: ${{ secrets.BOT_PAT_TOKEN }}
34 |
35 | renovate:
36 | runs-on: ubuntu-latest
37 | if: github.actor == 'renovate[bot]'
38 |
39 | steps:
40 | - name: Approve request
41 | id: approve
42 | run: gh pr review --approve ${{ github.event.pull_request.html_url }}
43 | env:
44 | GH_TOKEN: ${{ secrets.BOT_PAT_TOKEN }}
45 |
46 | - name: Enable automerge
47 | id: automerge
48 | run: gh pr merge --rebase --auto ${{ github.event.pull_request.html_url }}
49 | env:
50 | GH_TOKEN: ${{ secrets.BOT_PAT_TOKEN }}
51 |
52 | cbrgm:
53 | runs-on: ubuntu-latest
54 | if: github.actor == 'cbrgm' && contains(github.event.pull_request.labels.*.name, 'auto-merge')
55 |
56 | steps:
57 | - name: Enable automerge
58 | id: automerge
59 | run: gh pr merge --rebase --auto ${{ github.event.pull_request.html_url }}
60 | env:
61 | GH_TOKEN: ${{ secrets.BOT_PAT_TOKEN }}
62 | ...
63 |
--------------------------------------------------------------------------------
/.github/workflows/go.yaml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches: [ main ]
4 | pull_request:
5 | branches: [ main ]
6 | name: generate-and-test
7 | jobs:
8 | test:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: checkout
12 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
13 |
14 | - name: install Go
15 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
16 | with:
17 | go-version-file: .go-version
18 |
19 | - name: get modules
20 | run: go mod vendor
21 |
22 | - name: generate
23 | run: make generate
24 |
25 | - name: format
26 | run: make format && git diff --exit-code
27 |
28 | - name: golangci-lint
29 | uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
30 | with:
31 | version: v2.1.2
32 |
33 | - name: run tests
34 | run: make test
35 |
--------------------------------------------------------------------------------
/.github/workflows/notify.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: release-notification
3 |
4 | on:
5 | release:
6 | types: [published]
7 |
8 | permissions:
9 | contents: read
10 |
11 | jobs:
12 | notify-on-release:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Send Telegram Notification on new release
16 | uses: cbrgm/telegram-github-action@ae9dc892701436bfa54e34f5e8a49b1816c1a6c8 # v1.3.5
17 | with:
18 | token: ${{ secrets.TELEGRAM_TOKEN }}
19 | to: ${{ secrets.TELEGRAM_CHAT_ID }}
20 | message: |
21 | 🚀 New Release Published!
22 | Release Name: ${{ github.event.release.name }}
23 | Tag: ${{ github.event.release.tag_name }}
24 | Actor: ${{ github.actor }}
25 | Repository: ${{ github.repository }}
26 | Check it out: ${{ github.event.release.html_url }}
27 |
28 | - name: Send Mastodon Status on new release
29 | id: mastodon
30 | uses: cbrgm/mastodon-github-action@740aa5979f7dd752b329e3d3e3492166e5ada890 # v2.1.16
31 | if: ${{ !github.event.repository.private }}
32 | with:
33 | access-token: ${{ secrets.MASTODON_ACCESS_TOKEN }}
34 | url: ${{ secrets.MASTODON_URL }}
35 | language: "en"
36 | message: |
37 | 🚀 ${{ github.repository }} ${{ github.event.release.name }} published!
38 | Check it out: ${{ github.event.release.html_url }}
39 | ...
40 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: stale-issues-prs-branches
3 | on:
4 | schedule:
5 | - cron: 0 0 * * *
6 |
7 | permissions:
8 | issues: write
9 | pull-requests: write
10 | contents: write
11 |
12 | jobs:
13 | label-issues:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
17 | name: Setting issue as idle
18 | with:
19 | repo-token: '${{ secrets.GITHUB_TOKEN }}'
20 | stale-issue-message: "This issue is idle because it has been open for 60 days with no activity."
21 | stale-issue-label: idle
22 | days-before-stale: 60
23 | days-before-close: 7
24 | operations-per-run: 100
25 | exempt-issue-labels: backlog
26 |
27 | - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
28 | name: Setting PR as idle
29 | with:
30 | repo-token: '${{ secrets.GITHUB_TOKEN }}'
31 | stale-pr-message: "This PR is idle because it has been open for 60 days with no activity."
32 | stale-pr-label: idle
33 | days-before-stale: 60
34 | days-before-close: 7
35 | operations-per-run: 100
36 |
37 | - name: Cleanup Stale Branches
38 | uses: cbrgm/cleanup-stale-branches-action@main
39 | with:
40 | token: ${{ secrets.GITHUB_TOKEN }}
41 | repository: ${{ github.repository }}
42 | dry-run: false
43 | ...
44 |
--------------------------------------------------------------------------------
/.github/workflows/tag.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: publish-release-tag
3 |
4 | on:
5 | schedule:
6 | - cron: '0 12 1 * *' # At 12:00 (12 PM) on the 1st day of every month
7 |
8 | workflow_dispatch:
9 | inputs:
10 | bump-level:
11 | required: true
12 | type: choice
13 | description: 'The semver bump level'
14 | options:
15 | - 'major'
16 | - 'minor'
17 | - 'patch'
18 | - 'premajor'
19 | - 'preminor'
20 | - 'prepatch'
21 | - 'prerelease'
22 | default: 'patch'
23 |
24 | prerelease-tag:
25 | required: false
26 | description: 'The tag to use for prereleases'
27 | default: 'alpha'
28 |
29 | permissions:
30 | contents: write
31 |
32 | jobs:
33 | publish-release-tag:
34 | runs-on: ubuntu-latest
35 | steps:
36 |
37 | - name: Checkout
38 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
39 | with:
40 | token: ${{ secrets.BOT_PAT_TOKEN }}
41 |
42 | - name: Get Latest Tag
43 | id: current
44 | run: |
45 | git fetch --tags
46 | latest_tag=$(git tag | sort -V | tail -n 1)
47 | echo "current version is: $latest_tag"
48 | echo "latest_tag=$latest_tag" >> $GITHUB_ENV
49 |
50 | - name: Bump Version
51 | id: bump-semver
52 | uses: cbrgm/semver-bump-action@main
53 | with:
54 | current-version: ${{ env.latest_tag }}
55 | bump-level: ${{ github.event.inputs.bump-level || 'patch' }}
56 | prerelease-tag: ${{ github.event.inputs.prerelease-tag }}
57 |
58 | - name: Publish Git Tag
59 | run: |
60 | git fetch --tags
61 | latest_tag=$(git tag | sort -V | tail -n 1)
62 | new_tag=${{ steps.bump-semver.outputs.new_version }}
63 | if [[ $(git rev-list $latest_tag..HEAD --count) -gt 0 ]]; then
64 | git config user.name "GitHub Actions"
65 | git config user.email "github-actions@users.noreply.github.com"
66 | git tag $new_tag
67 | git push origin $new_tag
68 | else
69 | echo "No new commits since last tag. Skipping tag push. ($new_tag)"
70 | fi
71 | ...
72 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 |
10 | # Architecture specific extensions/prefixes
11 | *.[568vq]
12 | [568vq].out
13 |
14 | *.cgo1.go
15 | *.cgo2.c
16 | _cgo_defun.c
17 | _cgo_gotypes.go
18 | _cgo_export.*
19 |
20 | *.exe
21 | *.test
22 | *.prof
23 |
24 | .idea
25 |
26 | /.env
27 | /dist/
28 | /vendor
29 | /results
30 | /bin
31 | /out
32 |
--------------------------------------------------------------------------------
/.go-version:
--------------------------------------------------------------------------------
1 | 1.24.4
2 |
--------------------------------------------------------------------------------
/.golangci.yml:
--------------------------------------------------------------------------------
1 | version: "2"
2 | run:
3 | go: "1.24"
4 | modules-download-mode: readonly
5 | tests: false
6 | linters:
7 | enable:
8 | - gocyclo
9 | - godot
10 | - misspell
11 | - revive
12 | - whitespace
13 | settings:
14 | gocyclo:
15 | min-complexity: 20
16 | gosec:
17 | excludes:
18 | - G404
19 | - G114
20 | misspell:
21 | locale: US
22 | revive:
23 | severity: warning
24 | rules:
25 | - name: unexported-return
26 | severity: warning
27 | disabled: true
28 | exclusions:
29 | generated: lax
30 | rules:
31 | - linters:
32 | - errcheck
33 | path: _test.go
34 | paths:
35 | - cdk.out
36 | - vendor
37 | - third_party$
38 | - builtin$
39 | - examples$
40 | formatters:
41 | enable:
42 | - gofumpt
43 | settings:
44 | gofumpt:
45 | extra-rules: true
46 | exclusions:
47 | generated: lax
48 | paths:
49 | - cdk.out
50 | - vendor
51 | - third_party$
52 | - builtin$
53 | - examples$
54 |
55 |
56 |
--------------------------------------------------------------------------------
/.img/callbacks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cbrgm/githubevents/326cf0385c22f1d2e0f8bca7d157c9f15b2846f2/.img/callbacks.png
--------------------------------------------------------------------------------
/.img/callbacks.xml:
--------------------------------------------------------------------------------
1 | 7RvbcuI29Gt46QyMLV95DJdsO93MZLrttPuUEbYw6toWK4sA+/WVbBlbliHOxpBLSSbBOjqSpXM/R2JgTZPdJwrXqzsSongAjHA3sGYDAEzTd/mHgOwLiOP7BSCiOJRIFeAL/oEk0JDQDQ5RpiAyQmKG1yowIGmKAqbAIKVkq6ItSay+dQ0jpAG+BDDWoX/jkK3KfbnjquNXhKOVfLUPvKIjgSWy3Em2giHZ1kDWfGBNKSGseEp2UxQL4pV0KcbdHuk9LIyilHUZsEpmd7//tV5Ef8zwDXMt4hIyLFf7COON3LFcLduXJKBkk4ZIzGIMrMl2hRn6soaB6N1ypnPYiiUxb5n8cYnjeEpiQnk7JSlHmsg3IMrQ7ujazQNFuCghkiBG9xxFDrBdpxgipQjYkqjbiie2IXFWNXaYvkSEUg6iw9wVqfiDpNYzKGc675JyNuhIOeCdi3KWRicUcp2TTULZikQkhfG8gk5USlY4nwlZS/r9ixjbSwMCN4yo1OXkovt/5Pi88VU0Rk7ZnO3qnbN9vXWPKOZ7R1QCiw2IVZ/mCt8k2dAAnRIjadMgjRA7pajtXKYohgw/quvoX9Z9TdYZxVHECdLGys9wwb2AQn4Y4yjlzwEnkCDjRAg15mb2RnYkOAwLTqMM/4CLfD5B6zXBKcs35EwGzuyUVkgfIAdXlrfOl+MSeVSFhsbIcAygqJGU4c7kl5Pfi83UUMhymXG2N/lzWMMLWPa0dcq+IRasWsk84ZSbFn+c5GAqICPgtADbYJ4ONHU0/mG2vaEJbIN5OtDU0USrXLUKbIN5jr7i5mizZbTZGJ3LKNmwGKdoeohKBI2XJGWlhR8Ai//eCo5OIgpDjJS+21v71p/U+maY8okwSXPvQIXpVjwGHzOZmpbjcnjGKPmGaj3L/If3hDBbHaxoqYK5ut6TDMvpF4QxkrToKBO2Vlflug/jO5Qm2ARlW0qceCXM1gU5lngn1jHhQdFadCa7SMSPI7jN7BE3AbnZ/C0Q6xEWoXhSsbI068dFHjxdGVz4/sjRnKTn6z6yhPVucJ3XcJE9ejXQ0avZr+nVwFizkVvKQzQOWnBaBuIhhAx+DB/nPOnjbGCrevDWfRxo8XFuzKTdUXjmft+QsmOY5RpwwxHG613Vx58i8YkSiONhIQJDChkaCikY5rJByzfwBRcvKcZcnet7cq6ePzfs5znXmeFMTe9/41xjmCxC2I9/dQxPtStjPQW9qHe1L2k3uhqMVqE+t0i1SIg1CvcpTMhDuNC1AMw9a+K3aFV/BQvP6RSNAV1e/LOlv4YmMJ8oXMKUM9f4k+L16Jer/b+g/b+S8225U8u2fXDNVU+404TbigiFDxmijzhAD0tCHyJpQs5iNR3Pe+0c1uxQgkJpeCMOaQSLYphlOFB5pOa0aIdZXsItqra89VXiieeqgCsa+1rjjOXbMv16MtM1j9QYa9wpWVjnTgn72SSsDMFsVTysZnG/2KgcVT9EakzkG+pEttGYqCCENhHnMtzX0KQJ77xg2zFOrquJ75jjhgAXK+i3xqofnpUFhPndLf8vXoCD7GMUEMzTFmhojEzf9XoRV7UOMQbq+DMWzfWKAkUM4vRQCTK45eb/LSOH7HXWcnKzRoyteDgZKLcc9nXnfttBomopz+BRbEvP2sYtFssyjnP7Zf7E0pgzjckm3EIRaL/ddCqoFqmFQZ4znraGVf3lU45RRIZKcKCz0gdlvFBn5tg6FzPbcvB+goNaaFAFCq8SHJjvIzjQNN3tKzgwuwUHvZlvVxOqLKBCJT+GAz5yWiKnN0aGb6qe882fUh9U6XXughwab+MuSOdk4qXHZkfUt5kklG7jQupbvq6mvt83KN+ZcL1ineXJ3AcJqZ9w3Tykto13dyinF0ufW133u1XXZXZ1PZj7OJXE68HcZQ/m7JyD9ZCt5WLtRauG4HSWJ45bWu8dXvO9I7eZbAu0VIIvnO6B/tO9N3qft5Tfpy/0Gu1svEzO51oNKWnek++a87l+U9wum/MBPef7UFeTwemkT9zbsuzGlyN6kZDGgJ8JGHmz+npLgV59Scia/wc=
--------------------------------------------------------------------------------
/.img/gopher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cbrgm/githubevents/326cf0385c22f1d2e0f8bca7d157c9f15b2846f2/.img/gopher.png
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # github codeowners file
2 | #
3 | # https://help.github.com/articles/about-codeowners/
4 | #
5 | # These owners will be the default owners for everything in
6 | # the repo. Unless a later match takes precedence,
7 | # mentioned account names will be requested for
8 | # review when someone opens a pull request.
9 | * @cbrgm
10 |
11 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guide
2 |
3 | ## Table of Contents
4 | - [Introduction](#introduction)
5 | - [Feature Requests](#feature-requests)
6 | - [Bug Reports](#bug-reports)
7 | - [Pull Requests](#pull-requests)
8 | - [Collaboration](#collaboration)
9 | - [Additional Contributions](#additional-contributions)
10 | - [Collaborator Status](#collaborator-status)
11 | - [Final Notes](#final-notes)
12 |
13 | ## Introduction
14 | - Explore [Feature Requests](#feature-requests), [Bug Reports](#bug-reports), and [Pull Requests](#pull-requests) to contribute.
15 | - Got Questions? Email: .
16 |
17 | ## Feature Requests
18 | - Check ***[existing requests](https://github.com/cbrgm/githubevents/issues)***.
19 | - Submit a new request if needed, explaining benefits and relevance.
20 |
21 | ## Bug Reports
22 | - Verify if the bug is already reported via ***[open bugs](https://github.com/cbrgm/githubevents/issues)***.
23 | - Report new bugs with:
24 | - **Description**: Summary of the issue.
25 | - **Steps to Reproduce**: Clear steps.
26 | - **Expected vs. Actual Results**.
27 | - **Version Info**.
28 |
29 | ## Pull Requests
30 | - Review ***[existing PRs](https://github.com/cbrgm/githubevents/pulls)*** first.
31 | - Submit small, well-tested PRs anytime.
32 | - PRs undergo thorough reviews; responsiveness is key.
33 |
34 | ## Collaboration
35 | - **Engage** with feedback and reviews.
36 | - **Small, Focused Commits**: Easier to review and test.
37 | - **Respectful Interaction**: Collaboration thrives on patience.
38 |
39 | ## Additional Contributions
40 | - Improve documentation or suggest feature enhancements.
41 | - Report serious security issues to . Use PRs for less critical fixes.
42 |
43 | ## Collaborator Status
44 | - **After a PR is Merged**: Potential "collaborator status."
45 | - **Responsibilities**: Review PRs, resolve issues, and submit new contributions.
46 | - **Inactive Collaborators**: May be temporarily removed for security but reinstated later.
47 |
48 | Your ideas, reports, and contributions make this project valuable for everyone. Thank you so much for your help! :-)
49 |
50 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | PACKAGES = $(shell go list ./...)
2 | GO := CGO_ENABLED=0 go
3 |
4 | .PHONY: all
5 | all: build
6 |
7 | .PHONY: clean
8 | clean:
9 | $(GO) clean -i ./...
10 | rm -rf ./bin/
11 |
12 | .PHONY: format
13 | format: go/fmt
14 |
15 | .PHONY: go/fmt
16 | go/fmt:
17 | $(GO) fmt $(PACKAGES)
18 |
19 | .PHONY: test
20 | test:
21 | @for PKG in $(PACKAGES); do $(GO) test -cover $$PKG || exit 1; done;
22 |
23 | .PHONY: generate
24 | generate: build
25 | ./bin/githubhook-gen --output=githubevents
26 |
27 | .PHONY: build
28 | build: \
29 | bin/gen
30 |
31 | .PHONY: bin/gen
32 | bin/gen:
33 | mkdir -p bin
34 | $(GO) build -v -ldflags '-w $(LDFLAGS)' -o ./bin/githubhook-gen ./gen/*.go
35 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | # Examples
2 |
3 | This folder provides usage examples for `cbrgm/githubevents`.
4 |
5 | Feel free to contribute!
6 |
--------------------------------------------------------------------------------
/examples/simple-http-server-funcs/go.mod:
--------------------------------------------------------------------------------
1 | module simple-http-server-funcs
2 |
3 | go 1.24.0
4 |
5 | require github.com/cbrgm/githubevents/v2 v2.0.0-20250304131238-cf5ca4a066d3
6 |
7 | require (
8 | github.com/google/go-github/v69 v69.2.0 // indirect
9 | github.com/google/go-querystring v1.1.0 // indirect
10 | golang.org/x/sync v0.11.0 // indirect
11 | )
12 |
--------------------------------------------------------------------------------
/examples/simple-http-server-funcs/go.sum:
--------------------------------------------------------------------------------
1 | github.com/cbrgm/githubevents/v2 v2.0.0-20250304131238-cf5ca4a066d3 h1:E/yQPdllmKN7w5OYmVUUqgsQ4zpxcpv+H9q5Amb0tl4=
2 | github.com/cbrgm/githubevents/v2 v2.0.0-20250304131238-cf5ca4a066d3/go.mod h1:mD3XFxVIniUlfEuJ0jae1Vn8wmPKUwOb2W1StYP6xVc=
3 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
4 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
5 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
6 | github.com/google/go-github/v69 v69.2.0 h1:wR+Wi/fN2zdUx9YxSmYE0ktiX9IAR/BeePzeaUUbEHE=
7 | github.com/google/go-github/v69 v69.2.0/go.mod h1:xne4jymxLR6Uj9b7J7PyTpkMYstEMMwGZa0Aehh1azM=
8 | github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
9 | github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
10 | golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
11 | golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
12 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
13 |
--------------------------------------------------------------------------------
/examples/simple-http-server-funcs/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 |
8 | "github.com/cbrgm/githubevents/v2/githubevents"
9 | )
10 |
11 | func main() {
12 | handle := githubevents.New("")
13 |
14 | // pass the eventHandler to funcs that define callbacks
15 | newPing(handle)
16 | newPong(handle)
17 |
18 | http.HandleFunc("/hook", func(w http.ResponseWriter, r *http.Request) {
19 | err := handle.HandleEventRequest(r)
20 | if err != nil {
21 | fmt.Println("error")
22 | }
23 | })
24 |
25 | if err := http.ListenAndServe(":8080", nil); err != nil {
26 | panic(err)
27 | }
28 | }
29 |
30 | func newPing(handle *githubevents.EventHandler) {
31 | handle.OnBeforeAny(
32 | func(ctx context.Context, deliveryID, eventName string, event any) error {
33 | fmt.Println("ping!")
34 | return nil
35 | },
36 | )
37 | }
38 |
39 | func newPong(handle *githubevents.EventHandler) {
40 | handle.OnBeforeAny(
41 | func(ctx context.Context, deliveryID, eventName string, event any) error {
42 | fmt.Println("pong!")
43 | return nil
44 | },
45 | )
46 | }
47 |
--------------------------------------------------------------------------------
/examples/simple-http-server-packages/go.mod:
--------------------------------------------------------------------------------
1 | module simple-http-server-packages
2 |
3 | go 1.24.0
4 |
5 | require (
6 | github.com/cbrgm/githubevents/v2 v2.0.0-20250304131238-cf5ca4a066d3
7 | github.com/google/go-github/v72 v72.0.0
8 | )
9 |
10 | require (
11 | github.com/google/go-github/v69 v69.2.0 // indirect
12 | github.com/google/go-querystring v1.1.0 // indirect
13 | golang.org/x/sync v0.11.0 // indirect
14 | )
15 |
--------------------------------------------------------------------------------
/examples/simple-http-server-packages/go.sum:
--------------------------------------------------------------------------------
1 | github.com/cbrgm/githubevents/v2 v2.0.0-20250304131238-cf5ca4a066d3 h1:E/yQPdllmKN7w5OYmVUUqgsQ4zpxcpv+H9q5Amb0tl4=
2 | github.com/cbrgm/githubevents/v2 v2.0.0-20250304131238-cf5ca4a066d3/go.mod h1:mD3XFxVIniUlfEuJ0jae1Vn8wmPKUwOb2W1StYP6xVc=
3 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
4 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
5 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
6 | github.com/google/go-github/v69 v69.2.0 h1:wR+Wi/fN2zdUx9YxSmYE0ktiX9IAR/BeePzeaUUbEHE=
7 | github.com/google/go-github/v69 v69.2.0/go.mod h1:xne4jymxLR6Uj9b7J7PyTpkMYstEMMwGZa0Aehh1azM=
8 | github.com/google/go-github/v72 v72.0.0 h1:FcIO37BLoVPBO9igQQ6tStsv2asG4IPcYFi655PPvBM=
9 | github.com/google/go-github/v72 v72.0.0/go.mod h1:WWtw8GMRiL62mvIquf1kO3onRHeWWKmK01qdCY8c5fg=
10 | github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
11 | github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
12 | golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
13 | golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
14 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
15 |
--------------------------------------------------------------------------------
/examples/simple-http-server-packages/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 |
7 | "github.com/cbrgm/githubevents/v2/githubevents"
8 |
9 | "simple-http-server-packages/plugins"
10 | )
11 |
12 | func main() {
13 | handle := githubevents.New("")
14 |
15 | // return handleFuncs from other packages
16 | // and use them ad "plugins"
17 | handle.OnIssueCommentCreated(
18 | plugins.NewResponder("ping!"),
19 | plugins.NewResponder("pong!"),
20 | )
21 |
22 | http.HandleFunc("/hook", func(w http.ResponseWriter, r *http.Request) {
23 | err := handle.HandleEventRequest(r)
24 | if err != nil {
25 | fmt.Println("error")
26 | }
27 | })
28 |
29 | if err := http.ListenAndServe(":8080", nil); err != nil {
30 | panic(err)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/examples/simple-http-server-packages/plugins/responder.go:
--------------------------------------------------------------------------------
1 | package plugins
2 |
3 | import (
4 | "context"
5 | "fmt"
6 |
7 | "github.com/cbrgm/githubevents/v2/githubevents"
8 | "github.com/google/go-github/v72/github"
9 | )
10 |
11 | func NewResponder(msg string) githubevents.IssueCommentEventHandleFunc {
12 | // do some configuration here
13 | // ...
14 | return func(ctx context.Context, deliveryID, eventName string, event *github.IssueCommentEvent) error {
15 | fmt.Printf("commenting %s", msg)
16 | return nil
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/simple-http-server/go.mod:
--------------------------------------------------------------------------------
1 | module simple-http-server
2 |
3 | go 1.24.0
4 |
5 | require (
6 | github.com/cbrgm/githubevents/v2 v2.0.0-20250304131238-cf5ca4a066d3
7 | github.com/google/go-github/v72 v72.0.0
8 | )
9 |
10 | require (
11 | github.com/google/go-github/v69 v69.2.0 // indirect
12 | github.com/google/go-querystring v1.1.0 // indirect
13 | golang.org/x/sync v0.11.0 // indirect
14 | )
15 |
--------------------------------------------------------------------------------
/examples/simple-http-server/go.sum:
--------------------------------------------------------------------------------
1 | github.com/cbrgm/githubevents/v2 v2.0.0-20250304131238-cf5ca4a066d3 h1:E/yQPdllmKN7w5OYmVUUqgsQ4zpxcpv+H9q5Amb0tl4=
2 | github.com/cbrgm/githubevents/v2 v2.0.0-20250304131238-cf5ca4a066d3/go.mod h1:mD3XFxVIniUlfEuJ0jae1Vn8wmPKUwOb2W1StYP6xVc=
3 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
4 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
5 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
6 | github.com/google/go-github/v69 v69.2.0 h1:wR+Wi/fN2zdUx9YxSmYE0ktiX9IAR/BeePzeaUUbEHE=
7 | github.com/google/go-github/v69 v69.2.0/go.mod h1:xne4jymxLR6Uj9b7J7PyTpkMYstEMMwGZa0Aehh1azM=
8 | github.com/google/go-github/v72 v72.0.0 h1:FcIO37BLoVPBO9igQQ6tStsv2asG4IPcYFi655PPvBM=
9 | github.com/google/go-github/v72 v72.0.0/go.mod h1:WWtw8GMRiL62mvIquf1kO3onRHeWWKmK01qdCY8c5fg=
10 | github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
11 | github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
12 | golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
13 | golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
14 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
15 |
--------------------------------------------------------------------------------
/examples/simple-http-server/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 |
8 | "github.com/cbrgm/githubevents/v2/githubevents"
9 | "github.com/google/go-github/v72/github"
10 | )
11 |
12 | func main() {
13 | handle := githubevents.New("")
14 |
15 | handle.OnIssueCommentCreated(func(ctx context.Context, deliveryID, eventName string, event *github.IssueCommentEvent) error {
16 | fmt.Printf("%s has commented on issue %d", *event.Sender.Login, *event.Issue.ID)
17 | return nil
18 | })
19 |
20 | http.HandleFunc("/hook", func(w http.ResponseWriter, r *http.Request) {
21 | err := handle.HandleEventRequest(r)
22 | if err != nil {
23 | fmt.Println("error")
24 | }
25 | })
26 |
27 | if err := http.ListenAndServe(":8080", nil); err != nil {
28 | panic(err)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/gen/format.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bytes"
5 | "io"
6 | "os"
7 | "os/exec"
8 | )
9 |
10 | // format formats a template using gofmt.
11 | func format(in io.Reader) (io.Reader, error) {
12 | var out bytes.Buffer
13 |
14 | gofmt := exec.Command("gofmt", "-s")
15 | gofmt.Stdin = in
16 | gofmt.Stdout = &out
17 | gofmt.Stderr = os.Stderr
18 | err := gofmt.Run()
19 | return &out, err
20 | }
21 |
--------------------------------------------------------------------------------
/gen/generate.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bytes"
5 | _ "embed"
6 | "flag"
7 | "io"
8 | "os"
9 | "path/filepath"
10 | "text/template"
11 | )
12 |
13 | //go:embed template_markdown.go.tmpl
14 | var webhookMarkdownTemplate string
15 |
16 | //go:embed template_webhook_event.go.tmpl
17 | var webhookEventTemplate string
18 |
19 | //go:embed template_webhook_event_tests.go.tmpl
20 | var webhookTestsTemplate string
21 |
22 | //go:embed template_webhook_event_types.go.tmpl
23 | var webhookTypesTemplate string
24 |
25 | func main() {
26 | outputDir := flag.String("output", "githubevents", "output directory")
27 | docs := flag.Bool("docs", false, "generate markdown docs")
28 |
29 | flag.Parse()
30 | if *outputDir == "" {
31 | panic("output directory is empty")
32 | }
33 |
34 | // when -docs is set, create a list of all supported markdown events as yaml on stdout
35 | // todo(cbrgm): clean this up a little bit
36 | if *docs {
37 | err := ExecuteMarkdownTemplate("", webhookMarkdownTemplate, params)
38 | if err != nil {
39 | panic(err)
40 | }
41 | return
42 | }
43 |
44 | out := filepath.Join(".", *outputDir)
45 | err := os.MkdirAll(out, os.ModePerm)
46 | if err != nil {
47 | panic("failed to create output directory")
48 | }
49 |
50 | // create events.go
51 | err = ExecuteWebhookEventTemplate(filepath.Join(out, "events"), params)
52 | if err != nil {
53 | panic(err)
54 | }
55 |
56 | // create individual files for each webhook event type
57 | // webhook events_*.go files and events_*_test.go files are generated
58 | for _, param := range params.Webhooks {
59 | fileName := "events_" + param.Name
60 | outFile := filepath.Join(out, fileName)
61 | err := ExecuteWebhookEventTypesTemplate(outFile, TemplateParameters{
62 | Webhooks: []GithubWebhooks{param},
63 | })
64 | if err != nil {
65 | panic(err)
66 | }
67 | }
68 | }
69 |
70 | func ExecuteWebhookEventTemplate(file string, data any) error {
71 | err := ExecuteTemplate(file+".go", webhookEventTemplate, data)
72 | if err != nil {
73 | return err
74 | }
75 | return nil
76 | }
77 |
78 | func ExecuteWebhookEventTypesTemplate(file string, data any) error {
79 | err := ExecuteTemplate(file+".go", webhookTypesTemplate, data)
80 | if err != nil {
81 | return err
82 | }
83 | err = ExecuteTemplate(file+"_test.go", webhookTestsTemplate, data)
84 | if err != nil {
85 | return err
86 | }
87 | return nil
88 | }
89 |
90 | // ExecuteWebhookEventTypesTemplate renders the named template and writes to io.Writer wr.
91 | func ExecuteTemplate(file, tmpl string, data any) error {
92 | wr := os.Stdout
93 | if output := file; output != "" {
94 | wri, err := os.Create(output)
95 | if err != nil {
96 | return err
97 | }
98 | wr = wri
99 | defer func() {
100 | _ = wr.Close()
101 | }()
102 | }
103 |
104 | buf := new(bytes.Buffer)
105 |
106 | t, err := template.New("").Parse(tmpl)
107 | if err != nil {
108 | return err
109 | }
110 |
111 | err = t.ExecuteTemplate(buf, "", data)
112 | if err != nil {
113 | return err
114 | }
115 |
116 | src, err := format(buf)
117 | if err != nil {
118 | return err
119 | }
120 | _, err = io.Copy(wr, src)
121 | return err
122 | }
123 |
124 | // ExecuteMarkdownTemplate renders the named template and writes to io.Writer wr.
125 | func ExecuteMarkdownTemplate(_, tmpl string, data any) error {
126 | wr := os.Stdout
127 | buf := new(bytes.Buffer)
128 | t, err := template.New("").Parse(tmpl)
129 | if err != nil {
130 | return err
131 | }
132 | err = t.ExecuteTemplate(buf, "", data)
133 | if err != nil {
134 | return err
135 | }
136 | _, err = io.Copy(wr, buf)
137 | return err
138 | }
139 |
--------------------------------------------------------------------------------
/gen/template_markdown.go.tmpl:
--------------------------------------------------------------------------------
1 | {{ range $_, $webhook := .Webhooks }}
2 | * ***[{{ $webhook.Name }}](https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#{{ $webhook.Name }})***
3 | {{ end }}
4 | `
5 |
--------------------------------------------------------------------------------
/githubevents/events_create.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // CreateEvent is the event name of github.CreateEvent's
20 | CreateEvent = "create"
21 |
22 | // CreateEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.CreateEvent
24 | CreateEventAnyAction = "*"
25 | )
26 |
27 | // CreateEventHandleFunc represents a callback function triggered on github.CreateEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.CreateEvent) is the webhook payload.
31 | type CreateEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.CreateEvent) error
32 |
33 | // OnCreateEventAny registers callbacks listening to any events of type github.CreateEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnCreateEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#create
42 | func (g *EventHandler) OnCreateEventAny(callbacks ...CreateEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onCreateEvent == nil {
49 | g.onCreateEvent = make(map[string][]CreateEventHandleFunc)
50 | }
51 | g.onCreateEvent[CreateEventAnyAction] = append(
52 | g.onCreateEvent[CreateEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnCreateEventAny registers callbacks listening to any events of type github.CreateEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnCreateEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#create
67 | func (g *EventHandler) SetOnCreateEventAny(callbacks ...CreateEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onCreateEvent == nil {
74 | g.onCreateEvent = make(map[string][]CreateEventHandleFunc)
75 | }
76 | g.onCreateEvent[CreateEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handleCreateEventAny(ctx context.Context, deliveryID string, eventName string, event *github.CreateEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onCreateEvent[CreateEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onCreateEvent[CreateEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // CreateEvent handles github.CreateEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnCreateEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) CreateEvent(ctx context.Context, deliveryID string, eventName string, event *github.CreateEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handleCreateEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_create_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnCreateEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []CreateEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single CreateEventHandleFunc",
28 | args: args{
29 | []CreateEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.CreateEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple CreateEventHandleFuncs",
38 | args: args{
39 | []CreateEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.CreateEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.CreateEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnCreateEventAny(tt.args.callbacks...)
54 | if len(g.onCreateEvent[CreateEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onCreateEvent[CreateEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnCreateEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []CreateEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single CreateEventHandleFunc",
72 | args: args{
73 | []CreateEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.CreateEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple CreateEventHandleFuncs",
83 | args: args{
84 | []CreateEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.CreateEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.CreateEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnCreateEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.CreateEvent) error {
101 | return nil
102 | })
103 | g.SetOnCreateEventAny(tt.args.callbacks...)
104 | if len(g.onCreateEvent[CreateEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onCreateEvent[CreateEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandleCreateEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.CreateEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "create",
130 |
131 | event: &github.CreateEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "create",
142 |
143 | event: &github.CreateEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "create",
154 |
155 | event: &github.CreateEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "create",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnCreateEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.CreateEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handleCreateEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandleCreateEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestCreateEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.CreateEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger CreateEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onCreateEvent: map[string][]CreateEventHandleFunc{
229 | CreateEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.CreateEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: CreateEvent,
241 |
242 | event: &github.CreateEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.CreateEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("CreateEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_delete.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // DeleteEvent is the event name of github.DeleteEvent's
20 | DeleteEvent = "delete"
21 |
22 | // DeleteEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.DeleteEvent
24 | DeleteEventAnyAction = "*"
25 | )
26 |
27 | // DeleteEventHandleFunc represents a callback function triggered on github.DeleteEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.DeleteEvent) is the webhook payload.
31 | type DeleteEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.DeleteEvent) error
32 |
33 | // OnDeleteEventAny registers callbacks listening to any events of type github.DeleteEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnDeleteEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#delete
42 | func (g *EventHandler) OnDeleteEventAny(callbacks ...DeleteEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onDeleteEvent == nil {
49 | g.onDeleteEvent = make(map[string][]DeleteEventHandleFunc)
50 | }
51 | g.onDeleteEvent[DeleteEventAnyAction] = append(
52 | g.onDeleteEvent[DeleteEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnDeleteEventAny registers callbacks listening to any events of type github.DeleteEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnDeleteEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#delete
67 | func (g *EventHandler) SetOnDeleteEventAny(callbacks ...DeleteEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onDeleteEvent == nil {
74 | g.onDeleteEvent = make(map[string][]DeleteEventHandleFunc)
75 | }
76 | g.onDeleteEvent[DeleteEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handleDeleteEventAny(ctx context.Context, deliveryID string, eventName string, event *github.DeleteEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onDeleteEvent[DeleteEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onDeleteEvent[DeleteEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // DeleteEvent handles github.DeleteEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnDeleteEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) DeleteEvent(ctx context.Context, deliveryID string, eventName string, event *github.DeleteEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handleDeleteEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_delete_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnDeleteEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []DeleteEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single DeleteEventHandleFunc",
28 | args: args{
29 | []DeleteEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeleteEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple DeleteEventHandleFuncs",
38 | args: args{
39 | []DeleteEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeleteEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeleteEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnDeleteEventAny(tt.args.callbacks...)
54 | if len(g.onDeleteEvent[DeleteEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onDeleteEvent[DeleteEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnDeleteEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []DeleteEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single DeleteEventHandleFunc",
72 | args: args{
73 | []DeleteEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeleteEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple DeleteEventHandleFuncs",
83 | args: args{
84 | []DeleteEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeleteEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeleteEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnDeleteEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.DeleteEvent) error {
101 | return nil
102 | })
103 | g.SetOnDeleteEventAny(tt.args.callbacks...)
104 | if len(g.onDeleteEvent[DeleteEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onDeleteEvent[DeleteEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandleDeleteEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.DeleteEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "delete",
130 |
131 | event: &github.DeleteEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "delete",
142 |
143 | event: &github.DeleteEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "delete",
154 |
155 | event: &github.DeleteEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "delete",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnDeleteEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.DeleteEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handleDeleteEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandleDeleteEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestDeleteEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.DeleteEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger DeleteEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onDeleteEvent: map[string][]DeleteEventHandleFunc{
229 | DeleteEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeleteEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: DeleteEvent,
241 |
242 | event: &github.DeleteEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.DeleteEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("DeleteEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_deployment.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // DeploymentEvent is the event name of github.DeploymentEvent's
20 | DeploymentEvent = "deployment"
21 |
22 | // DeploymentEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.DeploymentEvent
24 | DeploymentEventAnyAction = "*"
25 | )
26 |
27 | // DeploymentEventHandleFunc represents a callback function triggered on github.DeploymentEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.DeploymentEvent) is the webhook payload.
31 | type DeploymentEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentEvent) error
32 |
33 | // OnDeploymentEventAny registers callbacks listening to any events of type github.DeploymentEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnDeploymentEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#deployment
42 | func (g *EventHandler) OnDeploymentEventAny(callbacks ...DeploymentEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onDeploymentEvent == nil {
49 | g.onDeploymentEvent = make(map[string][]DeploymentEventHandleFunc)
50 | }
51 | g.onDeploymentEvent[DeploymentEventAnyAction] = append(
52 | g.onDeploymentEvent[DeploymentEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnDeploymentEventAny registers callbacks listening to any events of type github.DeploymentEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnDeploymentEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#deployment
67 | func (g *EventHandler) SetOnDeploymentEventAny(callbacks ...DeploymentEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onDeploymentEvent == nil {
74 | g.onDeploymentEvent = make(map[string][]DeploymentEventHandleFunc)
75 | }
76 | g.onDeploymentEvent[DeploymentEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handleDeploymentEventAny(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onDeploymentEvent[DeploymentEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onDeploymentEvent[DeploymentEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // DeploymentEvent handles github.DeploymentEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnDeploymentEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) DeploymentEvent(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handleDeploymentEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_deployment_status.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // DeploymentStatusEvent is the event name of github.DeploymentStatusEvent's
20 | DeploymentStatusEvent = "deployment_status"
21 |
22 | // DeploymentStatusEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.DeploymentStatusEvent
24 | DeploymentStatusEventAnyAction = "*"
25 | )
26 |
27 | // DeploymentStatusEventHandleFunc represents a callback function triggered on github.DeploymentStatusEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.DeploymentStatusEvent) is the webhook payload.
31 | type DeploymentStatusEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentStatusEvent) error
32 |
33 | // OnDeploymentStatusEventAny registers callbacks listening to any events of type github.DeploymentStatusEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnDeploymentStatusEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#deployment_status
42 | func (g *EventHandler) OnDeploymentStatusEventAny(callbacks ...DeploymentStatusEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onDeploymentStatusEvent == nil {
49 | g.onDeploymentStatusEvent = make(map[string][]DeploymentStatusEventHandleFunc)
50 | }
51 | g.onDeploymentStatusEvent[DeploymentStatusEventAnyAction] = append(
52 | g.onDeploymentStatusEvent[DeploymentStatusEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnDeploymentStatusEventAny registers callbacks listening to any events of type github.DeploymentStatusEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnDeploymentStatusEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#deployment_status
67 | func (g *EventHandler) SetOnDeploymentStatusEventAny(callbacks ...DeploymentStatusEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onDeploymentStatusEvent == nil {
74 | g.onDeploymentStatusEvent = make(map[string][]DeploymentStatusEventHandleFunc)
75 | }
76 | g.onDeploymentStatusEvent[DeploymentStatusEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handleDeploymentStatusEventAny(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentStatusEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onDeploymentStatusEvent[DeploymentStatusEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onDeploymentStatusEvent[DeploymentStatusEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // DeploymentStatusEvent handles github.DeploymentStatusEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnDeploymentStatusEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) DeploymentStatusEvent(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentStatusEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handleDeploymentStatusEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_deployment_status_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnDeploymentStatusEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []DeploymentStatusEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single DeploymentStatusEventHandleFunc",
28 | args: args{
29 | []DeploymentStatusEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentStatusEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple DeploymentStatusEventHandleFuncs",
38 | args: args{
39 | []DeploymentStatusEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentStatusEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentStatusEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnDeploymentStatusEventAny(tt.args.callbacks...)
54 | if len(g.onDeploymentStatusEvent[DeploymentStatusEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onDeploymentStatusEvent[DeploymentStatusEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnDeploymentStatusEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []DeploymentStatusEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single DeploymentStatusEventHandleFunc",
72 | args: args{
73 | []DeploymentStatusEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentStatusEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple DeploymentStatusEventHandleFuncs",
83 | args: args{
84 | []DeploymentStatusEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentStatusEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentStatusEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnDeploymentStatusEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentStatusEvent) error {
101 | return nil
102 | })
103 | g.SetOnDeploymentStatusEventAny(tt.args.callbacks...)
104 | if len(g.onDeploymentStatusEvent[DeploymentStatusEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onDeploymentStatusEvent[DeploymentStatusEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandleDeploymentStatusEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.DeploymentStatusEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "deployment_status",
130 |
131 | event: &github.DeploymentStatusEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "deployment_status",
142 |
143 | event: &github.DeploymentStatusEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "deployment_status",
154 |
155 | event: &github.DeploymentStatusEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "deployment_status",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnDeploymentStatusEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentStatusEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handleDeploymentStatusEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandleDeploymentStatusEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestDeploymentStatusEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.DeploymentStatusEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger DeploymentStatusEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onDeploymentStatusEvent: map[string][]DeploymentStatusEventHandleFunc{
229 | DeploymentStatusEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentStatusEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: DeploymentStatusEvent,
241 |
242 | event: &github.DeploymentStatusEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.DeploymentStatusEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("DeploymentStatusEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_deployment_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnDeploymentEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []DeploymentEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single DeploymentEventHandleFunc",
28 | args: args{
29 | []DeploymentEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple DeploymentEventHandleFuncs",
38 | args: args{
39 | []DeploymentEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnDeploymentEventAny(tt.args.callbacks...)
54 | if len(g.onDeploymentEvent[DeploymentEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onDeploymentEvent[DeploymentEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnDeploymentEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []DeploymentEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single DeploymentEventHandleFunc",
72 | args: args{
73 | []DeploymentEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple DeploymentEventHandleFuncs",
83 | args: args{
84 | []DeploymentEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnDeploymentEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentEvent) error {
101 | return nil
102 | })
103 | g.SetOnDeploymentEventAny(tt.args.callbacks...)
104 | if len(g.onDeploymentEvent[DeploymentEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onDeploymentEvent[DeploymentEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandleDeploymentEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.DeploymentEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "deployment",
130 |
131 | event: &github.DeploymentEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "deployment",
142 |
143 | event: &github.DeploymentEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "deployment",
154 |
155 | event: &github.DeploymentEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "deployment",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnDeploymentEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handleDeploymentEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandleDeploymentEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestDeploymentEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.DeploymentEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger DeploymentEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onDeploymentEvent: map[string][]DeploymentEventHandleFunc{
229 | DeploymentEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.DeploymentEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: DeploymentEvent,
241 |
242 | event: &github.DeploymentEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.DeploymentEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("DeploymentEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_fork.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // ForkEvent is the event name of github.ForkEvent's
20 | ForkEvent = "fork"
21 |
22 | // ForkEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.ForkEvent
24 | ForkEventAnyAction = "*"
25 | )
26 |
27 | // ForkEventHandleFunc represents a callback function triggered on github.ForkEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.ForkEvent) is the webhook payload.
31 | type ForkEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.ForkEvent) error
32 |
33 | // OnForkEventAny registers callbacks listening to any events of type github.ForkEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnForkEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#fork
42 | func (g *EventHandler) OnForkEventAny(callbacks ...ForkEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onForkEvent == nil {
49 | g.onForkEvent = make(map[string][]ForkEventHandleFunc)
50 | }
51 | g.onForkEvent[ForkEventAnyAction] = append(
52 | g.onForkEvent[ForkEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnForkEventAny registers callbacks listening to any events of type github.ForkEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnForkEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#fork
67 | func (g *EventHandler) SetOnForkEventAny(callbacks ...ForkEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onForkEvent == nil {
74 | g.onForkEvent = make(map[string][]ForkEventHandleFunc)
75 | }
76 | g.onForkEvent[ForkEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handleForkEventAny(ctx context.Context, deliveryID string, eventName string, event *github.ForkEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onForkEvent[ForkEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onForkEvent[ForkEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // ForkEvent handles github.ForkEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnForkEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) ForkEvent(ctx context.Context, deliveryID string, eventName string, event *github.ForkEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handleForkEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_fork_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnForkEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []ForkEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single ForkEventHandleFunc",
28 | args: args{
29 | []ForkEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.ForkEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple ForkEventHandleFuncs",
38 | args: args{
39 | []ForkEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.ForkEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.ForkEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnForkEventAny(tt.args.callbacks...)
54 | if len(g.onForkEvent[ForkEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onForkEvent[ForkEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnForkEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []ForkEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single ForkEventHandleFunc",
72 | args: args{
73 | []ForkEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.ForkEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple ForkEventHandleFuncs",
83 | args: args{
84 | []ForkEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.ForkEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.ForkEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnForkEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.ForkEvent) error {
101 | return nil
102 | })
103 | g.SetOnForkEventAny(tt.args.callbacks...)
104 | if len(g.onForkEvent[ForkEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onForkEvent[ForkEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandleForkEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.ForkEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "fork",
130 |
131 | event: &github.ForkEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "fork",
142 |
143 | event: &github.ForkEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "fork",
154 |
155 | event: &github.ForkEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "fork",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnForkEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.ForkEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handleForkEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandleForkEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestForkEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.ForkEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger ForkEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onForkEvent: map[string][]ForkEventHandleFunc{
229 | ForkEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.ForkEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: ForkEvent,
241 |
242 | event: &github.ForkEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.ForkEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("ForkEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_gollum.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // GollumEvent is the event name of github.GollumEvent's
20 | GollumEvent = "gollum"
21 |
22 | // GollumEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.GollumEvent
24 | GollumEventAnyAction = "*"
25 | )
26 |
27 | // GollumEventHandleFunc represents a callback function triggered on github.GollumEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.GollumEvent) is the webhook payload.
31 | type GollumEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.GollumEvent) error
32 |
33 | // OnGollumEventAny registers callbacks listening to any events of type github.GollumEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnGollumEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#gollum
42 | func (g *EventHandler) OnGollumEventAny(callbacks ...GollumEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onGollumEvent == nil {
49 | g.onGollumEvent = make(map[string][]GollumEventHandleFunc)
50 | }
51 | g.onGollumEvent[GollumEventAnyAction] = append(
52 | g.onGollumEvent[GollumEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnGollumEventAny registers callbacks listening to any events of type github.GollumEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnGollumEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#gollum
67 | func (g *EventHandler) SetOnGollumEventAny(callbacks ...GollumEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onGollumEvent == nil {
74 | g.onGollumEvent = make(map[string][]GollumEventHandleFunc)
75 | }
76 | g.onGollumEvent[GollumEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handleGollumEventAny(ctx context.Context, deliveryID string, eventName string, event *github.GollumEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onGollumEvent[GollumEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onGollumEvent[GollumEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // GollumEvent handles github.GollumEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnGollumEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) GollumEvent(ctx context.Context, deliveryID string, eventName string, event *github.GollumEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handleGollumEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_gollum_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnGollumEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []GollumEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single GollumEventHandleFunc",
28 | args: args{
29 | []GollumEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.GollumEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple GollumEventHandleFuncs",
38 | args: args{
39 | []GollumEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.GollumEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.GollumEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnGollumEventAny(tt.args.callbacks...)
54 | if len(g.onGollumEvent[GollumEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onGollumEvent[GollumEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnGollumEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []GollumEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single GollumEventHandleFunc",
72 | args: args{
73 | []GollumEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.GollumEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple GollumEventHandleFuncs",
83 | args: args{
84 | []GollumEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.GollumEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.GollumEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnGollumEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.GollumEvent) error {
101 | return nil
102 | })
103 | g.SetOnGollumEventAny(tt.args.callbacks...)
104 | if len(g.onGollumEvent[GollumEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onGollumEvent[GollumEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandleGollumEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.GollumEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "gollum",
130 |
131 | event: &github.GollumEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "gollum",
142 |
143 | event: &github.GollumEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "gollum",
154 |
155 | event: &github.GollumEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "gollum",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnGollumEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.GollumEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handleGollumEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandleGollumEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestGollumEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.GollumEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger GollumEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onGollumEvent: map[string][]GollumEventHandleFunc{
229 | GollumEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.GollumEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: GollumEvent,
241 |
242 | event: &github.GollumEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.GollumEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("GollumEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_meta.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // MetaEvent is the event name of github.MetaEvent's
20 | MetaEvent = "meta"
21 |
22 | // MetaEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.MetaEvent
24 | MetaEventAnyAction = "*"
25 | )
26 |
27 | // MetaEventHandleFunc represents a callback function triggered on github.MetaEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.MetaEvent) is the webhook payload.
31 | type MetaEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.MetaEvent) error
32 |
33 | // OnMetaEventAny registers callbacks listening to any events of type github.MetaEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnMetaEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#meta
42 | func (g *EventHandler) OnMetaEventAny(callbacks ...MetaEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onMetaEvent == nil {
49 | g.onMetaEvent = make(map[string][]MetaEventHandleFunc)
50 | }
51 | g.onMetaEvent[MetaEventAnyAction] = append(
52 | g.onMetaEvent[MetaEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnMetaEventAny registers callbacks listening to any events of type github.MetaEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnMetaEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#meta
67 | func (g *EventHandler) SetOnMetaEventAny(callbacks ...MetaEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onMetaEvent == nil {
74 | g.onMetaEvent = make(map[string][]MetaEventHandleFunc)
75 | }
76 | g.onMetaEvent[MetaEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handleMetaEventAny(ctx context.Context, deliveryID string, eventName string, event *github.MetaEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onMetaEvent[MetaEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onMetaEvent[MetaEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // MetaEvent handles github.MetaEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnMetaEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) MetaEvent(ctx context.Context, deliveryID string, eventName string, event *github.MetaEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handleMetaEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_meta_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnMetaEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []MetaEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single MetaEventHandleFunc",
28 | args: args{
29 | []MetaEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.MetaEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple MetaEventHandleFuncs",
38 | args: args{
39 | []MetaEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.MetaEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.MetaEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnMetaEventAny(tt.args.callbacks...)
54 | if len(g.onMetaEvent[MetaEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onMetaEvent[MetaEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnMetaEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []MetaEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single MetaEventHandleFunc",
72 | args: args{
73 | []MetaEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.MetaEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple MetaEventHandleFuncs",
83 | args: args{
84 | []MetaEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.MetaEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.MetaEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnMetaEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.MetaEvent) error {
101 | return nil
102 | })
103 | g.SetOnMetaEventAny(tt.args.callbacks...)
104 | if len(g.onMetaEvent[MetaEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onMetaEvent[MetaEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandleMetaEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.MetaEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "meta",
130 |
131 | event: &github.MetaEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "meta",
142 |
143 | event: &github.MetaEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "meta",
154 |
155 | event: &github.MetaEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "meta",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnMetaEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.MetaEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handleMetaEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandleMetaEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestMetaEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.MetaEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger MetaEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onMetaEvent: map[string][]MetaEventHandleFunc{
229 | MetaEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.MetaEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: MetaEvent,
241 |
242 | event: &github.MetaEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.MetaEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("MetaEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_page_build.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // PageBuildEvent is the event name of github.PageBuildEvent's
20 | PageBuildEvent = "page_build"
21 |
22 | // PageBuildEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.PageBuildEvent
24 | PageBuildEventAnyAction = "*"
25 | )
26 |
27 | // PageBuildEventHandleFunc represents a callback function triggered on github.PageBuildEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.PageBuildEvent) is the webhook payload.
31 | type PageBuildEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.PageBuildEvent) error
32 |
33 | // OnPageBuildEventAny registers callbacks listening to any events of type github.PageBuildEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnPageBuildEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#page_build
42 | func (g *EventHandler) OnPageBuildEventAny(callbacks ...PageBuildEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onPageBuildEvent == nil {
49 | g.onPageBuildEvent = make(map[string][]PageBuildEventHandleFunc)
50 | }
51 | g.onPageBuildEvent[PageBuildEventAnyAction] = append(
52 | g.onPageBuildEvent[PageBuildEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnPageBuildEventAny registers callbacks listening to any events of type github.PageBuildEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnPageBuildEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#page_build
67 | func (g *EventHandler) SetOnPageBuildEventAny(callbacks ...PageBuildEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onPageBuildEvent == nil {
74 | g.onPageBuildEvent = make(map[string][]PageBuildEventHandleFunc)
75 | }
76 | g.onPageBuildEvent[PageBuildEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handlePageBuildEventAny(ctx context.Context, deliveryID string, eventName string, event *github.PageBuildEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onPageBuildEvent[PageBuildEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onPageBuildEvent[PageBuildEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // PageBuildEvent handles github.PageBuildEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnPageBuildEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) PageBuildEvent(ctx context.Context, deliveryID string, eventName string, event *github.PageBuildEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handlePageBuildEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_page_build_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnPageBuildEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []PageBuildEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single PageBuildEventHandleFunc",
28 | args: args{
29 | []PageBuildEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.PageBuildEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple PageBuildEventHandleFuncs",
38 | args: args{
39 | []PageBuildEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.PageBuildEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.PageBuildEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnPageBuildEventAny(tt.args.callbacks...)
54 | if len(g.onPageBuildEvent[PageBuildEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onPageBuildEvent[PageBuildEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnPageBuildEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []PageBuildEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single PageBuildEventHandleFunc",
72 | args: args{
73 | []PageBuildEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.PageBuildEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple PageBuildEventHandleFuncs",
83 | args: args{
84 | []PageBuildEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.PageBuildEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.PageBuildEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnPageBuildEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.PageBuildEvent) error {
101 | return nil
102 | })
103 | g.SetOnPageBuildEventAny(tt.args.callbacks...)
104 | if len(g.onPageBuildEvent[PageBuildEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onPageBuildEvent[PageBuildEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandlePageBuildEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.PageBuildEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "page_build",
130 |
131 | event: &github.PageBuildEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "page_build",
142 |
143 | event: &github.PageBuildEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "page_build",
154 |
155 | event: &github.PageBuildEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "page_build",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnPageBuildEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.PageBuildEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handlePageBuildEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandlePageBuildEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestPageBuildEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.PageBuildEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger PageBuildEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onPageBuildEvent: map[string][]PageBuildEventHandleFunc{
229 | PageBuildEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.PageBuildEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: PageBuildEvent,
241 |
242 | event: &github.PageBuildEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.PageBuildEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("PageBuildEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_ping.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // PingEvent is the event name of github.PingEvent's
20 | PingEvent = "ping"
21 |
22 | // PingEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.PingEvent
24 | PingEventAnyAction = "*"
25 | )
26 |
27 | // PingEventHandleFunc represents a callback function triggered on github.PingEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.PingEvent) is the webhook payload.
31 | type PingEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.PingEvent) error
32 |
33 | // OnPingEventAny registers callbacks listening to any events of type github.PingEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnPingEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#ping
42 | func (g *EventHandler) OnPingEventAny(callbacks ...PingEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onPingEvent == nil {
49 | g.onPingEvent = make(map[string][]PingEventHandleFunc)
50 | }
51 | g.onPingEvent[PingEventAnyAction] = append(
52 | g.onPingEvent[PingEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnPingEventAny registers callbacks listening to any events of type github.PingEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnPingEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#ping
67 | func (g *EventHandler) SetOnPingEventAny(callbacks ...PingEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onPingEvent == nil {
74 | g.onPingEvent = make(map[string][]PingEventHandleFunc)
75 | }
76 | g.onPingEvent[PingEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handlePingEventAny(ctx context.Context, deliveryID string, eventName string, event *github.PingEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onPingEvent[PingEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onPingEvent[PingEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // PingEvent handles github.PingEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnPingEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) PingEvent(ctx context.Context, deliveryID string, eventName string, event *github.PingEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handlePingEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_ping_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnPingEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []PingEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single PingEventHandleFunc",
28 | args: args{
29 | []PingEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.PingEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple PingEventHandleFuncs",
38 | args: args{
39 | []PingEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.PingEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.PingEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnPingEventAny(tt.args.callbacks...)
54 | if len(g.onPingEvent[PingEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onPingEvent[PingEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnPingEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []PingEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single PingEventHandleFunc",
72 | args: args{
73 | []PingEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.PingEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple PingEventHandleFuncs",
83 | args: args{
84 | []PingEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.PingEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.PingEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnPingEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.PingEvent) error {
101 | return nil
102 | })
103 | g.SetOnPingEventAny(tt.args.callbacks...)
104 | if len(g.onPingEvent[PingEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onPingEvent[PingEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandlePingEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.PingEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "ping",
130 |
131 | event: &github.PingEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "ping",
142 |
143 | event: &github.PingEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "ping",
154 |
155 | event: &github.PingEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "ping",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnPingEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.PingEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handlePingEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandlePingEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestPingEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.PingEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger PingEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onPingEvent: map[string][]PingEventHandleFunc{
229 | PingEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.PingEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: PingEvent,
241 |
242 | event: &github.PingEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.PingEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("PingEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_public.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // PublicEvent is the event name of github.PublicEvent's
20 | PublicEvent = "public"
21 |
22 | // PublicEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.PublicEvent
24 | PublicEventAnyAction = "*"
25 | )
26 |
27 | // PublicEventHandleFunc represents a callback function triggered on github.PublicEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.PublicEvent) is the webhook payload.
31 | type PublicEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.PublicEvent) error
32 |
33 | // OnPublicEventAny registers callbacks listening to any events of type github.PublicEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnPublicEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#public
42 | func (g *EventHandler) OnPublicEventAny(callbacks ...PublicEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onPublicEvent == nil {
49 | g.onPublicEvent = make(map[string][]PublicEventHandleFunc)
50 | }
51 | g.onPublicEvent[PublicEventAnyAction] = append(
52 | g.onPublicEvent[PublicEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnPublicEventAny registers callbacks listening to any events of type github.PublicEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnPublicEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#public
67 | func (g *EventHandler) SetOnPublicEventAny(callbacks ...PublicEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onPublicEvent == nil {
74 | g.onPublicEvent = make(map[string][]PublicEventHandleFunc)
75 | }
76 | g.onPublicEvent[PublicEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handlePublicEventAny(ctx context.Context, deliveryID string, eventName string, event *github.PublicEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onPublicEvent[PublicEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onPublicEvent[PublicEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // PublicEvent handles github.PublicEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnPublicEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) PublicEvent(ctx context.Context, deliveryID string, eventName string, event *github.PublicEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handlePublicEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_public_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnPublicEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []PublicEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single PublicEventHandleFunc",
28 | args: args{
29 | []PublicEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.PublicEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple PublicEventHandleFuncs",
38 | args: args{
39 | []PublicEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.PublicEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.PublicEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnPublicEventAny(tt.args.callbacks...)
54 | if len(g.onPublicEvent[PublicEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onPublicEvent[PublicEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnPublicEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []PublicEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single PublicEventHandleFunc",
72 | args: args{
73 | []PublicEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.PublicEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple PublicEventHandleFuncs",
83 | args: args{
84 | []PublicEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.PublicEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.PublicEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnPublicEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.PublicEvent) error {
101 | return nil
102 | })
103 | g.SetOnPublicEventAny(tt.args.callbacks...)
104 | if len(g.onPublicEvent[PublicEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onPublicEvent[PublicEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandlePublicEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.PublicEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "public",
130 |
131 | event: &github.PublicEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "public",
142 |
143 | event: &github.PublicEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "public",
154 |
155 | event: &github.PublicEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "public",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnPublicEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.PublicEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handlePublicEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandlePublicEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestPublicEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.PublicEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger PublicEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onPublicEvent: map[string][]PublicEventHandleFunc{
229 | PublicEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.PublicEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: PublicEvent,
241 |
242 | event: &github.PublicEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.PublicEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("PublicEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_push.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // PushEvent is the event name of github.PushEvent's
20 | PushEvent = "push"
21 |
22 | // PushEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.PushEvent
24 | PushEventAnyAction = "*"
25 | )
26 |
27 | // PushEventHandleFunc represents a callback function triggered on github.PushEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.PushEvent) is the webhook payload.
31 | type PushEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.PushEvent) error
32 |
33 | // OnPushEventAny registers callbacks listening to any events of type github.PushEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnPushEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#push
42 | func (g *EventHandler) OnPushEventAny(callbacks ...PushEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onPushEvent == nil {
49 | g.onPushEvent = make(map[string][]PushEventHandleFunc)
50 | }
51 | g.onPushEvent[PushEventAnyAction] = append(
52 | g.onPushEvent[PushEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnPushEventAny registers callbacks listening to any events of type github.PushEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnPushEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#push
67 | func (g *EventHandler) SetOnPushEventAny(callbacks ...PushEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onPushEvent == nil {
74 | g.onPushEvent = make(map[string][]PushEventHandleFunc)
75 | }
76 | g.onPushEvent[PushEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handlePushEventAny(ctx context.Context, deliveryID string, eventName string, event *github.PushEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onPushEvent[PushEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onPushEvent[PushEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // PushEvent handles github.PushEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnPushEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) PushEvent(ctx context.Context, deliveryID string, eventName string, event *github.PushEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handlePushEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_push_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnPushEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []PushEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single PushEventHandleFunc",
28 | args: args{
29 | []PushEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.PushEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple PushEventHandleFuncs",
38 | args: args{
39 | []PushEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.PushEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.PushEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnPushEventAny(tt.args.callbacks...)
54 | if len(g.onPushEvent[PushEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onPushEvent[PushEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnPushEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []PushEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single PushEventHandleFunc",
72 | args: args{
73 | []PushEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.PushEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple PushEventHandleFuncs",
83 | args: args{
84 | []PushEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.PushEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.PushEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnPushEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.PushEvent) error {
101 | return nil
102 | })
103 | g.SetOnPushEventAny(tt.args.callbacks...)
104 | if len(g.onPushEvent[PushEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onPushEvent[PushEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandlePushEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.PushEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "push",
130 |
131 | event: &github.PushEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "push",
142 |
143 | event: &github.PushEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "push",
154 |
155 | event: &github.PushEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "push",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnPushEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.PushEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handlePushEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandlePushEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestPushEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.PushEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger PushEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onPushEvent: map[string][]PushEventHandleFunc{
229 | PushEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.PushEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: PushEvent,
241 |
242 | event: &github.PushEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.PushEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("PushEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_repository_dispatch.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // RepositoryDispatchEvent is the event name of github.RepositoryDispatchEvent's
20 | RepositoryDispatchEvent = "repository_dispatch"
21 |
22 | // RepositoryDispatchEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.RepositoryDispatchEvent
24 | RepositoryDispatchEventAnyAction = "*"
25 | )
26 |
27 | // RepositoryDispatchEventHandleFunc represents a callback function triggered on github.RepositoryDispatchEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.RepositoryDispatchEvent) is the webhook payload.
31 | type RepositoryDispatchEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.RepositoryDispatchEvent) error
32 |
33 | // OnRepositoryDispatchEventAny registers callbacks listening to any events of type github.RepositoryDispatchEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnRepositoryDispatchEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#repository_dispatch
42 | func (g *EventHandler) OnRepositoryDispatchEventAny(callbacks ...RepositoryDispatchEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onRepositoryDispatchEvent == nil {
49 | g.onRepositoryDispatchEvent = make(map[string][]RepositoryDispatchEventHandleFunc)
50 | }
51 | g.onRepositoryDispatchEvent[RepositoryDispatchEventAnyAction] = append(
52 | g.onRepositoryDispatchEvent[RepositoryDispatchEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnRepositoryDispatchEventAny registers callbacks listening to any events of type github.RepositoryDispatchEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnRepositoryDispatchEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#repository_dispatch
67 | func (g *EventHandler) SetOnRepositoryDispatchEventAny(callbacks ...RepositoryDispatchEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onRepositoryDispatchEvent == nil {
74 | g.onRepositoryDispatchEvent = make(map[string][]RepositoryDispatchEventHandleFunc)
75 | }
76 | g.onRepositoryDispatchEvent[RepositoryDispatchEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handleRepositoryDispatchEventAny(ctx context.Context, deliveryID string, eventName string, event *github.RepositoryDispatchEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onRepositoryDispatchEvent[RepositoryDispatchEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onRepositoryDispatchEvent[RepositoryDispatchEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // RepositoryDispatchEvent handles github.RepositoryDispatchEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnRepositoryDispatchEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) RepositoryDispatchEvent(ctx context.Context, deliveryID string, eventName string, event *github.RepositoryDispatchEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handleRepositoryDispatchEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_status.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // StatusEvent is the event name of github.StatusEvent's
20 | StatusEvent = "status"
21 |
22 | // StatusEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.StatusEvent
24 | StatusEventAnyAction = "*"
25 | )
26 |
27 | // StatusEventHandleFunc represents a callback function triggered on github.StatusEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.StatusEvent) is the webhook payload.
31 | type StatusEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.StatusEvent) error
32 |
33 | // OnStatusEventAny registers callbacks listening to any events of type github.StatusEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnStatusEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#status
42 | func (g *EventHandler) OnStatusEventAny(callbacks ...StatusEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onStatusEvent == nil {
49 | g.onStatusEvent = make(map[string][]StatusEventHandleFunc)
50 | }
51 | g.onStatusEvent[StatusEventAnyAction] = append(
52 | g.onStatusEvent[StatusEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnStatusEventAny registers callbacks listening to any events of type github.StatusEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnStatusEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#status
67 | func (g *EventHandler) SetOnStatusEventAny(callbacks ...StatusEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onStatusEvent == nil {
74 | g.onStatusEvent = make(map[string][]StatusEventHandleFunc)
75 | }
76 | g.onStatusEvent[StatusEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handleStatusEventAny(ctx context.Context, deliveryID string, eventName string, event *github.StatusEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onStatusEvent[StatusEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onStatusEvent[StatusEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // StatusEvent handles github.StatusEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnStatusEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) StatusEvent(ctx context.Context, deliveryID string, eventName string, event *github.StatusEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handleStatusEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_status_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnStatusEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []StatusEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single StatusEventHandleFunc",
28 | args: args{
29 | []StatusEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.StatusEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple StatusEventHandleFuncs",
38 | args: args{
39 | []StatusEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.StatusEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.StatusEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnStatusEventAny(tt.args.callbacks...)
54 | if len(g.onStatusEvent[StatusEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onStatusEvent[StatusEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnStatusEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []StatusEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single StatusEventHandleFunc",
72 | args: args{
73 | []StatusEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.StatusEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple StatusEventHandleFuncs",
83 | args: args{
84 | []StatusEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.StatusEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.StatusEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnStatusEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.StatusEvent) error {
101 | return nil
102 | })
103 | g.SetOnStatusEventAny(tt.args.callbacks...)
104 | if len(g.onStatusEvent[StatusEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onStatusEvent[StatusEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandleStatusEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.StatusEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "status",
130 |
131 | event: &github.StatusEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "status",
142 |
143 | event: &github.StatusEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "status",
154 |
155 | event: &github.StatusEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "status",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnStatusEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.StatusEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handleStatusEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandleStatusEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestStatusEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.StatusEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger StatusEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onStatusEvent: map[string][]StatusEventHandleFunc{
229 | StatusEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.StatusEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: StatusEvent,
241 |
242 | event: &github.StatusEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.StatusEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("StatusEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_team_add.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // TeamAddEvent is the event name of github.TeamAddEvent's
20 | TeamAddEvent = "team_add"
21 |
22 | // TeamAddEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.TeamAddEvent
24 | TeamAddEventAnyAction = "*"
25 | )
26 |
27 | // TeamAddEventHandleFunc represents a callback function triggered on github.TeamAddEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.TeamAddEvent) is the webhook payload.
31 | type TeamAddEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.TeamAddEvent) error
32 |
33 | // OnTeamAddEventAny registers callbacks listening to any events of type github.TeamAddEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnTeamAddEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#team_add
42 | func (g *EventHandler) OnTeamAddEventAny(callbacks ...TeamAddEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onTeamAddEvent == nil {
49 | g.onTeamAddEvent = make(map[string][]TeamAddEventHandleFunc)
50 | }
51 | g.onTeamAddEvent[TeamAddEventAnyAction] = append(
52 | g.onTeamAddEvent[TeamAddEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnTeamAddEventAny registers callbacks listening to any events of type github.TeamAddEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnTeamAddEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#team_add
67 | func (g *EventHandler) SetOnTeamAddEventAny(callbacks ...TeamAddEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onTeamAddEvent == nil {
74 | g.onTeamAddEvent = make(map[string][]TeamAddEventHandleFunc)
75 | }
76 | g.onTeamAddEvent[TeamAddEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handleTeamAddEventAny(ctx context.Context, deliveryID string, eventName string, event *github.TeamAddEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onTeamAddEvent[TeamAddEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onTeamAddEvent[TeamAddEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // TeamAddEvent handles github.TeamAddEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnTeamAddEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) TeamAddEvent(ctx context.Context, deliveryID string, eventName string, event *github.TeamAddEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handleTeamAddEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_team_add_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnTeamAddEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []TeamAddEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single TeamAddEventHandleFunc",
28 | args: args{
29 | []TeamAddEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.TeamAddEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple TeamAddEventHandleFuncs",
38 | args: args{
39 | []TeamAddEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.TeamAddEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.TeamAddEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnTeamAddEventAny(tt.args.callbacks...)
54 | if len(g.onTeamAddEvent[TeamAddEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onTeamAddEvent[TeamAddEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnTeamAddEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []TeamAddEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single TeamAddEventHandleFunc",
72 | args: args{
73 | []TeamAddEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.TeamAddEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple TeamAddEventHandleFuncs",
83 | args: args{
84 | []TeamAddEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.TeamAddEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.TeamAddEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnTeamAddEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.TeamAddEvent) error {
101 | return nil
102 | })
103 | g.SetOnTeamAddEventAny(tt.args.callbacks...)
104 | if len(g.onTeamAddEvent[TeamAddEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onTeamAddEvent[TeamAddEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandleTeamAddEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.TeamAddEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "team_add",
130 |
131 | event: &github.TeamAddEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "team_add",
142 |
143 | event: &github.TeamAddEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "team_add",
154 |
155 | event: &github.TeamAddEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "team_add",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnTeamAddEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.TeamAddEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handleTeamAddEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandleTeamAddEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestTeamAddEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.TeamAddEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger TeamAddEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onTeamAddEvent: map[string][]TeamAddEventHandleFunc{
229 | TeamAddEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.TeamAddEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: TeamAddEvent,
241 |
242 | event: &github.TeamAddEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.TeamAddEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("TeamAddEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_watch.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // WatchEvent is the event name of github.WatchEvent's
20 | WatchEvent = "watch"
21 |
22 | // WatchEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.WatchEvent
24 | WatchEventAnyAction = "*"
25 | )
26 |
27 | // WatchEventHandleFunc represents a callback function triggered on github.WatchEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.WatchEvent) is the webhook payload.
31 | type WatchEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.WatchEvent) error
32 |
33 | // OnWatchEventAny registers callbacks listening to any events of type github.WatchEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnWatchEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#watch
42 | func (g *EventHandler) OnWatchEventAny(callbacks ...WatchEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onWatchEvent == nil {
49 | g.onWatchEvent = make(map[string][]WatchEventHandleFunc)
50 | }
51 | g.onWatchEvent[WatchEventAnyAction] = append(
52 | g.onWatchEvent[WatchEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnWatchEventAny registers callbacks listening to any events of type github.WatchEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnWatchEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#watch
67 | func (g *EventHandler) SetOnWatchEventAny(callbacks ...WatchEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onWatchEvent == nil {
74 | g.onWatchEvent = make(map[string][]WatchEventHandleFunc)
75 | }
76 | g.onWatchEvent[WatchEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handleWatchEventAny(ctx context.Context, deliveryID string, eventName string, event *github.WatchEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onWatchEvent[WatchEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onWatchEvent[WatchEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // WatchEvent handles github.WatchEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnWatchEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) WatchEvent(ctx context.Context, deliveryID string, eventName string, event *github.WatchEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handleWatchEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/githubevents/events_watch_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "errors"
13 | "github.com/google/go-github/v72/github"
14 | "sync"
15 | "testing"
16 | )
17 |
18 | func TestOnWatchEventAny(t *testing.T) {
19 | type args struct {
20 | callbacks []WatchEventHandleFunc
21 | }
22 | tests := []struct {
23 | name string
24 | args args
25 | }{
26 | {
27 | name: "must add single WatchEventHandleFunc",
28 | args: args{
29 | []WatchEventHandleFunc{
30 | func(ctx context.Context, deliveryID string, eventName string, event *github.WatchEvent) error {
31 | return nil
32 | },
33 | },
34 | },
35 | },
36 | {
37 | name: "must add multiple WatchEventHandleFuncs",
38 | args: args{
39 | []WatchEventHandleFunc{
40 | func(ctx context.Context, deliveryID string, eventName string, event *github.WatchEvent) error {
41 | return nil
42 | },
43 | func(ctx context.Context, deliveryID string, eventName string, event *github.WatchEvent) error {
44 | return nil
45 | },
46 | },
47 | },
48 | },
49 | }
50 | for _, tt := range tests {
51 | t.Run(tt.name, func(t *testing.T) {
52 | g := New("fake")
53 | g.OnWatchEventAny(tt.args.callbacks...)
54 | if len(g.onWatchEvent[WatchEventAnyAction]) == 0 {
55 | t.Errorf("failed to add callbacks, got %d", len(g.onWatchEvent[WatchEventAnyAction]))
56 | }
57 | })
58 | }
59 | }
60 |
61 | func TestSetOnWatchEventAny(t *testing.T) {
62 | type args struct {
63 | callbacks []WatchEventHandleFunc
64 | }
65 | tests := []struct {
66 | name string
67 | args args
68 | want int
69 | }{
70 | {
71 | name: "must add single WatchEventHandleFunc",
72 | args: args{
73 | []WatchEventHandleFunc{
74 | func(ctx context.Context, deliveryID string, eventName string, event *github.WatchEvent) error {
75 | return nil
76 | },
77 | },
78 | },
79 | want: 1,
80 | },
81 | {
82 | name: "must add multiple WatchEventHandleFuncs",
83 | args: args{
84 | []WatchEventHandleFunc{
85 | func(ctx context.Context, deliveryID string, eventName string, event *github.WatchEvent) error {
86 | return nil
87 | },
88 | func(ctx context.Context, deliveryID string, eventName string, event *github.WatchEvent) error {
89 | return nil
90 | },
91 | },
92 | },
93 | want: 2,
94 | },
95 | }
96 | for _, tt := range tests {
97 | t.Run(tt.name, func(t *testing.T) {
98 | g := New("fake")
99 | // add callbacks to be overwritten
100 | g.SetOnWatchEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.WatchEvent) error {
101 | return nil
102 | })
103 | g.SetOnWatchEventAny(tt.args.callbacks...)
104 | if len(g.onWatchEvent[WatchEventAnyAction]) != tt.want {
105 | t.Errorf("failed to add callbacks, got %d, want %d", len(g.onWatchEvent[WatchEventAnyAction]), tt.want)
106 | }
107 | })
108 | }
109 | }
110 |
111 | func TestHandleWatchEventAny(t *testing.T) {
112 |
113 | type args struct {
114 | deliveryID string
115 | eventName string
116 | event *github.WatchEvent
117 | fail bool
118 | panic bool
119 | }
120 | tests := []struct {
121 | name string
122 | args args
123 | wantErr bool
124 | }{
125 | {
126 | name: "must pass",
127 | args: args{
128 | deliveryID: "42",
129 | eventName: "watch",
130 |
131 | event: &github.WatchEvent{},
132 |
133 | fail: false,
134 | },
135 | wantErr: false,
136 | },
137 | {
138 | name: "must fail with error",
139 | args: args{
140 | deliveryID: "42",
141 | eventName: "watch",
142 |
143 | event: &github.WatchEvent{},
144 |
145 | fail: true,
146 | },
147 | wantErr: true,
148 | },
149 | {
150 | name: "must fail with error on panic recover",
151 | args: args{
152 | deliveryID: "42",
153 | eventName: "watch",
154 |
155 | event: &github.WatchEvent{},
156 |
157 | fail: false,
158 | panic: true,
159 | },
160 | wantErr: true,
161 | },
162 | {
163 | name: "must fail event nil",
164 | args: args{
165 | deliveryID: "42",
166 | eventName: "watch",
167 | event: nil,
168 | fail: false,
169 | },
170 | wantErr: true,
171 | },
172 | }
173 | for _, tt := range tests {
174 | t.Run(tt.name, func(t *testing.T) {
175 | g := New("fake")
176 | g.OnWatchEventAny(func(ctx context.Context, deliveryID string, eventName string, event *github.WatchEvent) error {
177 | if tt.args.fail {
178 | return errors.New("fake error")
179 | }
180 | if tt.args.panic {
181 | panic("fake panic")
182 | }
183 | return nil
184 | })
185 | if err := g.handleWatchEventAny(context.Background(), tt.args.deliveryID, tt.args.deliveryID, tt.args.event); (err != nil) != tt.wantErr {
186 | t.Errorf("TestHandleWatchEventAny() error = %v, wantErr %v", err, tt.wantErr)
187 | }
188 | })
189 | }
190 | }
191 |
192 | func TestWatchEvent(t *testing.T) {
193 | type fields struct {
194 | handler *EventHandler
195 | }
196 | type args struct {
197 | deliveryID string
198 | eventName string
199 | event *github.WatchEvent
200 | }
201 | tests := []struct {
202 | name string
203 | fields fields
204 | args args
205 | wantErr bool
206 | }{
207 | {
208 | name: "must trigger WatchEventAny with unknown event action",
209 | fields: fields{
210 | handler: &EventHandler{
211 | WebhookSecret: "fake",
212 | onBeforeAny: map[string][]EventHandleFunc{
213 | EventAnyAction: {
214 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
215 | t.Log("onBeforeAny called")
216 | return nil
217 | },
218 | },
219 | },
220 | onAfterAny: map[string][]EventHandleFunc{
221 | EventAnyAction: {
222 | func(ctx context.Context, deliveryID string, eventName string, event any) error {
223 | t.Log("onAfterAny called")
224 | return nil
225 | },
226 | },
227 | },
228 | onWatchEvent: map[string][]WatchEventHandleFunc{
229 | WatchEventAnyAction: {
230 | func(ctx context.Context, deliveryID string, eventName string, event *github.WatchEvent) error {
231 | t.Log("onAny action called")
232 | return nil
233 | },
234 | },
235 | },
236 | },
237 | },
238 | args: args{
239 | deliveryID: "42",
240 | eventName: WatchEvent,
241 |
242 | event: &github.WatchEvent{},
243 | },
244 | wantErr: false,
245 | },
246 | }
247 | for _, tt := range tests {
248 | t.Run(tt.name, func(t *testing.T) {
249 | g := &EventHandler{
250 | WebhookSecret: "fake",
251 | mu: sync.RWMutex{},
252 | }
253 | if err := g.WatchEvent(context.Background(), tt.args.deliveryID, tt.args.eventName, tt.args.event); (err != nil) != tt.wantErr {
254 | t.Errorf("WatchEvent() error = %v, wantErr %v", err, tt.wantErr)
255 | }
256 | })
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/githubevents/events_workflow_dispatch.go:
--------------------------------------------------------------------------------
1 | // Code generated by gen/generate.go. DO NOT EDIT.
2 | // make edits in gen/generate.go
3 |
4 | // Copyright 2022 The GithubEvents Authors. All rights reserved.
5 | // Use of this source code is governed by the MIT License
6 | // that can be found in the LICENSE file.
7 |
8 | package githubevents
9 |
10 | import (
11 | "context"
12 | "fmt"
13 | "github.com/google/go-github/v72/github"
14 | "golang.org/x/sync/errgroup"
15 | )
16 |
17 | // Actions are used to identify registered callbacks.
18 | const (
19 | // WorkflowDispatchEvent is the event name of github.WorkflowDispatchEvent's
20 | WorkflowDispatchEvent = "workflow_dispatch"
21 |
22 | // WorkflowDispatchEventAnyAction is used to identify callbacks
23 | // listening to all events of type github.WorkflowDispatchEvent
24 | WorkflowDispatchEventAnyAction = "*"
25 | )
26 |
27 | // WorkflowDispatchEventHandleFunc represents a callback function triggered on github.WorkflowDispatchEvent's.
28 | // 'deliveryID' (type: string) is the unique webhook delivery ID.
29 | // 'eventName' (type: string) is the name of the event.
30 | // 'event' (type: *github.WorkflowDispatchEvent) is the webhook payload.
31 | type WorkflowDispatchEventHandleFunc func(ctx context.Context, deliveryID string, eventName string, event *github.WorkflowDispatchEvent) error
32 |
33 | // OnWorkflowDispatchEventAny registers callbacks listening to any events of type github.WorkflowDispatchEvent
34 | //
35 | // This function appends the callbacks passed as arguments to already existing ones.
36 | // If already existing callbacks are to be overwritten, SetOnWorkflowDispatchEventAny must be used.
37 | //
38 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
39 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
40 | //
41 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#workflow_dispatch
42 | func (g *EventHandler) OnWorkflowDispatchEventAny(callbacks ...WorkflowDispatchEventHandleFunc) {
43 | g.mu.Lock()
44 | defer g.mu.Unlock()
45 | if callbacks == nil || len(callbacks) == 0 {
46 | panic("callbacks is nil or empty")
47 | }
48 | if g.onWorkflowDispatchEvent == nil {
49 | g.onWorkflowDispatchEvent = make(map[string][]WorkflowDispatchEventHandleFunc)
50 | }
51 | g.onWorkflowDispatchEvent[WorkflowDispatchEventAnyAction] = append(
52 | g.onWorkflowDispatchEvent[WorkflowDispatchEventAnyAction],
53 | callbacks...,
54 | )
55 | }
56 |
57 | // SetOnWorkflowDispatchEventAny registers callbacks listening to any events of type github.WorkflowDispatchEvent
58 | // and overwrites already registered callbacks.
59 | //
60 | // This function overwrites all previously registered callbacks.
61 | // If already registered callbacks are not to be overwritten, OnWorkflowDispatchEventAny must be used.
62 | //
63 | // Callbacks are executed in parallel. This function blocks until all callbacks executed in parallel have returned,
64 | // then returns the first non-nil error (if any) from them. If OnError callbacks have been set, they will be called when an error occurs.
65 | //
66 | // Reference: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#workflow_dispatch
67 | func (g *EventHandler) SetOnWorkflowDispatchEventAny(callbacks ...WorkflowDispatchEventHandleFunc) {
68 | g.mu.Lock()
69 | defer g.mu.Unlock()
70 | if callbacks == nil || len(callbacks) == 0 {
71 | panic("callbacks is nil or empty")
72 | }
73 | if g.onWorkflowDispatchEvent == nil {
74 | g.onWorkflowDispatchEvent = make(map[string][]WorkflowDispatchEventHandleFunc)
75 | }
76 | g.onWorkflowDispatchEvent[WorkflowDispatchEventAnyAction] = callbacks
77 | }
78 |
79 | func (g *EventHandler) handleWorkflowDispatchEventAny(ctx context.Context, deliveryID string, eventName string, event *github.WorkflowDispatchEvent) error {
80 | if event == nil {
81 | return fmt.Errorf("event was empty or nil")
82 | }
83 | if _, ok := g.onWorkflowDispatchEvent[WorkflowDispatchEventAnyAction]; !ok {
84 | return nil
85 | }
86 | eg := new(errgroup.Group)
87 | for _, h := range g.onWorkflowDispatchEvent[WorkflowDispatchEventAnyAction] {
88 | handle := h
89 | eg.Go(func() (err error) {
90 | defer func() {
91 | if r := recover(); r != nil {
92 | err = fmt.Errorf("recovered from panic: %v", r)
93 | }
94 | }()
95 | err = handle(ctx, deliveryID, eventName, event)
96 | if err != nil {
97 | return err
98 | }
99 | return nil
100 | })
101 | }
102 | if err := eg.Wait(); err != nil {
103 | return err
104 | }
105 | return nil
106 | }
107 |
108 | // WorkflowDispatchEvent handles github.WorkflowDispatchEvent.
109 | //
110 | // Callbacks are executed in the following order:
111 | //
112 | // 1) All callbacks registered with OnBeforeAny are executed in parallel.
113 | // 2) All callbacks registered with OnWorkflowDispatchEvent... are executed in parallel in case the Event has actions.
114 | // 3) All callbacks registered with OnAfterAny are executed in parallel.
115 | //
116 | // on any error all callbacks registered with OnError are executed in parallel.
117 | func (g *EventHandler) WorkflowDispatchEvent(ctx context.Context, deliveryID string, eventName string, event *github.WorkflowDispatchEvent) error {
118 |
119 | if event == nil {
120 | return fmt.Errorf("event action was empty or nil")
121 | }
122 |
123 | err := g.handleBeforeAny(ctx, deliveryID, eventName, event)
124 | if err != nil {
125 | return g.handleError(ctx, deliveryID, eventName, event, err)
126 | }
127 |
128 | err = g.handleWorkflowDispatchEventAny(ctx, deliveryID, eventName, event)
129 | if err != nil {
130 | return g.handleError(ctx, deliveryID, eventName, event, err)
131 | }
132 |
133 | err = g.handleAfterAny(ctx, deliveryID, eventName, event)
134 | if err != nil {
135 | return g.handleError(ctx, deliveryID, eventName, event, err)
136 | }
137 | return nil
138 | }
139 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/cbrgm/githubevents/v2
2 |
3 | go 1.24.0
4 |
5 | require (
6 | github.com/google/go-github/v72 v72.0.0
7 | golang.org/x/sync v0.15.0
8 | )
9 |
10 | require github.com/google/go-querystring v1.1.0 // indirect
11 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
2 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
3 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
4 | github.com/google/go-github/v72 v72.0.0 h1:FcIO37BLoVPBO9igQQ6tStsv2asG4IPcYFi655PPvBM=
5 | github.com/google/go-github/v72 v72.0.0/go.mod h1:WWtw8GMRiL62mvIquf1kO3onRHeWWKmK01qdCY8c5fg=
6 | github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
7 | github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
8 | golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
9 | golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
10 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
11 |
--------------------------------------------------------------------------------