-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate-versioning-pull-request.js
More file actions
136 lines (118 loc) · 3.77 KB
/
Copy pathcreate-versioning-pull-request.js
File metadata and controls
136 lines (118 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import {
LogLevel,
createVersioningPlan,
getCommitHistory,
getWorkspace,
logger,
readJsoncFile,
} from "conventional-versioning";
import { $ } from "execa";
import assert from "node:assert/strict";
import { Octokit } from "octokit";
logger.pipe((log) => {
if (log.level <= LogLevel.Warning) {
console.error(log.text);
}
});
const {
GITHUB_TOKEN,
GITHUB_REPO,
GITHUB_HEAD_BRANCH = "automated-versioning",
GITHUB_BASE_BRANCH = "main",
CONVER_CONFIG = "conver.json",
} = process.env;
assert(GITHUB_TOKEN, "Missing 'GITHUB_TOKEN' environment variable.");
assert(GITHUB_REPO, "Missing 'GITHUB_REPO' environment variable.");
const [owner, repo] = GITHUB_REPO.split("/");
// Make sure working directory is clean.
if (!(await isClean())) {
console.error("Working directory is not clean. Exiting.");
process.exit(1);
}
// Make sure current branch is base branch.
if ((await getCurrentBranch()) !== GITHUB_BASE_BRANCH) {
console.error("Switch to base branch before running. Exiting.");
process.exit(1);
}
// Switch to head branch.
console.info(`Switching branch to ${GITHUB_HEAD_BRANCH}.`);
await $`git checkout -B ${GITHUB_HEAD_BRANCH}`;
// Get versioning plan.
/** @type {import('conventional-versioning').Options} */
const options = await readJsoncFile(CONVER_CONFIG);
const workspace = await getWorkspace(options);
const history = await getCommitHistory(options);
const updates = createVersioningPlan(workspace, history, options);
// Do versioning.
await $`pnpm conver version --yes`;
if (await isClean()) {
console.log("No changes. Exiting.");
process.exit();
}
// Update lockfile.
await $`pnpm install --no-frozen-lockfile`;
// Push changes.
console.info(`Pushing changes to ${GITHUB_HEAD_BRANCH}.`);
await $`git commit -a -m ${"chore: version package(s)"}`;
await $`git push --force -u origin ${GITHUB_HEAD_BRANCH}`;
let pullBody =
"This pull request was opened by the " +
"[release action](https://github.com/tscpp/knuckles/actions/workflows/release.yml) " +
"since new versions are available and will automatically stay in sync.\n\n" +
updates
.map(
(update) =>
`- ${update.name}: ${update.oldVersion} -> ${update.newVersion}`,
)
.join("\n") +
"\n";
const octokit = new Octokit({
auth: GITHUB_TOKEN,
});
console.info("Searching for existing pull request.");
const response = await octokit.rest.pulls.list({
owner,
repo,
state: "open",
head: owner + ":" + GITHUB_HEAD_BRANCH,
base: GITHUB_BASE_BRANCH,
per_page: 1,
});
assert.equal(response.status, 200, "Expected response status code 200.");
const [pull] = response.data;
if (pull) {
console.info(`Found existing pull request #${pull.number}.`);
assert.equal(pull.head.ref, GITHUB_HEAD_BRANCH);
assert.equal(pull.base.ref, GITHUB_BASE_BRANCH);
console.info("Updating existing pull request.");
const response = await octokit.rest.pulls.update({
owner,
repo,
pull_number: pull.number,
body: pullBody,
});
assert.equal(response.status, 200, "Expected response status code 200.");
} else {
console.info("Did not find existing pull request.");
console.info("Creating a new pull request.");
const response = await octokit.rest.pulls.create({
owner,
repo,
head: GITHUB_HEAD_BRANCH,
base: GITHUB_BASE_BRANCH,
title: "chore: version package(s)",
body: pullBody,
});
assert.equal(response.status, 201, "Expected response status code 201.");
console.info(`Created pull request #${response.data.number}.`);
}
console.info(`Switching branch to ${GITHUB_BASE_BRANCH}.`);
await $`git checkout ${GITHUB_BASE_BRANCH}`;
async function isClean() {
const { stdout } = await $`git status --porcelain`;
return stdout.trim() === "";
}
async function getCurrentBranch() {
const { stdout } = await $`git branch --show-current`;
return stdout.trim();
}