feat: gitlab triggers integration
This commit is contained in:

committed by
Ali BARIN

parent
93a2e2151e
commit
3f8f022d48
@@ -8,6 +8,9 @@ services:
|
||||
volumes:
|
||||
- ..:/workspace:cached
|
||||
command: sleep infinity
|
||||
ports:
|
||||
- '3000:3000'
|
||||
- '3001:3001'
|
||||
postgres:
|
||||
image: 'postgres:14.5-alpine'
|
||||
environment:
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -125,3 +125,6 @@ dist
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# MacOS finder preferences
|
||||
.DS_store
|
||||
|
@@ -1,3 +1,6 @@
|
||||
import { createUser } from './utils';
|
||||
|
||||
createUser();
|
||||
(async () => {
|
||||
await createUser();
|
||||
process.exit();
|
||||
})();
|
||||
|
2
packages/backend/src/apps/gitlab/assets/favicon.svg
Normal file
2
packages/backend/src/apps/gitlab/assets/favicon.svg
Normal file
@@ -0,0 +1,2 @@
|
||||
<!-- https://about.gitlab.com/images/press/logo/svg/gitlab-logo-500.svg -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 380"><defs><style>.cls-1{fill:#e24329;}.cls-2{fill:#fc6d26;}.cls-3{fill:#fca326;}</style></defs><g id="LOGO"><path class="cls-1" d="M282.83,170.73l-.27-.69-26.14-68.22a6.81,6.81,0,0,0-2.69-3.24,7,7,0,0,0-8,.43,7,7,0,0,0-2.32,3.52l-17.65,54H154.29l-17.65-54A6.86,6.86,0,0,0,134.32,99a7,7,0,0,0-8-.43,6.87,6.87,0,0,0-2.69,3.24L97.44,170l-.26.69a48.54,48.54,0,0,0,16.1,56.1l.09.07.24.17,39.82,29.82,19.7,14.91,12,9.06a8.07,8.07,0,0,0,9.76,0l12-9.06,19.7-14.91,40.06-30,.1-.08A48.56,48.56,0,0,0,282.83,170.73Z"/><path class="cls-2" d="M282.83,170.73l-.27-.69a88.3,88.3,0,0,0-35.15,15.8L190,229.25c19.55,14.79,36.57,27.64,36.57,27.64l40.06-30,.1-.08A48.56,48.56,0,0,0,282.83,170.73Z"/><path class="cls-3" d="M153.43,256.89l19.7,14.91,12,9.06a8.07,8.07,0,0,0,9.76,0l12-9.06,19.7-14.91S209.55,244,190,229.25C170.45,244,153.43,256.89,153.43,256.89Z"/><path class="cls-2" d="M132.58,185.84A88.19,88.19,0,0,0,97.44,170l-.26.69a48.54,48.54,0,0,0,16.1,56.1l.09.07.24.17,39.82,29.82s17-12.85,36.57-27.64Z"/></g></svg>
|
After Width: | Height: | Size: 1.1 KiB |
24
packages/backend/src/apps/gitlab/auth/generate-auth-url.ts
Normal file
24
packages/backend/src/apps/gitlab/auth/generate-auth-url.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import { URLSearchParams } from 'url';
|
||||
|
||||
export default async function generateAuthUrl($: IGlobalVariable) {
|
||||
// ref: https://docs.gitlab.com/ee/api/oauth2.html#authorization-code-flow
|
||||
|
||||
const scopes = ['api', 'read_user'];
|
||||
|
||||
const searchParams = new URLSearchParams({
|
||||
client_id: $.auth.data.clientId as string,
|
||||
redirect_uri: $.auth.data.oAuthRedirectUrl as string,
|
||||
scope: scopes.join(' '),
|
||||
response_type: 'code',
|
||||
state: `${Date.now()}`,
|
||||
});
|
||||
|
||||
const url = `${
|
||||
$.auth.data.oInstanceUrl
|
||||
}/oauth/authorize?${searchParams.toString()}`;
|
||||
|
||||
await $.auth.set({
|
||||
url,
|
||||
});
|
||||
}
|
63
packages/backend/src/apps/gitlab/auth/index.ts
Normal file
63
packages/backend/src/apps/gitlab/auth/index.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import generateAuthUrl from './generate-auth-url';
|
||||
import verifyCredentials from './verify-credentials';
|
||||
import isStillVerified from './is-still-verified';
|
||||
import refreshToken from './refresh-token';
|
||||
|
||||
export default {
|
||||
fields: [
|
||||
{
|
||||
key: 'oInstanceUrl',
|
||||
label: 'Gitlab instance URL',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
readOnly: false,
|
||||
value: 'https://gitlab.com',
|
||||
placeholder: 'https://gitlab.com',
|
||||
description: 'Your Gitlab instance URL. Default is https://gitlab.com.',
|
||||
docUrl: 'https://automatisch.io/docs/gitlab#oauth-redirect-url',
|
||||
clickToCopy: true,
|
||||
},
|
||||
{
|
||||
key: 'oAuthRedirectUrl',
|
||||
label: 'OAuth Redirect URL',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: true,
|
||||
value: '{WEB_APP_URL}/app/gitlab/connections/add',
|
||||
placeholder: null,
|
||||
description:
|
||||
'When asked to input an OAuth callback or redirect URL in Gitlab OAuth, enter the URL above.',
|
||||
docUrl: 'https://automatisch.io/docs/gitlab#oauth-redirect-url',
|
||||
clickToCopy: true,
|
||||
},
|
||||
{
|
||||
key: 'clientId',
|
||||
label: 'Client ID',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description: null,
|
||||
docUrl: 'https://automatisch.io/docs/gitlab#client-id',
|
||||
clickToCopy: false,
|
||||
},
|
||||
{
|
||||
key: 'clientSecret',
|
||||
label: 'Client Secret',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description: null,
|
||||
docUrl: 'https://automatisch.io/docs/gitlab#client-secret',
|
||||
clickToCopy: false,
|
||||
},
|
||||
],
|
||||
|
||||
generateAuthUrl,
|
||||
refreshToken,
|
||||
verifyCredentials,
|
||||
isStillVerified,
|
||||
};
|
@@ -0,0 +1,9 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import getCurrentUser from '../common/get-current-user';
|
||||
|
||||
const isStillVerified = async ($: IGlobalVariable) => {
|
||||
const user = await getCurrentUser($);
|
||||
return !!user.id;
|
||||
};
|
||||
|
||||
export default isStillVerified;
|
24
packages/backend/src/apps/gitlab/auth/refresh-token.ts
Normal file
24
packages/backend/src/apps/gitlab/auth/refresh-token.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import { URLSearchParams } from 'url';
|
||||
|
||||
const refreshToken = async ($: IGlobalVariable) => {
|
||||
// ref: https://docs.gitlab.com/ee/api/oauth2.html#authorization-code-flow
|
||||
|
||||
const params = new URLSearchParams({
|
||||
grant_type: 'refresh_token',
|
||||
client_id: $.auth.data.clientId as string,
|
||||
client_secret: $.auth.data.clientSecret as string,
|
||||
refresh_token: $.auth.data.refreshToken as string,
|
||||
});
|
||||
|
||||
const { data } = await $.http.post('/oauth/token', params.toString());
|
||||
|
||||
await $.auth.set({
|
||||
accessToken: data.access_token,
|
||||
expiresIn: data.expires_in,
|
||||
tokenType: data.token_type,
|
||||
refreshToken: data.refresh_token,
|
||||
});
|
||||
};
|
||||
|
||||
export default refreshToken;
|
41
packages/backend/src/apps/gitlab/auth/verify-credentials.ts
Normal file
41
packages/backend/src/apps/gitlab/auth/verify-credentials.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import getCurrentUser from '../common/get-current-user';
|
||||
|
||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
||||
// ref: https://docs.gitlab.com/ee/api/oauth2.html#authorization-code-flow
|
||||
|
||||
const response = await $.http.post(
|
||||
`${$.auth.data.oInstanceUrl}/oauth/token`,
|
||||
{
|
||||
client_id: $.auth.data.clientId,
|
||||
client_secret: $.auth.data.clientSecret,
|
||||
code: $.auth.data.code,
|
||||
grant_type: 'authorization_code',
|
||||
redirect_uri: $.auth.data.oAuthRedirectUrl,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const data = response.data;
|
||||
|
||||
$.auth.data.accessToken = data.access_token;
|
||||
|
||||
const currentUser = await getCurrentUser($);
|
||||
|
||||
await $.auth.set({
|
||||
clientId: $.auth.data.clientId,
|
||||
clientSecret: $.auth.data.clientSecret,
|
||||
accessToken: data.access_token,
|
||||
refreshToken: data.refresh_token,
|
||||
scope: data.scope,
|
||||
tokenType: data.token_type,
|
||||
userId: currentUser.id,
|
||||
screenName: currentUser.username,
|
||||
});
|
||||
};
|
||||
|
||||
export default verifyCredentials;
|
14
packages/backend/src/apps/gitlab/common/add-auth-header.ts
Normal file
14
packages/backend/src/apps/gitlab/common/add-auth-header.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { TBeforeRequest } from '@automatisch/types';
|
||||
|
||||
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
|
||||
if ($.auth.data.oInstanceUrl) {
|
||||
requestConfig.baseURL = $.auth.data.oInstanceUrl as string;
|
||||
}
|
||||
|
||||
if (requestConfig.headers && $.auth.data?.accessToken) {
|
||||
requestConfig.headers.Authorization = `Bearer ${$.auth.data.accessToken}`;
|
||||
}
|
||||
return requestConfig;
|
||||
};
|
||||
|
||||
export default addAuthHeader;
|
11
packages/backend/src/apps/gitlab/common/get-current-user.ts
Normal file
11
packages/backend/src/apps/gitlab/common/get-current-user.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||
|
||||
const getCurrentUser = async ($: IGlobalVariable): Promise<IJSONObject> => {
|
||||
// ref: https://docs.gitlab.com/ee/api/users.html#list-current-user
|
||||
|
||||
const response = await $.http.get(`${$.auth.data.oInstanceUrl}/api/v4/user`);
|
||||
const currentUser = response.data;
|
||||
return currentUser;
|
||||
};
|
||||
|
||||
export default getCurrentUser;
|
33
packages/backend/src/apps/gitlab/common/paginate-all.ts
Normal file
33
packages/backend/src/apps/gitlab/common/paginate-all.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||
import type { AxiosResponse } from 'axios';
|
||||
import parseLinkHeader from '../../../helpers/parse-header-link';
|
||||
|
||||
type TResponse = {
|
||||
data: IJSONObject[];
|
||||
error?: IJSONObject;
|
||||
};
|
||||
|
||||
export default async function paginateAll(
|
||||
$: IGlobalVariable,
|
||||
request: Promise<AxiosResponse>
|
||||
) {
|
||||
const response = await request;
|
||||
|
||||
const aggregatedResponse: TResponse = {
|
||||
data: [...response.data],
|
||||
};
|
||||
|
||||
let links = parseLinkHeader(response.headers.link);
|
||||
|
||||
while (links.next) {
|
||||
const nextPageResponse = await $.http.request({
|
||||
...response.config,
|
||||
url: links.next.uri,
|
||||
});
|
||||
|
||||
aggregatedResponse.data.push(...nextPageResponse.data);
|
||||
links = parseLinkHeader(nextPageResponse.headers.link);
|
||||
}
|
||||
|
||||
return aggregatedResponse;
|
||||
}
|
3
packages/backend/src/apps/gitlab/dynamic-data/index.ts
Normal file
3
packages/backend/src/apps/gitlab/dynamic-data/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import listProjects from './list-projects';
|
||||
|
||||
export default [listProjects];
|
@@ -0,0 +1,33 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import paginateAll from '../../common/paginate-all';
|
||||
|
||||
export default {
|
||||
name: 'List projects',
|
||||
key: 'listProjects',
|
||||
|
||||
async run($: IGlobalVariable) {
|
||||
// ref:
|
||||
// - https://docs.gitlab.com/ee/api/projects.html#list-all-projects
|
||||
// - https://docs.gitlab.com/ee/api/rest/index.html#keyset-based-pagination
|
||||
|
||||
const firstPageRequest = $.http.get('/api/v4/projects', {
|
||||
params: {
|
||||
simple: true,
|
||||
pagination: 'keyset',
|
||||
order_by: 'id',
|
||||
sort: 'asc',
|
||||
},
|
||||
});
|
||||
|
||||
const response = await paginateAll($, firstPageRequest);
|
||||
|
||||
response.data = response.data.map((repo: { name: string; id: number }) => {
|
||||
return {
|
||||
value: repo.id,
|
||||
name: repo.name,
|
||||
};
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
};
|
20
packages/backend/src/apps/gitlab/index.ts
Normal file
20
packages/backend/src/apps/gitlab/index.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import defineApp from '../../helpers/define-app';
|
||||
import addAuthHeader from './common/add-auth-header';
|
||||
import auth from './auth';
|
||||
import triggers from './triggers';
|
||||
import dynamicData from './dynamic-data';
|
||||
|
||||
export default defineApp({
|
||||
name: 'Gitlab',
|
||||
key: 'gitlab',
|
||||
baseUrl: 'https://gitlab.com',
|
||||
apiBaseUrl: 'https://gitlab.com/api/v4',
|
||||
iconUrl: '{BASE_URL}/apps/gitlab/assets/favicon.svg',
|
||||
authDocUrl: 'https://automatisch.io/docs/apps/gitlab/connection',
|
||||
primaryColor: '000000',
|
||||
supportsConnections: true,
|
||||
beforeRequest: [addAuthHeader],
|
||||
auth,
|
||||
triggers,
|
||||
dynamicData,
|
||||
});
|
@@ -0,0 +1,27 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
// confidential_issues_events has the same event data as issues_events
|
||||
import data from './issues_events';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Confidential issue events',
|
||||
description:
|
||||
'Confidential issue events (triggered when a new confidential issue is created or an existing issue is updated, closed, or reopened)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events',
|
||||
key: GITLAB_EVENT_TYPE.confidential_issues_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.confidential_issues_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,159 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events
|
||||
|
||||
export default {
|
||||
object_kind: 'issue',
|
||||
event_type: 'issue',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/gitlabhq/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
namespace: 'GitlabHQ',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlabhq/gitlab-test',
|
||||
default_branch: 'master',
|
||||
ci_config_path: null,
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
},
|
||||
object_attributes: {
|
||||
id: 301,
|
||||
title: 'New API: create/update/delete file',
|
||||
assignee_ids: [51],
|
||||
assignee_id: 51,
|
||||
author_id: 51,
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
updated_by_id: 1,
|
||||
last_edited_at: null,
|
||||
last_edited_by_id: null,
|
||||
relative_position: 0,
|
||||
description: 'Create new API for manipulations with repository',
|
||||
milestone_id: null,
|
||||
state_id: 1,
|
||||
confidential: false,
|
||||
discussion_locked: true,
|
||||
due_date: null,
|
||||
moved_to_id: null,
|
||||
duplicated_to_id: null,
|
||||
time_estimate: 0,
|
||||
total_time_spent: 0,
|
||||
time_change: 0,
|
||||
human_total_time_spent: null,
|
||||
human_time_estimate: null,
|
||||
human_time_change: null,
|
||||
weight: null,
|
||||
iid: 23,
|
||||
url: 'http://example.com/diaspora/issues/23',
|
||||
state: 'opened',
|
||||
action: 'open',
|
||||
severity: 'high',
|
||||
escalation_status: 'triggered',
|
||||
escalation_policy: {
|
||||
id: 18,
|
||||
name: 'Engineering On-call',
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
},
|
||||
repository: {
|
||||
name: 'Gitlab Test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
},
|
||||
assignees: [
|
||||
{
|
||||
name: 'User1',
|
||||
username: 'user1',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
},
|
||||
],
|
||||
assignee: {
|
||||
name: 'User1',
|
||||
username: 'user1',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
changes: {
|
||||
updated_by_id: {
|
||||
previous: null,
|
||||
current: 1,
|
||||
},
|
||||
updated_at: {
|
||||
previous: '2017-09-15 16:50:55 UTC',
|
||||
current: '2017-09-15 16:52:00 UTC',
|
||||
},
|
||||
labels: {
|
||||
previous: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
current: [
|
||||
{
|
||||
id: 205,
|
||||
title: 'Platform',
|
||||
color: '#123123',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'Platform related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
@@ -0,0 +1,27 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
// confidential_note_events has the same event data as note_events
|
||||
import data from './note_events';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Confidential comment events',
|
||||
description:
|
||||
'Confidential comment events (triggered when a new confidential comment is made on commits, merge requests, issues, and code snippets)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-events',
|
||||
key: GITLAB_EVENT_TYPE.confidential_note_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.confidential_note_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,74 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-events
|
||||
|
||||
export default {
|
||||
object_kind: 'note',
|
||||
event_type: 'note',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
project_id: 5,
|
||||
project: {
|
||||
id: 5,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/gitlabhq/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
namespace: 'GitlabHQ',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlabhq/gitlab-test',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
},
|
||||
repository: {
|
||||
name: 'Gitlab Test',
|
||||
url: 'http://example.com/gitlab-org/gitlab-test.git',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
homepage: 'http://example.com/gitlab-org/gitlab-test',
|
||||
},
|
||||
object_attributes: {
|
||||
id: 1243,
|
||||
note: 'This is a commit comment. How does this work?',
|
||||
noteable_type: 'Commit',
|
||||
author_id: 1,
|
||||
created_at: '2015-05-17 18:08:09 UTC',
|
||||
updated_at: '2015-05-17 18:08:09 UTC',
|
||||
project_id: 5,
|
||||
attachment: null,
|
||||
line_code: 'bec9703f7a456cd2b4ab5fb3220ae016e3e394e3_0_1',
|
||||
commit_id: 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
|
||||
noteable_id: null,
|
||||
system: false,
|
||||
st_diff: {
|
||||
diff: '--- /dev/null\n+++ b/six\n@@ -0,0 +1 @@\n+Subproject commit 409f37c4f05865e4fb208c771485f211a22c4c2d\n',
|
||||
new_path: 'six',
|
||||
old_path: 'six',
|
||||
a_mode: '0',
|
||||
b_mode: '160000',
|
||||
new_file: true,
|
||||
renamed_file: false,
|
||||
deleted_file: false,
|
||||
},
|
||||
url: 'http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660#note_1243',
|
||||
},
|
||||
commit: {
|
||||
id: 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
|
||||
message:
|
||||
'Add submodule\n\nSigned-off-by: Example User \u003cuser@example.com.com\u003e\n',
|
||||
timestamp: '2014-02-27T10:06:20+02:00',
|
||||
url: 'http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
|
||||
author: {
|
||||
name: 'Example User',
|
||||
email: 'user@example.com',
|
||||
},
|
||||
},
|
||||
};
|
@@ -0,0 +1,45 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#deployment-events
|
||||
|
||||
export default {
|
||||
object_kind: 'deployment',
|
||||
status: 'success',
|
||||
status_changed_at: '2021-04-28 21:50:00 +0200',
|
||||
deployment_id: 15,
|
||||
deployable_id: 796,
|
||||
deployable_url:
|
||||
'http://10.126.0.2:3000/root/test-deployment-webhooks/-/jobs/796',
|
||||
environment: 'staging',
|
||||
environment_slug: 'staging',
|
||||
environment_external_url: 'https://staging.example.com',
|
||||
project: {
|
||||
id: 30,
|
||||
name: 'test-deployment-webhooks',
|
||||
description: '',
|
||||
web_url: 'http://10.126.0.2:3000/root/test-deployment-webhooks',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'ssh://vlad@10.126.0.2:2222/root/test-deployment-webhooks.git',
|
||||
git_http_url: 'http://10.126.0.2:3000/root/test-deployment-webhooks.git',
|
||||
namespace: 'Administrator',
|
||||
visibility_level: 0,
|
||||
path_with_namespace: 'root/test-deployment-webhooks',
|
||||
default_branch: 'master',
|
||||
ci_config_path: '',
|
||||
homepage: 'http://10.126.0.2:3000/root/test-deployment-webhooks',
|
||||
url: 'ssh://vlad@10.126.0.2:2222/root/test-deployment-webhooks.git',
|
||||
ssh_url: 'ssh://vlad@10.126.0.2:2222/root/test-deployment-webhooks.git',
|
||||
http_url: 'http://10.126.0.2:3000/root/test-deployment-webhooks.git',
|
||||
},
|
||||
short_sha: '279484c0',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
user_url: 'http://10.126.0.2:3000/root',
|
||||
commit_url:
|
||||
'http://10.126.0.2:3000/root/test-deployment-webhooks/-/commit/279484c09fbe69ededfced8c1bb6e6d24616b468',
|
||||
commit_title: 'Add new file',
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './deployment_events';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Deployment events',
|
||||
description:
|
||||
'Deployment events (triggered when a deployment starts, succeeds, fails or is canceled)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#deployment-events',
|
||||
key: GITLAB_EVENT_TYPE.deployment_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.deployment_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,38 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#feature-flag-events
|
||||
|
||||
export default {
|
||||
object_kind: 'feature_flag',
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/gitlabhq/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
namespace: 'GitlabHQ',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlabhq/gitlab-test',
|
||||
default_branch: 'master',
|
||||
ci_config_path: null,
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
},
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
user_url: 'http://example.com/root',
|
||||
object_attributes: {
|
||||
id: 6,
|
||||
name: 'test-feature-flag',
|
||||
description: 'test-feature-flag-description',
|
||||
active: true,
|
||||
},
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './feature_flag_events';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Feature flag events',
|
||||
description:
|
||||
'Feature flag events (triggered when a feature flag is turned on or off)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#feature-flag-events',
|
||||
key: GITLAB_EVENT_TYPE.feature_flag_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.feature_flag_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
29
packages/backend/src/apps/gitlab/triggers/index.ts
Normal file
29
packages/backend/src/apps/gitlab/triggers/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import confidentialIssueEvent from './confidential-issue-event';
|
||||
import confidentialNoteEvent from './confidential-note-event';
|
||||
import deploymentEvent from './deployment-event';
|
||||
import featureFlagEvent from './feature-flag-event';
|
||||
import issueEvent from './issue-event';
|
||||
import jobEvent from './job-event';
|
||||
import mergeRequestEvent from './merge-request-event';
|
||||
import noteEvent from './note-event';
|
||||
import pipelineEvent from './pipeline-event';
|
||||
import pushEvent from './push-event';
|
||||
import releaseEvent from './release-event';
|
||||
import tagPushEvent from './tag-push-event';
|
||||
import wikiPageEvent from './wiki-page-event';
|
||||
|
||||
export default [
|
||||
confidentialIssueEvent,
|
||||
confidentialNoteEvent,
|
||||
deploymentEvent,
|
||||
featureFlagEvent,
|
||||
issueEvent,
|
||||
jobEvent,
|
||||
mergeRequestEvent,
|
||||
noteEvent,
|
||||
pipelineEvent,
|
||||
pushEvent,
|
||||
releaseEvent,
|
||||
tagPushEvent,
|
||||
wikiPageEvent,
|
||||
];
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './issues_events';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Issue events',
|
||||
description:
|
||||
'Issue events (triggered when a new issue is created or an existing issue is updated, closed, or reopened)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events',
|
||||
key: GITLAB_EVENT_TYPE.issues_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.issues_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,159 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events
|
||||
|
||||
export default {
|
||||
object_kind: 'issue',
|
||||
event_type: 'issue',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/gitlabhq/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
namespace: 'GitlabHQ',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlabhq/gitlab-test',
|
||||
default_branch: 'master',
|
||||
ci_config_path: null,
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
},
|
||||
object_attributes: {
|
||||
id: 301,
|
||||
title: 'New API: create/update/delete file',
|
||||
assignee_ids: [51],
|
||||
assignee_id: 51,
|
||||
author_id: 51,
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
updated_by_id: 1,
|
||||
last_edited_at: null,
|
||||
last_edited_by_id: null,
|
||||
relative_position: 0,
|
||||
description: 'Create new API for manipulations with repository',
|
||||
milestone_id: null,
|
||||
state_id: 1,
|
||||
confidential: false,
|
||||
discussion_locked: true,
|
||||
due_date: null,
|
||||
moved_to_id: null,
|
||||
duplicated_to_id: null,
|
||||
time_estimate: 0,
|
||||
total_time_spent: 0,
|
||||
time_change: 0,
|
||||
human_total_time_spent: null,
|
||||
human_time_estimate: null,
|
||||
human_time_change: null,
|
||||
weight: null,
|
||||
iid: 23,
|
||||
url: 'http://example.com/diaspora/issues/23',
|
||||
state: 'opened',
|
||||
action: 'open',
|
||||
severity: 'high',
|
||||
escalation_status: 'triggered',
|
||||
escalation_policy: {
|
||||
id: 18,
|
||||
name: 'Engineering On-call',
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
},
|
||||
repository: {
|
||||
name: 'Gitlab Test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
},
|
||||
assignees: [
|
||||
{
|
||||
name: 'User1',
|
||||
username: 'user1',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
},
|
||||
],
|
||||
assignee: {
|
||||
name: 'User1',
|
||||
username: 'user1',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
changes: {
|
||||
updated_by_id: {
|
||||
previous: null,
|
||||
current: 1,
|
||||
},
|
||||
updated_at: {
|
||||
previous: '2017-09-15 16:50:55 UTC',
|
||||
current: '2017-09-15 16:52:00 UTC',
|
||||
},
|
||||
labels: {
|
||||
previous: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
current: [
|
||||
{
|
||||
id: 205,
|
||||
title: 'Platform',
|
||||
color: '#123123',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'Platform related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
25
packages/backend/src/apps/gitlab/triggers/job-event/index.ts
Normal file
25
packages/backend/src/apps/gitlab/triggers/job-event/index.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './job_events';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Job events',
|
||||
description: 'Job events (triggered when the status of a job changes)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#job-events',
|
||||
key: GITLAB_EVENT_TYPE.job_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.job_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,60 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#job-events
|
||||
|
||||
export default {
|
||||
object_kind: 'build',
|
||||
ref: 'gitlab-script-trigger',
|
||||
tag: false,
|
||||
before_sha: '2293ada6b400935a1378653304eaf6221e0fdb8f',
|
||||
sha: '2293ada6b400935a1378653304eaf6221e0fdb8f',
|
||||
build_id: 1977,
|
||||
build_name: 'test',
|
||||
build_stage: 'test',
|
||||
build_status: 'created',
|
||||
build_created_at: '2021-02-23T02:41:37.886Z',
|
||||
build_started_at: null,
|
||||
build_finished_at: null,
|
||||
build_duration: null,
|
||||
build_queued_duration: 1095.588715, // duration in seconds
|
||||
build_allow_failure: false,
|
||||
build_failure_reason: 'script_failure',
|
||||
retries_count: 2, // the second retry of this job
|
||||
pipeline_id: 2366,
|
||||
project_id: 380,
|
||||
project_name: 'gitlab-org/gitlab-test',
|
||||
user: {
|
||||
id: 3,
|
||||
name: 'User',
|
||||
email: 'user@gitlab.com',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
},
|
||||
commit: {
|
||||
id: 2366,
|
||||
name: 'Build pipeline',
|
||||
sha: '2293ada6b400935a1378653304eaf6221e0fdb8f',
|
||||
message: 'test\n',
|
||||
author_name: 'User',
|
||||
author_email: 'user@gitlab.com',
|
||||
status: 'created',
|
||||
duration: null,
|
||||
started_at: null,
|
||||
finished_at: null,
|
||||
},
|
||||
repository: {
|
||||
name: 'gitlab_test',
|
||||
description: 'Atque in sunt eos similique dolores voluptatem.',
|
||||
homepage: 'http://192.168.64.1:3005/gitlab-org/gitlab-test',
|
||||
git_ssh_url: 'git@192.168.64.1:gitlab-org/gitlab-test.git',
|
||||
git_http_url: 'http://192.168.64.1:3005/gitlab-org/gitlab-test.git',
|
||||
visibility_level: 20,
|
||||
},
|
||||
runner: {
|
||||
active: true,
|
||||
runner_type: 'project_type',
|
||||
is_shared: false,
|
||||
id: 380987,
|
||||
description: 'shared-runners-manager-6.gitlab.com',
|
||||
tags: ['linux', 'docker'],
|
||||
},
|
||||
environment: null,
|
||||
};
|
89
packages/backend/src/apps/gitlab/triggers/lib.ts
Normal file
89
packages/backend/src/apps/gitlab/triggers/lib.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||
import Crypto from 'crypto';
|
||||
import { GITLAB_EVENT_TYPE } from './types';
|
||||
import appConfig from '../../../config/app';
|
||||
|
||||
export const projectArgumentDescriptor = {
|
||||
label: 'Project',
|
||||
key: 'projectId',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'Pick a project to receive events from',
|
||||
variables: false,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listProjects',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const getTestRunFn =
|
||||
(eventData: IJSONObject) => ($: IGlobalVariable) => {
|
||||
/*
|
||||
Not fetching actual events from gitlab and using static event data from documentation
|
||||
as there is no way to filter out events of one category using gitlab event types,
|
||||
filtering is very limited and uses different grouping than what is applicable when creating a webhook.
|
||||
|
||||
ref:
|
||||
- https://docs.gitlab.com/ee/api/events.html#target-types
|
||||
- https://docs.gitlab.com/ee/api/projects.html#add-project-hook
|
||||
*/
|
||||
|
||||
if (!eventData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dataItem = {
|
||||
raw: eventData,
|
||||
meta: {
|
||||
// there is no distinct id on gitlab event object thus creating it
|
||||
internalId: Crypto.randomUUID(),
|
||||
},
|
||||
};
|
||||
|
||||
$.pushTriggerItem(dataItem);
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const getRegisterHookFn =
|
||||
(eventType: GITLAB_EVENT_TYPE) => async ($: IGlobalVariable) => {
|
||||
// ref: https://docs.gitlab.com/ee/api/projects.html#add-project-hook
|
||||
|
||||
const subscriptionPayload = {
|
||||
url: $.webhookUrl,
|
||||
token: appConfig.webhookSecretKey,
|
||||
enable_ssl_verification: true,
|
||||
[eventType]: true,
|
||||
};
|
||||
|
||||
if (
|
||||
['wildcard', 'regex'].includes(
|
||||
$.step.parameters.branch_filter_strategy as string
|
||||
)
|
||||
) {
|
||||
subscriptionPayload.branch_filter_strategy = $.step.parameters
|
||||
.branch_filter_strategy as string;
|
||||
subscriptionPayload.push_events_branch_filter = $.step.parameters
|
||||
.push_events_branch_filter as string;
|
||||
}
|
||||
|
||||
const { data } = await $.http.post(
|
||||
`/api/v4/projects/${$.step.parameters.projectId}/hooks`,
|
||||
subscriptionPayload
|
||||
);
|
||||
|
||||
await $.flow.setRemoteWebhookId(`${data.id}`);
|
||||
};
|
||||
|
||||
export const unregisterHook = async ($: IGlobalVariable) => {
|
||||
// ref: https://docs.gitlab.com/ee/api/projects.html#delete-project-hook
|
||||
await $.http.delete(
|
||||
`/api/v4/projects/${$.step.parameters.projectId}/hooks/${$.flow.remoteWebhookId}`
|
||||
);
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './merge_requests_events';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Merge request events',
|
||||
description:
|
||||
'Merge request events (triggered when merge request is created, updated, or closed)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#merge-request-events',
|
||||
key: GITLAB_EVENT_TYPE.merge_requests_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.merge_requests_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,208 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#merge-request-events
|
||||
|
||||
export default {
|
||||
object_kind: 'merge_request',
|
||||
event_type: 'merge_request',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/gitlabhq/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
namespace: 'GitlabHQ',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlabhq/gitlab-test',
|
||||
default_branch: 'master',
|
||||
ci_config_path: '',
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
},
|
||||
repository: {
|
||||
name: 'Gitlab Test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
},
|
||||
object_attributes: {
|
||||
id: 99,
|
||||
iid: 1,
|
||||
target_branch: 'master',
|
||||
source_branch: 'ms-viewport',
|
||||
source_project_id: 14,
|
||||
author_id: 51,
|
||||
assignee_ids: [6],
|
||||
assignee_id: 6,
|
||||
reviewer_ids: [6],
|
||||
title: 'MS-Viewport',
|
||||
created_at: '2013-12-03T17:23:34Z',
|
||||
updated_at: '2013-12-03T17:23:34Z',
|
||||
last_edited_at: '2013-12-03T17:23:34Z',
|
||||
last_edited_by_id: 1,
|
||||
milestone_id: null,
|
||||
state_id: 1,
|
||||
state: 'opened',
|
||||
blocking_discussions_resolved: true,
|
||||
work_in_progress: false,
|
||||
first_contribution: true,
|
||||
merge_status: 'unchecked',
|
||||
target_project_id: 14,
|
||||
description: '',
|
||||
total_time_spent: 1800,
|
||||
time_change: 30,
|
||||
human_total_time_spent: '30m',
|
||||
human_time_change: '30s',
|
||||
human_time_estimate: '30m',
|
||||
url: 'http://example.com/diaspora/merge_requests/1',
|
||||
source: {
|
||||
name: 'Awesome Project',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/awesome_space/awesome_project',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:awesome_space/awesome_project.git',
|
||||
git_http_url: 'http://example.com/awesome_space/awesome_project.git',
|
||||
namespace: 'Awesome Space',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'awesome_space/awesome_project',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/awesome_space/awesome_project',
|
||||
url: 'http://example.com/awesome_space/awesome_project.git',
|
||||
ssh_url: 'git@example.com:awesome_space/awesome_project.git',
|
||||
http_url: 'http://example.com/awesome_space/awesome_project.git',
|
||||
},
|
||||
target: {
|
||||
name: 'Awesome Project',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/awesome_space/awesome_project',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:awesome_space/awesome_project.git',
|
||||
git_http_url: 'http://example.com/awesome_space/awesome_project.git',
|
||||
namespace: 'Awesome Space',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'awesome_space/awesome_project',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/awesome_space/awesome_project',
|
||||
url: 'http://example.com/awesome_space/awesome_project.git',
|
||||
ssh_url: 'git@example.com:awesome_space/awesome_project.git',
|
||||
http_url: 'http://example.com/awesome_space/awesome_project.git',
|
||||
},
|
||||
last_commit: {
|
||||
id: 'da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
|
||||
message: 'fixed readme',
|
||||
title: 'Update file README.md',
|
||||
timestamp: '2012-01-03T23:36:29+02:00',
|
||||
url: 'http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
|
||||
author: {
|
||||
name: 'GitLab dev user',
|
||||
email: 'gitlabdev@dv6700.(none)',
|
||||
},
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
action: 'open',
|
||||
detailed_merge_status: 'mergeable',
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
changes: {
|
||||
updated_by_id: {
|
||||
previous: null,
|
||||
current: 1,
|
||||
},
|
||||
updated_at: {
|
||||
previous: '2017-09-15 16:50:55 UTC',
|
||||
current: '2017-09-15 16:52:00 UTC',
|
||||
},
|
||||
labels: {
|
||||
previous: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
current: [
|
||||
{
|
||||
id: 205,
|
||||
title: 'Platform',
|
||||
color: '#123123',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'Platform related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
},
|
||||
last_edited_at: {
|
||||
previous: null,
|
||||
current: '2023-03-15 00:00:10 UTC',
|
||||
},
|
||||
last_edited_by_id: {
|
||||
previous: null,
|
||||
current: 3278533,
|
||||
},
|
||||
},
|
||||
assignees: [
|
||||
{
|
||||
id: 6,
|
||||
name: 'User1',
|
||||
username: 'user1',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
},
|
||||
],
|
||||
reviewers: [
|
||||
{
|
||||
id: 6,
|
||||
name: 'User1',
|
||||
username: 'user1',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
},
|
||||
],
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './note_events';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Comment events',
|
||||
description:
|
||||
'Comment events (triggered when a new comment is made on commits, merge requests, issues, and code snippets)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-events',
|
||||
key: GITLAB_EVENT_TYPE.note_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.note_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,74 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-events
|
||||
|
||||
export default {
|
||||
object_kind: 'note',
|
||||
event_type: 'note',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
project_id: 5,
|
||||
project: {
|
||||
id: 5,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/gitlabhq/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
namespace: 'GitlabHQ',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlabhq/gitlab-test',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
},
|
||||
repository: {
|
||||
name: 'Gitlab Test',
|
||||
url: 'http://example.com/gitlab-org/gitlab-test.git',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
homepage: 'http://example.com/gitlab-org/gitlab-test',
|
||||
},
|
||||
object_attributes: {
|
||||
id: 1243,
|
||||
note: 'This is a commit comment. How does this work?',
|
||||
noteable_type: 'Commit',
|
||||
author_id: 1,
|
||||
created_at: '2015-05-17 18:08:09 UTC',
|
||||
updated_at: '2015-05-17 18:08:09 UTC',
|
||||
project_id: 5,
|
||||
attachment: null,
|
||||
line_code: 'bec9703f7a456cd2b4ab5fb3220ae016e3e394e3_0_1',
|
||||
commit_id: 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
|
||||
noteable_id: null,
|
||||
system: false,
|
||||
st_diff: {
|
||||
diff: '--- /dev/null\n+++ b/six\n@@ -0,0 +1 @@\n+Subproject commit 409f37c4f05865e4fb208c771485f211a22c4c2d\n',
|
||||
new_path: 'six',
|
||||
old_path: 'six',
|
||||
a_mode: '0',
|
||||
b_mode: '160000',
|
||||
new_file: true,
|
||||
renamed_file: false,
|
||||
deleted_file: false,
|
||||
},
|
||||
url: 'http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660#note_1243',
|
||||
},
|
||||
commit: {
|
||||
id: 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
|
||||
message:
|
||||
'Add submodule\n\nSigned-off-by: Example User \u003cuser@example.com.com\u003e\n',
|
||||
timestamp: '2014-02-27T10:06:20+02:00',
|
||||
url: 'http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
|
||||
author: {
|
||||
name: 'Example User',
|
||||
email: 'user@example.com',
|
||||
},
|
||||
},
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './pipeline_events';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Pipeline events',
|
||||
description:
|
||||
'Pipeline events (triggered when the status of a pipeline changes)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#pipeline-events',
|
||||
key: GITLAB_EVENT_TYPE.pipeline_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.pipeline_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,254 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#pipeline-events
|
||||
|
||||
export default {
|
||||
object_kind: 'pipeline',
|
||||
object_attributes: {
|
||||
id: 31,
|
||||
iid: 3,
|
||||
ref: 'master',
|
||||
tag: false,
|
||||
sha: 'bcbb5ec396a2c0f828686f14fac9b80b780504f2',
|
||||
before_sha: 'bcbb5ec396a2c0f828686f14fac9b80b780504f2',
|
||||
source: 'merge_request_event',
|
||||
status: 'success',
|
||||
stages: ['build', 'test', 'deploy'],
|
||||
created_at: '2016-08-12 15:23:28 UTC',
|
||||
finished_at: '2016-08-12 15:26:29 UTC',
|
||||
duration: 63,
|
||||
variables: [
|
||||
{
|
||||
key: 'NESTOR_PROD_ENVIRONMENT',
|
||||
value: 'us-west-1',
|
||||
},
|
||||
],
|
||||
},
|
||||
merge_request: {
|
||||
id: 1,
|
||||
iid: 1,
|
||||
title: 'Test',
|
||||
source_branch: 'test',
|
||||
source_project_id: 1,
|
||||
target_branch: 'master',
|
||||
target_project_id: 1,
|
||||
state: 'opened',
|
||||
merge_status: 'can_be_merged',
|
||||
detailed_merge_status: 'mergeable',
|
||||
url: 'http://192.168.64.1:3005/gitlab-org/gitlab-test/merge_requests/1',
|
||||
},
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
email: 'user_email@gitlab.com',
|
||||
},
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Atque in sunt eos similique dolores voluptatem.',
|
||||
web_url: 'http://192.168.64.1:3005/gitlab-org/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@192.168.64.1:gitlab-org/gitlab-test.git',
|
||||
git_http_url: 'http://192.168.64.1:3005/gitlab-org/gitlab-test.git',
|
||||
namespace: 'Gitlab Org',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlab-org/gitlab-test',
|
||||
default_branch: 'master',
|
||||
},
|
||||
commit: {
|
||||
id: 'bcbb5ec396a2c0f828686f14fac9b80b780504f2',
|
||||
message: 'test\n',
|
||||
timestamp: '2016-08-12T17:23:21+02:00',
|
||||
url: 'http://example.com/gitlab-org/gitlab-test/commit/bcbb5ec396a2c0f828686f14fac9b80b780504f2',
|
||||
author: {
|
||||
name: 'User',
|
||||
email: 'user@gitlab.com',
|
||||
},
|
||||
},
|
||||
source_pipeline: {
|
||||
project: {
|
||||
id: 41,
|
||||
web_url: 'https://gitlab.example.com/gitlab-org/upstream-project',
|
||||
path_with_namespace: 'gitlab-org/upstream-project',
|
||||
},
|
||||
pipeline_id: 30,
|
||||
job_id: 3401,
|
||||
},
|
||||
builds: [
|
||||
{
|
||||
id: 380,
|
||||
stage: 'deploy',
|
||||
name: 'production',
|
||||
status: 'skipped',
|
||||
created_at: '2016-08-12 15:23:28 UTC',
|
||||
started_at: null,
|
||||
finished_at: null,
|
||||
duration: null,
|
||||
queued_duration: null,
|
||||
failure_reason: null,
|
||||
when: 'manual',
|
||||
manual: true,
|
||||
allow_failure: false,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
runner: null,
|
||||
artifacts_file: {
|
||||
filename: null,
|
||||
size: null,
|
||||
},
|
||||
environment: {
|
||||
name: 'production',
|
||||
action: 'start',
|
||||
deployment_tier: 'production',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 377,
|
||||
stage: 'test',
|
||||
name: 'test-image',
|
||||
status: 'success',
|
||||
created_at: '2016-08-12 15:23:28 UTC',
|
||||
started_at: '2016-08-12 15:26:12 UTC',
|
||||
finished_at: '2016-08-12 15:26:29 UTC',
|
||||
duration: 17.0,
|
||||
queued_duration: 196.0,
|
||||
failure_reason: null,
|
||||
when: 'on_success',
|
||||
manual: false,
|
||||
allow_failure: false,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
runner: {
|
||||
id: 380987,
|
||||
description: 'shared-runners-manager-6.gitlab.com',
|
||||
active: true,
|
||||
runner_type: 'instance_type',
|
||||
is_shared: true,
|
||||
tags: ['linux', 'docker', 'shared-runner'],
|
||||
},
|
||||
artifacts_file: {
|
||||
filename: null,
|
||||
size: null,
|
||||
},
|
||||
environment: null,
|
||||
},
|
||||
{
|
||||
id: 378,
|
||||
stage: 'test',
|
||||
name: 'test-build',
|
||||
status: 'failed',
|
||||
created_at: '2016-08-12 15:23:28 UTC',
|
||||
started_at: '2016-08-12 15:26:12 UTC',
|
||||
finished_at: '2016-08-12 15:26:29 UTC',
|
||||
duration: 17.0,
|
||||
queued_duration: 196.0,
|
||||
failure_reason: 'script_failure',
|
||||
when: 'on_success',
|
||||
manual: false,
|
||||
allow_failure: false,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
runner: {
|
||||
id: 380987,
|
||||
description: 'shared-runners-manager-6.gitlab.com',
|
||||
active: true,
|
||||
runner_type: 'instance_type',
|
||||
is_shared: true,
|
||||
tags: ['linux', 'docker'],
|
||||
},
|
||||
artifacts_file: {
|
||||
filename: null,
|
||||
size: null,
|
||||
},
|
||||
environment: null,
|
||||
},
|
||||
{
|
||||
id: 376,
|
||||
stage: 'build',
|
||||
name: 'build-image',
|
||||
status: 'success',
|
||||
created_at: '2016-08-12 15:23:28 UTC',
|
||||
started_at: '2016-08-12 15:24:56 UTC',
|
||||
finished_at: '2016-08-12 15:25:26 UTC',
|
||||
duration: 17.0,
|
||||
queued_duration: 196.0,
|
||||
failure_reason: null,
|
||||
when: 'on_success',
|
||||
manual: false,
|
||||
allow_failure: false,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
runner: {
|
||||
id: 380987,
|
||||
description: 'shared-runners-manager-6.gitlab.com',
|
||||
active: true,
|
||||
runner_type: 'instance_type',
|
||||
is_shared: true,
|
||||
tags: ['linux', 'docker'],
|
||||
},
|
||||
artifacts_file: {
|
||||
filename: null,
|
||||
size: null,
|
||||
},
|
||||
environment: null,
|
||||
},
|
||||
{
|
||||
id: 379,
|
||||
stage: 'deploy',
|
||||
name: 'staging',
|
||||
status: 'created',
|
||||
created_at: '2016-08-12 15:23:28 UTC',
|
||||
started_at: null,
|
||||
finished_at: null,
|
||||
duration: null,
|
||||
queued_duration: null,
|
||||
failure_reason: null,
|
||||
when: 'on_success',
|
||||
manual: false,
|
||||
allow_failure: false,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
runner: null,
|
||||
artifacts_file: {
|
||||
filename: null,
|
||||
size: null,
|
||||
},
|
||||
environment: {
|
||||
name: 'staging',
|
||||
action: 'start',
|
||||
deployment_tier: 'staging',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
@@ -0,0 +1,62 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './push_events';
|
||||
|
||||
export const branchFilterStrategyArgumentDescriptor = {
|
||||
label: 'What type of filter to use?',
|
||||
key: 'branch_filter_strategy',
|
||||
type: 'dropdown' as const,
|
||||
description: 'Defaults to including all branches',
|
||||
required: true,
|
||||
variables: false,
|
||||
value: 'all_branches',
|
||||
options: [
|
||||
{
|
||||
label: 'All branches',
|
||||
value: 'all_branches',
|
||||
},
|
||||
{
|
||||
label: 'Wildcard pattern (ex: *-stable)',
|
||||
value: 'wildcard',
|
||||
},
|
||||
{
|
||||
label: 'Regular expression (ex: ^(feature|hotfix)/)',
|
||||
value: 'regex',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const pushEventsBranchFilterArgumentDescriptor = {
|
||||
label: 'Filter value',
|
||||
key: 'push_events_branch_filter',
|
||||
description: 'Leave empty when using "all branches"',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
variables: false,
|
||||
};
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Push events',
|
||||
description: 'Push events (triggered when you push to the repository)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#push-events',
|
||||
key: GITLAB_EVENT_TYPE.push_events,
|
||||
type: 'webhook',
|
||||
arguments: [
|
||||
projectArgumentDescriptor,
|
||||
branchFilterStrategyArgumentDescriptor,
|
||||
pushEventsBranchFilterArgumentDescriptor,
|
||||
],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.push_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,75 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#push-events
|
||||
|
||||
export default {
|
||||
object_kind: 'push',
|
||||
event_name: 'push',
|
||||
before: '95790bf891e76fee5e1747ab589903a6a1f80f22',
|
||||
after: 'da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
|
||||
ref: 'refs/heads/master',
|
||||
checkout_sha: 'da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
|
||||
user_id: 4,
|
||||
user_name: 'John Smith',
|
||||
user_username: 'jsmith',
|
||||
user_email: 'john@example.com',
|
||||
user_avatar:
|
||||
'https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80',
|
||||
project_id: 15,
|
||||
project: {
|
||||
id: 15,
|
||||
name: 'Diaspora',
|
||||
description: '',
|
||||
web_url: 'http://example.com/mike/diaspora',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:mike/diaspora.git',
|
||||
git_http_url: 'http://example.com/mike/diaspora.git',
|
||||
namespace: 'Mike',
|
||||
visibility_level: 0,
|
||||
path_with_namespace: 'mike/diaspora',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/mike/diaspora',
|
||||
url: 'git@example.com:mike/diaspora.git',
|
||||
ssh_url: 'git@example.com:mike/diaspora.git',
|
||||
http_url: 'http://example.com/mike/diaspora.git',
|
||||
},
|
||||
repository: {
|
||||
name: 'Diaspora',
|
||||
url: 'git@example.com:mike/diaspora.git',
|
||||
description: '',
|
||||
homepage: 'http://example.com/mike/diaspora',
|
||||
git_http_url: 'http://example.com/mike/diaspora.git',
|
||||
git_ssh_url: 'git@example.com:mike/diaspora.git',
|
||||
visibility_level: 0,
|
||||
},
|
||||
commits: [
|
||||
{
|
||||
id: 'b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327',
|
||||
message:
|
||||
'Update Catalan translation to e38cb41.\n\nSee https://gitlab.com/gitlab-org/gitlab for more information',
|
||||
title: 'Update Catalan translation to e38cb41.',
|
||||
timestamp: '2011-12-12T14:27:31+02:00',
|
||||
url: 'http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327',
|
||||
author: {
|
||||
name: 'Jordi Mallach',
|
||||
email: 'jordi@softcatala.org',
|
||||
},
|
||||
added: ['CHANGELOG'],
|
||||
modified: ['app/controller/application.rb'],
|
||||
removed: [],
|
||||
},
|
||||
{
|
||||
id: 'da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
|
||||
message: 'fixed readme',
|
||||
title: 'fixed readme',
|
||||
timestamp: '2012-01-03T23:36:29+02:00',
|
||||
url: 'http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
|
||||
author: {
|
||||
name: 'GitLab dev user',
|
||||
email: 'gitlabdev@dv6700.(none)',
|
||||
},
|
||||
added: ['CHANGELOG'],
|
||||
modified: ['app/controller/application.rb'],
|
||||
removed: [],
|
||||
},
|
||||
],
|
||||
total_commits_count: 4,
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './releases_events';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Release events',
|
||||
description:
|
||||
'Release events (triggered when a release is created or updated)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#release-events',
|
||||
key: GITLAB_EVENT_TYPE.releases_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.releases_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,72 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#release-events
|
||||
|
||||
export default {
|
||||
object_kind: 'release',
|
||||
id: 1,
|
||||
created_at: '2020-11-02 12:55:12 UTC',
|
||||
description: 'v1.1 has been released',
|
||||
name: 'v1.1',
|
||||
released_at: '2020-11-02 12:55:12 UTC',
|
||||
tag: 'v1.1',
|
||||
project: {
|
||||
id: 2,
|
||||
name: 'release-webhook-example',
|
||||
description: '',
|
||||
web_url: 'https://example.com/gitlab-org/release-webhook-example',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'ssh://git@example.com/gitlab-org/release-webhook-example.git',
|
||||
git_http_url: 'https://example.com/gitlab-org/release-webhook-example.git',
|
||||
namespace: 'Gitlab',
|
||||
visibility_level: 0,
|
||||
path_with_namespace: 'gitlab-org/release-webhook-example',
|
||||
default_branch: 'master',
|
||||
ci_config_path: null,
|
||||
homepage: 'https://example.com/gitlab-org/release-webhook-example',
|
||||
url: 'ssh://git@example.com/gitlab-org/release-webhook-example.git',
|
||||
ssh_url: 'ssh://git@example.com/gitlab-org/release-webhook-example.git',
|
||||
http_url: 'https://example.com/gitlab-org/release-webhook-example.git',
|
||||
},
|
||||
url: 'https://example.com/gitlab-org/release-webhook-example/-/releases/v1.1',
|
||||
action: 'create',
|
||||
assets: {
|
||||
count: 5,
|
||||
links: [
|
||||
{
|
||||
id: 1,
|
||||
external: true, // deprecated in GitLab 15.9, will be removed in GitLab 16.0.
|
||||
link_type: 'other',
|
||||
name: 'Changelog',
|
||||
url: 'https://example.net/changelog',
|
||||
},
|
||||
],
|
||||
sources: [
|
||||
{
|
||||
format: 'zip',
|
||||
url: 'https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.zip',
|
||||
},
|
||||
{
|
||||
format: 'tar.gz',
|
||||
url: 'https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.tar.gz',
|
||||
},
|
||||
{
|
||||
format: 'tar.bz2',
|
||||
url: 'https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.tar.bz2',
|
||||
},
|
||||
{
|
||||
format: 'tar',
|
||||
url: 'https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.tar',
|
||||
},
|
||||
],
|
||||
},
|
||||
commit: {
|
||||
id: 'ee0a3fb31ac16e11b9dbb596ad16d4af654d08f8',
|
||||
message: 'Release v1.1',
|
||||
title: 'Release v1.1',
|
||||
timestamp: '2020-10-31T14:58:32+11:00',
|
||||
url: 'https://example.com/gitlab-org/release-webhook-example/-/commit/ee0a3fb31ac16e11b9dbb596ad16d4af654d08f8',
|
||||
author: {
|
||||
name: 'Example User',
|
||||
email: 'user@example.com',
|
||||
},
|
||||
},
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './tag_push_events';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Tag events',
|
||||
description:
|
||||
'Tag events (triggered when you create or delete tags in the repository)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#tag-events',
|
||||
key: GITLAB_EVENT_TYPE.tag_push_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.tag_push_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,43 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#tag-events
|
||||
|
||||
export default {
|
||||
object_kind: 'tag_push',
|
||||
event_name: 'tag_push',
|
||||
before: '0000000000000000000000000000000000000000',
|
||||
after: '82b3d5ae55f7080f1e6022629cdb57bfae7cccc7',
|
||||
ref: 'refs/tags/v1.0.0',
|
||||
checkout_sha: '82b3d5ae55f7080f1e6022629cdb57bfae7cccc7',
|
||||
user_id: 1,
|
||||
user_name: 'John Smith',
|
||||
user_avatar:
|
||||
'https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80',
|
||||
project_id: 1,
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'Example',
|
||||
description: '',
|
||||
web_url: 'http://example.com/jsmith/example',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:jsmith/example.git',
|
||||
git_http_url: 'http://example.com/jsmith/example.git',
|
||||
namespace: 'Jsmith',
|
||||
visibility_level: 0,
|
||||
path_with_namespace: 'jsmith/example',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/jsmith/example',
|
||||
url: 'git@example.com:jsmith/example.git',
|
||||
ssh_url: 'git@example.com:jsmith/example.git',
|
||||
http_url: 'http://example.com/jsmith/example.git',
|
||||
},
|
||||
repository: {
|
||||
name: 'Example',
|
||||
url: 'ssh://git@example.com/jsmith/example.git',
|
||||
description: '',
|
||||
homepage: 'http://example.com/jsmith/example',
|
||||
git_http_url: 'http://example.com/jsmith/example.git',
|
||||
git_ssh_url: 'git@example.com:jsmith/example.git',
|
||||
visibility_level: 0,
|
||||
},
|
||||
commits: [],
|
||||
total_commits_count: 0,
|
||||
};
|
24
packages/backend/src/apps/gitlab/triggers/types.ts
Normal file
24
packages/backend/src/apps/gitlab/triggers/types.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
export enum GITLAB_EVENT_TYPE {
|
||||
// ref: https://docs.gitlab.com/ee/api/projects.html#add-project-hook
|
||||
confidential_issues_events = 'confidential_issues_events',
|
||||
confidential_note_events = 'confidential_note_events',
|
||||
deployment_events = 'deployment_events',
|
||||
feature_flag_events = 'feature_flag_events',
|
||||
issues_events = 'issues_events',
|
||||
job_events = 'job_events',
|
||||
merge_requests_events = 'merge_requests_events',
|
||||
note_events = 'note_events',
|
||||
pipeline_events = 'pipeline_events',
|
||||
push_events = 'push_events',
|
||||
releases_events = 'releases_events',
|
||||
tag_push_events = 'tag_push_events',
|
||||
wiki_page_events = 'wiki_page_events',
|
||||
}
|
||||
|
||||
export type EventDescriptor = {
|
||||
name: string;
|
||||
description: string;
|
||||
info?: string;
|
||||
type: GITLAB_EVENT_TYPE;
|
||||
data: any;
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './wiki_page_events';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Wiki page events',
|
||||
description:
|
||||
'Wiki page events (triggered when a wiki page is created, updated, or deleted)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#wiki-page-events',
|
||||
key: GITLAB_EVENT_TYPE.wiki_page_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.wiki_page_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,48 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#wiki-page-events
|
||||
|
||||
export default {
|
||||
object_kind: 'wiki_page',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'awesome-project',
|
||||
description: 'This is awesome',
|
||||
web_url: 'http://example.com/root/awesome-project',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:root/awesome-project.git',
|
||||
git_http_url: 'http://example.com/root/awesome-project.git',
|
||||
namespace: 'root',
|
||||
visibility_level: 0,
|
||||
path_with_namespace: 'root/awesome-project',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/root/awesome-project',
|
||||
url: 'git@example.com:root/awesome-project.git',
|
||||
ssh_url: 'git@example.com:root/awesome-project.git',
|
||||
http_url: 'http://example.com/root/awesome-project.git',
|
||||
},
|
||||
wiki: {
|
||||
web_url: 'http://example.com/root/awesome-project/-/wikis/home',
|
||||
git_ssh_url: 'git@example.com:root/awesome-project.wiki.git',
|
||||
git_http_url: 'http://example.com/root/awesome-project.wiki.git',
|
||||
path_with_namespace: 'root/awesome-project.wiki',
|
||||
default_branch: 'master',
|
||||
},
|
||||
object_attributes: {
|
||||
title: 'Awesome',
|
||||
content: 'awesome content goes here',
|
||||
format: 'markdown',
|
||||
message: 'adding an awesome page to the wiki',
|
||||
slug: 'awesome',
|
||||
url: 'http://example.com/root/awesome-project/-/wikis/awesome',
|
||||
action: 'create',
|
||||
diff_url:
|
||||
'http://example.com/root/awesome-project/-/wikis/home/diff?version_id=78ee4a6705abfbff4f4132c6646dbaae9c8fb6ec',
|
||||
},
|
||||
};
|
28
packages/types/index.d.ts
vendored
28
packages/types/index.d.ts
vendored
@@ -4,7 +4,13 @@ import type { Request } from 'express';
|
||||
|
||||
// Type definitions for automatisch
|
||||
|
||||
export type IJSONValue = string | number | boolean | IJSONObject | IJSONArray;
|
||||
export type IJSONValue =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
| IJSONObject
|
||||
| IJSONArray;
|
||||
export type IJSONArray = Array<IJSONValue>;
|
||||
export interface IJSONObject {
|
||||
[x: string]: IJSONValue;
|
||||
@@ -338,7 +344,7 @@ export type TPaymentPlan = {
|
||||
name: string;
|
||||
limit: string;
|
||||
productId: string;
|
||||
}
|
||||
};
|
||||
|
||||
export type TSubscription = {
|
||||
status: string;
|
||||
@@ -354,28 +360,28 @@ export type TSubscription = {
|
||||
title: string;
|
||||
action: BillingCardAction;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
type TBillingCardAction = TBillingTextCardAction | TBillingLinkCardAction;
|
||||
|
||||
type TBillingTextCardAction = {
|
||||
type: 'text';
|
||||
text: string;
|
||||
}
|
||||
};
|
||||
|
||||
type TBillingLinkCardAction = {
|
||||
type: 'link';
|
||||
text: string;
|
||||
src: string;
|
||||
}
|
||||
};
|
||||
|
||||
type TInvoice = {
|
||||
id: number
|
||||
amount: number
|
||||
currency: string
|
||||
payout_date: string
|
||||
receipt_url: string
|
||||
}
|
||||
id: number;
|
||||
amount: number;
|
||||
currency: string;
|
||||
payout_date: string;
|
||||
receipt_url: string;
|
||||
};
|
||||
|
||||
declare module 'axios' {
|
||||
interface AxiosResponse {
|
||||
|
Reference in New Issue
Block a user