Skip to content

Conversation

@fabienfleureau
Copy link
Contributor

  • Introduce unified provider abstraction and models for GitLab/GitHub
  • Implement GitHub provider (API client + webhooks) and extend GitLab provider
  • Add approval & pipeline info (fetchApprovalInfo, UnifiedApprovalInfo, PR.pipeline)
  • Improve review messages with pipeline/mergeable emojis and accurate approval counts
  • Restore project threshold warnings and add GitHub project channel counting

@fabienfleureau
Copy link
Contributor Author

Hello @M0nkeySan I tried to cherry-pick what I did to enable github support, maybe some changes are not necessary for MM context.

@fabienfleureau fabienfleureau force-pushed the feat/gh_review_support branch 2 times, most recently from 3f8fc12 to 16f53c1 Compare November 19, 2025 09:45
- Introduce unified provider abstraction and models for GitLab/GitHub
- Implement GitHub provider (API client + webhooks) and extend GitLab provider
- Add approval & pipeline info (fetchApprovalInfo, UnifiedApprovalInfo, PR.pipeline)
- Improve review messages with pipeline/mergeable emojis and accurate approval counts
- Restore project threshold warnings and add GitHub project channel counting
@M0nkeySan
Copy link
Collaborator

Hello @fabienfleureau, I will review your PR asap.

In the mean time, can you fix the test failing in the pipeline ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part (line 22) need to be adapted to handle github hook body :

const { merge_request, object_attributes, project } = req.body as {
    merge_request: {
      author_id: number;
      iid: number;
    };
    object_attributes: { author_id: number; note: string; url: string };
    project: GitlabProjectDetails;
  };

This is payload I received for an issue comment webhook event :

