@uxf/scripts 10.7.0 → 11.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uxf/scripts",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "11.10.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "",
|
|
15
15
|
"typecheck": "",
|
|
16
|
-
"test": "./node_modules/.bin/eslint ./bin"
|
|
16
|
+
"test": "./node_modules/.bin/eslint ./bin",
|
|
17
|
+
"run:mr-notifier": "GOOGLE_WEBHOOK_URL=<<TODO>> GITLAB_TOKEN=<<TODO>> CI_SERVER_URL=https://gitlab.uxf.cz node ./bin/uxf-merge-requests-notifier.js"
|
|
17
18
|
},
|
|
18
19
|
"publishConfig": {
|
|
19
20
|
"access": "public"
|
|
@@ -24,8 +25,8 @@
|
|
|
24
25
|
"author": "",
|
|
25
26
|
"license": "ISC",
|
|
26
27
|
"dependencies": {
|
|
27
|
-
"@commitlint/parse": "
|
|
28
|
-
"axios": "1.
|
|
28
|
+
"@commitlint/parse": "18.6.1",
|
|
29
|
+
"axios": "1.6.7",
|
|
29
30
|
"cheerio": "1.0.0-rc.12",
|
|
30
31
|
"dayjs": "1.11.10",
|
|
31
32
|
"madge": "6.1.0",
|
package/src/GitLab.js
CHANGED
|
@@ -5,12 +5,35 @@ const parse = require("@commitlint/parse").default;
|
|
|
5
5
|
|
|
6
6
|
const axios = create({
|
|
7
7
|
baseURL: `${env.CI_SERVER_URL}/api/v4`,
|
|
8
|
-
|
|
9
8
|
headers: {
|
|
10
9
|
Authorization: `Bearer ${env.GITLAB_TOKEN}`,
|
|
11
10
|
},
|
|
12
11
|
});
|
|
13
12
|
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param {string} url
|
|
16
|
+
* @param {axios.AxiosRequestConfig<any>} config
|
|
17
|
+
*/
|
|
18
|
+
async function getAll(url, config) {
|
|
19
|
+
let nextPage = "1";
|
|
20
|
+
const data = [];
|
|
21
|
+
do {
|
|
22
|
+
const response = await axios.get(url, {
|
|
23
|
+
...config,
|
|
24
|
+
params: {
|
|
25
|
+
...(config.params ?? {}),
|
|
26
|
+
per_page: "100",
|
|
27
|
+
page: nextPage,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
nextPage = response.headers["x-next-page"];
|
|
31
|
+
data.push(...response.data);
|
|
32
|
+
} while (nextPage);
|
|
33
|
+
|
|
34
|
+
return data;
|
|
35
|
+
}
|
|
36
|
+
|
|
14
37
|
async function loadCommits(from) {
|
|
15
38
|
const commits = [];
|
|
16
39
|
console.log(`- start date: ${from}`);
|
|
@@ -94,9 +117,33 @@ async function createRelease(description, dryRun = false) {
|
|
|
94
117
|
console.log(`\n🎉🎉🎉 Release "${tag}" published\n\n${description}`);
|
|
95
118
|
}
|
|
96
119
|
|
|
120
|
+
function getSingleMergeRequestChanges(projectId, mr_iid) {
|
|
121
|
+
return axios.get(`/projects/${projectId}/merge_requests/${mr_iid}/changes`).then((r) => r.data);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function getAllMergeRequests() {
|
|
125
|
+
return getAll("/merge_requests", {
|
|
126
|
+
params: {
|
|
127
|
+
approwed: "no",
|
|
128
|
+
wip: "no",
|
|
129
|
+
sort: "asc",
|
|
130
|
+
scope: "all",
|
|
131
|
+
state: "opened",
|
|
132
|
+
order_by: "updated_at",
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function getAllProjects() {
|
|
138
|
+
return getAll("/projects", { params: { simple: false } });
|
|
139
|
+
}
|
|
140
|
+
|
|
97
141
|
module.exports = {
|
|
98
142
|
loadCommits,
|
|
99
143
|
loadIssues,
|
|
100
144
|
getLastTag,
|
|
101
145
|
createRelease,
|
|
146
|
+
getAllMergeRequests,
|
|
147
|
+
getAllProjects,
|
|
148
|
+
getSingleMergeRequestChanges,
|
|
102
149
|
};
|
package/src/GoogleChat.js
CHANGED
|
@@ -15,6 +15,13 @@ async function chatPostMessage(data, dryRun) {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
async function messageCardsV2(cardsV2) {
|
|
19
|
+
return axios
|
|
20
|
+
.post(env.GOOGLE_WEBHOOK_URL, { cardsV2 }, { headers: { "Content-Type": "application/json; charset=UTF-8" } })
|
|
21
|
+
.then((r) => r.data);
|
|
22
|
+
}
|
|
23
|
+
|
|
18
24
|
module.exports = {
|
|
19
25
|
chatPostMessage,
|
|
26
|
+
messageCardsV2,
|
|
20
27
|
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const { argv, env } = require("process");
|
|
2
|
+
|
|
3
|
+
module.exports = async () => {
|
|
4
|
+
const cli = require("yargs")
|
|
5
|
+
.command("$0", "UXF merge requests notifier", (yargs) => {
|
|
6
|
+
yargs.demandCommand(0, 0).usage(`Usage:
|
|
7
|
+
uxf-merge-requests-notifier [options]
|
|
8
|
+
|
|
9
|
+
Environment variables:
|
|
10
|
+
GITLAB_TOKEN - required
|
|
11
|
+
GOOGLE_WEBHOOK_URL - required
|
|
12
|
+
CI_SERVER_URL - required - setting by GitLab CI`);
|
|
13
|
+
})
|
|
14
|
+
.option("h", { alias: "help", group: "Options" })
|
|
15
|
+
.strict(false)
|
|
16
|
+
.exitProcess(false);
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const { help, ...options } = cli.parse(argv.slice(2));
|
|
20
|
+
|
|
21
|
+
if (Boolean(help)) {
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!env.GITLAB_TOKEN) {
|
|
26
|
+
console.log("GitLab token must be set. Use environment variable GITLAB_TOKEN.");
|
|
27
|
+
return 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!env.GOOGLE_WEBHOOK_URL) {
|
|
31
|
+
console.log("Google webhook url must be set. Use environment variable GOOGLE_WEBHOOK_URL.");
|
|
32
|
+
return 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
await require("./index")();
|
|
36
|
+
} catch (e) {
|
|
37
|
+
console.error(e);
|
|
38
|
+
return 1;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const GitLab = require("../GitLab");
|
|
2
|
+
const GoogleChat = require("../GoogleChat");
|
|
3
|
+
const relativeTime = require("dayjs/plugin/relativeTime");
|
|
4
|
+
const dayjs = require("dayjs");
|
|
5
|
+
require("dayjs/locale/cs");
|
|
6
|
+
dayjs.locale("cs");
|
|
7
|
+
dayjs.extend(relativeTime);
|
|
8
|
+
|
|
9
|
+
function inflect(value, word1, word2, word3) {
|
|
10
|
+
return `${value} ${value === 1 ? word1 : value <= 4 ? word2 : word3}`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = async function run() {
|
|
14
|
+
const projects = await GitLab.getAllProjects();
|
|
15
|
+
const allMergeRequests = await GitLab.getAllMergeRequests();
|
|
16
|
+
|
|
17
|
+
const result = allMergeRequests
|
|
18
|
+
.map((mr) => ({
|
|
19
|
+
id: mr.id,
|
|
20
|
+
iid: mr.iid,
|
|
21
|
+
reviewers: mr.reviewers ?? [],
|
|
22
|
+
project: projects.find((project) => project.id === mr.project_id),
|
|
23
|
+
title: mr.title,
|
|
24
|
+
author: mr.author,
|
|
25
|
+
createdAt: mr.created_at,
|
|
26
|
+
updatedAt: mr.updated_at,
|
|
27
|
+
webUrl: mr.web_url,
|
|
28
|
+
state: mr.state.toUpperCase(),
|
|
29
|
+
targetBranch: mr.target_branch,
|
|
30
|
+
sourceBranch: mr.source_branch,
|
|
31
|
+
}))
|
|
32
|
+
.filter((mr) => mr.reviewers.length === 0)
|
|
33
|
+
.filter((mr) => mr.sourceBranch !== "develop" || mr.targetBranch !== "master")
|
|
34
|
+
.filter((mr) => !mr.project.archived);
|
|
35
|
+
|
|
36
|
+
if (result.length === 0) {
|
|
37
|
+
console.log("No merge requests to code review.");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
await GoogleChat.chatPostMessage({
|
|
42
|
+
text: `🔥🔥🔥 ${inflect(
|
|
43
|
+
result.length,
|
|
44
|
+
"MR čekající na code review",
|
|
45
|
+
"MR čekající na code review",
|
|
46
|
+
"MR čekajících na code review",
|
|
47
|
+
)}`,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
for (const mr of result) {
|
|
51
|
+
const changes = await GitLab.getSingleMergeRequestChanges(mr.project.id, mr.iid);
|
|
52
|
+
const changesCount = Number.parseInt(changes.changes_count);
|
|
53
|
+
|
|
54
|
+
await GoogleChat.messageCardsV2([
|
|
55
|
+
{
|
|
56
|
+
cardId: `mr-card-${mr.id}`,
|
|
57
|
+
card: {
|
|
58
|
+
header: {
|
|
59
|
+
title: `${mr.project.name} | ${mr.title}`,
|
|
60
|
+
subtitle: `${mr.author.name} | ${dayjs(mr.updatedAt).fromNow()} | ${inflect(
|
|
61
|
+
changesCount,
|
|
62
|
+
"soubor",
|
|
63
|
+
"soubory",
|
|
64
|
+
"souborů",
|
|
65
|
+
)}`,
|
|
66
|
+
},
|
|
67
|
+
sections: [
|
|
68
|
+
{
|
|
69
|
+
widgets: [
|
|
70
|
+
{
|
|
71
|
+
buttonList: {
|
|
72
|
+
buttons: [{ text: "Otevřít MR", onClick: { openLink: { url: mr.webUrl } } }],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
]);
|
|
81
|
+
}
|
|
82
|
+
};
|