Skip to content

Commit

Permalink
WIP - bad commit message to ensure fixups are created for actual merging
Browse files Browse the repository at this point in the history
  • Loading branch information
josephperrott committed Sep 24, 2021
1 parent e520244 commit cf69b01
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 271 deletions.
181 changes: 80 additions & 101 deletions github-actions/slash-commands/main.js

Large diffs are not rendered by default.

100 changes: 100 additions & 0 deletions ng-dev/pr/common/fetch-pull-request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {params, types as graphqlTypes} from 'typed-graphqlify';
import {AuthenticatedGitClient} from '../../utils/git/authenticated-git-client';
import {getPr} from '../../utils/github';

/** Graphql schema for the response body the requested pull request. */
/** Graphql schema for the response body the requested pull request. */
export const PR_SCHEMA = {
url: graphqlTypes.string,
isDraft: graphqlTypes.boolean,
state: graphqlTypes.custom<PullRequestState>(),
number: graphqlTypes.number,
mergeable: graphqlTypes.custom<MergeableState>(),
updatedAt: graphqlTypes.string,
// Only the last 100 commits from a pull request are obtained as we likely will never see a pull
// requests with more than 100 commits.
commits: params(
{last: 100},
{
totalCount: graphqlTypes.number,
nodes: [
{
commit: {
statusCheckRollup: {
state: graphqlTypes.custom<StatusState>(),
contexts: params(
{last: 100},
{
nodes: [
onUnion({
CheckRun: {
__typename: graphqlTypes.constant('CheckRun'),
status: graphqlTypes.custom<CheckStatusState>(),
conclusion: graphqlTypes.custom<CheckConclusionState>(),
name: graphqlTypes.string,
},
StatusContext: {
__typename: graphqlTypes.constant('StatusContext'),
state: graphqlTypes.custom<StatusState>(),
context: graphqlTypes.string,
},
}),
],
},
),
},
message: graphqlTypes.string,
},
},
],
},
),
maintainerCanModify: graphqlTypes.boolean,
viewerDidAuthor: graphqlTypes.boolean,
headRefOid: graphqlTypes.string,
headRef: {
name: graphqlTypes.string,
repository: {
url: graphqlTypes.string,
nameWithOwner: graphqlTypes.string,
},
},
baseRef: {
name: graphqlTypes.string,
repository: {
url: graphqlTypes.string,
nameWithOwner: graphqlTypes.string,
},
},
baseRefName: graphqlTypes.string,
title: graphqlTypes.string,
labels: params(
{first: 100},
{
nodes: [
{
name: graphqlTypes.string,
},
],
},
),
};

/** A pull request retrieved from github via the graphql API. */
export type RawPullRequest = typeof PR_SCHEMA;

/** Fetches a pull request from Github. Returns null if an error occurred. */
export async function fetchPullRequestFromGithub(
git: AuthenticatedGitClient,
prNumber: number,
): Promise<RawPullRequest | null> {
return await getPr(PR_SCHEMA, prNumber, git);
}
22 changes: 7 additions & 15 deletions ng-dev/pr/common/fetch-pull-request/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,22 @@

import {AuthenticatedGitClient} from '../../../utils/git/authenticated-git-client';
import {getPendingPrs, getPr} from '../../../utils/github';
import {normalizePullRequest, PullRequest} from './normalize-pull-request';
import {PR_SCHEMA} from './schema';
import {PullRequestFromGithub, PR_SCHEMA} from './schema';

export {PullRequest};
export {getStatusesForCommit} from './normalize-pull-request';
export {PullRequestFromGithub};

/** Fetches a pull request from Github. Returns null if an error occurred. */
export async function fetchPullRequestFromGithub(
git: AuthenticatedGitClient,
prNumber: number,
): Promise<PullRequest | null> {
const pullRequest = await getPr(PR_SCHEMA, prNumber, git);
if (pullRequest === null) {
return null;
}
return normalizePullRequest(pullRequest);
): Promise<PullRequestFromGithub | null> {
return await getPr(PR_SCHEMA, prNumber, git);
}