{
"action": "created",
"issue": {
  "url": "https://api.github.com/repos/M0nkeySan/homer/issues/1",
  "repository_url": "https://api.github.com/repos/M0nkeySan/homer",
  "labels_url": "https://api.github.com/repos/M0nkeySan/homer/issues/1/labels{/name}",
  "comments_url": "https://api.github.com/repos/M0nkeySan/homer/issues/1/comments",
  "events_url": "https://api.github.com/repos/M0nkeySan/homer/issues/1/events",
  "html_url": "https://github.com/M0nkeySan/homer/pull/1",
  "id": 3642028010,
  "node_id": "PR_kwDONH_Bn860USOp",
  "number": 1,
  "title": "Automatic mr review",
  "user": {
    "login": "M0nkeySan",
    "id": 10235926,
    "node_id": "MDQ6VXNlcjEwMjM1OTI2",
    "avatar_url": "https://avatars.githubusercontent.com/u/10235926?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/M0nkeySan",
    "html_url": "https://github.com/M0nkeySan",
    "followers_url": "https://api.github.com/users/M0nkeySan/followers",
    "following_url": "https://api.github.com/users/M0nkeySan/following{/other_user}",
    "gists_url": "https://api.github.com/users/M0nkeySan/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/M0nkeySan/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/M0nkeySan/subscriptions",
    "organizations_url": "https://api.github.com/users/M0nkeySan/orgs",
    "repos_url": "https://api.github.com/users/M0nkeySan/repos",
    "events_url": "https://api.github.com/users/M0nkeySan/events{/privacy}",
    "received_events_url": "https://api.github.com/users/M0nkeySan/received_events",
    "type": "User",
    "user_view_type": "public",
    "site_admin": false
  },
  "labels": [
    {
      "id": 9675882250,
      "node_id": "LA_kwDONH_Bn88AAAACQLo_Cg",
      "url": "https://api.github.com/repos/M0nkeySan/homer/labels/homer-review",
      "name": "homer-review",
      "color": "DCEEF1",
      "default": false,
      "description": ""
    }
  ],
  "state": "open",
  "locked": false,
  "assignee": null,
  "assignees": [],
  "milestone": null,
  "comments": 2,
  "created_at": "2025-11-19T10:14:49Z",
  "updated_at": "2025-11-19T10:18:17Z",
  "closed_at": null,
  "author_association": "OWNER",
  "active_lock_reason": null,
  "draft": false,
  "pull_request": {
    "url": "https://api.github.com/repos/M0nkeySan/homer/pulls/1",
    "html_url": "https://github.com/M0nkeySan/homer/pull/1",
    "diff_url": "https://github.com/M0nkeySan/homer/pull/1.diff",
    "patch_url": "https://github.com/M0nkeySan/homer/pull/1.patch",
    "merged_at": null
  },
  "body": null,
  "reactions": {
    "url": "https://api.github.com/repos/M0nkeySan/homer/issues/1/reactions",
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
  },
  "timeline_url": "https://api.github.com/repos/M0nkeySan/homer/issues/1/timeline",
  "performed_via_github_app": null,
  "state_reason": null
},
"comment": {
  "url": "https://api.github.com/repos/M0nkeySan/homer/issues/comments/3551915836",
  "html_url": "https://github.com/M0nkeySan/homer/pull/1#issuecomment-3551915836",
  "issue_url": "https://api.github.com/repos/M0nkeySan/homer/issues/1",
  "id": 3551915836,
  "node_id": "IC_kwDONH_Bn87Tte88",
  "user": {
    "login": "M0nkeySan",
    "id": 10235926,
    "node_id": "MDQ6VXNlcjEwMjM1OTI2",
    "avatar_url": "https://avatars.githubusercontent.com/u/10235926?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/M0nkeySan",
    "html_url": "https://github.com/M0nkeySan",
    "followers_url": "https://api.github.com/users/M0nkeySan/followers",
    "following_url": "https://api.github.com/users/M0nkeySan/following{/other_user}",
    "gists_url": "https://api.github.com/users/M0nkeySan/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/M0nkeySan/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/M0nkeySan/subscriptions",
    "organizations_url": "https://api.github.com/users/M0nkeySan/orgs",
    "repos_url": "https://api.github.com/users/M0nkeySan/repos",
    "events_url": "https://api.github.com/users/M0nkeySan/events{/privacy}",
    "received_events_url": "https://api.github.com/users/M0nkeySan/received_events",
    "type": "User",
    "user_view_type": "public",
    "site_admin": false
  },
  "created_at": "2025-11-19T10:18:17Z",
  "updated_at": "2025-11-19T10:18:17Z",
  "body": "test",
  "author_association": "OWNER",
  "reactions": {
    "url": "https://api.github.com/repos/M0nkeySan/homer/issues/comments/3551915836/reactions",
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
  },
  "performed_via_github_app": null
},
"repository": {
  "id": 880787871,
  "node_id": "R_kgDONH_Bnw",
  "name": "homer",
  "full_name": "M0nkeySan/homer",
  "private": false,
  "owner": {
    "login": "M0nkeySan",
    "id": 10235926,
    "node_id": "MDQ6VXNlcjEwMjM1OTI2",
    "avatar_url": "https://avatars.githubusercontent.com/u/10235926?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/M0nkeySan",
    "html_url": "https://github.com/M0nkeySan",
    "followers_url": "https://api.github.com/users/M0nkeySan/followers",
    "following_url": "https://api.github.com/users/M0nkeySan/following{/other_user}",
    "gists_url": "https://api.github.com/users/M0nkeySan/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/M0nkeySan/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/M0nkeySan/subscriptions",
    "organizations_url": "https://api.github.com/users/M0nkeySan/orgs",
    "repos_url": "https://api.github.com/users/M0nkeySan/repos",
    "events_url": "https://api.github.com/users/M0nkeySan/events{/privacy}",
    "received_events_url": "https://api.github.com/users/M0nkeySan/received_events",
    "type": "User",
    "user_view_type": "public",
    "site_admin": false
  },
  "html_url": "https://github.com/M0nkeySan/homer",
  "description": "Homer is a Slack bot intended to help you to easily share and follow Gitlab merge requests.",
  "fork": true,
  "url": "https://api.github.com/repos/M0nkeySan/homer",
  "forks_url": "https://api.github.com/repos/M0nkeySan/homer/forks",
  "keys_url": "https://api.github.com/repos/M0nkeySan/homer/keys{/key_id}",
  "collaborators_url": "https://api.github.com/repos/M0nkeySan/homer/collaborators{/collaborator}",
  "teams_url": "https://api.github.com/repos/M0nkeySan/homer/teams",
  "hooks_url": "https://api.github.com/repos/M0nkeySan/homer/hooks",
  "issue_events_url": "https://api.github.com/repos/M0nkeySan/homer/issues/events{/number}",
  "events_url": "https://api.github.com/repos/M0nkeySan/homer/events",
  "assignees_url": "https://api.github.com/repos/M0nkeySan/homer/assignees{/user}",
  "branches_url": "https://api.github.com/repos/M0nkeySan/homer/branches{/branch}",
  "tags_url": "https://api.github.com/repos/M0nkeySan/homer/tags",
  "blobs_url": "https://api.github.com/repos/M0nkeySan/homer/git/blobs{/sha}",
  "git_tags_url": "https://api.github.com/repos/M0nkeySan/homer/git/tags{/sha}",
  "git_refs_url": "https://api.github.com/repos/M0nkeySan/homer/git/refs{/sha}",
  "trees_url": "https://api.github.com/repos/M0nkeySan/homer/git/trees{/sha}",
  "statuses_url": "https://api.github.com/repos/M0nkeySan/homer/statuses/{sha}",
  "languages_url": "https://api.github.com/repos/M0nkeySan/homer/languages",
  "stargazers_url": "https://api.github.com/repos/M0nkeySan/homer/stargazers",
  "contributors_url": "https://api.github.com/repos/M0nkeySan/homer/contributors",
  "subscribers_url": "https://api.github.com/repos/M0nkeySan/homer/subscribers",
  "subscription_url": "https://api.github.com/repos/M0nkeySan/homer/subscription",
  "commits_url": "https://api.github.com/repos/M0nkeySan/homer/commits{/sha}",
  "git_commits_url": "https://api.github.com/repos/M0nkeySan/homer/git/commits{/sha}",
  "comments_url": "https://api.github.com/repos/M0nkeySan/homer/comments{/number}",
  "issue_comment_url": "https://api.github.com/repos/M0nkeySan/homer/issues/comments{/number}",
  "contents_url": "https://api.github.com/repos/M0nkeySan/homer/contents/{+path}",
  "compare_url": "https://api.github.com/repos/M0nkeySan/homer/compare/{base}...{head}",
  "merges_url": "https://api.github.com/repos/M0nkeySan/homer/merges",
  "archive_url": "https://api.github.com/repos/M0nkeySan/homer/{archive_format}{/ref}",
  "downloads_url": "https://api.github.com/repos/M0nkeySan/homer/downloads",
  "issues_url": "https://api.github.com/repos/M0nkeySan/homer/issues{/number}",
  "pulls_url": "https://api.github.com/repos/M0nkeySan/homer/pulls{/number}",
  "milestones_url": "https://api.github.com/repos/M0nkeySan/homer/milestones{/number}",
  "notifications_url": "https://api.github.com/repos/M0nkeySan/homer/notifications{?since,all,participating}",
  "labels_url": "https://api.github.com/repos/M0nkeySan/homer/labels{/name}",
  "releases_url": "https://api.github.com/repos/M0nkeySan/homer/releases{/id}",
  "deployments_url": "https://api.github.com/repos/M0nkeySan/homer/deployments",
  "created_at": "2024-10-30T11:07:28Z",
  "updated_at": "2025-10-17T13:04:09Z",
  "pushed_at": "2025-10-21T12:25:34Z",
  "git_url": "git://github.com/M0nkeySan/homer.git",
  "ssh_url": "[email protected]:M0nkeySan/homer.git",
  "clone_url": "https://github.com/M0nkeySan/homer.git",
  "svn_url": "https://github.com/M0nkeySan/homer",
  "homepage": "",
  "size": 2061,
  "stargazers_count": 0,
  "watchers_count": 0,
  "language": "TypeScript",
  "has_issues": false,
  "has_projects": true,
  "has_downloads": true,
  "has_wiki": false,
  "has_pages": false,
  "has_discussions": false,
  "forks_count": 0,
  "mirror_url": null,
  "archived": false,
  "disabled": false,
  "open_issues_count": 1,
  "license": {
    "key": "mit",
    "name": "MIT License",
    "spdx_id": "MIT",
    "url": "https://api.github.com/licenses/mit",
    "node_id": "MDc6TGljZW5zZTEz"
  },
  "allow_forking": true,
  "is_template": false,
  "web_commit_signoff_required": false,
  "topics": [],
  "visibility": "public",
  "forks": 0,
  "open_issues": 1,
  "watchers": 0,
  "default_branch": "main"
},
"sender": {
  "login": "M0nkeySan",
  "id": 10235926,
  "node_id": "MDQ6VXNlcjEwMjM1OTI2",
  "avatar_url": "https://avatars.githubusercontent.com/u/10235926?v=4",
  "gravatar_id": "",
  "url": "https://api.github.com/users/M0nkeySan",
  "html_url": "https://github.com/M0nkeySan",
  "followers_url": "https://api.github.com/users/M0nkeySan/followers",
  "following_url": "https://api.github.com/users/M0nkeySan/following{/other_user}",
  "gists_url": "https://api.github.com/users/M0nkeySan/gists{/gist_id}",
  "starred_url": "https://api.github.com/users/M0nkeySan/starred{/owner}{/repo}",
  "subscriptions_url": "https://api.github.com/users/M0nkeySan/subscriptions",
  "organizations_url": "https://api.github.com/users/M0nkeySan/orgs",
  "repos_url": "https://api.github.com/users/M0nkeySan/repos",
  "events_url": "https://api.github.com/users/M0nkeySan/events{/privacy}",
  "received_events_url": "https://api.github.com/users/M0nkeySan/received_events",
  "type": "User",
  "user_view_type": "public",
  "site_admin": false
}
}

Comment on lines +160 to +181
{
text: {
type: 'plain_text',
text: 'Create a pipeline',
},
value: injectActionsParameters(
'review-create-pipeline',
projectId,
pullRequest.sourceBranch,
),
},
{
text: {
type: 'plain_text',
text: 'Rebase source branch',
},
value: injectActionsParameters(
'review-rebase-source-branch',
projectId,
pullRequest.iid,
),
},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should remove this 2 actions for Github because they are not implemented yet.

Comment on lines +107 to +108
// 'commented' state - treat as update
action = 'update';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it wanted to handle the commented state here ?

Because with this behaviour, we don't have the comments send to the slack thread.

@benjoz
Copy link

benjoz commented Nov 20, 2025

Can't wait to see github support from my beloved Homer bot :)
I miss it !

*/

describe('UnifiedModels Type Definitions', () => {
it('should pass TypeScript compilation', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this test?

@fabienfleureau
Copy link
Contributor Author

Hi, I didn't have time to check your comment yet! I'l do it asap

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants