Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Skipping this action when repository is not inlcuded in ZenHub workspace #20

Merged
merged 13 commits into from
Aug 4, 2023
2 changes: 2 additions & 0 deletions src/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export const PARENT_TEAM_SLUG = 'product-engineering';

export const ZENHUB_WORKSPACE_ID = '5f6454160d9f82000fa6733f';

export const ZENHUB_WORKSPACE_NAME = 'Platform Team';

export const TEAM_LABEL_PREFIX = 't-';

export const TEAM_NAME_TO_LABEL: { [name: string]: string} = {
Expand Down
8 changes: 8 additions & 0 deletions src/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
findCurrentTeamMilestone,
getTeamLabelName,
// ensureCorrectLinkingAndEstimates,
// isRepoIncludedInZenHubWorkspace,
getLinkedIssue,
getLinkedEpics,
ZenhubTimelineItem,
Expand Down Expand Up @@ -171,4 +172,11 @@ describe('isPullRequestTested', () => {
console.log(await isPullRequestTested(getOctokit('xxx'), pullRequest));
});
});

describe('isRepoIncludedInZenHubWorkspace', () => {
test('works correctly with a PR', async () => {
const pullRequest = require('./mocks/pull_request.json'); // eslint-disable-line
console.log(await isRepoIncludedInZenHubWorkspace(pullRequest.base.repo.name));
});
});
*/
48 changes: 48 additions & 0 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
PARENT_TEAM_SLUG,
TEAM_NAME_TO_LABEL,
ZENHUB_WORKSPACE_ID,
ZENHUB_WORKSPACE_NAME,
} from './consts';

type Milestone = components['schemas']['milestone'];
Expand Down Expand Up @@ -222,6 +223,53 @@ query getIssueInfo($repositoryGhId: Int!, $issueNumber: Int!) {
}
`;

const ZENHUB_WORKSPACE_REPOSITORIES_QUERY = `
query getWorkspaceRepositories($workspaceName: String!, $endCursor: String) {
viewer {
id
searchWorkspaces(query: $workspaceName) {
nodes {
id
name
repositoriesConnection(first: 100, after: $endCursor) {
nodes {
id
name
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
}
`;

/**
* Checks if the repository is included in the ZenHub workspace defined by ZENHUB_WORKSPACE_NAME.
*/
export async function isRepoIncludedInZenHubWorkspace(repositoryName: string): Promise<boolean> {
const repositories = [];
let pageInfo;

do {
const response = await queryZenhubGraphql('getWorkspaceRepositories', ZENHUB_WORKSPACE_REPOSITORIES_QUERY, {
workspaceName: ZENHUB_WORKSPACE_NAME,
endCursor: pageInfo?.endCursor,
});

const { repositoriesConnection } = response.data.data.viewer.searchWorkspaces.nodes[0].repositoriesConnectio;
const repos = repositoriesConnection.nodes;
pageInfo = repositoriesConnection.pageInfo as { endCursor: string, hasNextPage: boolean };

repositories.push(...repos);
} while (pageInfo.hasNextPage);

return repositories.map((repo) => repo.name).includes(repositoryName);
};

/**
* Makes sure that:
* - PR either has issue or epic linked or has `adhoc` label
Expand Down
26 changes: 24 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
addTeamLabel,
ensureCorrectLinkingAndEstimates,
isPullRequestTested,
isRepoIncludedInZenHubWorkspace,
} from './helpers';
import {
TEAM_LABEL_PREFIX,
Expand Down Expand Up @@ -39,19 +40,38 @@ async function run(): Promise<void> {
pull_number: pullRequestContext.number,
});

// Skip the PR if not a member of one of the product teams.
const teamName = await findUsersTeamName(orgOctokit, pullRequestContext.user.login);
if (!teamName) {
core.warning(`User ${pullRequestContext.user.login} is not a member of team. Skipping toolkit action.`);
return;
}

// Skip if the repository is not connected to the ZenHub workspace.
if (!isRepoIncludedInZenHubWorkspace(pullRequest.base.repo.name)) {
core.warning(`Repository ${pullRequest.base.repo.name} is not included in ZenHub workspace. Skipping toolkit action.`);
return;
}

// Skip if the team is listed in TEAMS_NOT_USING_ZENHUB.
const isTeamUsingZenhub = !TEAMS_NOT_USING_ZENHUB.includes(teamName);
if (!isTeamUsingZenhub) return;

// All these 4 actions below are idempotent, so they can be run on every PR update.
// Also, these actions do not require any action from a PR author.

// 1. Assigns PR creator if not already assigned.
const isCreatorAssigned = pullRequestContext.assignees.find((u: Assignee) => u?.login === pullRequestContext.user.login);
if (!isCreatorAssigned) await assignPrCreator(github.context, repoOctokit, pullRequest);
if (!pullRequestContext.milestone && isTeamUsingZenhub) await fillCurrentMilestone(github.context, repoOctokit, pullRequest, teamName);

// 2. Assigns current milestone if not already assigned.
if (!pullRequestContext.milestone) await fillCurrentMilestone(github.context, repoOctokit, pullRequest, teamName);

// 3. Adds team label if not already there.
const teamLabel = pullRequestContext.labels.find((label: Label) => label.name.startsWith(TEAM_LABEL_PREFIX));
if (!teamLabel) await addTeamLabel(github.context, repoOctokit, pullRequest, teamName);

// 4. Checks if PR is tested and adds a `tested` label if so.
const isTested = await isPullRequestTested(repoOctokit, pullRequest);
if (isTested) {
await repoOctokit.rest.issues.addLabels({
Expand All @@ -62,8 +82,10 @@ async function run(): Promise<void> {
});
}

// On the other hand, this is a check that author of the PR correctly filled in the details.
// I.e., that the PR is linked to the ZenHub issue and that the estimate is set either on issue or on the PR.
try {
if (isTeamUsingZenhub) await ensureCorrectLinkingAndEstimates(pullRequest, repoOctokit, true);
await ensureCorrectLinkingAndEstimates(pullRequest, repoOctokit, true);
} catch (err) {
console.log('Function ensureCorrectLinkingAndEstimates() has failed on dry run');
console.log(err);
Expand Down