/** Fetches a pull request from Github. Returns null if an error occurred. */
export async function fetchPendingPullRequestsFromGithub(
git: AuthenticatedGitClient,
): Promise<PullRequest[] | null> {
const pullRequests = await getPendingPrs(PR_SCHEMA, git);
if (pullRequests === null) {
return null;
}
return pullRequests.map(normalizePullRequest);
): Promise<PullRequestFromGithub[] | null> {
return await getPendingPrs(PR_SCHEMA, git);
}
129 changes: 25 additions & 104 deletions ng-dev/pr/common/fetch-pull-request/normalize-pull-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,118 +6,42 @@
* found in the LICENSE file at https://angular.io/license
*/

import {
CheckStatusState,
CheckConclusionState,
PullRequestStatus,
StatusState,
PullRequestState,
MergeableState,
} from './pull-request-types';
import {PR_SCHEMA} from './schema';
import {PullRequestStatus} from './pull-request-types';
import {CheckConclusionState, StatusState, CheckStatusState} from '@octokit/graphql-schema';
import {PullRequestFromGithub} from './schema';

/** Pull Request information from Github normalized for consistency. */
export interface PullRequest {
url: string;
isDraft: boolean;
state: typeof PullRequestState[number];
number: number;
mergeable: typeof MergeableState[number];
updatedAt: string;
commits: {
totalCount: number;
commits: {
status: PullRequestStatus;
statuses: {
type: 'check' | 'status';
name: string;
status: PullRequestStatus;
}[];
message: string;
}[];
};
maintainerCanModify: boolean;
viewerDidAuthor: boolean;
headRefOid: string;
headRef: {
name: string;
repository: {
url: string;
nameWithOwner: string;
};
};
baseRef: {
name: string;
repository: {
url: string;
nameWithOwner: string;
};
};
baseRefName: string;
title: string;
labels: {name: string}[];
}

/** The raw pull request response from Github. */
type PullRequestFromSchema = typeof PR_SCHEMA;

/** Normalize the retrieved pull request, using consistent statues, labeling, etc. */
export function normalizePullRequest(pullRequest: PullRequestFromSchema): PullRequest {
return {
...pullRequest,
labels: normalizeLabels(pullRequest.labels),
commits: normalizeCommits(pullRequest.commits),
};
}

/** Normalize the label entries. */
function normalizeLabels(labels: PullRequestFromSchema['labels']) {
return labels.nodes.map((label) => label);
}
type PullRequestCommitFromGithub = PullRequestFromGithub['commits']['nodes'][number]['commit'];

