Skip to content

Commit 92f6f81

Browse files
authored
Merge branch 'cppdoc-cc:main' into main
2 parents 51a8c63 + ee79648 commit 92f6f81

File tree

7 files changed

+6937
-2
lines changed

7 files changed

+6937
-2
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Cleanup Migrate Branches
2+
3+
on:
4+
schedule:
5+
- cron: "0 0 * * *"
6+
workflow_dispatch:
7+
8+
jobs:
9+
cleanup:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: write
13+
pull-requests: read
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v6
17+
with:
18+
fetch-depth: 0
19+
token: ${{ secrets.GITHUB_TOKEN }}
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v6
23+
with:
24+
node-version: "22"
25+
cache: "npm"
26+
27+
- name: Install dependencies
28+
run: npm ci
29+
30+
- name: Run cleanup script
31+
env:
32+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33+
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
34+
GITHUB_REPOSITORY: ${{ github.repository }}
35+
run: npm run cleanup-branches
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Update Migration Progress
2+
3+
on:
4+
schedule:
5+
- cron: "0 * * * *"
6+
workflow_dispatch:
7+
inputs:
8+
force:
9+
description: "Force update even if no changes"
10+
required: false
11+
type: boolean
12+
13+
jobs:
14+
update-progress:
15+
runs-on: ubuntu-latest
16+
permissions:
17+
contents: write
18+
pull-requests: read
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v6
22+
with:
23+
fetch-depth: 0
24+
token: ${{ secrets.GITHUB_TOKEN }}
25+
26+
- name: Setup Node.js
27+
uses: actions/setup-node@v6
28+
with:
29+
node-version: "22"
30+
cache: "npm"
31+
32+
- name: Install dependencies
33+
run: npm ci
34+
35+
- name: Run update migration progress script
36+
run: npm run update-migrate-progress
37+
38+
- name: Create orphan branch and force push
39+
run: |
40+
git config user.name "github-actions[bot]"
41+
git config user.email "github-actions[bot]@users.noreply.github.com"
42+
git checkout --orphan migrate-progress
43+
git add CPPREF_MIGRATE_PROGRESS.md
44+
git commit -m "chore: update migration progress [skip ci]"
45+
git push --force origin migrate-progress

migrate/cleanup-branches.ts

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { Octokit } from "@octokit/rest";
2+
import { execSync } from "child_process";
3+
4+
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
5+
const REPO_OWNER = process.env.GITHUB_REPOSITORY_OWNER || "owner";
6+
const REPO_NAME = process.env.GITHUB_REPOSITORY?.split("/")[1] || "cppdoc";
7+
8+
if (!GITHUB_TOKEN) {
9+
console.error("Missing GITHUB_TOKEN");
10+
process.exit(1);
11+
}
12+
13+
const octokit = new Octokit({ auth: GITHUB_TOKEN });
14+
15+
async function getAllOpenPRs() {
16+
const prs = [];
17+
let page = 1;
18+
const perPage = 100;
19+
20+
while (true) {
21+
const { data } = await octokit.pulls.list({
22+
owner: REPO_OWNER,
23+
repo: REPO_NAME,
24+
state: "open",
25+
per_page: perPage,
26+
page,
27+
});
28+
if (data.length === 0) break;
29+
prs.push(...data);
30+
if (data.length < perPage) break;
31+
page++;
32+
}
33+
34+
console.log(`Found ${prs.length} open PRs`);
35+
return prs;
36+
}
37+
38+
async function getAllBranches() {
39+
const branches = [];
40+
let page = 1;
41+
const perPage = 100;
42+
43+
while (true) {
44+
const { data } = await octokit.repos.listBranches({
45+
owner: REPO_OWNER,
46+
repo: REPO_NAME,
47+
per_page: perPage,
48+
page,
49+
});
50+
if (data.length === 0) break;
51+
branches.push(...data);
52+
if (data.length < perPage) break;
53+
page++;
54+
}
55+
56+
console.log(`Found ${branches.length} branches`);
57+
return branches;
58+
}
59+
60+
function filterMigrateBranches(branches: { name: string }[]) {
61+
return branches.filter((b) => b.name.startsWith("migrate/"));
62+
}
63+
64+
async function deleteBranch(branchName: string) {
65+
try {
66+
await octokit.git.deleteRef({
67+
owner: REPO_OWNER,
68+
repo: REPO_NAME,
69+
ref: `heads/${branchName}`,
70+
});
71+
console.log(`Deleted remote branch ${branchName}`);
72+
} catch (error) {
73+
console.error(`Failed to delete branch ${branchName}:`, error);
74+
}
75+
}
76+
77+
async function main() {
78+
console.log("Starting cleanup of migrate branches without open PRs...");
79+
80+
const [prs, branches] = await Promise.all([
81+
getAllOpenPRs(),
82+
getAllBranches(),
83+
]);
84+
85+
const prBranchNames = new Set(prs.map((pr) => pr.head.ref));
86+
console.log("PR branches:", Array.from(prBranchNames));
87+
88+
const migrateBranches = filterMigrateBranches(branches);
89+
console.log(
90+
"Migrate branches:",
91+
migrateBranches.map((b) => b.name)
92+
);
93+
94+
const toDelete = migrateBranches.filter((b) => !prBranchNames.has(b.name));
95+
console.log(`Found ${toDelete.length} branches to delete:`);
96+
toDelete.forEach((b) => console.log(` - ${b.name}`));
97+
98+
if (toDelete.length === 0) {
99+
console.log("No branches to delete.");
100+
return;
101+
}
102+
103+
for (const branch of toDelete) {
104+
await deleteBranch(branch.name);
105+
}
106+
107+
console.log("Cleanup completed.");
108+
}
109+
110+
main().catch((err) => {
111+
console.error(err);
112+
process.exit(1);
113+
});

0 commit comments

Comments
 (0)