Merge pull request #57 from 8398a7/issue/31

Issue/31
This commit is contained in:
839 2020-04-05 18:03:25 +09:00 коммит произвёл GitHub
Родитель 9008c1f807 8a535cb26d
Коммит 032eda2e1a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 218 добавлений и 72 удалений

Просмотреть файл

@ -15,46 +15,90 @@ import {
Failure,
Cancelled,
Always,
Field,
} from '../src/client';
const fixedFields = (sha?: string) => {
return [
{
short: true,
title: 'repo',
value: '<https://github.com/8398a7/action-slack|8398a7/action-slack>',
},
{
short: true,
title: 'message',
value: '[#19] support for multiple user mentions',
},
{
short: true,
title: 'commit',
value: `<https://github.com/8398a7/action-slack/commit/${process.env.GITHUB_SHA}|${process.env.GITHUB_SHA}>`,
},
{ short: true, title: 'author', value: '839<8398a7@gmail.com>' },
{
short: true,
title: 'action',
value: `<https://github.com/8398a7/action-slack/commit/${sha ??
process.env.GITHUB_SHA}/checks|action>`,
},
{ short: true, title: 'eventName', value: process.env.GITHUB_EVENT_NAME },
{ short: true, title: 'ref', value: process.env.GITHUB_REF },
{ short: true, title: 'workflow', value: process.env.GITHUB_WORKFLOW },
];
const repo = (): Field => {
return {
short: true,
title: 'repo',
value: '<https://github.com/8398a7/action-slack|8398a7/action-slack>',
};
};
const getTemplate: any = (text: string, sha?: string) => {
const message = (): Field => {
return {
short: true,
title: 'message',
value: '[#19] support for multiple user mentions',
};
};
const commit = (): Field => {
return {
short: true,
title: 'commit',
value: `<https://github.com/8398a7/action-slack/commit/${process.env.GITHUB_SHA}|${process.env.GITHUB_SHA}>`,
};
};
const author = (): Field => {
return { short: true, title: 'author', value: '839<8398a7@gmail.com>' };
};
const action = (sha?: string): Field => {
return {
short: true,
title: 'action',
value: `<https://github.com/8398a7/action-slack/commit/${sha ??
process.env.GITHUB_SHA}/checks|action>`,
};
};
const eventName = (): Field => {
return {
short: true,
title: 'eventName',
value: process.env.GITHUB_EVENT_NAME as string,
};
};
const ref = (): Field => {
return { short: true, title: 'ref', value: process.env.GITHUB_REF as string };
};
const workflow = (): Field => {
return {
short: true,
title: 'workflow',
value: process.env.GITHUB_WORKFLOW as string,
};
};
const fixedFields = (client: Client, sha?: string) => {
return client.filterField(
[
client.includesField('repo') ? repo() : undefined,
client.includesField('message') ? message() : undefined,
client.includesField('commit') ? commit() : undefined,
client.includesField('author') ? author() : undefined,
client.includesField('action') ? action(sha) : undefined,
client.includesField('eventName') ? eventName() : undefined,
client.includesField('ref') ? ref() : undefined,
client.includesField('workflow') ? workflow() : undefined,
],
undefined,
);
};
const getTemplate: any = (client: Client, text: string, sha?: string) => {
return {
text,
attachments: [
{
author_name: '',
color: '',
fields: fixedFields(sha),
fields: fixedFields(client, sha),
},
],
username: '',
@ -92,6 +136,26 @@ describe('8398a7/action-slack', () => {
github.context.payload = {};
});
describe('fields', () => {
it('is full fields', async () => {
const withParams: With = {
status: '',
mention: '',
author_name: '',
if_mention: '',
username: '',
icon_emoji: '',
icon_url: '',
channel: '',
fields: 'repo,message,commit,author,action,eventName,ref,workflow',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const payload = getTemplate(client, `${successMsg}\n`);
payload.attachments[0].color = 'good';
expect(await client.success('')).toStrictEqual(payload);
});
});
describe('text is not specified', () => {
it('is success', async () => {
const withParams: With = {
@ -103,9 +167,10 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const payload = getTemplate(`${successMsg}\n`);
const payload = getTemplate(client, `${successMsg}\n`);
payload.attachments[0].color = 'good';
expect(await client.success('')).toStrictEqual(payload);
});
@ -119,9 +184,10 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const payload = getTemplate(`${failMsg}\n`);
const payload = getTemplate(client, `${failMsg}\n`);
payload.attachments[0].color = 'danger';
expect(await client.fail('')).toStrictEqual(payload);
});
@ -135,9 +201,10 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const payload = getTemplate(`${cancelMsg}\n`);
const payload = getTemplate(client, `${cancelMsg}\n`);
payload.attachments[0].color = 'warning';
expect(await client.cancel('')).toStrictEqual(payload);
});
@ -153,10 +220,11 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'mention test';
const payload = getTemplate(msg);
const payload = getTemplate(client, msg);
payload.attachments[0].color = 'good';
expect(await client.success(msg)).toStrictEqual(payload);
});
@ -171,16 +239,17 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
let client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'mention test';
let payload = getTemplate(msg);
let payload = getTemplate(client, msg);
payload.attachments[0].color = 'good';
expect(await client.success(msg)).toStrictEqual(payload);
withParams.mention = '';
client = new Client(withParams, process.env.GITHUB_TOKEN, '');
payload = getTemplate(msg);
payload = getTemplate(client, msg);
payload.attachments[0].color = 'danger';
expect(await client.fail(msg)).toStrictEqual(payload);
});
@ -195,10 +264,11 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'mention test';
const payload = getTemplate(`<!here> ${msg}`);
const payload = getTemplate(client, `<!here> ${msg}`);
payload.attachments[0].color = 'good';
expect(await client.success(msg)).toStrictEqual(payload);
});
@ -213,10 +283,11 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'mention test';
const payload = getTemplate(`<!here> ${msg}`);
const payload = getTemplate(client, `<!here> ${msg}`);
payload.attachments[0].color = 'good';
expect(await client.success(msg)).toStrictEqual(payload);
});
@ -231,10 +302,11 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'mention test';
const payload = getTemplate(`<!here> ${msg}`);
const payload = getTemplate(client, `<!here> ${msg}`);
payload.attachments[0].color = 'danger';
expect(await client.fail(msg)).toStrictEqual(payload);
});
@ -249,10 +321,11 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'mention test';
const payload = getTemplate(`<!here> ${msg}`);
const payload = getTemplate(client, `<!here> ${msg}`);
payload.attachments[0].color = 'warning';
expect(await client.cancel(msg)).toStrictEqual(payload);
});
@ -267,18 +340,19 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'mention test';
let payload = getTemplate(`<!here> ${msg}`);
let payload = getTemplate(client, `<!here> ${msg}`);
payload.attachments[0].color = 'good';
expect(await client.success(msg)).toStrictEqual(payload);
payload = getTemplate(`<!here> ${msg}`);
payload = getTemplate(client, `<!here> ${msg}`);
payload.attachments[0].color = 'danger';
expect(await client.fail(msg)).toStrictEqual(payload);
payload = getTemplate(`<!here> ${msg}`);
payload = getTemplate(client, `<!here> ${msg}`);
payload.attachments[0].color = 'warning';
expect(await client.cancel(msg)).toStrictEqual(payload);
});
@ -293,10 +367,11 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'mention test';
const payload = getTemplate(`<@user_id> ${msg}`);
const payload = getTemplate(client, `<@user_id> ${msg}`);
payload.attachments[0].color = 'good';
expect(await client.success(msg)).toStrictEqual(payload);
});
@ -311,10 +386,11 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'mention test';
const payload = getTemplate(`<!here> ${msg}`);
const payload = getTemplate(client, `<!here> ${msg}`);
payload.attachments[0].color = 'good';
expect(await client.success(msg)).toStrictEqual(payload);
});
@ -329,10 +405,11 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'mention test';
const payload = getTemplate(`<!channel> ${msg}`);
const payload = getTemplate(client, `<!channel> ${msg}`);
payload.attachments[0].color = 'good';
expect(await client.success(msg)).toStrictEqual(payload);
});
@ -347,10 +424,11 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'mention test';
const payload = getTemplate(`<@user_id> <@user_id2> ${msg}`);
const payload = getTemplate(client, `<@user_id> <@user_id2> ${msg}`);
payload.attachments[0].color = 'good';
expect(await client.success(msg)).toStrictEqual(payload);
});
@ -365,11 +443,12 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
let client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'hello';
let payload = getTemplate(`<@user_id> <@user_id2> ${msg}`);
let payload = getTemplate(client, `<@user_id> <@user_id2> ${msg}`);
payload.attachments[0].color = 'good';
expect(await client.success(msg)).toStrictEqual(payload);
});
@ -384,22 +463,23 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'hello';
// for success
let payload = getTemplate(msg);
let payload = getTemplate(client, msg);
payload.attachments[0].color = 'good';
expect(await client.success(msg)).toStrictEqual(payload);
// for cancel
payload = getTemplate(msg);
payload = getTemplate(client, msg);
payload.attachments[0].color = 'warning';
expect(await client.cancel(msg)).toStrictEqual(payload);
// for fail
payload = getTemplate(msg);
payload = getTemplate(client, msg);
payload.attachments[0].color = 'danger';
expect(await client.fail(msg)).toStrictEqual(payload);
});
@ -414,9 +494,10 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: 'message,author',
};
const client = new Client(withParams, undefined, '');
const payload = getTemplate(`${successMsg}\n`);
const payload = getTemplate(client, `${successMsg}\n`);
payload.attachments[0].color = 'good';
payload.attachments[0].fields = payload.attachments[0].fields.filter(
(field: any) => !['message', 'author'].includes(field.title),
@ -452,10 +533,11 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: 'action',
};
const client = new Client(withParams, process.env.GITHUB_TOKEN, '');
const msg = 'mention test';
const payload = getTemplate(`<@user_id> ${msg}`, sha);
const payload = getTemplate(client, `<@user_id> ${msg}`, sha);
payload.attachments[0].color = 'good';
expect(await client.success(msg)).toStrictEqual(payload);
});
@ -471,6 +553,7 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
expect(() => new Client(withParams, undefined)).toThrow(
'Specify secrets.SLACK_WEBHOOK_URL',
@ -499,6 +582,7 @@ describe('8398a7/action-slack', () => {
icon_emoji: '',
icon_url: '',
channel: '',
fields: '',
};
const client = new Client(withParams, undefined, mockSlackWebhookUrl);

Просмотреть файл

@ -4,39 +4,56 @@ author: 8398a7
inputs:
status:
description: Specify success or failure or cancelled or custom.
required: true
fields:
description: |
You can choose the items you want to add to the fields at the time of notification.
If you have more than one, please enter it in csv format.
e.g. commit,repo
default: ""
required: false
custom_payload:
description: |
json payload
refs https://github.com/slackapi/node-slack-sdk/blob/v5.0.0/packages/webhook/src/IncomingWebhook.ts#L91-L106)
required: false
mention:
description: |
Specify channel or here or `user_id`.
refs: https://api.slack.com/reference/surfaces/formatting#mentioning-users
default: ""
required: false
if_mention:
description: |
Specify success or failure or cancelled or custom or always.
Multiple statuses can be specified in csv format.
e.g. success,failure
default: ""
required: false
author_name:
description: User name for slack notification.
default: 8398a7@action-slack
required: false
text:
description: You can overwrite text.
default: ""
required: false
username:
description: override the legacy integration's default name.
default: ""
required: false
icon_emoji:
description: an emoji code string to use in place of the default icon.
default: ""
required: false
icon_url:
description: an icon image URL string to use in place of the default icon.
default: ""
required: false
channel:
description: override the legacy integration's default channel. This should be an ID, such as C8UJ12P4P.
default: ""
required: false
runs:
using: node12
main: dist/index.js

Просмотреть файл

@ -11,6 +11,7 @@ This page describes the elements that can be specified in with.
|key|value|default|
|---|---|---|
|[status](/with#status)|`'success'` or `'failure'` or `'cancelled'` or `'custom'`|`''`|
|[fields](/with#fields)|You can choose the items you want to add to the fields at the time of notification.|`''`|
|[text](/with#text)|Specify the text you want to add.|`''`|
|[author_name](/with#author_name)|It can be overwritten by specifying. The job name is recommend.|`'8398a7@action-slack'`|
|[mention](/with#mention)|`'here'` or `'channel'` or [user_id](https://api.slack.com/reference/surfaces/formatting#mentioning-users)|`''`|
@ -35,6 +36,29 @@ steps:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} # required
```
# fields
If you have more than one, please enter it in csv format.
Corresponding types are as follows.
- repo
- commit
- author
- action
- eventName
- ref
- workflow
```yaml
steps:
- uses: 8398a7/action-slack@v3
with:
fields: commit,repo
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # optional
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} # required
```
# text
e.g.

Просмотреть файл

@ -21,9 +21,10 @@ export interface With {
icon_emoji: string;
icon_url: string;
channel: string;
fields: string;
}
interface Field {
export interface Field {
title: string;
value: string;
short: boolean;
@ -91,6 +92,22 @@ export class Client {
core.debug('send message');
}
includesField(field: string) {
const { fields } = this.with;
const normalized = fields.replace(/ /g, '').split(',');
return normalized.includes(field);
}
filterField<T extends Array<Field | undefined>, U extends undefined>(
array: T,
diff: U,
) {
return array.filter(item => item !== diff) as Exclude<
T extends { [K in keyof T]: infer U } ? U : never,
U
>[];
}
private async payloadTemplate() {
const text = '';
const { username, icon_emoji, icon_url, channel } = this.with;
@ -125,7 +142,7 @@ export class Client {
return this.filterField(
[
this.repo,
commit
commit && this.includesField('message')
? {
title: 'message',
value: commit.data.commit.message,
@ -133,7 +150,7 @@ export class Client {
}
: undefined,
this.commit,
author
author && this.includesField('author')
? {
title: 'author',
value: `${author.name}<${author.email}>`,
@ -149,7 +166,9 @@ export class Client {
);
}
private get commit(): Field {
private get commit(): Field | undefined {
if (!this.includesField('commit')) return undefined;
const { sha } = github.context;
const { owner, repo } = github.context.repo;
@ -160,7 +179,9 @@ export class Client {
};
}
private get repo(): Field {
private get repo(): Field | undefined {
if (!this.includesField('repo')) return undefined;
const { owner, repo } = github.context.repo;
return {
@ -170,7 +191,9 @@ export class Client {
};
}
private get action(): Field {
private get action(): Field | undefined {
if (!this.includesField('action')) return undefined;
const sha =
github.context.payload.pull_request?.head.sha ?? github.context.sha;
const { owner, repo } = github.context.repo;
@ -182,7 +205,9 @@ export class Client {
};
}
private get eventName(): Field {
private get eventName(): Field | undefined {
if (!this.includesField('eventName')) return undefined;
return {
title: 'eventName',
value: github.context.eventName,
@ -190,11 +215,15 @@ export class Client {
};
}
private get ref(): Field {
private get ref(): Field | undefined {
if (!this.includesField('ref')) return undefined;
return { title: 'ref', value: github.context.ref, short: true };
}
private get workflow(): Field {
private get workflow(): Field | undefined {
if (!this.includesField('workflow')) return undefined;
return { title: 'workflow', value: github.context.workflow, short: true };
}
@ -222,16 +251,6 @@ export class Client {
return '';
}
private filterField<T extends Array<Field | undefined>, U extends undefined>(
array: T,
diff: U,
) {
return array.filter(item => item !== diff) as Exclude<
T extends { [K in keyof T]: infer U } ? U : never,
U
>[];
}
private insertText(defaultText: string, text: string) {
return text === '' ? defaultText : text;
}

Просмотреть файл

@ -15,6 +15,7 @@ async function run(): Promise<void> {
const channel = core.getInput('channel');
const custom_payload = core.getInput('custom_payload');
const payload = core.getInput('payload');
const fields = core.getInput('fields');
core.debug(`status: ${status}`);
core.debug(`mention: ${mention}`);
@ -38,6 +39,7 @@ async function run(): Promise<void> {
icon_emoji,
icon_url,
channel,
fields,
},
process.env.GITHUB_TOKEN,
process.env.SLACK_WEBHOOK_URL,