Flatten Api, normalize signatures

Signed-off-by: Erik Engervall <erik.engervall@gmail.com>
This commit is contained in:
Erik Engervall
2021-04-29 22:32:14 +02:00
parent fd5b531567
commit 496bdbf041
7 changed files with 255 additions and 262 deletions
@@ -32,14 +32,15 @@ describe('GitReleaseApiClient', () => {
expect(gitReleaseApiClient).toMatchInlineSnapshot(`
GitReleaseApiClient {
"baseUrl": "https://api.github.com",
"createRc": Object {
"createRelease": [Function],
"getComparison": [Function],
},
"createCommit": [Function],
"createRef": [Function],
"createRelease": [Function],
"createTagObject": [Function],
"getAllReleases": [Function],
"getAllTags": [Function],
"getBranch": [Function],
"getCommit": [Function],
"getComparison": [Function],
"getHost": [Function],
"getLatestRelease": [Function],
"getOwners": [Function],
@@ -47,6 +48,7 @@ describe('GitReleaseApiClient', () => {
"getRepoPath": [Function],
"getRepositories": [Function],
"getRepository": [Function],
"getSingleTag": [Function],
"getUser": [Function],
"githubAuthApi": Object {
"getAccessToken": [MockFunction],
@@ -54,18 +56,12 @@ describe('GitReleaseApiClient', () => {
"host": "github.com",
"patch": Object {
"createCherryPickCommit": [Function],
"createTempCommit": [Function],
"forceBranchHeadToTempCommit": [Function],
"merge": [Function],
"replaceTempCommit": [Function],
"updateRelease": [Function],
},
"promoteRelease": [Function],
"stats": Object {
"getAllReleases": [Function],
"getAllTags": [Function],
"getSingleTag": [Function],
},
}
`);
});
@@ -259,47 +259,50 @@ export class GitReleaseApiClient implements GitReleaseApi {
};
};
createRc: GitReleaseApi['createRc'] = {
getComparison: async ({ owner, repo, base, head }) => {
const { octokit } = await this.getOctokit();
const compareCommitsResponse = await octokit.repos.compareCommits({
owner,
repo,
base,
head,
});
return {
htmlUrl: compareCommitsResponse.data.html_url,
aheadBy: compareCommitsResponse.data.ahead_by,
};
},
createRelease: async ({
getComparison: GitReleaseApi['getComparison'] = async ({
owner,
repo,
base,
head,
}) => {
const { octokit } = await this.getOctokit();
const compareCommitsResponse = await octokit.repos.compareCommits({
owner,
repo,
rcReleaseTag,
releaseName,
rcBranch,
releaseBody,
}) => {
const { octokit } = await this.getOctokit();
const createReleaseResponse = await octokit.repos.createRelease({
owner,
repo,
tag_name: rcReleaseTag,
name: releaseName,
target_commitish: rcBranch,
body: releaseBody,
prerelease: true,
});
base,
head,
});
return {
name: createReleaseResponse.data.name,
htmlUrl: createReleaseResponse.data.html_url,
tagName: createReleaseResponse.data.tag_name,
};
},
return {
htmlUrl: compareCommitsResponse.data.html_url,
aheadBy: compareCommitsResponse.data.ahead_by,
};
};
createRelease: GitReleaseApi['createRelease'] = async ({
owner,
repo,
tagName,
name,
targetCommitish,
body,
}) => {
const { octokit } = await this.getOctokit();
const createReleaseResponse = await octokit.repos.createRelease({
owner,
repo,
tag_name: tagName,
name: name,
target_commitish: targetCommitish,
body,
prerelease: true,
});
return {
name: createReleaseResponse.data.name,
htmlUrl: createReleaseResponse.data.html_url,
tagName: createReleaseResponse.data.tag_name,
};
};
createTagObject: GitReleaseApi['createTagObject'] = async ({
@@ -332,41 +335,36 @@ export class GitReleaseApiClient implements GitReleaseApi {
};
};
createCommit: GitReleaseApi['createCommit'] = async ({
owner,
repo,
message,
tree,
parents,
}) => {
const { octokit } = await this.getOctokit();
const { data: commit } = await octokit.git.createCommit({
owner,
repo,
message,
tree,
parents,
});
return {
message: commit.message,
sha: commit.sha,
};
};
patch: GitReleaseApi['patch'] = {
createTempCommit: async ({
owner,
repo,
tagParts,
releaseBranchTree,
selectedPatchCommit,
}) => {
const { octokit } = await this.getOctokit();
const { data: tempCommit } = await octokit.git.createCommit({
owner,
repo,
message: `Temporary commit for patch ${tagParts.patch}`,
tree: releaseBranchTree,
parents: [selectedPatchCommit.firstParentSha ?? ''], // TODO: Avoid `??`
});
return {
message: tempCommit.message,
sha: tempCommit.sha,
};
},
forceBranchHeadToTempCommit: async ({
owner,
repo,
releaseBranchName,
tempCommit,
}) => {
forceBranchHeadToTempCommit: async ({ owner, repo, ref, sha }) => {
const { octokit } = await this.getOctokit();
await octokit.git.updateRef({
owner,
repo,
ref: `heads/${releaseBranchName}`,
sha: tempCommit.sha,
ref,
sha,
force: true,
});
},
@@ -491,61 +489,63 @@ ${selectedPatchCommit.commit.message}`,
};
};
stats: GitReleaseApi['stats'] = {
getAllTags: async ({ owner, repo }) => {
const { octokit } = await this.getOctokit();
getAllTags: GitReleaseApi['getAllTags'] = async ({ owner, repo }) => {
const { octokit } = await this.getOctokit();
const tags = await octokit.paginate(octokit.git.listMatchingRefs, {
owner,
repo,
ref: 'tags',
per_page: 100,
...DISABLE_CACHE,
});
const tags = await octokit.paginate(octokit.git.listMatchingRefs, {
owner,
repo,
ref: 'tags',
per_page: 100,
...DISABLE_CACHE,
});
return tags
.map(tag => ({
tagName: tag.ref.replace('refs/tags/', ''),
tagSha: tag.object.sha,
tagType: tag.object.type as 'tag' | 'commit',
}))
.reverse();
},
return tags
.map(tag => ({
tagName: tag.ref.replace('refs/tags/', ''),
tagSha: tag.object.sha,
tagType: tag.object.type as 'tag' | 'commit',
}))
.reverse();
};
getAllReleases: async ({ owner, repo }) => {
const { octokit } = await this.getOctokit();
getAllReleases: GitReleaseApi['getAllReleases'] = async ({ owner, repo }) => {
const { octokit } = await this.getOctokit();
const releases = await octokit.paginate(octokit.repos.listReleases, {
owner,
repo,
per_page: 100,
...DISABLE_CACHE,
});
const releases = await octokit.paginate(octokit.repos.listReleases, {
owner,
repo,
per_page: 100,
...DISABLE_CACHE,
});
return releases.map(release => ({
id: release.id,
name: release.name,
tagName: release.tag_name,
createdAt: release.published_at,
htmlUrl: release.html_url,
}));
},
return releases.map(release => ({
id: release.id,
name: release.name,
tagName: release.tag_name,
createdAt: release.published_at,
htmlUrl: release.html_url,
}));
};
getSingleTag: async ({ owner, repo, tagSha }) => {
const { octokit } = await this.getOctokit();
const singleTag = await octokit.git.getTag({
owner,
repo,
tag_sha: tagSha,
});
getSingleTag: GitReleaseApi['getSingleTag'] = async ({
owner,
repo,
tagSha,
}) => {
const { octokit } = await this.getOctokit();
const singleTag = await octokit.git.getTag({
owner,
repo,
tag_sha: tagSha,
});
return {
date: singleTag.data.tagger.date,
username: singleTag.data.tagger.name,
userEmail: singleTag.data.tagger.email,
objectSha: singleTag.data.object.sha,
};
},
return {
date: singleTag.data.tagger.date,
username: singleTag.data.tagger.name,
userEmail: singleTag.data.tagger.email,
objectSha: singleTag.data.object.sha,
};
};
}
@@ -654,30 +654,28 @@ export interface GitReleaseApi {
objectSha: string;
}>;
createRc: {
getComparison: (
args: {
base: string;
head: string;
} & OwnerRepo,
) => Promise<{
htmlUrl: string;
aheadBy: number;
}>;
getComparison: (
args: {
base: string;
head: string;
} & OwnerRepo,
) => Promise<{
htmlUrl: string;
aheadBy: number;
}>;
createRelease: (
args: {
rcReleaseTag: string;
releaseName: string;
rcBranch: string;
releaseBody: string;
} & OwnerRepo,
) => Promise<{
name: string | null;
htmlUrl: string;
createRelease: (
args: {
tagName: string;
}>;
};
name: string;
targetCommitish: string;
body: string;
} & OwnerRepo,
) => Promise<{
name: string | null;
htmlUrl: string;
tagName: string;
}>;
createTagObject: (
args: {
@@ -692,24 +690,22 @@ export interface GitReleaseApi {
tagSha: string;
}>;
patch: {
createTempCommit: (
args: {
tagParts: SemverTagParts | CalverTagParts;
releaseBranchTree: string;
selectedPatchCommit: UnboxArray<
UnboxReturnedPromise<GitReleaseApi['getRecentCommits']>
>;
} & OwnerRepo,
) => Promise<{
createCommit: (
args: {
message: string;
sha: string;
}>;
tree: string;
parents: string[];
} & OwnerRepo,
) => Promise<{
message: string;
sha: string;
}>;
patch: {
forceBranchHeadToTempCommit: (
args: {
releaseBranchName: string;
tempCommit: CreateTempCommitResult;
sha: string;
ref: string;
} & OwnerRepo,
) => Promise<void>;
@@ -782,40 +778,47 @@ export interface GitReleaseApi {
htmlUrl: string;
}>;
stats: {
getAllTags: (
args: OwnerRepo,
) => Promise<
Array<{
tagName: string;
tagSha: string;
tagType: 'tag' | 'commit';
}>
>;
/**
* Used for the Stats feature
*/
getAllTags: (
args: OwnerRepo,
) => Promise<
Array<{
tagName: string;
tagSha: string;
tagType: 'tag' | 'commit';
}>
>;
getAllReleases: (
args: OwnerRepo,
) => Promise<
Array<{
id: number;
name: string | null;
tagName: string;
createdAt: string | null;
htmlUrl: string;
}>
>;
/**
* Used for the Stats feature
*/
getAllReleases: (
args: OwnerRepo,
) => Promise<
Array<{
id: number;
name: string | null;
tagName: string;
createdAt: string | null;
htmlUrl: string;
}>
>;
getSingleTag: (
args: {
tagSha: string;
} & OwnerRepo,
) => Promise<{
date: string;
username: string;
userEmail: string;
objectSha: string;
}>;
};
/**
* Used for the Stats feature
*/
getSingleTag: (
args: {
tagSha: string;
} & OwnerRepo,
) => Promise<{
date: string;
username: string;
userEmail: string;
objectSha: string;
}>;
}
export type GetOwnersResult = UnboxReturnedPromise<GitReleaseApi['getOwners']>;
@@ -839,13 +842,10 @@ export type GetLatestCommitResult = UnboxReturnedPromise<
export type GetBranchResult = UnboxReturnedPromise<GitReleaseApi['getBranch']>;
export type CreateRefResult = UnboxReturnedPromise<GitReleaseApi['createRef']>;
export type GetComparisonResult = UnboxReturnedPromise<
GitReleaseApi['createRc']['getComparison']
GitReleaseApi['getComparison']
>;
export type CreateReleaseResult = UnboxReturnedPromise<
GitReleaseApi['createRc']['createRelease']
>;
export type CreateTempCommitResult = UnboxReturnedPromise<
GitReleaseApi['patch']['createTempCommit']
GitReleaseApi['createRelease']
>;
export type ForceBranchHeadToTempCommitResult = UnboxReturnedPromise<
GitReleaseApi['patch']['forceBranchHeadToTempCommit']
@@ -867,11 +867,11 @@ export type PromoteReleaseResult = UnboxReturnedPromise<
GitReleaseApi['promoteRelease']
>;
export type GetAllTagsResult = UnboxReturnedPromise<
GitReleaseApi['stats']['getAllTags']
GitReleaseApi['getAllTags']
>;
export type GetAllReleasesResult = UnboxReturnedPromise<
GitReleaseApi['stats']['getAllReleases']
GitReleaseApi['getAllReleases']
>;
export type GetSingleTagResult = UnboxReturnedPromise<
GitReleaseApi['stats']['getSingleTag']
GitReleaseApi['getSingleTag']
>;
@@ -197,7 +197,7 @@ export function useCreateReleaseCandidate({
? latestRelease.targetCommitish
: defaultBranch;
const nextReleaseBranch = releaseCandidateGitInfo.rcBranch;
const comparison = await pluginApiClient.createRc
const comparison = await pluginApiClient
.getComparison({
owner: project.owner,
repo: project.repo,
@@ -235,14 +235,14 @@ export function useCreateReleaseCandidate({
abortIfError(getComparisonRes.error);
if (!getComparisonRes.value) return undefined;
const createReleaseResult = await pluginApiClient.createRc
const createReleaseResult = await pluginApiClient
.createRelease({
owner: project.owner,
repo: project.repo,
rcReleaseTag: releaseCandidateGitInfo.rcReleaseTag,
releaseName: releaseCandidateGitInfo.releaseName,
rcBranch: releaseCandidateGitInfo.rcBranch,
releaseBody: getComparisonRes.value.releaseBody,
tagName: releaseCandidateGitInfo.rcReleaseTag,
name: releaseCandidateGitInfo.releaseName,
targetCommitish: releaseCandidateGitInfo.rcBranch,
body: getComparisonRes.value.releaseBody,
})
.catch(asyncCatcher);
@@ -97,14 +97,15 @@ export function usePatch({
abortIfError(releaseBranchRes.error);
if (!releaseBranchRes.value) return undefined;
const tempCommit = await pluginApiClient.patch
.createTempCommit({
const tempCommit = await pluginApiClient
.createCommit({
owner: project.owner,
repo: project.repo,
releaseBranchTree:
releaseBranchRes.value.releaseBranch.commit.commit.tree.sha,
selectedPatchCommit: releaseBranchRes.value.selectedPatchCommit,
tagParts,
message: `Temporary commit for patch ${tagParts.patch}`,
parents: [
releaseBranchRes.value.selectedPatchCommit.firstParentSha ?? '',
],
tree: releaseBranchRes.value.releaseBranch.commit.commit.tree.sha,
})
.catch(asyncCatcher);
@@ -130,8 +131,8 @@ export function usePatch({
.forceBranchHeadToTempCommit({
owner: project.owner,
repo: project.repo,
tempCommit: tempCommitRes.value,
releaseBranchName,
sha: tempCommitRes.value.sha,
ref: `heads/${releaseBranchName}`,
})
.catch(asyncCatcher);
@@ -140,7 +141,7 @@ export function usePatch({
});
return {
great: 'success 🚀',
trigger: 'next step 🚀 ',
};
}, [tempCommitRes.value, tempCommitRes.error]);
@@ -39,12 +39,12 @@ export const getTagDates = async ({
}: GetTagDates) => {
if (startTag.tagType === 'tag' && endTag.tagType === 'tag') {
const [{ date: startDate }, { date: endDate }] = await Promise.all([
pluginApiClient.stats.getSingleTag({
pluginApiClient.getSingleTag({
owner: project.owner,
repo: project.repo,
tagSha: startTag.tagSha,
}),
pluginApiClient.stats.getSingleTag({
pluginApiClient.getSingleTag({
owner: project.owner,
repo: project.repo,
tagSha: endTag.tagSha,
@@ -126,7 +126,7 @@ async function getCommitFromTag({
project: GetTagDates['project'];
tag: GetTagDates['startTag'] | GetTagDates['endTag'];
}) {
const singleTag = await pluginApiClient.stats.getSingleTag({
const singleTag = await pluginApiClient.getSingleTag({
owner: project.owner,
repo: project.repo,
tagSha: tag.tagSha,
@@ -26,11 +26,11 @@ export const useGetStats = () => {
const stats = useAsync(async () => {
const [allReleases, allTags] = await Promise.all([
pluginApiClient.stats.getAllReleases({
pluginApiClient.getAllReleases({
owner: project.owner,
repo: project.repo,
}),
pluginApiClient.stats.getAllTags({
pluginApiClient.getAllTags({
owner: project.owner,
repo: project.repo,
}),
@@ -225,35 +225,33 @@ export const mockApiClient: GitReleaseApi = {
objectSha: 'mock_createRef_objectSha',
})),
createRc: {
createRelease: jest.fn(async () => ({
name: 'mock_createRelease_name',
htmlUrl: 'mock_createRelease_html_url',
tagName: 'mock_createRelease_tag_name',
})),
createRelease: jest.fn(async () => ({
name: 'mock_createRelease_name',
htmlUrl: 'mock_createRelease_html_url',
tagName: 'mock_createRelease_tag_name',
})),
getComparison: jest.fn(async () => ({
htmlUrl: 'mock_compareCommits_html_url',
aheadBy: 1,
})),
},
getComparison: jest.fn(async () => ({
htmlUrl: 'mock_compareCommits_html_url',
aheadBy: 1,
})),
createTagObject: jest.fn(async () => ({
tagName: 'mock_tag_object_tag',
tagSha: 'mock_tag_object_sha',
})),
createCommit: jest.fn(async () => ({
message: 'mock_commit_message',
sha: 'mock_commit_sha',
})),
patch: {
createCherryPickCommit: jest.fn(async () => ({
message: 'mock_cherrypick_message',
sha: 'mock_cherrypick_sha',
})),
createTempCommit: jest.fn(async () => ({
message: 'mock_commit_message',
sha: 'mock_commit_sha',
})),
forceBranchHeadToTempCommit: jest.fn(async () => undefined),
merge: jest.fn(async () => ({
@@ -286,30 +284,28 @@ export const mockApiClient: GitReleaseApi = {
htmlUrl: 'mock_release_html_url',
})),
stats: {
getAllTags: jest.fn(async () => [
{
tagName: MOCK_RELEASE_CANDIDATE_TAG_NAME_CALVER,
tagSha: 'mock_sha',
tagType: 'tag' as const,
},
]),
getAllTags: jest.fn(async () => [
{
tagName: MOCK_RELEASE_CANDIDATE_TAG_NAME_CALVER,
tagSha: 'mock_sha',
tagType: 'tag' as const,
},
]),
getAllReleases: jest.fn(async () => [
{
id: 1,
name: 'mock_release_name',
tagName: 'mock_release_tag_name',
createdAt: 'mock_release_published_at',
htmlUrl: 'mock_release_html_url',
},
]),
getAllReleases: jest.fn(async () => [
{
id: 1,
name: 'mock_release_name',
tagName: 'mock_release_tag_name',
createdAt: 'mock_release_published_at',
htmlUrl: 'mock_release_html_url',
},
]),
getSingleTag: jest.fn(async () => ({
date: '2021-04-29T12:48:30.120Z',
username: 'mock_user_single_tag_name',
userEmail: 'mock_user_single_tag_email',
objectSha: 'mock_single_tag_object_sha',
})),
},
getSingleTag: jest.fn(async () => ({
date: '2021-04-29T12:48:30.120Z',
username: 'mock_user_single_tag_name',
userEmail: 'mock_user_single_tag_email',
objectSha: 'mock_single_tag_object_sha',
})),
};