diff --git a/src/cli.ts b/src/cli.ts index 37f07516..bd3994a5 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -13,14 +13,12 @@ * this program. If not, see . */ import {Api} from '@openstapps/gitlab-api'; -import {MergeRequest} from '@openstapps/gitlab-api/lib/types'; import {Logger} from '@openstapps/logger'; -import {WebClient} from '@slack/client'; -import {asyncPool} from 'async-pool-native/dist/async-pool'; import * as commander from 'commander'; import {existsSync, readFileSync} from 'fs'; import {join} from 'path'; -import {GITLAB_API_URL, GROUPS} from './configuration'; +import {GITLAB_API_URL} from './configuration'; +import {remind} from './tasks/remind'; import {report} from './tasks/report'; import {tidy} from './tasks/tidy'; import {unlabel} from './tasks/unlabel'; @@ -69,38 +67,8 @@ commander commander .command('remind') .action(async () => { - const mergeRequests: MergeRequest[] = - await gitlabApi.makeGitLabAPIRequest(`groups/${GROUPS[0]}/merge_requests?state=opened`); - - const client = new WebClient(process.env.SLACK_API_TOKEN); - - await asyncPool(2, mergeRequests, async (mergeRequest) => { - if (mergeRequest.title.indexOf('WIP') !== 0) { - const config = await gitlabApi.makeGitLabAPIRequest( - `/projects/${mergeRequest.project_id}/merge_requests/${mergeRequest.iid}/approvals`, - ); - - if (config.merge_status === 'can_be_merged') { - if (config.approvals_left > 0) { - logger.warn(`Merge request '${mergeRequest.title}' needs more approvals!`); - - await client.chat.postMessage({ - channel: 'C762UG76Z', - text: `Merge request '${mergeRequest.title}' needs more approvals! See ${mergeRequest.web_url}!`, - }); - } else { - logger.log(`Merge request '${mergeRequest.title}' is ready to be merged!`); - - await client.chat.postMessage({ - channel: 'C762UG76Z', - text: `Merge request '${mergeRequest.title}' is ready to be merged! See ${mergeRequest.web_url}!`, - }); - } - } - } else { - logger.info(`Merge request '${mergeRequest.title}' is WIP.`); - } - }); + await remind(gitlabApi); + logger.ok('Done!'); }); commander diff --git a/src/tasks/report.ts b/src/tasks/report.ts index 318ef9aa..d21e7ca7 100644 --- a/src/tasks/report.ts +++ b/src/tasks/report.ts @@ -13,7 +13,7 @@ * this program. If not, see . */ import {Api} from '@openstapps/gitlab-api'; -import {Issue, Project, User} from '@openstapps/gitlab-api/lib/types'; +import {Issue, IssueState, MembershipScope, MergeRequestState, Project, User} from '@openstapps/gitlab-api/lib/types'; import {asyncPool} from 'async-pool-native/dist/async-pool'; import {readFileSync, writeFile} from 'fs'; import * as moment from 'moment'; @@ -30,7 +30,7 @@ const asyncWriteFile = promisify(writeFile); * * @param state State to check */ -export function issueStateIsOpenedOrClosed(state: string): state is 'opened' | 'closed' { +export function issueStateIsOpenedOrClosed(state: IssueState): state is IssueState.OPENED | IssueState.CLOSED { return ['opened', 'closed'].indexOf(state) >= 0; } @@ -191,8 +191,8 @@ export function groupIssuesByAssignee(issues: Issue[]): { [k: number]: AssigneeW }; } - if (issue.state === 'reopened') { - issue.state = 'opened'; + if (issue.state === IssueState.REOPENED) { + issue.state = IssueState.OPENED; } if (issueStateIsOpenedOrClosed(issue.state)) { @@ -273,7 +273,7 @@ export async function getMergeRequestsForProjects(api: Api, } // get all merge requests for project - const mergeRequests = await api.getMergeRequestsForProject(project.id); + const mergeRequests = await api.getMergeRequests(MembershipScope.PROJECTS, project.id, MergeRequestState.OPENED); // extract issue number from merge request projectMergeRequests[project.id] = mergeRequests.map((mergeRequest) => { @@ -332,11 +332,11 @@ export async function report(api: Api, label: string) { } }); - if (a.state === 'closed') { + if (a.state === IssueState.CLOSED) { weightA -= 10; } - if (b.state === 'closed') { + if (b.state === IssueState.CLOSED) { weightB -= 10; } diff --git a/src/tasks/tidy.ts b/src/tasks/tidy.ts index 4f0bac20..f84951c4 100644 --- a/src/tasks/tidy.ts +++ b/src/tasks/tidy.ts @@ -13,7 +13,14 @@ * this program. If not, see . */ import {Api} from '@openstapps/gitlab-api'; -import {AccessLevel, Label, Milestone, Project} from '@openstapps/gitlab-api/lib/types'; +import { + AccessLevel, + IssueState, + MembershipScope, + Milestone, + Project, + Scope, +} from '@openstapps/gitlab-api/lib/types'; import {asyncPool} from 'async-pool-native/dist/async-pool'; import {flatten2dArray, getProjects, logger} from '../common'; import {GROUPS, NEEDED_LABELS, NEEDED_MILESTONES, NOTE_PREFIX, PROTECTED_BRANCHES, SCHOOLS} from '../configuration'; @@ -31,7 +38,7 @@ export async function tidyIssuesWithoutMilestone(api: Api): Promise { return api.getIssues({ groupId: groupId, milestone: 'No Milestone', - state: 'opened', + state: IssueState.OPENED, }); }); @@ -66,6 +73,7 @@ export async function tidyIssuesWithoutMilestone(api: Api): Promise { await api.createNote( issue.project_id, + Scope.ISSUES, issue.iid, `${NOTE_PREFIX} Milestone was set automatically to \`Meeting\`.`, ); @@ -86,7 +94,7 @@ export async function tidyOpenIssuesWithoutMeetingLabel(api: Api): Promise const issueResults = await asyncPool(3, GROUPS, (groupId) => { return api.getIssues({ groupId: groupId, - state: 'opened', + state: IssueState.OPENED, }); }); @@ -110,6 +118,7 @@ export async function tidyOpenIssuesWithoutMeetingLabel(api: Api): Promise return api.createNote( issue.project_id, + Scope.ISSUES, issue.iid, `${NOTE_PREFIX} Automatically adding label 'meeting'\n\n/label ~meeting`); }); @@ -128,21 +137,21 @@ export async function tidyLabels(api: Api, projects: Project[]): Promise { const labels = await api.getLabels(project.id); const neededLabels = NEEDED_LABELS.slice(0); - const extraneousLabels: Label[] = []; + // const extraneousLabels: Label[] = []; labels.forEach((label) => { - let needed = false; + // let needed = false; neededLabels.forEach((neededLabel, neededLabelIdx) => { if (neededLabel.name.toLowerCase() === label.name.toLowerCase()) { neededLabels.splice(neededLabelIdx, 1); - needed = true; + // needed = true; } }); - if (!needed) { + /* if (!needed) { extraneousLabels.push(label); - } + } */ }); await asyncPool(2, neededLabels, async (neededLabel) => { @@ -225,7 +234,7 @@ export async function tidyProtectedBranches(api: Api, projects: Project[]): Prom * @param api GitLab API instance to use for the requests */ export async function tidySubGroupMembers(api: Api): Promise { - const stappsMembers = await api.getMembers('groups', GROUPS[0]); + const stappsMembers = await api.getMembers(MembershipScope.GROUPS, GROUPS[0]); const stappsMemberIds = stappsMembers.map((member) => member.id); const groupIdsToSchool: any = {}; @@ -235,12 +244,12 @@ export async function tidySubGroupMembers(api: Api): Promise { }); await asyncPool(2, GROUPS.slice(1), async (groupId) => { - const members = await api.getMembers('groups', groupId); + const members = await api.getMembers(MembershipScope.GROUPS, groupId); const memberIds = members.map((member) => member.id); await asyncPool(2, stappsMembers, async (stappsMember) => { if (memberIds.indexOf(stappsMember.id) === -1) { - await api.addMember('groups', groupId, stappsMember.id, AccessLevel.Developer); + await api.addMember(MembershipScope.GROUPS, groupId, stappsMember.id, AccessLevel.Developer); logger.log('Added ' + stappsMember.name + ' to group ' + groupIdsToSchool[groupId] + '.'); } @@ -248,7 +257,7 @@ export async function tidySubGroupMembers(api: Api): Promise { await asyncPool(2, members, async (member) => { if (stappsMemberIds.indexOf(member.id) === -1) { - await api.deleteMember('groups', groupId, member.id); + await api.deleteMember(MembershipScope.GROUPS, groupId, member.id); logger.log('Deleted member ' + member.name + ' from group ' + groupIdsToSchool[groupId] + '.'); } @@ -270,7 +279,7 @@ export async function tidyIssuesWithoutAssignee(api: Api): Promise { const issueResults = await asyncPool(3, GROUPS, (groupId) => { return api.getIssues({ groupId: groupId, - state: 'opened', + state: IssueState.OPENED, }); }); @@ -290,6 +299,7 @@ export async function tidyIssuesWithoutAssignee(api: Api): Promise { await api.createNote( issue.project_id, + Scope.ISSUES, issue.iid, `${NOTE_PREFIX} Assignee was set automatically to author.`, ); diff --git a/src/tasks/unlabel.ts b/src/tasks/unlabel.ts index b0339263..ed1d1bfc 100644 --- a/src/tasks/unlabel.ts +++ b/src/tasks/unlabel.ts @@ -13,6 +13,7 @@ * this program. If not, see . */ import {Api} from '@openstapps/gitlab-api'; +import {IssueState, Scope} from '@openstapps/gitlab-api/lib/types'; import {asyncPool} from 'async-pool-native/dist/async-pool'; import {flatten2dArray, logger} from '../common'; import {GROUPS, NOTE_PREFIX} from '../configuration'; @@ -26,7 +27,7 @@ export async function unlabel(api: Api) { const issueResults = await asyncPool(3, GROUPS, (groupId) => { return api.getIssues({ groupId: groupId, - state: 'closed', + state: IssueState.CLOSED, }); }); @@ -40,6 +41,7 @@ export async function unlabel(api: Api) { await api.createNote( issue.project_id, + Scope.ISSUES, issue.iid, `${NOTE_PREFIX} Removed label \`meeting\` automatically. /unlabel ~meeting`,