/**
* Normalize the commits retrieved for the pull request, using a consistent interface for both
* Normalize the statuses for a commit from a pull requeste, using a consistent interface for both
* status and checks results.
*/
function normalizeCommits({
nodes,
totalCount,
}: PullRequestFromSchema['commits']): PullRequest['commits'] {
const commits = nodes.map(({commit}) => {
const statuses = commit.statusCheckRollup.contexts.nodes.map<
PullRequest['commits']['commits'][number]['statuses'][number]
>((context) => {
switch (context.__typename) {
case 'CheckRun':
return {
type: 'check',
name: context.name,
status: normalizeGithubCheckStatusState(context.conclusion, context.status),
};
case 'StatusContext':
return {
type: 'status',
name: context.context,
status: normalizeGithubStatusState(context.state),
};
}
});

return {
status: normalizeGithubStatusState(commit.statusCheckRollup.state),
statuses,
message: commit.message,
};
export function getStatusesForCommit({statusCheckRollup}: PullRequestCommitFromGithub) {
const statuses = statusCheckRollup.contexts.nodes.map((context) => {
switch (context.__typename) {
case 'CheckRun':
return {
type: 'check',
name: context.name,
status: normalizeGithubCheckStatusState(context.conclusion, context.status),
};
case 'StatusContext':
return {
type: 'status',
name: context.context,
status: normalizeGithubStatusState(context.state),
};
}
});

return {
commits,
totalCount,
combinedStatus: normalizeGithubStatusState(statusCheckRollup.state),
statuses,
};
}

/** Retrieve the normalized PullRequestStatus for the provided github status state. */
function normalizeGithubStatusState(state: typeof StatusState[number]) {
function normalizeGithubStatusState(state: StatusState) {
switch (state) {
case 'FAILURE':
case 'ERROR':
Expand All @@ -131,10 +55,7 @@ function normalizeGithubStatusState(state: typeof StatusState[number]) {
}

/** Retrieve the normalized PullRequestStatus for the provided github check state. */
function normalizeGithubCheckStatusState(
conclusion: typeof CheckConclusionState[number],
status: typeof CheckStatusState[number],
) {
function normalizeGithubCheckStatusState(conclusion: CheckConclusionState, status: CheckStatusState) {
switch (status) {
case 'QUEUED':
case 'IN_PROGRESS':
Expand Down
28 changes: 0 additions & 28 deletions ng-dev/pr/common/fetch-pull-request/pull-request-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,3 @@ export enum PullRequestStatus {
FAILING,
PENDING,
}

// Possible return values for objects in the Github response cannot be enums as the typings become
// the enum OR any of the strings within the enum, which typescript does not like for the
// normalization functions. Instead these are simply defined as array constants expressing all of
// the possible values.
export const PullRequestState = ['OPEN', 'CLOSED', 'MERGED'] as const;
export const StatusState = ['FAILURE', 'PENDING', 'SUCCESS', 'EXPECTED', 'ERROR'] as const;
export const CheckConclusionState = [
'ACTION_REQUIRED',
'TIMED_OUT',
'CANCELLED',
'FAILURE',
'SUCCESS',
'NEUTRAL',
'SKIPPED',
'STARTUP_FAILURE',
'STALE',
] as const;
export const CheckStatusState = [
'QUEUED',
'IN_PROGRESS',
'COMPLETED',
'WAITING',
'PENDING',
'REQUESTED',
] as const;

export const MergeableState = ['MERGEABLE', 'CONFLICTING', 'UNKNOWN'] as const;
27 changes: 14 additions & 13 deletions ng-dev/pr/common/fetch-pull-request/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,15 @@
*/

import {params, types as graphqlTypes, onUnion} from 'typed-graphqlify';
import {
CheckConclusionState,
CheckStatusState,
MergeableState,
PullRequestState,
StatusState,
} from './pull-request-types';
import {CheckConclusionState, StatusState, PullRequestState, MergeableState, CheckStatusState} from '@octokit/graphql-schema';

/** Graphql schema for the response body the requested pull request. */
export const PR_SCHEMA = {
url: graphqlTypes.string,
isDraft: graphqlTypes.boolean,
state: graphqlTypes.oneOf(PullRequestState),
state: graphqlTypes.custom<PullRequestState>(),
number: graphqlTypes.number,
mergeable: graphqlTypes.oneOf(MergeableState),
mergeable: graphqlTypes.custom<MergeableState>(),
updatedAt: graphqlTypes.string,
// Only the last 100 commits from a pull request are obtained as we likely will never see a pull
// requests with more than 100 commits.
Expand All @@ -33,21 +27,21 @@ export const PR_SCHEMA = {
{
commit: {
statusCheckRollup: {
state: graphqlTypes.oneOf(StatusState),
state: graphqlTypes.custom<StatusState>(),
contexts: params(
{last: 100},
{
nodes: [
onUnion({
CheckRun: {
__typename: graphqlTypes.constant('CheckRun'),
status: graphqlTypes.oneOf(CheckStatusState),
conclusion: graphqlTypes.oneOf(CheckConclusionState),
status: graphqlTypes.custom<CheckStatusState>(),
conclusion: graphqlTypes.custom<CheckConclusionState>(),
name: graphqlTypes.string,
},
StatusContext: {
__typename: graphqlTypes.constant('StatusContext'),
state: graphqlTypes.oneOf(StatusState),
state: graphqlTypes.custom<StatusState>(),
context: graphqlTypes.string,
},
}),
Expand Down Expand Up @@ -91,3 +85,10 @@ export const PR_SCHEMA = {
},
),
};

export type PullRequestFromGithub = typeof PR_SCHEMA;


let x: PullRequestFromGithub;

x.commits.nodes[0].commit.statusCheckRollup.contexts.nodes[0].
Loading

0 comments on commit cf69b01

Please sign in to comment.