Skip to content

Instantly share code, notes, and snippets.

@ThomasChan
Created March 22, 2024 02:23
Show Gist options
  • Save ThomasChan/218dac9a91575121d6d4eac7f99e789f to your computer and use it in GitHub Desktop.
Save ThomasChan/218dac9a91575121d6d4eac7f99e789f to your computer and use it in GitHub Desktop.
Batch reassignee self-hosted gitlab issues
/**
* @author ThomasChan
* @usage deno run --allow-net reassignee.ts --token=xxx --assignee=AAA --assignTo=BBB
*/
import { Gitlab } from 'https://esm.sh/@gitbeaker/rest?dts';
function parseArgs(args: string[]) {
const params: { [key: string]: string } = {};
args.forEach(arg => {
const [key, value] = arg.split('=');
if (key.startsWith('--')) {
params[key.slice(2)] = value;
}
});
return params;
}
const args = parseArgs(Deno.args);
const host = args.host;
const token = args.token;
const projectId = parseInt(args.projectId);
const assignee = args.assignee;
const assignTo = args.assignTo;
const perPage = parseInt(args.perPage ?? '100');
const api = new Gitlab({
host: host,
token: token,
});
async function reassignIssue(issueId: number, assigneeIds: number[]) {
try {
await api.Issues.edit(projectId, issueId, {
assigneeIds,
});
await new Promise(resolve => setTimeout(resolve, 200));
console.log(`Issue ${issueId} reassignee to ${assigneeIds.join(',')}`);
} catch (error) {
console.error(`Issue ${issueId} reassignee failed:`, error);
}
}
async function main() {
try {
const users = await api.Users.all();
const transferFrom = users.find(user => user.username === assignee);
const transferTo = users.find(user => user.username === assignTo);
if (!transferFrom) {
console.error('Cannot found username: ', transferFrom);
return Deno.exit(1);
}
if (!transferTo) {
console.error('Cannot found username: ', transferTo);
return Deno.exit(1);
}
let processed = 0;
while (true) {
const issues = await api.Issues.all({
projectId: projectId,
assigneeUsername: [assignee],
state: 'opened',
perPage: perPage,
page: 1,
});
if (!issues.length) {
break;
}
for (const issue of issues) {
await reassignIssue(issue.iid, issue.assignees.map(assigner => assigner.id).filter(id => id !== transferFrom.id).concat(transferTo.id));
}
processed += issues.length;
console.log(`Processed ${processed} issues`);
}
Deno.exit(0);
} catch (error) {
console.error(error);
Deno.exit(1);
}
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment