Skip to content

Commit

Permalink
Merge branch 'master' into release-bump-1.7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mickmister committed Aug 7, 2023
2 parents ef64264 + 03e6909 commit 0a18dc3
Show file tree
Hide file tree
Showing 15 changed files with 1,080 additions and 32 deletions.
175 changes: 166 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,182 @@
# Mattermost/GitLab Integration

The GitLab/Mattermost plugin documentation is currently being updated and relocated to a new location: https://mattermost.gitbook.io/gitlab-plugin/ - let us know your thoughts on the new format in the [Plugin: GitLab Channel](https://community-daily.mattermost.com/core/channels/gitlab-plugin) on our Mattermost community!

# Mattermost GitLab Plugin

[![Build Status](https://img.shields.io/circleci/project/github/mattermost/mattermost-plugin-gitlab/master.svg)](https://circleci.com/gh/mattermost/mattermost-plugin-gitlab)
[![Code Coverage](https://img.shields.io/codecov/c/github/mattermost/mattermost-plugin-gitlab/master.svg)](https://codecov.io/gh/mattermost/mattermost-plugin-gitlab)
[![Release](https://img.shields.io/github/v/release/mattermost/mattermost-plugin-gitlab)](https://github.com/mattermost/mattermost-plugin-gitlab/releases/latest)
[![HW](https://img.shields.io/github/issues/mattermost/mattermost-plugin-gitlab/Up%20For%20Grabs?color=dark%20green&label=Help%20Wanted)](https://github.com/mattermost/mattermost-plugin-gitlab/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22Up+For+Grabs%22+label%3A%22Help+Wanted%22)

A GitLab plugin for Mattermost. This plugin supports a two-way integration between Mattermost and GitLab. This plugin supports Software-as-a-Service (SaaS) or on-premises versions of GitLab.

![GitLab Plugin screenshot](https://user-images.githubusercontent.com/13119842/69115984-96b3ff80-0a58-11ea-92a3-9176b6b05a89.png)

Originally developed by [Romain Maneschi](https://github.com/manland). This project is a fork of the [mattermost-plugin-github](https://github.com/mattermost/mattermost-plugin-github). Thanks to all contributors of it.

**Maintainer:** [@mickmister](https://github.com/mickmister)

**Co-Maintainer:** [@hanzei](https://github.com/hanzei)

A GitLab plugin for Mattermost. Originally developed by [Romain Maneschi](https://github.com/manland).
## Feature summary of GitLab to Mattermost notifications

![GitLab Plugin screenshot](https://user-images.githubusercontent.com/13119842/69115984-96b3ff80-0a58-11ea-92a3-9176b6b05a89.png)
### Channel subscriptions

Notify your team of the latest updates by sending notifications from your GitLab group or repository to Mattermost channels. When team members log in the first time to Mattermost each day, they can get a post letting them know what issues and merge requests need their attention. They can also get a refresh of new events by selecting **Refresh** from every webhook configured in GitLab.

You can specify which events trigger a notification. They can see:

- issues - includes new and closed issues
- merges - includes new and closed merge requests
- pushes - includes pushes
- issue_comments - includes new issue comments
- merge_request_comments - include new merge-request comments
- pipeline - include pipeline
- tag - include tag creation
- pull_reviews - includes merge request reviews
- label:"<labelname>" - must include "merges" or "issues" in feature list when using a label
- Defaults to "merges,issues,tag"

### Personal notifications: GitLab bot

Each user in Mattermost is connected with their own personal GitLab account. Users can get a direct message in Mattermost when someone mentions them, requests their review, comments on, or modifies one of their merge requests/issues, or assigns them on GitLab.

### Sidebar buttons

Team members can stay up-to-date with how many reviews, unread messages, assignments, and open merge requests they have by using buttons in the Mattermost sidebar.

## Admin guide

Get started by installing the GitLab plugin from the Marketplace.

### Prerequisites

* The GitLab plugin is included in the Plugin Marketplace in Mattermost v5.16 and above.
* For Mattermost v5.13 and earlier, a manual install is necessary.

## Installation

### Marketplace installation

1. Go to **Main Menu > Plugin Marketplace** in Mattermost.
2. Search for "gitlab" or manually find the plugin from the list and select **Install**.
3. After the plugin has downloaded and been installed, select the **Configure** button.

### Manual installation

If your server doesn't have access to the internet, you can download the latest [plugin binary release](https://github.com/mattermost/mattermost-plugin-gitlab/releases) and upload it to your server via **System Console > Plugins > Plugin Management**. The releases on this page are the same used by the Marketplace.

See the [GitLab plugin release page](https://github.com/mattermost/mattermost-plugin-gitlab/releases) for compatibility considerations.

## Configuration

### Step 1: Register an OAuth application in GitLab

1. Go to https://gitlab.com/-/profile/applications or https://gitlab.yourdomain.com/-/profile/applications to register an OAuth app.
1. Set the following values:
- **Name**: `Mattermost GitLab Plugin - <your company name>`
- **Redirect URI**: `https://your-mattermost-url.com/plugins/com.github.manland.mattermost-plugin-gitlab/oauth/complete`, replacing `https://your-mattermost-url.com` with your Mattermost URL
1. Select `api` and `read_user` in **Scopes**.
1. Save the application. Copy the **Application ID** and **Secret** fields in the resulting screen.
1. In Mattermost, go to **Plugins Marketplace > GitLab > Configure**, and enter the **GitLab URL**, **GitLab OAuth Client ID**, and **GitLab OAuth Client Secret**.

### Step 2: Configure the plugin in Mattermost

1. Go to **System Console > Plugins > GitLab** and do the following:
- Generate a new value for **Webhook Secret**.
- Generate a new value for **At Rest Encryption Key**.
- (Optional) **GitLab Group**: Lock the plugin to a single GitLab group by setting this field to the name of your GitLab group.
- (Optional) **Enable Private Repositories**: Allow the plugin to receive notifications from private repositories by setting this value to `true`. When enabled, existing users must reconnect their accounts to gain access to private project. Affected users will be notified by the plugin once private repositories are enabled.
1. Select **Save**.
1. Go to **Plugins Marketplace > GitLab > Configure > Enable Plugin** and select **Enable** to enable the GitLab plugin.

### Step 3: Connect your GitLab accounts

Run the `/gitlab connect` slash command to connect your Mattermost account with GitLab.

### Step 4: Subscribe to projects and groups

For each project you want to receive notifications for or subscribe to, you must create a webhook. Run the subscribe slash command to watch events sent from GitLab.

## Inspiration
``/gitlab subscriptions add group[/project]``

This project is a fork of the [mattermost-plugin-github](https://github.com/mattermost/mattermost-plugin-github). Thanks to all contributors of it.
Run the webhook slash command to have GitLab send events to Mattermost.

## Feedback and Feature Requests
``/gitlab webhook add group[/project]``

For versions prior to 1.2:

1. In GitLab, go to the project you want to subscribe to, select **Settings > Integrations** in the sidebar.
2. Set the following values:
- **URL**: `https://your-mattermost-url.com/plugins/com.github.manland.mattermost-plugin-gitlab/webhook`, replacing `https://your-mattermost-url.com` with your Mattermost URL. Ensure that you add `/plugins/com.github.manland.mattermost-plugin-gitlab/webhook` to the URL or the webhook won't work.
- **Secret Token**: The webhook secret you copied previously.
3. Select all the events in **Triggers**.
4. Add the webhook.

### Compatibility

| Mattermost-Plugin-Gitlab| Mattermost | GitLab |
|:-----------------------:|:----------:|:------:|
| 0.3.0 | 5.10+ | 11.2+ |
| 0.2.0 | 5.8+ | 11.2+ |
| 0.1.0 | 5.8+ | 11.2+ |

### Update the plugin

When a new version of the plugin is released to the **Plugin Marketplace**, the system will display a prompt asking you to update your current version of the GitLab plugin to the newest one. There may be a warning shown if there is a major version change that **may** affect the installation. Generally, updates are seamless and don't interrupt the user experience in Mattermost.

## Mattermost commands user guide

Interact with the GitLab plugin using the `/gitlab` slash command.

### Subscribe to/unsubscribe from a repository

Use `/gitlab subscriptions add owner[/repo] [features]` to subscribe a Mattermost channel to receive posts for new merge requests and/or issues, or other features (as listed above), from a GitLab repository. Ensure that the webhook is configured, otherwise this will not work properly.

Use `/gitlab subscriptions delete owner/repo` to unsubscribe from it.

`/gitlab subscriptions list` lists what you have subscribed to.

### Connect to/disconnect from GitLab

Connect your Mattermost account to your GitLab account using `/gitlab connect` and disconnect it using`/gitlab disconnect`.

`/gitlab me` displays the connected GitLab account.

### Get "To Do" items

Use `/gitlab todo` to get a list of unread messages and merge requests awaiting your review.

### Update settings

Use `/gitlab settings [setting] [value]` to update your settings for the plugin. There are two settings:

- To turn **personal notifications** `on` or `off.
- To turn **reminders** `on` or `off` for when you connect for the first time each day.

### And more...

Run `/gitlab help` to see what else the slash command can do.

**Tip**: Don't forget to add a webhook in GitLab!

## Development

This plugin contains both a server and web app portion. Read our documentation about the [Developer Workflow](https://developers.mattermost.com/extend/plugins/developer-workflow/) and [Developer Setup](https://developers.mattermost.com/extend/plugins/developer-setup/) for more information about developing and extending plugins.

## Help wanted!

If you're interested in joining our community of developers who contribute to Mattermost - check out the current set of issues [that are being requested](https://github.com/mattermost/mattermost-plugin-gitlab/issues?q=is%3Aissue+is%3Aopen+label%3AEnhancement).

You can also find issues labeled ["Help Wanted"](https://github.com/mattermost/mattermost-plugin-gitlab/issues?q=is%3Aissue+is%3Aopen+label%3A%22Help+Wanted%22) in the GitLab plugin repository that we have laid out the primary requirements for and could use some coding help from the community.

## Help and support

For Mattermost customers - please open a [support case](https://mattermost.zendesk.com/hc/en-us/requests/new) to ensure your issue is tracked properly.

For Questions, suggestions, and help - please find us on our forum at [https://forum.mattermost.org/c/plugins](https://forum.mattermost.org/c/plugins).

Alternatively, join our public Mattermost server and join the [Integrations and Apps channel](https://community-daily.mattermost.com/core/channels/integrations).

## Feedback and feature requests

Feel free to create a GitHub issue or [join the GitLab Plugin channel on our community Mattermost instance](https://community.mattermost.com/core/channels/plugin-gitlab) to discuss.

Share your thoughts in the [Plugin: GitLab Channel](https://community-daily.mattermost.com/core/channels/gitlab-plugin) on our Mattermost community!
23 changes: 22 additions & 1 deletion plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,30 @@
"key": "EnablePrivateRepo",
"display_name": "Enable Private Repositories:",
"type": "bool",
"help_text": "(Optional) Allow the plugin to work with private repositories.",
"help_text": "(Optional) Allow the plugin to work with private repositories for subscriptions.",
"placeholder": "",
"default": null
},
{
"key": "EnableCodePreview",
"display_name": "Enable Code Previews:",
"type": "dropdown",
"help_text": "Allow the plugin to expand permalinks to GitLab files with an actual preview of the linked file.",
"default": "public",
"options": [
{
"display_name": "Enable for public projects",
"value": "public"
},
{
"display_name": "Enable for public and private projects. This might leak confidential code into public channels",
"value": "privateAndPublic"
},
{
"display_name": "Disable",
"value": "disable"
}
]
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion server/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const commandHelp = `* |/gitlab connect| - Connect your Mattermost account to yo
* label:"<labelname>" - must include "merges" or "issues" in feature list when using a label
* Defaults to "merges,issues,tag"
* |/gitlab subscriptions delete owner/repo| - Unsubscribe the current channel from a repository
* |/gitlab pipeline run [owner]/repo [ref]| - Run a pipeline for specific repository and ref (branch/tag)
* |/gitlab pipelines run [owner]/repo [ref]| - Run a pipeline for specific repository and ref (branch/tag)
* |/gitlab me| - Display the connected GitLab account
* |/gitlab settings [setting] [value]| - Update your user settings
* |setting| can be "notifications" or "reminders"
Expand Down
1 change: 1 addition & 0 deletions server/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type configuration struct {
EncryptionKey string `json:"encryptionkey"`
GitlabGroup string `json:"gitlabgroup"`
EnablePrivateRepo bool `json:"enableprivaterepo"`
EnableCodePreview string `json:"enablecodepreview"`
UsePreregisteredApplication bool `json:"usepreregisteredapplication"`
}

Expand Down
31 changes: 18 additions & 13 deletions server/gitlab/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type Issue struct {

// NewGroupHook creates a webhook associated with a GitLab group
func (g *gitlab) NewGroupHook(ctx context.Context, user *UserInfo, token *oauth2.Token, groupName string, webhookOptions *AddWebhookOptions) (*WebhookInfo, error) {
client, err := g.gitlabConnect(*token)
client, err := g.GitlabConnect(*token)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -87,7 +87,7 @@ func (g *gitlab) NewGroupHook(ctx context.Context, user *UserInfo, token *oauth2

// NewProjectHook creates a webhook associated with a GitLab project
func (g *gitlab) NewProjectHook(ctx context.Context, user *UserInfo, token *oauth2.Token, projectID interface{}, webhookOptions *AddWebhookOptions) (*WebhookInfo, error) {
client, err := g.gitlabConnect(*token)
client, err := g.GitlabConnect(*token)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -123,7 +123,7 @@ func (g *gitlab) NewProjectHook(ctx context.Context, user *UserInfo, token *oaut

// GetGroupHooks gathers all the group level hooks for a GitLab group.
func (g *gitlab) GetGroupHooks(ctx context.Context, user *UserInfo, token *oauth2.Token, owner string) ([]*WebhookInfo, error) {
client, err := g.gitlabConnect(*token)
client, err := g.GitlabConnect(*token)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -230,7 +230,7 @@ func getGroupHookInfo(hook *internGitlab.GroupHook) *WebhookInfo {

// GetProjectHooks gathers all the project level hooks from a single GitLab project.
func (g *gitlab) GetProjectHooks(ctx context.Context, user *UserInfo, token *oauth2.Token, owner string, repo string) ([]*WebhookInfo, error) {
client, err := g.gitlabConnect(*token)
client, err := g.GitlabConnect(*token)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -263,7 +263,7 @@ func (g *gitlab) GetProjectHooks(ctx context.Context, user *UserInfo, token *oau
}

func (g *gitlab) GetProject(ctx context.Context, user *UserInfo, token *oauth2.Token, owner, repo string) (*internGitlab.Project, error) {
client, err := g.gitlabConnect(*token)
client, err := g.GitlabConnect(*token)
if err != nil {
return nil, err
}
Expand All @@ -283,7 +283,7 @@ func (g *gitlab) GetProject(ctx context.Context, user *UserInfo, token *oauth2.T
}

func (g *gitlab) GetReviews(ctx context.Context, user *UserInfo, token *oauth2.Token) ([]*MergeRequest, error) {
client, err := g.gitlabConnect(*token)
client, err := g.GitlabConnect(*token)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -354,7 +354,7 @@ func (g *gitlab) GetReviews(ctx context.Context, user *UserInfo, token *oauth2.T
}

func (g *gitlab) GetYourPrs(ctx context.Context, user *UserInfo, token *oauth2.Token) ([]*MergeRequest, error) {
client, err := g.gitlabConnect(*token)
client, err := g.GitlabConnect(*token)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -451,7 +451,7 @@ func (g *gitlab) GetLabelDetails(client *internGitlab.Client, pid int, labels in
}

func (g *gitlab) GetYourPrDetails(ctx context.Context, log logger.Logger, user *UserInfo, token *oauth2.Token, prList []*PRDetails) ([]*PRDetails, error) {
client, err := g.gitlabConnect(*token)
client, err := g.GitlabConnect(*token)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -519,7 +519,7 @@ func (g *gitlab) fetchYourPrDetails(c context.Context, log logger.Logger, client
}

func (g *gitlab) GetYourAssignments(ctx context.Context, user *UserInfo, token *oauth2.Token) ([]*Issue, error) {
client, err := g.gitlabConnect(*token)
client, err := g.GitlabConnect(*token)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -589,7 +589,7 @@ func (g *gitlab) GetYourAssignments(ctx context.Context, user *UserInfo, token *
}

func (g *gitlab) GetUnreads(ctx context.Context, user *UserInfo, token *oauth2.Token) ([]*internGitlab.Todo, error) {
client, err := g.gitlabConnect(*token)
client, err := g.GitlabConnect(*token)
if err != nil {
return nil, err
}
Expand All @@ -611,9 +611,14 @@ func (g *gitlab) GetUnreads(ctx context.Context, user *UserInfo, token *oauth2.T
}
opt.Page = resp.NextPage
}

notifications := make([]*internGitlab.Todo, 0, len(todos))
for _, todo := range todos {
if g.checkGroup(strings.TrimSuffix(todo.Project.PathWithNamespace, "/"+todo.Project.Path)) != nil {
if todo == nil {
continue
}

if todo.Project != nil && g.checkGroup(strings.TrimSuffix(todo.Project.PathWithNamespace, "/"+todo.Project.Path)) != nil {
continue
}
notifications = append(notifications, todo)
Expand All @@ -630,7 +635,7 @@ func (g *gitlab) ResolveNamespaceAndProject(
allowPrivate bool,
) (owner string, repo string, err error) {
// Initialize client
client, err := g.gitlabConnect(*token)
client, err := g.GitlabConnect(*token)
if err != nil {
return "", "", err
}
Expand Down Expand Up @@ -716,7 +721,7 @@ func (g *gitlab) ResolveNamespaceAndProject(

// TriggerProjectPipeline runs a pipeline in a specific project
func (g *gitlab) TriggerProjectPipeline(userInfo *UserInfo, token *oauth2.Token, projectID string, ref string) (*PipelineInfo, error) {
client, err := g.gitlabConnect(*token)
client, err := g.GitlabConnect(*token)
if err != nil {
return &PipelineInfo{}, err
}
Expand Down
3 changes: 2 additions & 1 deletion server/gitlab/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var (

// Gitlab is a client to call GitLab api see New() to build one
type Gitlab interface {
GitlabConnect(token oauth2.Token) (*internGitlab.Client, error)
GetCurrentUser(ctx context.Context, userID string, token oauth2.Token) (*UserInfo, error)
GetUserDetails(ctx context.Context, user *UserInfo, token *oauth2.Token) (*internGitlab.User, error)
GetProject(ctx context.Context, user *UserInfo, token *oauth2.Token, owner, repo string) (*internGitlab.Project, error)
Expand Down Expand Up @@ -78,7 +79,7 @@ func New(gitlabURL string, gitlabGroup string, checkGroup func(projectNameWithGr
return &gitlab{gitlabURL: gitlabURL, gitlabGroup: gitlabGroup, checkGroup: checkGroup}
}

func (g *gitlab) gitlabConnect(token oauth2.Token) (*internGitlab.Client, error) {
func (g *gitlab) GitlabConnect(token oauth2.Token) (*internGitlab.Client, error) {
if g.gitlabURL == "" || strings.EqualFold(g.gitlabURL, Gitlabdotcom) {
return internGitlab.NewOAuthClient(token.AccessToken)
}
Expand Down

0 comments on commit 0a18dc3

Please sign in to comment.