Skip to content

Commit 5253cd1

Browse files
committed
Add Retarget Draft Releases transform
1 parent 7bd9640 commit 5253cd1

File tree

3 files changed

+201
-0
lines changed

3 files changed

+201
-0
lines changed

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ module.exports = async (argv) => {
5050
"update-default-branch",
5151
"github-pages",
5252
"retarget-pull-requests",
53+
"retarget-draft-releases",
5354
"branch-protection",
5455
"delete-old-branch",
5556
];

transforms/retarget-draft-releases.js

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
module.exports = async function ({
2+
owner,
3+
repo,
4+
old,
5+
target,
6+
dryRun,
7+
log,
8+
octokit,
9+
}) {
10+
log = log.extend("transforms:retarget-draft-releases");
11+
12+
log("Fetching all draft releases");
13+
// List all PRs
14+
let releases = await octokit.paginate(
15+
"GET /repos/:owner/:repo/releases",
16+
{
17+
owner,
18+
repo,
19+
per_page: 100,
20+
},
21+
(response) => response.data
22+
);
23+
log(`Found [${releases.length}] releases`);
24+
25+
if (releases.length == 0) {
26+
log(`No releases found. Exiting`);
27+
return;
28+
}
29+
30+
// Filter down to draft releases
31+
releases = releases.filter((r) => r.draft);
32+
if (releases.length === 0) {
33+
log(`No draft releases found. Exiting`);
34+
return;
35+
}
36+
37+
// Update the target branch for all open PRs
38+
for (let release of releases) {
39+
if (release.target_commitish != old) {
40+
log(`Skipping [${release.name}] as it didn't target [${old}]`);
41+
continue;
42+
}
43+
44+
log(
45+
`Updating release [${release.name}] in [${repo}] from [${release.target_commitish}] to [${target}]`
46+
);
47+
48+
if (!dryRun) {
49+
await octokit.repos.updateRelease({
50+
owner,
51+
repo,
52+
release_id: release.id,
53+
target_commitish: target,
54+
tag_name: release.tag_name,
55+
});
56+
}
57+
}
58+
};
+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
const nock = require("nock");
2+
nock.disableNetConnect();
3+
4+
const log = require("../src/mock-debug");
5+
6+
const retarget = require("./retarget-draft-releases");
7+
const octokit = require("../src/octokit")();
8+
9+
afterEach(() => {
10+
if (!nock.isDone()) {
11+
throw new Error("Not all nock interceptors were used");
12+
}
13+
log.cleanAll();
14+
nock.cleanAll();
15+
});
16+
17+
describe("#retarget-pull-requests", () => {
18+
it("exits if there are no draft releases", async () => {
19+
nock("https://api.github.com/")
20+
.get("/repos/demo/repo/releases?per_page=100")
21+
.reply(200, []);
22+
23+
await retarget({
24+
owner: "demo",
25+
repo: "repo",
26+
target: "main",
27+
old: "master",
28+
octokit,
29+
log,
30+
});
31+
32+
expect(log.logger).toBeCalledWith("Found [0] releases");
33+
expect(log.logger).toBeCalledWith("No releases found. Exiting");
34+
});
35+
36+
it("exits if there are no draft releases", async () => {
37+
nock("https://api.github.com/")
38+
.get("/repos/demo/repo/releases?per_page=100")
39+
.reply(200, [{ draft: false }]);
40+
41+
await retarget({
42+
owner: "demo",
43+
repo: "repo",
44+
target: "main",
45+
old: "master",
46+
octokit,
47+
log,
48+
});
49+
50+
expect(log.logger).toBeCalledWith("No draft releases found. Exiting");
51+
});
52+
53+
it("skips releases with a different target", async () => {
54+
nock("https://api.github.com/")
55+
.get("/repos/demo/repo/releases?per_page=100")
56+
.reply(200, [
57+
{
58+
name: "OtherTag",
59+
target_commitish: "other-branch",
60+
draft: true,
61+
},
62+
]);
63+
64+
await retarget({
65+
owner: "demo",
66+
repo: "repo",
67+
target: "main",
68+
old: "master",
69+
octokit,
70+
log,
71+
});
72+
73+
expect(log.logger).toBeCalledWith("Found [1] releases");
74+
expect(log.logger).toBeCalledWith(
75+
"Skipping [OtherTag] as it didn't target [master]"
76+
);
77+
});
78+
79+
it("retargets valid pull requests", async () => {
80+
nock("https://api.github.com/")
81+
.get("/repos/demo/repo/releases?per_page=100")
82+
.reply(200, [
83+
{
84+
id: 1234,
85+
name: "OtherTag",
86+
target_commitish: "master",
87+
tag_name: "v1",
88+
draft: true,
89+
},
90+
]);
91+
92+
nock("https://api.github.com/")
93+
.patch("/repos/demo/repo/releases/1234", {
94+
target_commitish: "main",
95+
tag_name: "v1",
96+
})
97+
.reply(200);
98+
99+
await retarget({
100+
owner: "demo",
101+
repo: "repo",
102+
target: "main",
103+
old: "master",
104+
octokit,
105+
log,
106+
});
107+
108+
expect(log.logger).toBeCalledWith("Found [1] releases");
109+
expect(log.logger).toBeCalledWith(
110+
"Updating release [OtherTag] in [repo] from [master] to [main]"
111+
);
112+
});
113+
114+
it("respects dryRun mode", async () => {
115+
nock("https://api.github.com/")
116+
.get("/repos/demo/repo/releases?per_page=100")
117+
.reply(200, [
118+
{
119+
id: 1234,
120+
name: "OtherTag",
121+
target_commitish: "master",
122+
tag_name: "v1",
123+
draft: true,
124+
},
125+
]);
126+
127+
await retarget({
128+
owner: "demo",
129+
repo: "repo",
130+
target: "main",
131+
old: "master",
132+
octokit,
133+
log,
134+
dryRun: true,
135+
});
136+
137+
expect(log.logger).toBeCalledWith("Found [1] releases");
138+
expect(log.logger).toBeCalledWith(
139+
"Updating release [OtherTag] in [repo] from [master] to [main]"
140+
);
141+
});
142+
});

0 commit comments

Comments
 (0)