@allurereport/ci 3.12.0 → 3.13.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/dist/detectors/amazon.js +103 -2
- package/dist/detectors/azure.js +85 -6
- package/dist/detectors/bitbucket.js +53 -3
- package/dist/detectors/circle.js +48 -2
- package/dist/detectors/drone.js +86 -9
- package/dist/detectors/github.js +55 -9
- package/dist/detectors/gitlab.js +43 -4
- package/dist/detectors/jenkins.js +57 -1
- package/dist/detectors/local.js +27 -0
- package/dist/helpers/gitProvider.d.ts +13 -0
- package/dist/helpers/gitProvider.js +115 -0
- package/dist/helpers/github.d.ts +2 -0
- package/dist/helpers/github.js +50 -0
- package/package.json +2 -2
package/dist/detectors/amazon.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { CiType } from "@allurereport/core-api";
|
|
2
|
+
import { resolveRepositoryFromGitUrl, stripRefsHeads } from "../helpers/gitProvider.js";
|
|
2
3
|
import { getEnv, getReponameFromRepoUrl } from "../utils.js";
|
|
3
4
|
const AMAZON_REGEXP = /^arn:aws:codebuild:([^:]+):([\d]+):(?:build|build-batch)\/([^:]+):([\da-f-]+)$/;
|
|
4
5
|
const PIPELINE_REGEXP = /^(?:codepipeline\/)(.+)$/;
|
|
6
|
+
const REF_PREFIX = "refs/";
|
|
7
|
+
const BRANCH_REF_PREFIX = "refs/heads/";
|
|
8
|
+
const TAG_REF_PREFIX = "refs/tags/";
|
|
9
|
+
const GIT_SHA_REGEXP = /^[\da-f]{40}$/i;
|
|
5
10
|
export const parseArnValues = (source) => {
|
|
6
11
|
if (!source) {
|
|
7
12
|
return [];
|
|
@@ -21,6 +26,72 @@ export const getPipelineName = () => {
|
|
|
21
26
|
}
|
|
22
27
|
return initiator.match(PIPELINE_REGEXP)?.[1] ?? "";
|
|
23
28
|
};
|
|
29
|
+
const stripCommitSuffix = (sourceVersion) => sourceVersion.replace(/\^\{[^}]+\}$/, "");
|
|
30
|
+
const parseBranchFromWebhookTrigger = () => {
|
|
31
|
+
const branchTrigger = getEnv("CODEBUILD_WEBHOOK_TRIGGER") || "";
|
|
32
|
+
if (branchTrigger.startsWith("branch/")) {
|
|
33
|
+
const branch = branchTrigger.slice("branch/".length);
|
|
34
|
+
return branch || undefined;
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
};
|
|
38
|
+
const isTagWebhookTrigger = () => (getEnv("CODEBUILD_WEBHOOK_TRIGGER") || "").startsWith("tag/");
|
|
39
|
+
const parseBranchFromSourceVersion = (sourceVersion) => {
|
|
40
|
+
const normalizedSourceVersion = stripCommitSuffix((sourceVersion ?? "").trim());
|
|
41
|
+
if (!normalizedSourceVersion) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
if (normalizedSourceVersion.startsWith(BRANCH_REF_PREFIX)) {
|
|
45
|
+
const branch = normalizedSourceVersion.slice(BRANCH_REF_PREFIX.length);
|
|
46
|
+
return branch || undefined;
|
|
47
|
+
}
|
|
48
|
+
if (normalizedSourceVersion.startsWith(TAG_REF_PREFIX) ||
|
|
49
|
+
normalizedSourceVersion.match(/^pr\/\d+$/i) ||
|
|
50
|
+
normalizedSourceVersion.match(/^refs\/pull\/\d+\//i)) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
if (normalizedSourceVersion.startsWith(REF_PREFIX)) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
const triggerBranch = parseBranchFromWebhookTrigger();
|
|
57
|
+
if (triggerBranch) {
|
|
58
|
+
return triggerBranch;
|
|
59
|
+
}
|
|
60
|
+
if (isTagWebhookTrigger() || GIT_SHA_REGEXP.test(normalizedSourceVersion)) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
return normalizedSourceVersion;
|
|
64
|
+
};
|
|
65
|
+
const parseBranchFromWebhookHeadRef = (headRef) => {
|
|
66
|
+
const normalizedHeadRef = (headRef ?? "").trim();
|
|
67
|
+
if (!normalizedHeadRef || normalizedHeadRef.startsWith(TAG_REF_PREFIX) || isTagWebhookTrigger()) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
if (normalizedHeadRef.startsWith(BRANCH_REF_PREFIX)) {
|
|
71
|
+
const branch = normalizedHeadRef.slice(BRANCH_REF_PREFIX.length);
|
|
72
|
+
return branch || undefined;
|
|
73
|
+
}
|
|
74
|
+
if (normalizedHeadRef.startsWith(REF_PREFIX)) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
return normalizedHeadRef;
|
|
78
|
+
};
|
|
79
|
+
const parsePullRequestFromSourceVersion = (sourceVersion) => {
|
|
80
|
+
const normalizedSourceVersion = sourceVersion ?? "";
|
|
81
|
+
const prPrefixMatch = normalizedSourceVersion.match(/^pr\/(?<id>\d+)$/i)?.groups?.id;
|
|
82
|
+
if (prPrefixMatch) {
|
|
83
|
+
return prPrefixMatch;
|
|
84
|
+
}
|
|
85
|
+
return normalizedSourceVersion.match(/refs\/pull\/(?<id>\d+)\//)?.groups?.id;
|
|
86
|
+
};
|
|
87
|
+
const parsePullRequestFromWebhookTrigger = () => {
|
|
88
|
+
const trigger = getEnv("CODEBUILD_WEBHOOK_TRIGGER") || "";
|
|
89
|
+
return trigger.match(/^pr\/(?<id>\d+)$/i)?.groups?.id;
|
|
90
|
+
};
|
|
91
|
+
const getRepository = () => {
|
|
92
|
+
const repoUrl = getEnv("CODEBUILD_SOURCE_REPO_URL");
|
|
93
|
+
return repoUrl ? resolveRepositoryFromGitUrl(repoUrl) : undefined;
|
|
94
|
+
};
|
|
24
95
|
export const amazon = {
|
|
25
96
|
type: CiType.Amazon,
|
|
26
97
|
get detected() {
|
|
@@ -118,8 +189,7 @@ export const amazon = {
|
|
|
118
189
|
},
|
|
119
190
|
get jobRunBranch() {
|
|
120
191
|
const sourceVersion = getEnv("CODEBUILD_SOURCE_VERSION");
|
|
121
|
-
|
|
122
|
-
return branch ?? "";
|
|
192
|
+
return parseBranchFromSourceVersion(sourceVersion) ?? "";
|
|
123
193
|
},
|
|
124
194
|
get pullRequestUrl() {
|
|
125
195
|
return "";
|
|
@@ -127,4 +197,35 @@ export const amazon = {
|
|
|
127
197
|
get pullRequestName() {
|
|
128
198
|
return "";
|
|
129
199
|
},
|
|
200
|
+
get provider() {
|
|
201
|
+
return getRepository()?.provider;
|
|
202
|
+
},
|
|
203
|
+
get repository() {
|
|
204
|
+
const repository = getRepository();
|
|
205
|
+
return repository
|
|
206
|
+
? {
|
|
207
|
+
slug: repository.slug,
|
|
208
|
+
url: repository.url,
|
|
209
|
+
}
|
|
210
|
+
: undefined;
|
|
211
|
+
},
|
|
212
|
+
get sourceBranch() {
|
|
213
|
+
return (parseBranchFromWebhookHeadRef(getEnv("CODEBUILD_WEBHOOK_HEAD_REF")) ||
|
|
214
|
+
parseBranchFromSourceVersion(getEnv("CODEBUILD_SOURCE_VERSION")) ||
|
|
215
|
+
this.jobRunBranch ||
|
|
216
|
+
undefined);
|
|
217
|
+
},
|
|
218
|
+
get targetBranch() {
|
|
219
|
+
return stripRefsHeads(getEnv("CODEBUILD_WEBHOOK_BASE_REF")) || undefined;
|
|
220
|
+
},
|
|
221
|
+
get pullRequest() {
|
|
222
|
+
const pullRequestId = parsePullRequestFromWebhookTrigger() || parsePullRequestFromSourceVersion(getEnv("CODEBUILD_SOURCE_VERSION"));
|
|
223
|
+
return pullRequestId
|
|
224
|
+
? {
|
|
225
|
+
id: pullRequestId,
|
|
226
|
+
url: this.pullRequestUrl || undefined,
|
|
227
|
+
title: this.pullRequestName || undefined,
|
|
228
|
+
}
|
|
229
|
+
: undefined;
|
|
230
|
+
},
|
|
130
231
|
};
|
package/dist/detectors/azure.js
CHANGED
|
@@ -1,9 +1,52 @@
|
|
|
1
|
-
import { CiType } from "@allurereport/core-api";
|
|
1
|
+
import { CiType, GitProvider } from "@allurereport/core-api";
|
|
2
|
+
import { resolveRepositoryFromGitUrl } from "../helpers/gitProvider.js";
|
|
2
3
|
import { getEnv } from "../utils.js";
|
|
4
|
+
const REF_PREFIX = "refs/";
|
|
5
|
+
const BRANCH_REF_PREFIX = "refs/heads/";
|
|
6
|
+
const TAG_REF_PREFIX = "refs/tags/";
|
|
3
7
|
export const getRootURL = () => getEnv("SYSTEM_COLLECTIONURI");
|
|
4
8
|
export const getBuildID = () => getEnv("BUILD_BUILDID");
|
|
5
9
|
export const getDefinitionID = () => getEnv("SYSTEM_DEFINITIONID");
|
|
6
10
|
export const getProjectID = () => getEnv("SYSTEM_TEAMPROJECTID");
|
|
11
|
+
const mapAzureRepositoryProvider = (provider) => {
|
|
12
|
+
switch (provider) {
|
|
13
|
+
case "GitHub":
|
|
14
|
+
return GitProvider.Github;
|
|
15
|
+
case "Bitbucket":
|
|
16
|
+
return GitProvider.Bitbucket;
|
|
17
|
+
default:
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const normalizeBranchRef = (branch) => {
|
|
22
|
+
const trimmed = branch?.trim() ?? "";
|
|
23
|
+
if (!trimmed || trimmed.startsWith(TAG_REF_PREFIX)) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
if (trimmed.startsWith(BRANCH_REF_PREFIX)) {
|
|
27
|
+
const branchName = trimmed.slice(BRANCH_REF_PREFIX.length);
|
|
28
|
+
return branchName || undefined;
|
|
29
|
+
}
|
|
30
|
+
if (trimmed.startsWith(REF_PREFIX)) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
return trimmed;
|
|
34
|
+
};
|
|
35
|
+
const getSourceBranch = () => {
|
|
36
|
+
const sourceBranch = getEnv("BUILD_SOURCEBRANCH");
|
|
37
|
+
if (sourceBranch) {
|
|
38
|
+
return normalizeBranchRef(sourceBranch);
|
|
39
|
+
}
|
|
40
|
+
return normalizeBranchRef(getEnv("BUILD_SOURCEBRANCHNAME"));
|
|
41
|
+
};
|
|
42
|
+
const getPullRequestId = () => {
|
|
43
|
+
return getEnv("SYSTEM_PULLREQUEST_PULLREQUESTNUMBER") || getEnv("SYSTEM_PULLREQUEST_PULLREQUESTID") || undefined;
|
|
44
|
+
};
|
|
45
|
+
const getRepositoryUrl = () => getEnv("BUILD_REPOSITORY_URI") || getEnv("SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI");
|
|
46
|
+
const getRepositoryFromUrl = () => {
|
|
47
|
+
const repositoryUrl = getRepositoryUrl();
|
|
48
|
+
return repositoryUrl ? resolveRepositoryFromGitUrl(repositoryUrl) : undefined;
|
|
49
|
+
};
|
|
7
50
|
export const azure = {
|
|
8
51
|
type: CiType.Azure,
|
|
9
52
|
get detected() {
|
|
@@ -32,21 +75,57 @@ export const azure = {
|
|
|
32
75
|
return getEnv("BUILD_BUILDNUMBER");
|
|
33
76
|
},
|
|
34
77
|
get jobRunBranch() {
|
|
35
|
-
return
|
|
78
|
+
return getSourceBranch() ?? "";
|
|
36
79
|
},
|
|
37
80
|
get pullRequestUrl() {
|
|
38
81
|
const repositoryProvider = getEnv("BUILD_REPOSITORY_PROVIDER");
|
|
39
|
-
const repositoryUrl = getEnv("SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI");
|
|
40
|
-
const
|
|
82
|
+
const repositoryUrl = getEnv("SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI") || getEnv("BUILD_REPOSITORY_URI");
|
|
83
|
+
const pullRequestId = getPullRequestId();
|
|
84
|
+
if (!repositoryUrl || !pullRequestId) {
|
|
85
|
+
return "";
|
|
86
|
+
}
|
|
41
87
|
if (repositoryProvider === "GitHub") {
|
|
42
|
-
return `${repositoryUrl}/pull/${
|
|
88
|
+
return `${repositoryUrl}/pull/${pullRequestId}`;
|
|
43
89
|
}
|
|
44
90
|
if (repositoryProvider === "TfsGit" || repositoryProvider === "TfsVersionControl") {
|
|
45
|
-
return `${repositoryUrl}/pullrequest/${
|
|
91
|
+
return `${repositoryUrl}/pullrequest/${pullRequestId}`;
|
|
46
92
|
}
|
|
47
93
|
return "";
|
|
48
94
|
},
|
|
49
95
|
get pullRequestName() {
|
|
50
96
|
return "";
|
|
51
97
|
},
|
|
98
|
+
get provider() {
|
|
99
|
+
return getRepositoryFromUrl()?.provider ?? mapAzureRepositoryProvider(getEnv("BUILD_REPOSITORY_PROVIDER"));
|
|
100
|
+
},
|
|
101
|
+
get repository() {
|
|
102
|
+
const repositoryUrl = getRepositoryUrl();
|
|
103
|
+
const fromUrl = repositoryUrl ? resolveRepositoryFromGitUrl(repositoryUrl) : undefined;
|
|
104
|
+
const slug = fromUrl?.slug ?? (getEnv("BUILD_REPOSITORY_NAME") || undefined);
|
|
105
|
+
if (!this.provider || !slug) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
slug,
|
|
110
|
+
url: fromUrl?.url ?? repositoryUrl,
|
|
111
|
+
};
|
|
112
|
+
},
|
|
113
|
+
get sourceBranch() {
|
|
114
|
+
return normalizeBranchRef(getEnv("SYSTEM_PULLREQUEST_SOURCEBRANCH")) || getSourceBranch() || undefined;
|
|
115
|
+
},
|
|
116
|
+
get targetBranch() {
|
|
117
|
+
return (normalizeBranchRef(getEnv("SYSTEM_PULLREQUEST_TARGETBRANCH")) ||
|
|
118
|
+
normalizeBranchRef(getEnv("SYSTEM_PULLREQUEST_TARGETBRANCHNAME")) ||
|
|
119
|
+
undefined);
|
|
120
|
+
},
|
|
121
|
+
get pullRequest() {
|
|
122
|
+
const pullRequestNumber = getPullRequestId();
|
|
123
|
+
return pullRequestNumber
|
|
124
|
+
? {
|
|
125
|
+
id: pullRequestNumber,
|
|
126
|
+
url: this.pullRequestUrl || undefined,
|
|
127
|
+
title: this.pullRequestName || undefined,
|
|
128
|
+
}
|
|
129
|
+
: undefined;
|
|
130
|
+
},
|
|
52
131
|
};
|
|
@@ -1,7 +1,26 @@
|
|
|
1
|
-
import { CiType } from "@allurereport/core-api";
|
|
1
|
+
import { CiType, GitProvider } from "@allurereport/core-api";
|
|
2
2
|
import { getEnv } from "../utils.js";
|
|
3
|
+
const stripGitSuffix = (url) => url.replace(/\.git\/?$/i, "");
|
|
4
|
+
const getRepositoryUrl = () => {
|
|
5
|
+
const origin = (getEnv("BITBUCKET_GIT_HTTP_ORIGIN") || "").trim();
|
|
6
|
+
if (!origin) {
|
|
7
|
+
return "";
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
const url = new URL(origin);
|
|
11
|
+
url.username = "";
|
|
12
|
+
url.password = "";
|
|
13
|
+
url.pathname = stripGitSuffix(url.pathname).replace(/\/+$/, "");
|
|
14
|
+
url.search = "";
|
|
15
|
+
url.hash = "";
|
|
16
|
+
return url.toString().replace(/\/$/, "");
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return stripGitSuffix(origin).replace(/\/+$/, "");
|
|
20
|
+
}
|
|
21
|
+
};
|
|
3
22
|
export const getJobURL = () => {
|
|
4
|
-
const origin =
|
|
23
|
+
const origin = getRepositoryUrl();
|
|
5
24
|
return `${origin}/pipelines`;
|
|
6
25
|
};
|
|
7
26
|
export const bitbucket = {
|
|
@@ -38,10 +57,41 @@ export const bitbucket = {
|
|
|
38
57
|
if (!prId) {
|
|
39
58
|
return "";
|
|
40
59
|
}
|
|
41
|
-
const origin =
|
|
60
|
+
const origin = getRepositoryUrl();
|
|
61
|
+
if (!origin) {
|
|
62
|
+
return "";
|
|
63
|
+
}
|
|
42
64
|
return `${origin}/pull-requests/${prId}`;
|
|
43
65
|
},
|
|
44
66
|
get pullRequestName() {
|
|
45
67
|
return "";
|
|
46
68
|
},
|
|
69
|
+
get provider() {
|
|
70
|
+
return GitProvider.Bitbucket;
|
|
71
|
+
},
|
|
72
|
+
get repository() {
|
|
73
|
+
const repositorySlug = getEnv("BITBUCKET_REPO_FULL_NAME");
|
|
74
|
+
return repositorySlug
|
|
75
|
+
? {
|
|
76
|
+
slug: repositorySlug,
|
|
77
|
+
url: getRepositoryUrl() || undefined,
|
|
78
|
+
}
|
|
79
|
+
: undefined;
|
|
80
|
+
},
|
|
81
|
+
get sourceBranch() {
|
|
82
|
+
return getEnv("BITBUCKET_BRANCH") || this.jobRunBranch || undefined;
|
|
83
|
+
},
|
|
84
|
+
get targetBranch() {
|
|
85
|
+
return getEnv("BITBUCKET_PR_DESTINATION_BRANCH") || undefined;
|
|
86
|
+
},
|
|
87
|
+
get pullRequest() {
|
|
88
|
+
const prId = getEnv("BITBUCKET_PR_ID");
|
|
89
|
+
return prId
|
|
90
|
+
? {
|
|
91
|
+
id: prId,
|
|
92
|
+
url: this.pullRequestUrl || undefined,
|
|
93
|
+
title: this.pullRequestName || undefined,
|
|
94
|
+
}
|
|
95
|
+
: undefined;
|
|
96
|
+
},
|
|
47
97
|
};
|
package/dist/detectors/circle.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CiType } from "@allurereport/core-api";
|
|
2
|
+
import { parsePullRequestNumberFromUrl, resolveRepositoryFromGitUrl } from "../helpers/gitProvider.js";
|
|
2
3
|
import { getEnv, parseURLPath } from "../utils.js";
|
|
3
4
|
export const getBuildNumber = () => getEnv("CIRCLE_BUILD_NUM");
|
|
4
5
|
export const getJobRunURL = () => getEnv("CIRCLE_BUILD_URL");
|
|
@@ -7,6 +8,25 @@ const getJobURL = () => {
|
|
|
7
8
|
const buildNumber = getBuildNumber();
|
|
8
9
|
return jobRunURL.replace(`/${buildNumber}`, "");
|
|
9
10
|
};
|
|
11
|
+
const getRepository = () => {
|
|
12
|
+
const repositoryUrl = getEnv("CIRCLE_REPOSITORY_URL");
|
|
13
|
+
return repositoryUrl ? resolveRepositoryFromGitUrl(repositoryUrl) : undefined;
|
|
14
|
+
};
|
|
15
|
+
const getPullRequestUrl = () => {
|
|
16
|
+
const pullRequestUrl = getEnv("CIRCLE_PULL_REQUEST").trim();
|
|
17
|
+
if (pullRequestUrl) {
|
|
18
|
+
return pullRequestUrl;
|
|
19
|
+
}
|
|
20
|
+
return (getEnv("CIRCLE_PULL_REQUESTS")
|
|
21
|
+
.split(",")
|
|
22
|
+
.map((url) => url.trim())
|
|
23
|
+
.find(Boolean) ?? "");
|
|
24
|
+
};
|
|
25
|
+
const getPullRequestNumber = () => {
|
|
26
|
+
const pullRequestUrl = getPullRequestUrl();
|
|
27
|
+
const pullRequestNumber = pullRequestUrl ? parsePullRequestNumberFromUrl(pullRequestUrl) : undefined;
|
|
28
|
+
return pullRequestNumber || getEnv("CIRCLE_PR_NUMBER") || undefined;
|
|
29
|
+
};
|
|
10
30
|
export const circle = {
|
|
11
31
|
type: CiType.Circle,
|
|
12
32
|
get detected() {
|
|
@@ -26,7 +46,7 @@ export const circle = {
|
|
|
26
46
|
return getJobURL();
|
|
27
47
|
},
|
|
28
48
|
get jobName() {
|
|
29
|
-
const username = getEnv("CIRCLE_USERNAME");
|
|
49
|
+
const username = getEnv("CIRCLE_PROJECT_USERNAME") || getEnv("CIRCLE_USERNAME");
|
|
30
50
|
const reponame = getEnv("CIRCLE_PROJECT_REPONAME");
|
|
31
51
|
return `${username}/${reponame}`;
|
|
32
52
|
},
|
|
@@ -43,9 +63,35 @@ export const circle = {
|
|
|
43
63
|
return getEnv("CIRCLE_BRANCH");
|
|
44
64
|
},
|
|
45
65
|
get pullRequestUrl() {
|
|
46
|
-
return
|
|
66
|
+
return getPullRequestUrl();
|
|
47
67
|
},
|
|
48
68
|
get pullRequestName() {
|
|
49
69
|
return "";
|
|
50
70
|
},
|
|
71
|
+
get provider() {
|
|
72
|
+
return getRepository()?.provider;
|
|
73
|
+
},
|
|
74
|
+
get repository() {
|
|
75
|
+
const repository = getRepository();
|
|
76
|
+
return repository
|
|
77
|
+
? {
|
|
78
|
+
slug: repository.slug,
|
|
79
|
+
url: repository.url,
|
|
80
|
+
}
|
|
81
|
+
: undefined;
|
|
82
|
+
},
|
|
83
|
+
get sourceBranch() {
|
|
84
|
+
return getEnv("CIRCLE_BRANCH") || this.jobRunBranch || undefined;
|
|
85
|
+
},
|
|
86
|
+
get pullRequest() {
|
|
87
|
+
const pullRequestUrl = getPullRequestUrl();
|
|
88
|
+
const pullRequestNumber = getPullRequestNumber();
|
|
89
|
+
return pullRequestNumber
|
|
90
|
+
? {
|
|
91
|
+
id: pullRequestNumber,
|
|
92
|
+
url: this.pullRequestUrl || pullRequestUrl || undefined,
|
|
93
|
+
title: this.pullRequestName || undefined,
|
|
94
|
+
}
|
|
95
|
+
: undefined;
|
|
96
|
+
},
|
|
51
97
|
};
|
package/dist/detectors/drone.js
CHANGED
|
@@ -1,12 +1,54 @@
|
|
|
1
|
-
import { CiType } from "@allurereport/core-api";
|
|
1
|
+
import { CiType, GitProvider } from "@allurereport/core-api";
|
|
2
|
+
import { resolveRepositoryFromGitUrl } from "../helpers/gitProvider.js";
|
|
2
3
|
import { getEnv } from "../utils.js";
|
|
3
|
-
export const getJobRunUID = () => getEnv("
|
|
4
|
+
export const getJobRunUID = () => getEnv("DRONE_BUILD_NUMBER");
|
|
4
5
|
export const getJobRunURL = () => getEnv("DRONE_BUILD_LINK");
|
|
5
6
|
export const getJobURL = () => {
|
|
6
7
|
const jobRunURL = getJobRunURL();
|
|
7
8
|
const jobRunUID = getJobRunUID();
|
|
8
9
|
return jobRunURL.replace(jobRunUID, "");
|
|
9
10
|
};
|
|
11
|
+
const getRepository = () => {
|
|
12
|
+
const repoLink = getEnv("DRONE_REPO_LINK");
|
|
13
|
+
return repoLink ? resolveRepositoryFromGitUrl(repoLink) : undefined;
|
|
14
|
+
};
|
|
15
|
+
const normalizeRepositoryUrl = (url) => url
|
|
16
|
+
.trim()
|
|
17
|
+
.replace(/\.git\/?$/i, "")
|
|
18
|
+
.replace(/\/+$/, "");
|
|
19
|
+
const getPullRequestNumber = () => {
|
|
20
|
+
const pullRequestNumber = getEnv("DRONE_PULL_REQUEST").trim();
|
|
21
|
+
return pullRequestNumber && pullRequestNumber !== "0" ? pullRequestNumber : undefined;
|
|
22
|
+
};
|
|
23
|
+
const getPullRequestUrlForProvider = (provider, repositoryUrl, pullRequestNumber) => {
|
|
24
|
+
const normalizedRepositoryUrl = normalizeRepositoryUrl(repositoryUrl);
|
|
25
|
+
switch (provider) {
|
|
26
|
+
case GitProvider.Github:
|
|
27
|
+
return `${normalizedRepositoryUrl}/pull/${pullRequestNumber}`;
|
|
28
|
+
case GitProvider.Gitlab:
|
|
29
|
+
return `${normalizedRepositoryUrl}/-/merge_requests/${pullRequestNumber}`;
|
|
30
|
+
case GitProvider.Bitbucket:
|
|
31
|
+
return `${normalizedRepositoryUrl}/pull-requests/${pullRequestNumber}`;
|
|
32
|
+
default:
|
|
33
|
+
return "";
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const getSourceBranch = () => {
|
|
37
|
+
if (getEnv("DRONE_TAG")) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
const sourceBranch = getEnv("DRONE_SOURCE_BRANCH");
|
|
41
|
+
if (sourceBranch) {
|
|
42
|
+
return sourceBranch;
|
|
43
|
+
}
|
|
44
|
+
return getPullRequestNumber() ? undefined : getEnv("DRONE_BRANCH") || undefined;
|
|
45
|
+
};
|
|
46
|
+
const getTargetBranch = () => {
|
|
47
|
+
if (getEnv("DRONE_TAG")) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
return getEnv("DRONE_TARGET_BRANCH") || (getPullRequestNumber() ? getEnv("DRONE_BRANCH") : "") || undefined;
|
|
51
|
+
};
|
|
10
52
|
export const drone = {
|
|
11
53
|
type: CiType.Drone,
|
|
12
54
|
get detected() {
|
|
@@ -34,17 +76,24 @@ export const drone = {
|
|
|
34
76
|
return getEnv("DRONE_BUILD_NUMBER");
|
|
35
77
|
},
|
|
36
78
|
get jobRunBranch() {
|
|
37
|
-
return getEnv("DRONE_BRANCH");
|
|
79
|
+
return getEnv("DRONE_TAG") ? "" : getEnv("DRONE_BRANCH");
|
|
38
80
|
},
|
|
39
81
|
get pullRequestUrl() {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
82
|
+
const pullRequestNumber = getPullRequestNumber();
|
|
83
|
+
if (!pullRequestNumber) {
|
|
84
|
+
return "";
|
|
85
|
+
}
|
|
86
|
+
const repository = getRepository();
|
|
87
|
+
if (repository) {
|
|
88
|
+
return getPullRequestUrlForProvider(repository.provider, repository.url, pullRequestNumber);
|
|
89
|
+
}
|
|
90
|
+
const githubServer = normalizeRepositoryUrl(getEnv("DRONE_GITHUB_SERVER") || "");
|
|
91
|
+
const gitlabServer = normalizeRepositoryUrl(getEnv("DRONE_GITLAB_SERVER") || "");
|
|
92
|
+
const repoLink = normalizeRepositoryUrl(getEnv("DRONE_REPO_LINK") || "");
|
|
93
|
+
if (githubServer && repoLink.startsWith(githubServer)) {
|
|
45
94
|
return `${repoLink}/pull/${pullRequestNumber}`;
|
|
46
95
|
}
|
|
47
|
-
if (repoLink.startsWith(gitlabServer)) {
|
|
96
|
+
if (gitlabServer && repoLink.startsWith(gitlabServer)) {
|
|
48
97
|
return `${repoLink}/-/merge_requests/${pullRequestNumber}`;
|
|
49
98
|
}
|
|
50
99
|
return "";
|
|
@@ -52,4 +101,32 @@ export const drone = {
|
|
|
52
101
|
get pullRequestName() {
|
|
53
102
|
return getEnv("DRONE_PULL_REQUEST_TITLE");
|
|
54
103
|
},
|
|
104
|
+
get provider() {
|
|
105
|
+
return getRepository()?.provider;
|
|
106
|
+
},
|
|
107
|
+
get repository() {
|
|
108
|
+
const repository = getRepository();
|
|
109
|
+
return repository
|
|
110
|
+
? {
|
|
111
|
+
slug: repository.slug,
|
|
112
|
+
url: repository.url,
|
|
113
|
+
}
|
|
114
|
+
: undefined;
|
|
115
|
+
},
|
|
116
|
+
get sourceBranch() {
|
|
117
|
+
return getSourceBranch();
|
|
118
|
+
},
|
|
119
|
+
get targetBranch() {
|
|
120
|
+
return getTargetBranch();
|
|
121
|
+
},
|
|
122
|
+
get pullRequest() {
|
|
123
|
+
const pullRequestNumber = getPullRequestNumber();
|
|
124
|
+
return pullRequestNumber
|
|
125
|
+
? {
|
|
126
|
+
id: pullRequestNumber,
|
|
127
|
+
url: this.pullRequestUrl || undefined,
|
|
128
|
+
title: this.pullRequestName || getEnv("DRONE_PULL_REQUEST_TITLE") || undefined,
|
|
129
|
+
}
|
|
130
|
+
: undefined;
|
|
131
|
+
},
|
|
55
132
|
};
|
package/dist/detectors/github.js
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
import { join } from "node:path/posix";
|
|
2
|
-
import { CiType } from "@allurereport/core-api";
|
|
2
|
+
import { CiType, GitProvider } from "@allurereport/core-api";
|
|
3
|
+
import { resolveGithubPullRequestNumber } from "../helpers/github.js";
|
|
4
|
+
import { stripRefsHeads } from "../helpers/gitProvider.js";
|
|
3
5
|
import { getEnv } from "../utils.js";
|
|
4
|
-
const pullRequestSuffixRe = /\/merge$/;
|
|
5
6
|
const getBaseURL = () => getEnv("GITHUB_SERVER_URL");
|
|
6
7
|
const getRunID = () => getEnv("GITHUB_RUN_ID");
|
|
7
8
|
const getWorkflow = () => getEnv("GITHUB_WORKFLOW");
|
|
8
9
|
const getRepo = () => getEnv("GITHUB_REPOSITORY");
|
|
10
|
+
const isTagRef = () => getEnv("GITHUB_REF_TYPE") === "tag" || getEnv("GITHUB_REF").startsWith("refs/tags/");
|
|
11
|
+
const getBranchFromRef = () => {
|
|
12
|
+
const ref = getEnv("GITHUB_REF");
|
|
13
|
+
if (ref.startsWith("refs/heads/")) {
|
|
14
|
+
return stripRefsHeads(ref);
|
|
15
|
+
}
|
|
16
|
+
if (ref.startsWith("refs/tags/") || ref.startsWith("refs/pull/")) {
|
|
17
|
+
return "";
|
|
18
|
+
}
|
|
19
|
+
return getEnv("GITHUB_REF_TYPE") === "branch" ? getEnv("GITHUB_REF_NAME") : "";
|
|
20
|
+
};
|
|
21
|
+
const getSourceBranch = () => {
|
|
22
|
+
const headRef = getEnv("GITHUB_HEAD_REF");
|
|
23
|
+
if (headRef) {
|
|
24
|
+
return headRef;
|
|
25
|
+
}
|
|
26
|
+
return isTagRef() ? "" : getBranchFromRef();
|
|
27
|
+
};
|
|
9
28
|
export const github = {
|
|
10
29
|
type: CiType.Github,
|
|
11
30
|
get detected() {
|
|
@@ -37,25 +56,52 @@ export const github = {
|
|
|
37
56
|
return `${job} #${runNumber}`;
|
|
38
57
|
},
|
|
39
58
|
get jobRunBranch() {
|
|
40
|
-
return (
|
|
59
|
+
return getSourceBranch();
|
|
41
60
|
},
|
|
42
61
|
get pullRequestUrl() {
|
|
43
|
-
const
|
|
44
|
-
if (!
|
|
62
|
+
const pullRequestNumber = resolveGithubPullRequestNumber();
|
|
63
|
+
if (!pullRequestNumber) {
|
|
45
64
|
return "";
|
|
46
65
|
}
|
|
47
|
-
const pullRequestNumber = refName.replace(pullRequestSuffixRe, "");
|
|
48
66
|
const serverUrl = getEnv("GITHUB_SERVER_URL");
|
|
49
67
|
const repo = getRepo();
|
|
50
68
|
const pathname = join(repo, "pull", pullRequestNumber);
|
|
51
69
|
return new URL(pathname, serverUrl).toString();
|
|
52
70
|
},
|
|
53
71
|
get pullRequestName() {
|
|
54
|
-
const
|
|
55
|
-
if (!
|
|
72
|
+
const pullRequestNumber = resolveGithubPullRequestNumber();
|
|
73
|
+
if (!pullRequestNumber) {
|
|
56
74
|
return "";
|
|
57
75
|
}
|
|
58
|
-
const pullRequestNumber = refName.replace(pullRequestSuffixRe, "");
|
|
59
76
|
return `Pull request #${pullRequestNumber}`;
|
|
60
77
|
},
|
|
78
|
+
get provider() {
|
|
79
|
+
return GitProvider.Github;
|
|
80
|
+
},
|
|
81
|
+
get repository() {
|
|
82
|
+
const repositorySlug = getEnv("GITHUB_REPOSITORY");
|
|
83
|
+
const serverUrl = getEnv("GITHUB_SERVER_URL");
|
|
84
|
+
return repositorySlug
|
|
85
|
+
? {
|
|
86
|
+
slug: repositorySlug,
|
|
87
|
+
url: serverUrl ? `${serverUrl}/${repositorySlug}` : undefined,
|
|
88
|
+
}
|
|
89
|
+
: undefined;
|
|
90
|
+
},
|
|
91
|
+
get sourceBranch() {
|
|
92
|
+
return getSourceBranch() || undefined;
|
|
93
|
+
},
|
|
94
|
+
get targetBranch() {
|
|
95
|
+
return getEnv("GITHUB_BASE_REF") || undefined;
|
|
96
|
+
},
|
|
97
|
+
get pullRequest() {
|
|
98
|
+
const pullRequestId = resolveGithubPullRequestNumber();
|
|
99
|
+
return pullRequestId
|
|
100
|
+
? {
|
|
101
|
+
id: pullRequestId,
|
|
102
|
+
url: this.pullRequestUrl || undefined,
|
|
103
|
+
title: this.pullRequestName || undefined,
|
|
104
|
+
}
|
|
105
|
+
: undefined;
|
|
106
|
+
},
|
|
61
107
|
};
|
package/dist/detectors/gitlab.js
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
import { CiType } from "@allurereport/core-api";
|
|
1
|
+
import { CiType, GitProvider } from "@allurereport/core-api";
|
|
2
2
|
import { getEnv } from "../utils.js";
|
|
3
|
+
const getMergeRequestProjectUrl = () => getEnv("CI_MERGE_REQUEST_PROJECT_URL") || getEnv("CI_PROJECT_URL");
|
|
4
|
+
const isTagPipeline = () => Boolean(getEnv("CI_COMMIT_TAG"));
|
|
5
|
+
const getSourceBranch = () => {
|
|
6
|
+
if (isTagPipeline()) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
return (getEnv("CI_MERGE_REQUEST_SOURCE_BRANCH_NAME") ||
|
|
10
|
+
getEnv("CI_COMMIT_BRANCH") ||
|
|
11
|
+
getEnv("CI_COMMIT_REF_NAME") ||
|
|
12
|
+
undefined);
|
|
13
|
+
};
|
|
3
14
|
export const gitlab = {
|
|
4
15
|
type: CiType.Gitlab,
|
|
5
16
|
get detected() {
|
|
@@ -27,17 +38,45 @@ export const gitlab = {
|
|
|
27
38
|
return getEnv("CI_PIPELINE_ID");
|
|
28
39
|
},
|
|
29
40
|
get jobRunBranch() {
|
|
30
|
-
return
|
|
41
|
+
return getSourceBranch() || "";
|
|
31
42
|
},
|
|
32
43
|
get pullRequestUrl() {
|
|
33
44
|
const mergeRequestIID = getEnv("CI_MERGE_REQUEST_IID");
|
|
34
45
|
if (!mergeRequestIID) {
|
|
35
46
|
return "";
|
|
36
47
|
}
|
|
37
|
-
const projectUrl =
|
|
38
|
-
return `${projectUrl}/-/merge_requests/${mergeRequestIID}
|
|
48
|
+
const projectUrl = getMergeRequestProjectUrl().replace(/\/+$/, "");
|
|
49
|
+
return projectUrl ? `${projectUrl}/-/merge_requests/${mergeRequestIID}` : "";
|
|
39
50
|
},
|
|
40
51
|
get pullRequestName() {
|
|
41
52
|
return getEnv("CI_MERGE_REQUEST_TITLE");
|
|
42
53
|
},
|
|
54
|
+
get provider() {
|
|
55
|
+
return GitProvider.Gitlab;
|
|
56
|
+
},
|
|
57
|
+
get repository() {
|
|
58
|
+
const projectPath = getEnv("CI_PROJECT_PATH");
|
|
59
|
+
return projectPath
|
|
60
|
+
? {
|
|
61
|
+
slug: projectPath,
|
|
62
|
+
url: getEnv("CI_PROJECT_URL") || undefined,
|
|
63
|
+
}
|
|
64
|
+
: undefined;
|
|
65
|
+
},
|
|
66
|
+
get sourceBranch() {
|
|
67
|
+
return getSourceBranch();
|
|
68
|
+
},
|
|
69
|
+
get targetBranch() {
|
|
70
|
+
return getEnv("CI_MERGE_REQUEST_TARGET_BRANCH_NAME") || undefined;
|
|
71
|
+
},
|
|
72
|
+
get pullRequest() {
|
|
73
|
+
const mergeRequestIid = getEnv("CI_MERGE_REQUEST_IID");
|
|
74
|
+
return mergeRequestIid
|
|
75
|
+
? {
|
|
76
|
+
id: mergeRequestIid,
|
|
77
|
+
url: this.pullRequestUrl || undefined,
|
|
78
|
+
title: getEnv("CI_MERGE_REQUEST_TITLE") || this.pullRequestName || undefined,
|
|
79
|
+
}
|
|
80
|
+
: undefined;
|
|
81
|
+
},
|
|
43
82
|
};
|
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import { CiType } from "@allurereport/core-api";
|
|
2
|
+
import { resolveRepositoryFromGitUrl } from "../helpers/gitProvider.js";
|
|
2
3
|
import { getEnv, getReponameFromRepoUrl } from "../utils.js";
|
|
4
|
+
const getRepository = () => {
|
|
5
|
+
const gitUrl = getEnv("GIT_URL");
|
|
6
|
+
return gitUrl ? resolveRepositoryFromGitUrl(gitUrl) : undefined;
|
|
7
|
+
};
|
|
8
|
+
const isTagBuild = () => Boolean(getEnv("TAG_NAME"));
|
|
9
|
+
const getGitPluginBranch = () => {
|
|
10
|
+
const localBranch = (getEnv("GIT_LOCAL_BRANCH") || "").trim();
|
|
11
|
+
if (localBranch) {
|
|
12
|
+
return localBranch;
|
|
13
|
+
}
|
|
14
|
+
const gitBranch = (getEnv("GIT_BRANCH") || "").trim();
|
|
15
|
+
if (!gitBranch) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
const normalizedBranch = gitBranch.replace(/^refs\/heads\//, "");
|
|
19
|
+
const remoteBranchMatch = normalizedBranch.match(/^(?:refs\/remotes\/|remotes\/)?[^/]+\/(.+)$/);
|
|
20
|
+
return remoteBranchMatch?.[1] ?? normalizedBranch;
|
|
21
|
+
};
|
|
22
|
+
const getBranchName = () => {
|
|
23
|
+
if (isTagBuild()) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
return getEnv("BRANCH_NAME") || getGitPluginBranch();
|
|
27
|
+
};
|
|
3
28
|
export const jenkins = {
|
|
4
29
|
type: CiType.Jenkins,
|
|
5
30
|
get detected() {
|
|
@@ -31,7 +56,7 @@ export const jenkins = {
|
|
|
31
56
|
return getEnv("BUILD_DISPLAY_NAME");
|
|
32
57
|
},
|
|
33
58
|
get jobRunBranch() {
|
|
34
|
-
return
|
|
59
|
+
return getBranchName() ?? "";
|
|
35
60
|
},
|
|
36
61
|
get pullRequestUrl() {
|
|
37
62
|
return getEnv("CHANGE_URL");
|
|
@@ -39,4 +64,35 @@ export const jenkins = {
|
|
|
39
64
|
get pullRequestName() {
|
|
40
65
|
return getEnv("CHANGE_TITLE");
|
|
41
66
|
},
|
|
67
|
+
get provider() {
|
|
68
|
+
return getRepository()?.provider;
|
|
69
|
+
},
|
|
70
|
+
get repository() {
|
|
71
|
+
const repository = getRepository();
|
|
72
|
+
return repository
|
|
73
|
+
? {
|
|
74
|
+
slug: repository.slug,
|
|
75
|
+
url: repository.url,
|
|
76
|
+
}
|
|
77
|
+
: undefined;
|
|
78
|
+
},
|
|
79
|
+
get sourceBranch() {
|
|
80
|
+
if (isTagBuild()) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
return getEnv("CHANGE_BRANCH") || getBranchName();
|
|
84
|
+
},
|
|
85
|
+
get targetBranch() {
|
|
86
|
+
return isTagBuild() ? undefined : getEnv("CHANGE_TARGET") || undefined;
|
|
87
|
+
},
|
|
88
|
+
get pullRequest() {
|
|
89
|
+
const changeId = getEnv("CHANGE_ID");
|
|
90
|
+
return changeId
|
|
91
|
+
? {
|
|
92
|
+
id: changeId,
|
|
93
|
+
url: this.pullRequestUrl || getEnv("CHANGE_URL") || undefined,
|
|
94
|
+
title: this.pullRequestName || getEnv("CHANGE_TITLE") || undefined,
|
|
95
|
+
}
|
|
96
|
+
: undefined;
|
|
97
|
+
},
|
|
42
98
|
};
|
package/dist/detectors/local.js
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import { basename } from "node:path";
|
|
3
3
|
import { CiType } from "@allurereport/core-api";
|
|
4
|
+
import { resolveRepositoryFromGitUrl } from "../helpers/gitProvider.js";
|
|
5
|
+
const readGitRemoteUrl = () => {
|
|
6
|
+
const output = spawnSync("git", ["remote", "get-url", "origin"]);
|
|
7
|
+
if (output.error) {
|
|
8
|
+
return "";
|
|
9
|
+
}
|
|
10
|
+
return output.stdout.toString().trim();
|
|
11
|
+
};
|
|
12
|
+
const getRepository = () => {
|
|
13
|
+
const remoteUrl = readGitRemoteUrl();
|
|
14
|
+
return remoteUrl ? resolveRepositoryFromGitUrl(remoteUrl) : undefined;
|
|
15
|
+
};
|
|
4
16
|
export const local = {
|
|
5
17
|
type: CiType.Local,
|
|
6
18
|
get detected() {
|
|
@@ -44,5 +56,20 @@ export const local = {
|
|
|
44
56
|
get pullRequestName() {
|
|
45
57
|
return "";
|
|
46
58
|
},
|
|
59
|
+
get provider() {
|
|
60
|
+
return getRepository()?.provider;
|
|
61
|
+
},
|
|
62
|
+
get repository() {
|
|
63
|
+
const repository = getRepository();
|
|
64
|
+
return repository
|
|
65
|
+
? {
|
|
66
|
+
slug: repository.slug,
|
|
67
|
+
url: repository.url,
|
|
68
|
+
}
|
|
69
|
+
: undefined;
|
|
70
|
+
},
|
|
71
|
+
get sourceBranch() {
|
|
72
|
+
return this.jobRunBranch || undefined;
|
|
73
|
+
},
|
|
47
74
|
};
|
|
48
75
|
export const isLocalCiDescriptor = (ci) => ci.type === CiType.Local;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { GitProvider } from "@allurereport/core-api";
|
|
2
|
+
export declare const stripRefsHeads: (ref: string) => string;
|
|
3
|
+
export declare const parsePullRequestNumberFromUrl: (pullRequestUrl: string) => string | undefined;
|
|
4
|
+
export declare const hostMatchesProvider: (host: string, provider: GitProvider) => boolean;
|
|
5
|
+
export declare const normalizeGitRemoteUrl: (remote: string) => string | undefined;
|
|
6
|
+
export declare const inferGitProviderFromUrl: (remote: string) => GitProvider | undefined;
|
|
7
|
+
export declare const parseRepositorySlugFromUrl: (remote: string, provider: GitProvider) => string | undefined;
|
|
8
|
+
export type ResolvedGitRepository = {
|
|
9
|
+
provider: GitProvider;
|
|
10
|
+
slug: string;
|
|
11
|
+
url: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const resolveRepositoryFromGitUrl: (remote: string) => ResolvedGitRepository | undefined;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { GitProvider } from "@allurereport/core-api";
|
|
2
|
+
const stripGitSuffix = (url) => url.replace(/\.git\/?$/i, "");
|
|
3
|
+
export const stripRefsHeads = (ref) => ref.replace(/^refs\/heads\//, "");
|
|
4
|
+
export const parsePullRequestNumberFromUrl = (pullRequestUrl) => {
|
|
5
|
+
const trimmed = pullRequestUrl.trim();
|
|
6
|
+
if (!trimmed) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
const match = trimmed.match(/\/pull\/(\d+)\/?$/i) ??
|
|
10
|
+
trimmed.match(/\/merge_requests\/(\d+)\/?$/i) ??
|
|
11
|
+
trimmed.match(/\/pull-requests\/(\d+)\/?$/i);
|
|
12
|
+
return match?.[1];
|
|
13
|
+
};
|
|
14
|
+
export const hostMatchesProvider = (host, provider) => {
|
|
15
|
+
const normalizedHost = host.toLowerCase();
|
|
16
|
+
switch (provider) {
|
|
17
|
+
case GitProvider.Github:
|
|
18
|
+
return (normalizedHost === "github.com" ||
|
|
19
|
+
normalizedHost.endsWith(".github.com") ||
|
|
20
|
+
normalizedHost.startsWith("github."));
|
|
21
|
+
case GitProvider.Gitlab:
|
|
22
|
+
return (normalizedHost === "gitlab.com" ||
|
|
23
|
+
normalizedHost.endsWith(".gitlab.com") ||
|
|
24
|
+
normalizedHost.startsWith("gitlab."));
|
|
25
|
+
case GitProvider.Bitbucket:
|
|
26
|
+
return (normalizedHost === "bitbucket.org" ||
|
|
27
|
+
normalizedHost.endsWith(".bitbucket.org") ||
|
|
28
|
+
normalizedHost.startsWith("bitbucket."));
|
|
29
|
+
default:
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
export const normalizeGitRemoteUrl = (remote) => {
|
|
34
|
+
const trimmed = remote.trim();
|
|
35
|
+
if (!trimmed) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
if (trimmed.startsWith("http://") || trimmed.startsWith("https://")) {
|
|
39
|
+
return trimmed;
|
|
40
|
+
}
|
|
41
|
+
if (trimmed.startsWith("ssh://")) {
|
|
42
|
+
try {
|
|
43
|
+
const parsed = new URL(trimmed);
|
|
44
|
+
return `https://${parsed.hostname}${parsed.pathname}`;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const scpMatch = /^[^@]+@([^:]+):(.+)$/.exec(trimmed);
|
|
51
|
+
if (scpMatch) {
|
|
52
|
+
return `https://${scpMatch[1]}/${scpMatch[2].replace(/^\//, "")}`;
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
};
|
|
56
|
+
export const inferGitProviderFromUrl = (remote) => {
|
|
57
|
+
const normalized = normalizeGitRemoteUrl(remote);
|
|
58
|
+
if (!normalized) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const host = new URL(normalized).hostname.toLowerCase();
|
|
63
|
+
for (const provider of [GitProvider.Github, GitProvider.Gitlab, GitProvider.Bitbucket]) {
|
|
64
|
+
if (hostMatchesProvider(host, provider)) {
|
|
65
|
+
return provider;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
};
|
|
74
|
+
export const parseRepositorySlugFromUrl = (remote, provider) => {
|
|
75
|
+
const normalized = normalizeGitRemoteUrl(remote);
|
|
76
|
+
if (!normalized) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const pathname = new URL(normalized).pathname.replace(/^\/+/, "").replace(/\.git\/?$/i, "");
|
|
81
|
+
if (!pathname) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
85
|
+
if (provider === GitProvider.Github || provider === GitProvider.Bitbucket) {
|
|
86
|
+
if (segments.length < 2) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
return `${segments[0]}/${segments[1]}`;
|
|
90
|
+
}
|
|
91
|
+
return pathname;
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
export const resolveRepositoryFromGitUrl = (remote) => {
|
|
98
|
+
const provider = inferGitProviderFromUrl(remote);
|
|
99
|
+
if (!provider) {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
const slug = parseRepositorySlugFromUrl(remote, provider);
|
|
103
|
+
if (!slug) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
const normalized = normalizeGitRemoteUrl(remote);
|
|
107
|
+
if (!normalized) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
provider,
|
|
112
|
+
slug,
|
|
113
|
+
url: stripGitSuffix(normalized),
|
|
114
|
+
};
|
|
115
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { getEnv } from "../utils.js";
|
|
3
|
+
const PULL_REQUEST_REF_NAME_RE = /^(\d+)\/merge$/;
|
|
4
|
+
const PULL_REQUEST_MERGE_REF_RE = /^refs\/pull\/(\d+)\/merge$/;
|
|
5
|
+
const normalizePullRequestNumber = (value) => {
|
|
6
|
+
if (value === undefined || value === null) {
|
|
7
|
+
return "";
|
|
8
|
+
}
|
|
9
|
+
return String(value);
|
|
10
|
+
};
|
|
11
|
+
export const parsePullRequestNumberFromEventJson = (content) => {
|
|
12
|
+
try {
|
|
13
|
+
const event = JSON.parse(content);
|
|
14
|
+
return normalizePullRequestNumber(event?.number ?? event?.pull_request?.number);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return "";
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const readPullRequestNumberFromEventPath = () => {
|
|
21
|
+
const eventPath = getEnv("GITHUB_EVENT_PATH");
|
|
22
|
+
if (!eventPath) {
|
|
23
|
+
return "";
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const content = readFileSync(eventPath, "utf-8");
|
|
27
|
+
return parsePullRequestNumberFromEventJson(content);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return "";
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
export const resolveGithubPullRequestNumber = () => {
|
|
34
|
+
const refName = getEnv("GITHUB_REF_NAME") || "";
|
|
35
|
+
const refNameMatch = refName.match(PULL_REQUEST_REF_NAME_RE);
|
|
36
|
+
if (refNameMatch) {
|
|
37
|
+
return refNameMatch[1];
|
|
38
|
+
}
|
|
39
|
+
const githubRef = getEnv("GITHUB_REF") || "";
|
|
40
|
+
const mergeRefMatch = githubRef.match(PULL_REQUEST_MERGE_REF_RE);
|
|
41
|
+
if (mergeRefMatch) {
|
|
42
|
+
return mergeRefMatch[1];
|
|
43
|
+
}
|
|
44
|
+
const headRef = getEnv("GITHUB_HEAD_REF");
|
|
45
|
+
const baseRef = getEnv("GITHUB_BASE_REF");
|
|
46
|
+
if (headRef && baseRef) {
|
|
47
|
+
return readPullRequestNumberFromEventPath();
|
|
48
|
+
}
|
|
49
|
+
return "";
|
|
50
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allurereport/ci",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.13.0",
|
|
4
4
|
"description": "Utilities set to get useful report data from different CI",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"allure",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"lint:fix": "oxlint --import-plugin --fix src test features stories"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@allurereport/core-api": "3.
|
|
33
|
+
"@allurereport/core-api": "3.13.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^20",
|