forked from anomalyco/opencode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbeta.ts
More file actions
executable file
·138 lines (117 loc) · 4.35 KB
/
beta.ts
File metadata and controls
executable file
·138 lines (117 loc) · 4.35 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
137
138
#!/usr/bin/env bun
interface PR {
number: number
title: string
}
interface RunResult {
exitCode: number
stdout: string
stderr: string
}
async function main() {
console.log("Fetching open contributor PRs...")
const prsResult = await $`gh pr list --label contributor --state open --json number,title --limit 100`.nothrow()
if (prsResult.exitCode !== 0) {
throw new Error(`Failed to fetch PRs: ${prsResult.stderr}`)
}
const prs: PR[] = JSON.parse(prsResult.stdout)
console.log(`Found ${prs.length} open contributor PRs`)
console.log("Fetching latest dev branch...")
const fetchDev = await $`git fetch origin dev`.nothrow()
if (fetchDev.exitCode !== 0) {
throw new Error(`Failed to fetch dev branch: ${fetchDev.stderr}`)
}
console.log("Checking out beta branch...")
const checkoutBeta = await $`git checkout -B beta origin/dev`.nothrow()
if (checkoutBeta.exitCode !== 0) {
throw new Error(`Failed to checkout beta branch: ${checkoutBeta.stderr}`)
}
const applied: number[] = []
const skipped: Array<{ number: number; reason: string }> = []
for (const pr of prs) {
console.log(`\nProcessing PR #${pr.number}: ${pr.title}`)
console.log(" Fetching PR head...")
const fetch = await run(["git", "fetch", "origin", `pull/${pr.number}/head:pr/${pr.number}`])
if (fetch.exitCode !== 0) {
console.log(` Failed to fetch PR head: ${fetch.stderr}`)
skipped.push({ number: pr.number, reason: `Fetch failed: ${fetch.stderr}` })
continue
}
console.log(" Merging...")
const merge = await run(["git", "merge", "--no-commit", "--no-ff", `pr/${pr.number}`])
if (merge.exitCode !== 0) {
console.log(" Failed to merge (conflicts)")
await $`git merge --abort`.nothrow()
await $`git checkout -- .`.nothrow()
await $`git clean -fd`.nothrow()
skipped.push({ number: pr.number, reason: "Has conflicts" })
continue
}
const mergeHead = await $`git rev-parse -q --verify MERGE_HEAD`.nothrow()
if (mergeHead.exitCode !== 0) {
console.log(" No changes, skipping")
skipped.push({ number: pr.number, reason: "No changes" })
continue
}
const add = await $`git add -A`.nothrow()
if (add.exitCode !== 0) {
console.log(" Failed to stage")
await $`git checkout -- .`.nothrow()
await $`git clean -fd`.nothrow()
skipped.push({ number: pr.number, reason: "Failed to stage" })
continue
}
const commitMsg = `Apply PR #${pr.number}: ${pr.title}`
const commit = await run(["git", "commit", "-m", commitMsg])
if (commit.exitCode !== 0) {
console.log(` Failed to commit: ${commit.stderr}`)
await $`git checkout -- .`.nothrow()
await $`git clean -fd`.nothrow()
skipped.push({ number: pr.number, reason: `Commit failed: ${commit.stderr}` })
continue
}
console.log(" Applied successfully")
applied.push(pr.number)
}
console.log("\n--- Summary ---")
console.log(`Applied: ${applied.length} PRs`)
applied.forEach((num) => console.log(` - PR #${num}`))
console.log(`Skipped: ${skipped.length} PRs`)
skipped.forEach((x) => console.log(` - PR #${x.number}: ${x.reason}`))
console.log("\nForce pushing beta branch...")
const push = await $`git push origin beta --force --no-verify`.nothrow()
if (push.exitCode !== 0) {
throw new Error(`Failed to push beta branch: ${push.stderr}`)
}
console.log("Successfully synced beta branch")
}
main().catch((err) => {
console.error("Error:", err)
process.exit(1)
})
async function run(args: string[], stdin?: Uint8Array): Promise<RunResult> {
const proc = Bun.spawn(args, {
stdin: stdin ?? "inherit",
stdout: "pipe",
stderr: "pipe",
})
const exitCode = await proc.exited
const stdout = await new Response(proc.stdout).text()
const stderr = await new Response(proc.stderr).text()
return { exitCode, stdout, stderr }
}
function $(strings: TemplateStringsArray, ...values: unknown[]) {
const cmd = strings.reduce((acc, str, i) => acc + str + (values[i] ?? ""), "")
return {
async nothrow() {
const proc = Bun.spawn(cmd.split(" "), {
stdout: "pipe",
stderr: "pipe",
})
const exitCode = await proc.exited
const stdout = await new Response(proc.stdout).text()
const stderr = await new Response(proc.stderr).text()
return { exitCode, stdout, stderr }
},
}
}