@catladder/cli 0.0.0-next-883523ef → 0.0.0-next-d71e41ba
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/apps/cli/src/catci.js +12 -0
- package/dist/apps/cli/src/catci.js.map +1 -1
- package/dist/apps/cli/src/release/changesetCheck.d.ts +35 -0
- package/dist/apps/cli/src/release/changesetCheck.js +31 -0
- package/dist/apps/cli/src/release/changesetCheck.js.map +1 -0
- package/dist/apps/cli/src/release/changesetCheckJob.d.ts +2 -0
- package/dist/apps/cli/src/release/changesetCheckJob.js +169 -0
- package/dist/apps/cli/src/release/changesetCheckJob.js.map +1 -0
- package/dist/apps/cli/src/release/changesetsReleaseJob.d.ts +2 -0
- package/dist/apps/cli/src/release/changesetsReleaseJob.js +43 -52
- package/dist/apps/cli/src/release/changesetsReleaseJob.js.map +1 -1
- package/dist/apps/cli/src/release/releaseGit.d.ts +9 -0
- package/dist/apps/cli/src/release/releaseGit.js +49 -0
- package/dist/apps/cli/src/release/releaseGit.js.map +1 -0
- package/dist/bundles/catci/index.js +4 -4
- package/dist/bundles/catenv/index.js +109 -4
- package/dist/bundles/cli/index.js +109 -4
- package/dist/bundles/runner-images/changesets/scripts/changesetCheck +23 -0
- package/dist/bundles/skills/catladder-releases/SKILL.md +31 -2
- package/dist/packages/pipeline/src/backends/github/GithubBackend.js +3 -0
- package/dist/packages/pipeline/src/backends/github/GithubBackend.js.map +1 -1
- package/dist/packages/pipeline/src/backends/github/githubReleaseJobs.d.ts +7 -0
- package/dist/packages/pipeline/src/backends/github/githubReleaseJobs.js +75 -4
- package/dist/packages/pipeline/src/backends/github/githubReleaseJobs.js.map +1 -1
- package/dist/packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.d.ts +26 -4
- package/dist/packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.js +29 -0
- package/dist/packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.js.map +1 -1
- package/dist/packages/pipeline/src/release/index.d.ts +12 -0
- package/dist/packages/pipeline/src/release/index.js +2 -0
- package/dist/packages/pipeline/src/release/index.js.map +1 -1
- package/dist/packages/pipeline/src/types/github-types.d.ts +1 -0
- package/dist/runner-images/changesets/scripts/changesetCheck +23 -0
- package/dist/skills/catladder-releases/SKILL.md +31 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/catci.ts +14 -0
- package/src/release/__tests__/changesetCheck.test.ts +69 -0
- package/src/release/changesetCheck.ts +82 -0
- package/src/release/changesetCheckJob.ts +199 -0
- package/src/release/changesetsReleaseJob.ts +36 -48
- package/src/release/releaseGit.ts +47 -0
|
@@ -16,6 +16,7 @@ const rest_1 = require("@gitbeaker/rest");
|
|
|
16
16
|
const evaluateSecurityAudit_1 = require("./security/evaluateSecurityAudit");
|
|
17
17
|
const createSecurityAuditMergeRequest_1 = require("./security/createSecurityAuditMergeRequest");
|
|
18
18
|
const changesetsReleaseJob_1 = require("./release/changesetsReleaseJob");
|
|
19
|
+
const changesetCheckJob_1 = require("./release/changesetCheckJob");
|
|
19
20
|
const npmPublishJob_1 = require("./publish/npmPublishJob");
|
|
20
21
|
const GITLAB_HOST = "https://git.panter.ch";
|
|
21
22
|
const USAGE = `catci — catladder CI companion
|
|
@@ -35,6 +36,12 @@ usage:
|
|
|
35
36
|
from the last v* tag, writes the changelog, commits, tags and
|
|
36
37
|
pushes (no-op when no changesets are pending)
|
|
37
38
|
|
|
39
|
+
catci release changeset-check
|
|
40
|
+
MR/PR pipelines: reports which changesets the merge request adds,
|
|
41
|
+
what is pending and what version merging would release (job log,
|
|
42
|
+
changeset-report.md, sticky MR/PR comment where a token allows);
|
|
43
|
+
exits 1 when the merge request adds no changeset
|
|
44
|
+
|
|
38
45
|
catci release dispatch-tagged-workflow <tag>
|
|
39
46
|
github only: dispatches the generated taggedRelease workflow for
|
|
40
47
|
the tag (tags pushed with the job token don't trigger it)
|
|
@@ -109,6 +116,11 @@ const main = async () => {
|
|
|
109
116
|
if (group === "release" && command === "changesets" && args.length === 0) {
|
|
110
117
|
return (0, changesetsReleaseJob_1.changesetsReleaseJob)();
|
|
111
118
|
}
|
|
119
|
+
if (group === "release" &&
|
|
120
|
+
command === "changeset-check" &&
|
|
121
|
+
args.length === 0) {
|
|
122
|
+
return (0, changesetCheckJob_1.changesetCheckJob)();
|
|
123
|
+
}
|
|
112
124
|
if (group === "release" &&
|
|
113
125
|
command === "dispatch-tagged-workflow" &&
|
|
114
126
|
args.length === 1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catci.js","sourceRoot":"","sources":["../../../../src/catci.ts"],"names":[],"mappings":";;AAAA;;;;;;;;;;;GAWG;AACH,0CAAyC;AACzC,4EAG0C;AAC1C,gGAGoD;AACpD,yEAGwC;AACxC,2DAA6E;AAE7E,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAE5C,MAAM,KAAK,GAAG;;;;kBAII,0DAAwB;;;;kBAIxB,0DAAwB
|
|
1
|
+
{"version":3,"file":"catci.js","sourceRoot":"","sources":["../../../../src/catci.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pure logic of the changeset check (run in MR/PR pipelines by catci):
|
|
3
|
+
* given the changesets added by the merge request and everything
|
|
4
|
+
* pending on the branch, render the markdown report shown as job
|
|
5
|
+
* output, exposed artifact and sticky MR/PR comment.
|
|
6
|
+
*/
|
|
7
|
+
import type { Changeset } from "./changesets";
|
|
8
|
+
/**
|
|
9
|
+
* identifies the sticky comment across pushes: the check finds the
|
|
10
|
+
* existing comment carrying this marker and updates it in place
|
|
11
|
+
* instead of posting a new one
|
|
12
|
+
*/
|
|
13
|
+
export declare const CHANGESET_CHECK_MARKER = "<!-- catladder-changeset-check -->";
|
|
14
|
+
export type ChangesetCheckInput = {
|
|
15
|
+
/**
|
|
16
|
+
* file names of changesets ADDED by this merge request (relative to
|
|
17
|
+
* `.changeset/`)
|
|
18
|
+
*/
|
|
19
|
+
addedFiles: string[];
|
|
20
|
+
/**
|
|
21
|
+
* all changesets pending on this branch (added here or merged
|
|
22
|
+
* earlier and not yet released)
|
|
23
|
+
*/
|
|
24
|
+
pending: Changeset[];
|
|
25
|
+
lastTag: string | null;
|
|
26
|
+
/** platform wording: "merge request" (gitlab) or "pull request" (github) */
|
|
27
|
+
requestLabel: string;
|
|
28
|
+
};
|
|
29
|
+
export type ChangesetCheckResult = {
|
|
30
|
+
/** whether this merge request adds at least one changeset */
|
|
31
|
+
addsChangeset: boolean;
|
|
32
|
+
/** the full report, marker included (comment + artifact body) */
|
|
33
|
+
markdown: string;
|
|
34
|
+
};
|
|
35
|
+
export declare const runChangesetCheck: ({ addedFiles, pending, lastTag, requestLabel, }: ChangesetCheckInput) => ChangesetCheckResult;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runChangesetCheck = exports.CHANGESET_CHECK_MARKER = void 0;
|
|
4
|
+
const changesets_1 = require("./changesets");
|
|
5
|
+
/**
|
|
6
|
+
* identifies the sticky comment across pushes: the check finds the
|
|
7
|
+
* existing comment carrying this marker and updates it in place
|
|
8
|
+
* instead of posting a new one
|
|
9
|
+
*/
|
|
10
|
+
exports.CHANGESET_CHECK_MARKER = "<!-- catladder-changeset-check -->";
|
|
11
|
+
const runChangesetCheck = ({ addedFiles, pending, lastTag, requestLabel, }) => {
|
|
12
|
+
const addsChangeset = addedFiles.length > 0;
|
|
13
|
+
const lines = [exports.CHANGESET_CHECK_MARKER, "## 🦋 Changeset check", ""];
|
|
14
|
+
if (addsChangeset) {
|
|
15
|
+
lines.push(`✅ This ${requestLabel} adds ${addedFiles.length} changeset${addedFiles.length === 1 ? "" : "s"}: ${addedFiles.map((f) => `\`${f}\``).join(", ")}`);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
lines.push(`⚠️ **This ${requestLabel} adds no changeset.** If the change is user-facing it will be missing from the next release's changelog — add \`.changeset/<name>.md\` (or run \`yarn changeset\`). For docs/chore changes this warning can be ignored.`);
|
|
19
|
+
}
|
|
20
|
+
lines.push("");
|
|
21
|
+
if (pending.length === 0) {
|
|
22
|
+
lines.push("No changesets are pending — merging will **not** trigger a release.");
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const version = (0, changesets_1.getNextVersion)(lastTag, (0, changesets_1.maxBump)(pending.map((c) => c.bump)));
|
|
26
|
+
lines.push(`${pending.length} changeset${pending.length === 1 ? " is" : "s are"} pending after merge — the next release will be **v${version}**${lastTag ? ` (from ${lastTag})` : " (first release)"}:`, "", "<details><summary>Changelog preview</summary>", "", (0, changesets_1.renderChangelogEntries)(pending), "", "</details>");
|
|
27
|
+
}
|
|
28
|
+
return { addsChangeset, markdown: lines.join("\n") };
|
|
29
|
+
};
|
|
30
|
+
exports.runChangesetCheck = runChangesetCheck;
|
|
31
|
+
//# sourceMappingURL=changesetCheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changesetCheck.js","sourceRoot":"","sources":["../../../../../src/release/changesetCheck.ts"],"names":[],"mappings":";;;AAOA,6CAA+E;AAE/E;;;;GAIG;AACU,QAAA,sBAAsB,GAAG,oCAAoC,CAAC;AAyBpE,MAAM,iBAAiB,GAAG,CAAC,EAChC,UAAU,EACV,OAAO,EACP,OAAO,EACP,YAAY,GACQ,EAAwB,EAAE;IAC9C,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;IAE5C,MAAM,KAAK,GAAa,CAAC,8BAAsB,EAAE,uBAAuB,EAAE,EAAE,CAAC,CAAC;IAE9E,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CACR,UAAU,YAAY,SAAS,UAAU,CAAC,MAAM,aAAa,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACnJ,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CACR,aAAa,YAAY,yNAAyN,CACnP,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CACR,qEAAqE,CACtE,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,IAAA,2BAAc,EAC5B,OAAO,EACP,IAAA,oBAAO,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CACpC,CAAC;QACF,KAAK,CAAC,IAAI,CACR,GAAG,OAAO,CAAC,MAAM,aAAa,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,sDAAsD,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,OAAO,GAAG,CAAC,CAAC,CAAC,kBAAkB,GAAG,EAC5L,EAAE,EACF,+CAA+C,EAC/C,EAAE,EACF,IAAA,mCAAsB,EAAC,OAAO,CAAC,EAC/B,EAAE,EACF,YAAY,CACb,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACvD,CAAC,CAAC;AA1CW,QAAA,iBAAiB,qBA0C5B"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.changesetCheckJob = exports.CHANGESET_REPORT_FILE = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* the changeset check CI job (run by catci via the `changesetCheck`
|
|
6
|
+
* script of the `changesets` job image, in MR/PR pipelines only):
|
|
7
|
+
* reports which changesets the merge request adds, what is pending and
|
|
8
|
+
* what version merging would release. The report goes to the job log,
|
|
9
|
+
* to `changeset-report.md` (exposed as an artifact on gitlab) and to a
|
|
10
|
+
* sticky MR/PR comment where a token allows it. Exits 1 (the job runs
|
|
11
|
+
* with allow_failure) when the merge request adds no changeset.
|
|
12
|
+
*/
|
|
13
|
+
const promises_1 = require("fs/promises");
|
|
14
|
+
const changesetCheck_1 = require("./changesetCheck");
|
|
15
|
+
const changesetsReleaseJob_1 = require("./changesetsReleaseJob");
|
|
16
|
+
const releaseGit_1 = require("./releaseGit");
|
|
17
|
+
exports.CHANGESET_REPORT_FILE = "changeset-report.md";
|
|
18
|
+
const onGithub = () => process.env.GITHUB_ACTIONS === "true";
|
|
19
|
+
/**
|
|
20
|
+
* the changeset files added by this merge request: diffed against the
|
|
21
|
+
* merge base with the target branch (fetched explicitly — CI checkouts
|
|
22
|
+
* don't carry the target branch). Returns null when there is no MR/PR
|
|
23
|
+
* context to diff against.
|
|
24
|
+
*/
|
|
25
|
+
const getAddedChangesetFiles = async () => {
|
|
26
|
+
const targetBranch = onGithub()
|
|
27
|
+
? process.env.GITHUB_BASE_REF
|
|
28
|
+
: process.env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME;
|
|
29
|
+
if (!targetBranch) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
await (0, releaseGit_1.git)("fetch", "--quiet", "origin", targetBranch);
|
|
33
|
+
// FETCH_HEAD instead of origin/<branch>: CI remotes don't always
|
|
34
|
+
// carry the standard branch refspec
|
|
35
|
+
const mergeBase = await (0, releaseGit_1.git)("merge-base", "HEAD", "FETCH_HEAD");
|
|
36
|
+
const diff = await (0, releaseGit_1.git)("diff", "--name-only", "--diff-filter=A", mergeBase, "HEAD");
|
|
37
|
+
return diff
|
|
38
|
+
.split("\n")
|
|
39
|
+
.filter((file) => file.startsWith(".changeset/") &&
|
|
40
|
+
file.endsWith(".md") &&
|
|
41
|
+
!file.toLowerCase().endsWith("readme.md"))
|
|
42
|
+
.map((file) => file.slice(".changeset/".length));
|
|
43
|
+
};
|
|
44
|
+
const findSticky = (comments) => comments.find((comment) => { var _a; return (_a = comment.body) === null || _a === void 0 ? void 0 : _a.includes(changesetCheck_1.CHANGESET_CHECK_MARKER); });
|
|
45
|
+
const request = async (url, init) => {
|
|
46
|
+
var _a;
|
|
47
|
+
const response = await fetch(url, init);
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(`${(_a = init.method) !== null && _a !== void 0 ? _a : "GET"} ${url} failed: ${response.status} ${await response.text()}`);
|
|
50
|
+
}
|
|
51
|
+
return response;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* sticky PR comment via the workflow's own token
|
|
55
|
+
* (`permissions: pull-requests: write`)
|
|
56
|
+
*/
|
|
57
|
+
const upsertGithubComment = async (markdown) => {
|
|
58
|
+
var _a, _b;
|
|
59
|
+
const token = process.env.GITHUB_TOKEN;
|
|
60
|
+
const apiUrl = (_a = process.env.GITHUB_API_URL) !== null && _a !== void 0 ? _a : "https://api.github.com";
|
|
61
|
+
const repository = process.env.GITHUB_REPOSITORY;
|
|
62
|
+
// pull_request workflows check out refs/pull/<number>/merge
|
|
63
|
+
const prNumber = parseInt((_b = process.env.GITHUB_REF_NAME) !== null && _b !== void 0 ? _b : "");
|
|
64
|
+
if (!token || !repository || !prNumber) {
|
|
65
|
+
console.log("no PR context/token — skipping the PR comment");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const headers = {
|
|
69
|
+
authorization: `Bearer ${token}`,
|
|
70
|
+
accept: "application/vnd.github+json",
|
|
71
|
+
"content-type": "application/json",
|
|
72
|
+
};
|
|
73
|
+
const comments = await (await request(`${apiUrl}/repos/${repository}/issues/${prNumber}/comments?per_page=100`, { headers })).json();
|
|
74
|
+
const existing = findSticky(comments);
|
|
75
|
+
if (existing) {
|
|
76
|
+
await request(`${apiUrl}/repos/${repository}/issues/comments/${existing.id}`, {
|
|
77
|
+
method: "PATCH",
|
|
78
|
+
headers,
|
|
79
|
+
body: JSON.stringify({ body: markdown }),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
await request(`${apiUrl}/repos/${repository}/issues/${prNumber}/comments`, {
|
|
84
|
+
method: "POST",
|
|
85
|
+
headers,
|
|
86
|
+
body: JSON.stringify({ body: markdown }),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
console.log("updated the sticky PR comment");
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* sticky MR note — only when the project makes GL_TOKEN available to
|
|
93
|
+
* MR pipelines (opt-in: an api-scope token in MR pipelines is a
|
|
94
|
+
* security trade-off). Without it the report is still in the job log
|
|
95
|
+
* and the exposed artifact.
|
|
96
|
+
*/
|
|
97
|
+
const upsertGitlabComment = async (markdown) => {
|
|
98
|
+
const token = process.env.GL_TOKEN;
|
|
99
|
+
if (!token) {
|
|
100
|
+
console.log("GL_TOKEN is not available in this pipeline — skipping the MR comment (report available in the job log and the exposed artifact)");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const apiUrl = process.env.CI_API_V4_URL;
|
|
104
|
+
const projectId = process.env.CI_PROJECT_ID;
|
|
105
|
+
const mrIid = process.env.CI_MERGE_REQUEST_IID;
|
|
106
|
+
if (!apiUrl || !projectId || !mrIid) {
|
|
107
|
+
console.log("no MR context — skipping the MR comment");
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const headers = {
|
|
111
|
+
"PRIVATE-TOKEN": token,
|
|
112
|
+
"content-type": "application/json",
|
|
113
|
+
};
|
|
114
|
+
const notesUrl = `${apiUrl}/projects/${projectId}/merge_requests/${mrIid}/notes`;
|
|
115
|
+
const notes = await (await request(`${notesUrl}?per_page=100`, { headers })).json();
|
|
116
|
+
const existing = findSticky(notes);
|
|
117
|
+
if (existing) {
|
|
118
|
+
await request(`${notesUrl}/${existing.id}`, {
|
|
119
|
+
method: "PUT",
|
|
120
|
+
headers,
|
|
121
|
+
body: JSON.stringify({ body: markdown }),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
await request(notesUrl, {
|
|
126
|
+
method: "POST",
|
|
127
|
+
headers,
|
|
128
|
+
body: JSON.stringify({ body: markdown }),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
console.log("updated the sticky MR comment");
|
|
132
|
+
};
|
|
133
|
+
const changesetCheckJob = async () => {
|
|
134
|
+
await (0, releaseGit_1.ensureReleaseHistory)();
|
|
135
|
+
const pending = await (0, changesetsReleaseJob_1.readPendingChangesets)();
|
|
136
|
+
const lastTag = await (0, releaseGit_1.getLastReleaseTag)();
|
|
137
|
+
const addedFiles = await getAddedChangesetFiles();
|
|
138
|
+
const result = (0, changesetCheck_1.runChangesetCheck)({
|
|
139
|
+
addedFiles: addedFiles !== null && addedFiles !== void 0 ? addedFiles : [],
|
|
140
|
+
pending,
|
|
141
|
+
lastTag,
|
|
142
|
+
requestLabel: onGithub() ? "pull request" : "merge request",
|
|
143
|
+
});
|
|
144
|
+
console.log(result.markdown.replace(`${changesetCheck_1.CHANGESET_CHECK_MARKER}\n`, ""));
|
|
145
|
+
await (0, promises_1.writeFile)(exports.CHANGESET_REPORT_FILE, result.markdown);
|
|
146
|
+
// a failed comment must not fail the check — the report has already
|
|
147
|
+
// been printed and written
|
|
148
|
+
try {
|
|
149
|
+
if (onGithub()) {
|
|
150
|
+
await upsertGithubComment(result.markdown);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
await upsertGitlabComment(result.markdown);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
console.warn(`could not update the sticky comment: ${error}`);
|
|
158
|
+
}
|
|
159
|
+
if (addedFiles === null) {
|
|
160
|
+
console.log("not running against a merge request — check skipped");
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (!result.addsChangeset) {
|
|
164
|
+
// exit 1 turns the (allow_failure) job yellow so reviewers notice
|
|
165
|
+
process.exitCode = 1;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
exports.changesetCheckJob = changesetCheckJob;
|
|
169
|
+
//# sourceMappingURL=changesetCheckJob.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changesetCheckJob.js","sourceRoot":"","sources":["../../../../../src/release/changesetCheckJob.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.changesetsReleaseJob = exports.dispatchTaggedReleaseWorkflow = void 0;
|
|
3
|
+
exports.changesetsReleaseJob = exports.dispatchTaggedReleaseWorkflow = exports.readPendingChangesets = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* the changesets release CI job (run by catci via the
|
|
6
6
|
* `changesetsRelease` script of the `changesets` job image):
|
|
@@ -8,12 +8,10 @@ exports.changesetsReleaseJob = exports.dispatchTaggedReleaseWorkflow = void 0;
|
|
|
8
8
|
* from the last `v*` tag, writes the changelog, commits, tags and
|
|
9
9
|
* pushes — the pushed tag triggers the taggedRelease pipeline.
|
|
10
10
|
*/
|
|
11
|
-
const child_process_1 = require("child_process");
|
|
12
11
|
const promises_1 = require("fs/promises");
|
|
13
12
|
const path_1 = require("path");
|
|
14
|
-
const util_1 = require("util");
|
|
15
13
|
const changesets_1 = require("./changesets");
|
|
16
|
-
const
|
|
14
|
+
const releaseGit_1 = require("./releaseGit");
|
|
17
15
|
const CHANGESET_DIR = ".changeset";
|
|
18
16
|
const CHANGELOG_FILE = "CHANGELOG.md";
|
|
19
17
|
/**
|
|
@@ -22,53 +20,19 @@ const CHANGELOG_FILE = "CHANGELOG.md";
|
|
|
22
20
|
* `workflowFileName` in pipeline/src/backends/github/GithubBackend.ts.
|
|
23
21
|
*/
|
|
24
22
|
const GITHUB_TAGGED_RELEASE_WORKFLOW = "catladder-release.yml";
|
|
25
|
-
const git = async (...args) => {
|
|
26
|
-
const { stdout } = await execFile("git", args);
|
|
27
|
-
return stdout.trim();
|
|
28
|
-
};
|
|
29
23
|
const readPendingChangesets = async () => {
|
|
30
24
|
const entries = await (0, promises_1.readdir)(CHANGESET_DIR).catch(() => []);
|
|
31
25
|
const files = entries.filter((file) => file.endsWith(".md") && file.toLowerCase() !== "readme.md");
|
|
32
26
|
return Promise.all(files.map(async (file) => (0, changesets_1.parseChangesetFile)(file, await (0, promises_1.readFile)((0, path_1.join)(CHANGESET_DIR, file), "utf-8"))));
|
|
33
27
|
};
|
|
34
|
-
|
|
35
|
-
* CI checkouts are usually shallow and tagless (gitlab clones with
|
|
36
|
-
* depth 1; github's checkout needs fetch-depth: 0) — the local history
|
|
37
|
-
* then cannot answer "nearest v* tag" and the job would rederive the
|
|
38
|
-
* FIRST release version. Deepen and fetch tags before deriving.
|
|
39
|
-
*/
|
|
40
|
-
const ensureReleaseHistory = async () => {
|
|
41
|
-
const shallow = await git("rev-parse", "--is-shallow-repository").catch(() => "false");
|
|
42
|
-
try {
|
|
43
|
-
if (shallow === "true") {
|
|
44
|
-
await git("fetch", "--quiet", "--unshallow", "--tags", "origin");
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
await git("fetch", "--quiet", "--tags", "origin");
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
catch (e) {
|
|
51
|
-
console.warn(`could not fetch tags from origin (${e}) — version derivation may be wrong on a shallow clone`);
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
const getLastReleaseTag = async () => {
|
|
55
|
-
try {
|
|
56
|
-
// the nearest v* tag in the history of HEAD — on hotfix branches
|
|
57
|
-
// this is deliberately the branch's own release line, not the
|
|
58
|
-
// globally highest version
|
|
59
|
-
return await git("describe", "--tags", "--abbrev=0", "--match", "v[0-9]*");
|
|
60
|
-
}
|
|
61
|
-
catch (_a) {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
};
|
|
28
|
+
exports.readPendingChangesets = readPendingChangesets;
|
|
65
29
|
const ensureGitIdentity = async () => {
|
|
66
|
-
const email = await git("config", "user.email").catch(() => "");
|
|
30
|
+
const email = await (0, releaseGit_1.git)("config", "user.email").catch(() => "");
|
|
67
31
|
if (email !== "")
|
|
68
32
|
return;
|
|
69
33
|
const onGithub = process.env.GITHUB_ACTIONS === "true";
|
|
70
|
-
await git("config", "user.name", onGithub ? "github-actions[bot]" : "catladder");
|
|
71
|
-
await git("config", "user.email", onGithub
|
|
34
|
+
await (0, releaseGit_1.git)("config", "user.name", onGithub ? "github-actions[bot]" : "catladder");
|
|
35
|
+
await (0, releaseGit_1.git)("config", "user.email", onGithub
|
|
72
36
|
? "41898282+github-actions[bot]@users.noreply.github.com"
|
|
73
37
|
: "catladder-release@panter.ch");
|
|
74
38
|
};
|
|
@@ -93,7 +57,7 @@ const pushCommitAndTag = async (tag) => {
|
|
|
93
57
|
// rederived an existing version)
|
|
94
58
|
if (process.env.GITHUB_ACTIONS === "true") {
|
|
95
59
|
const branch = requireEnv("GITHUB_REF_NAME");
|
|
96
|
-
await git("push", "--atomic", "origin", `HEAD:refs/heads/${branch}`, tag);
|
|
60
|
+
await (0, releaseGit_1.git)("push", "--atomic", "origin", `HEAD:refs/heads/${branch}`, tag);
|
|
97
61
|
return;
|
|
98
62
|
}
|
|
99
63
|
const token = requireEnv("GL_TOKEN");
|
|
@@ -101,7 +65,7 @@ const pushCommitAndTag = async (tag) => {
|
|
|
101
65
|
const projectPath = requireEnv("CI_PROJECT_PATH");
|
|
102
66
|
const branch = requireEnv("CI_COMMIT_BRANCH");
|
|
103
67
|
const remote = `https://oauth2:${token}@${host}/${projectPath}.git`;
|
|
104
|
-
await git("push", "--atomic", remote, `HEAD:refs/heads/${branch}`, tag);
|
|
68
|
+
await (0, releaseGit_1.git)("push", "--atomic", remote, `HEAD:refs/heads/${branch}`, tag);
|
|
105
69
|
};
|
|
106
70
|
/**
|
|
107
71
|
* tags pushed with the default GITHUB_TOKEN do not trigger `on: push:
|
|
@@ -129,15 +93,32 @@ const dispatchTaggedReleaseWorkflow = async (tag) => {
|
|
|
129
93
|
console.log(`dispatched ${GITHUB_TAGGED_RELEASE_WORKFLOW} for ${tag}`);
|
|
130
94
|
};
|
|
131
95
|
exports.dispatchTaggedReleaseWorkflow = dispatchTaggedReleaseWorkflow;
|
|
96
|
+
/**
|
|
97
|
+
* the escape hatch of the force-release job: releasing without pending
|
|
98
|
+
* changesets (e.g. a hotfix merged without one) must not require a new
|
|
99
|
+
* MR, so a forced empty release becomes a patch bump with a generic
|
|
100
|
+
* changelog entry instead of a no-op
|
|
101
|
+
*/
|
|
102
|
+
const FORCED_RELEASE_CHANGESET = {
|
|
103
|
+
fileName: "",
|
|
104
|
+
bump: "patch",
|
|
105
|
+
summary: "Forced release without pending changesets.",
|
|
106
|
+
};
|
|
132
107
|
const changesetsReleaseJob = async () => {
|
|
133
|
-
const
|
|
134
|
-
|
|
108
|
+
const pending = await (0, exports.readPendingChangesets)();
|
|
109
|
+
const forcedEmpty = pending.length === 0 && process.env.CATLADDER_FORCE_RELEASE === "true";
|
|
110
|
+
if (pending.length === 0 && !forcedEmpty) {
|
|
135
111
|
console.log(`no changesets found in ${CHANGESET_DIR}/ — nothing to release`);
|
|
136
112
|
console.log("add one with `yarn changeset` (or write .changeset/<name>.md by hand) and merge it to release");
|
|
113
|
+
console.log("to release anyway (patch bump), run the force release job instead");
|
|
137
114
|
return;
|
|
138
115
|
}
|
|
139
|
-
|
|
140
|
-
|
|
116
|
+
const changesets = forcedEmpty ? [FORCED_RELEASE_CHANGESET] : pending;
|
|
117
|
+
if (forcedEmpty) {
|
|
118
|
+
console.log("no changesets pending — forced release, bumping a patch");
|
|
119
|
+
}
|
|
120
|
+
await (0, releaseGit_1.ensureReleaseHistory)();
|
|
121
|
+
const lastTag = await (0, releaseGit_1.getLastReleaseTag)();
|
|
141
122
|
const version = (0, changesets_1.getNextVersion)(lastTag, (0, changesets_1.maxBump)(changesets.map((c) => c.bump)));
|
|
142
123
|
const tag = `v${version}`;
|
|
143
124
|
console.log(`releasing ${tag} (${lastTag !== null && lastTag !== void 0 ? lastTag : "first release"} + ${changesets.length} changeset(s))`);
|
|
@@ -145,11 +126,21 @@ const changesetsReleaseJob = async () => {
|
|
|
145
126
|
const existingChangelog = await (0, promises_1.readFile)(CHANGELOG_FILE, "utf-8").catch(() => null);
|
|
146
127
|
const date = new Date().toISOString().slice(0, 10);
|
|
147
128
|
await (0, promises_1.writeFile)(CHANGELOG_FILE, (0, changesets_1.prependToChangelog)(existingChangelog, version, date, entries));
|
|
148
|
-
await Promise.all(
|
|
129
|
+
await Promise.all(
|
|
130
|
+
// pending, not changesets: the synthetic forced-release changeset
|
|
131
|
+
// has no file to delete
|
|
132
|
+
pending.map((changeset) => (0, promises_1.rm)((0, path_1.join)(CHANGESET_DIR, changeset.fileName))));
|
|
149
133
|
await ensureGitIdentity();
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
134
|
+
// a forced empty release consumes no changeset files — and .changeset/
|
|
135
|
+
// may not even exist yet, which `git add` would reject
|
|
136
|
+
if (forcedEmpty) {
|
|
137
|
+
await (0, releaseGit_1.git)("add", CHANGELOG_FILE);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
await (0, releaseGit_1.git)("add", CHANGELOG_FILE, CHANGESET_DIR);
|
|
141
|
+
}
|
|
142
|
+
await (0, releaseGit_1.git)("commit", "-m", `chore(release): ${version}\n\n${entries}`);
|
|
143
|
+
await (0, releaseGit_1.git)("tag", tag);
|
|
153
144
|
await pushCommitAndTag(tag);
|
|
154
145
|
console.log(`released ${tag}`);
|
|
155
146
|
if (process.env.GITHUB_ACTIONS === "true") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changesetsReleaseJob.js","sourceRoot":"","sources":["../../../../../src/release/changesetsReleaseJob.ts"],"names":[],"mappings":";;;AAAA;;;;;;GAMG;AACH,
|
|
1
|
+
{"version":3,"file":"changesetsReleaseJob.js","sourceRoot":"","sources":["../../../../../src/release/changesetsReleaseJob.ts"],"names":[],"mappings":";;;AAAA;;;;;;GAMG;AACH,0CAA+D;AAC/D,+BAA4B;AAE5B,6CAMsB;AACtB,6CAA4E;AAE5E,MAAM,aAAa,GAAG,YAAY,CAAC;AACnC,MAAM,cAAc,GAAG,cAAc,CAAC;AAEtC;;;;GAIG;AACH,MAAM,8BAA8B,GAAG,uBAAuB,CAAC;AAExD,MAAM,qBAAqB,GAAG,KAAK,IAAI,EAAE;IAC9C,MAAM,OAAO,GAAG,MAAM,IAAA,kBAAO,EAAC,aAAa,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAC1B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,WAAW,CACrE,CAAC;IACF,OAAO,OAAO,CAAC,GAAG,CAChB,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CACvB,IAAA,+BAAkB,EAChB,IAAI,EACJ,MAAM,IAAA,mBAAQ,EAAC,IAAA,WAAI,EAAC,aAAa,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CACnD,CACF,CACF,CAAC;AACJ,CAAC,CAAC;AAbW,QAAA,qBAAqB,yBAahC;AAEF,MAAM,iBAAiB,GAAG,KAAK,IAAI,EAAE;IACnC,MAAM,KAAK,GAAG,MAAM,IAAA,gBAAG,EAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAChE,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO;IACzB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,CAAC;IACvD,MAAM,IAAA,gBAAG,EACP,QAAQ,EACR,WAAW,EACX,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,WAAW,CAC/C,CAAC;IACF,MAAM,IAAA,gBAAG,EACP,QAAQ,EACR,YAAY,EACZ,QAAQ;QACN,CAAC,CAAC,uDAAuD;QACzD,CAAC,CAAC,6BAA6B,CAClC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,IAAY,EAAU,EAAE;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,uCAAuC,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,gBAAgB,GAAG,KAAK,EAAE,GAAW,EAAE,EAAE;IAC7C,iEAAiE;IACjE,+DAA+D;IAC/D,iCAAiC;IACjC,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;QAC7C,MAAM,IAAA,gBAAG,EAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,mBAAmB,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;QAC1E,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,kBAAkB,KAAK,IAAI,IAAI,IAAI,WAAW,MAAM,CAAC;IACpE,MAAM,IAAA,gBAAG,EAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF;;;;;;GAMG;AACI,MAAM,6BAA6B,GAAG,KAAK,EAAE,GAAW,EAAE,EAAE;;IACjE,MAAM,MAAM,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,cAAc,mCAAI,wBAAwB,CAAC;IACtE,MAAM,UAAU,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,MAAM,UAAU,UAAU,sBAAsB,8BAA8B,aAAa,EAC9F;QACE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,MAAM,EAAE,6BAA6B;SACtC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;KACnC,CACF,CAAC;IACF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,eAAe,8BAA8B,QAAQ,GAAG,YAAY,QAAQ,CAAC,MAAM,IAAI,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,CAC/G,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,cAAc,8BAA8B,QAAQ,GAAG,EAAE,CAAC,CAAC;AACzE,CAAC,CAAC;AArBW,QAAA,6BAA6B,iCAqBxC;AAEF;;;;;GAKG;AACH,MAAM,wBAAwB,GAAc;IAC1C,QAAQ,EAAE,EAAE;IACZ,IAAI,EAAE,OAAO;IACb,OAAO,EAAE,4CAA4C;CACtD,CAAC;AAEK,MAAM,oBAAoB,GAAG,KAAK,IAAI,EAAE;IAC7C,MAAM,OAAO,GAAG,MAAM,IAAA,6BAAqB,GAAE,CAAC;IAC9C,MAAM,WAAW,GACf,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,MAAM,CAAC;IACzE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,CACT,0BAA0B,aAAa,wBAAwB,CAChE,CAAC;QACF,OAAO,CAAC,GAAG,CACT,+FAA+F,CAChG,CAAC;QACF,OAAO,CAAC,GAAG,CACT,mEAAmE,CACpE,CAAC;QACF,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACtE,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,IAAA,iCAAoB,GAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,MAAM,IAAA,8BAAiB,GAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAA,2BAAc,EAC5B,OAAO,EACP,IAAA,oBAAO,EAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CACvC,CAAC;IACF,MAAM,GAAG,GAAG,IAAI,OAAO,EAAE,CAAC;IAC1B,OAAO,CAAC,GAAG,CACT,aAAa,GAAG,KAAK,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,eAAe,MAAM,UAAU,CAAC,MAAM,gBAAgB,CACvF,CAAC;IAEF,MAAM,OAAO,GAAG,IAAA,mCAAsB,EAAC,UAAU,CAAC,CAAC;IACnD,MAAM,iBAAiB,GAAG,MAAM,IAAA,mBAAQ,EAAC,cAAc,EAAE,OAAO,CAAC,CAAC,KAAK,CACrE,GAAG,EAAE,CAAC,IAAI,CACX,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACnD,MAAM,IAAA,oBAAS,EACb,cAAc,EACd,IAAA,+BAAkB,EAAC,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAC9D,CAAC;IACF,MAAM,OAAO,CAAC,GAAG;IACf,kEAAkE;IAClE,wBAAwB;IACxB,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAA,aAAE,EAAC,IAAA,WAAI,EAAC,aAAa,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CACxE,CAAC;IAEF,MAAM,iBAAiB,EAAE,CAAC;IAC1B,uEAAuE;IACvE,uDAAuD;IACvD,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,IAAA,gBAAG,EAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,MAAM,IAAA,gBAAG,EAAC,KAAK,EAAE,cAAc,EAAE,aAAa,CAAC,CAAC;IAClD,CAAC;IACD,MAAM,IAAA,gBAAG,EAAC,QAAQ,EAAE,IAAI,EAAE,mBAAmB,OAAO,OAAO,OAAO,EAAE,CAAC,CAAC;IACtE,MAAM,IAAA,gBAAG,EAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACtB,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAE/B,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;QAC1C,MAAM,IAAA,qCAA6B,EAAC,GAAG,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC;AA/DW,QAAA,oBAAoB,wBA+D/B"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const git: (...args: string[]) => Promise<string>;
|
|
2
|
+
/**
|
|
3
|
+
* CI checkouts are usually shallow and tagless (gitlab clones with
|
|
4
|
+
* depth 1; github's checkout needs fetch-depth: 0) — the local history
|
|
5
|
+
* then cannot answer "nearest v* tag" and the job would rederive the
|
|
6
|
+
* FIRST release version. Deepen and fetch tags before deriving.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ensureReleaseHistory: () => Promise<void>;
|
|
9
|
+
export declare const getLastReleaseTag: () => Promise<string | null>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getLastReleaseTag = exports.ensureReleaseHistory = exports.git = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* git helpers shared by the release-related catci jobs (changesets
|
|
6
|
+
* release, changeset check).
|
|
7
|
+
*/
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
9
|
+
const util_1 = require("util");
|
|
10
|
+
const execFile = (0, util_1.promisify)(child_process_1.execFile);
|
|
11
|
+
const git = async (...args) => {
|
|
12
|
+
const { stdout } = await execFile("git", args);
|
|
13
|
+
return stdout.trim();
|
|
14
|
+
};
|
|
15
|
+
exports.git = git;
|
|
16
|
+
/**
|
|
17
|
+
* CI checkouts are usually shallow and tagless (gitlab clones with
|
|
18
|
+
* depth 1; github's checkout needs fetch-depth: 0) — the local history
|
|
19
|
+
* then cannot answer "nearest v* tag" and the job would rederive the
|
|
20
|
+
* FIRST release version. Deepen and fetch tags before deriving.
|
|
21
|
+
*/
|
|
22
|
+
const ensureReleaseHistory = async () => {
|
|
23
|
+
const shallow = await (0, exports.git)("rev-parse", "--is-shallow-repository").catch(() => "false");
|
|
24
|
+
try {
|
|
25
|
+
if (shallow === "true") {
|
|
26
|
+
await (0, exports.git)("fetch", "--quiet", "--unshallow", "--tags", "origin");
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
await (0, exports.git)("fetch", "--quiet", "--tags", "origin");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
console.warn(`could not fetch tags from origin (${e}) — version derivation may be wrong on a shallow clone`);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
exports.ensureReleaseHistory = ensureReleaseHistory;
|
|
37
|
+
const getLastReleaseTag = async () => {
|
|
38
|
+
try {
|
|
39
|
+
// the nearest v* tag in the history of HEAD — on hotfix branches
|
|
40
|
+
// this is deliberately the branch's own release line, not the
|
|
41
|
+
// globally highest version
|
|
42
|
+
return await (0, exports.git)("describe", "--tags", "--abbrev=0", "--match", "v[0-9]*");
|
|
43
|
+
}
|
|
44
|
+
catch (_a) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.getLastReleaseTag = getLastReleaseTag;
|
|
49
|
+
//# sourceMappingURL=releaseGit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"releaseGit.js","sourceRoot":"","sources":["../../../../../src/release/releaseGit.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,iDAAuD;AACvD,+BAAiC;AAEjC,MAAM,QAAQ,GAAG,IAAA,gBAAS,EAAC,wBAAU,CAAC,CAAC;AAEhC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAG,IAAc,EAAmB,EAAE;IAC9D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC,CAAC;AAHW,QAAA,GAAG,OAGd;AAEF;;;;;GAKG;AACI,MAAM,oBAAoB,GAAG,KAAK,IAAI,EAAE;IAC7C,MAAM,OAAO,GAAG,MAAM,IAAA,WAAG,EAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC,KAAK,CACrE,GAAG,EAAE,CAAC,OAAO,CACd,CAAC;IACF,IAAI,CAAC;QACH,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;YACvB,MAAM,IAAA,WAAG,EAAC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,MAAM,IAAA,WAAG,EAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CACV,qCAAqC,CAAC,wDAAwD,CAC/F,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAfW,QAAA,oBAAoB,wBAe/B;AAEK,MAAM,iBAAiB,GAAG,KAAK,IAA4B,EAAE;IAClE,IAAI,CAAC;QACH,iEAAiE;QACjE,8DAA8D;QAC9D,2BAA2B;QAC3B,OAAO,MAAM,IAAA,WAAG,EAAC,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAC7E,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AATW,QAAA,iBAAiB,qBAS5B"}
|