diff --git a/plugins/git-release-manager/src/api/GitReleaseApiClient.test.ts b/plugins/git-release-manager/src/api/GitReleaseApiClient.test.ts index 4d89e5b2e6..b37500451f 100644 --- a/plugins/git-release-manager/src/api/GitReleaseApiClient.test.ts +++ b/plugins/git-release-manager/src/api/GitReleaseApiClient.test.ts @@ -37,6 +37,16 @@ describe('GitReleaseApiClient', () => { "createRelease": [Function], "getComparison": [Function], }, + "getBranch": [Function], + "getHost": [Function], + "getLatestCommit": [Function], + "getLatestRelease": [Function], + "getOwners": [Function], + "getRecentCommits": [Function], + "getRepoPath": [Function], + "getRepositories": [Function], + "getRepository": [Function], + "getUser": [Function], "githubAuthApi": Object { "getAccessToken": [MockFunction], }, @@ -58,6 +68,7 @@ describe('GitReleaseApiClient', () => { "getAllReleases": [Function], "getAllTags": [Function], "getCommit": [Function], + "getSingleTag": [Function], }, } `); diff --git a/plugins/git-release-manager/src/api/GitReleaseApiClient.ts b/plugins/git-release-manager/src/api/GitReleaseApiClient.ts index 8e15f5c912..22762ac812 100644 --- a/plugins/git-release-manager/src/api/GitReleaseApiClient.ts +++ b/plugins/git-release-manager/src/api/GitReleaseApiClient.ts @@ -262,18 +262,13 @@ export class GitReleaseApiClient implements GitReleaseApi { }; }, - getComparison: async ({ - owner, - repo, - previousReleaseBranch, - nextReleaseBranch, - }) => { + getComparison: async ({ owner, repo, base, head }) => { const { octokit } = await this.getOctokit(); const compareCommitsResponse = await octokit.repos.compareCommits({ owner, repo, - base: previousReleaseBranch, - head: nextReleaseBranch, + base, + head, }); return { @@ -416,15 +411,15 @@ ${selectedPatchCommit.sha}`, }; }, - createTagObject: async ({ owner, repo, bumpedTag, updatedReference }) => { + createTagObject: async ({ owner, repo, tag, objectSha }) => { const { octokit } = await this.getOctokit(); const { data: createdTagObject } = await octokit.git.createTag({ owner, repo, message: 'Tag generated by your friendly neighborhood Backstage Release Manager', - tag: bumpedTag, - object: updatedReference.object.sha, + tag, + object: objectSha, type: 'commit', }); @@ -545,6 +540,21 @@ ${selectedPatchCommit.commit.message}`, createdAt: commit.commit.committer?.date, }; }, + + 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, + }; + }, }; } @@ -654,8 +664,8 @@ export interface GitReleaseApi { getComparison: ( args: { - previousReleaseBranch: string; - nextReleaseBranch: string; + base: string; + head: string; } & OwnerRepo, ) => Promise<{ htmlUrl: string; @@ -695,13 +705,13 @@ export interface GitReleaseApi { tempCommit: CreateTempCommitResult; } & OwnerRepo, ) => Promise; - merge: ({ - base, - head, - }: { - base: string; - head: string; - } & OwnerRepo) => Promise<{ + + merge: ( + args: { + base: string; + head: string; + } & OwnerRepo, + ) => Promise<{ htmlUrl: string; commit: { message: string; @@ -739,13 +749,12 @@ export interface GitReleaseApi { }; }>; - createTagObject: ({ - bumpedTag, - updatedReference, - }: { - bumpedTag: string; - updatedReference: ReplaceTempCommitResult; - } & OwnerRepo) => Promise<{ + createTagObject: ( + args: { + tag: string; + objectSha: string; + } & OwnerRepo, + ) => Promise<{ tag: string; sha: string; }>; @@ -793,6 +802,7 @@ export interface GitReleaseApi { sha: string; }> >; + getAllReleases: ( args: OwnerRepo, ) => Promise< @@ -812,6 +822,16 @@ export interface GitReleaseApi { ) => Promise<{ createdAt: string | undefined; }>; + + getSingleTag: ( + args: { + tagSha: string; + } & OwnerRepo, + ) => Promise<{ + date: string; + username: string; + userEmail: string; + }>; }; } diff --git a/plugins/git-release-manager/src/features/CreateReleaseCandidate/hooks/useCreateReleaseCandidate.ts b/plugins/git-release-manager/src/features/CreateReleaseCandidate/hooks/useCreateReleaseCandidate.ts index 236ba7edbf..ca203a1d10 100644 --- a/plugins/git-release-manager/src/features/CreateReleaseCandidate/hooks/useCreateReleaseCandidate.ts +++ b/plugins/git-release-manager/src/features/CreateReleaseCandidate/hooks/useCreateReleaseCandidate.ts @@ -135,8 +135,8 @@ export function useCreateReleaseCandidate({ .getComparison({ owner: project.owner, repo: project.repo, - previousReleaseBranch, - nextReleaseBranch, + base: previousReleaseBranch, + head: nextReleaseBranch, }) .catch(asyncCatcher); diff --git a/plugins/git-release-manager/src/features/Patch/hooks/usePatch.ts b/plugins/git-release-manager/src/features/Patch/hooks/usePatch.ts index 4ad29d1699..d188e2bf51 100644 --- a/plugins/git-release-manager/src/features/Patch/hooks/usePatch.ts +++ b/plugins/git-release-manager/src/features/Patch/hooks/usePatch.ts @@ -238,8 +238,8 @@ export function usePatch({ .createTagObject({ owner: project.owner, repo: project.repo, - bumpedTag, - updatedReference: updatedRefRes.value, + tag: bumpedTag, + objectSha: updatedRefRes.value.object.sha, }) .catch(asyncCatcher); diff --git a/plugins/git-release-manager/src/features/Stats/Info/hooks/useGetReleaseTimes.tsx b/plugins/git-release-manager/src/features/Stats/Info/hooks/useGetReleaseTimes.tsx index 37f1d88a88..59ae036405 100644 --- a/plugins/git-release-manager/src/features/Stats/Info/hooks/useGetReleaseTimes.tsx +++ b/plugins/git-release-manager/src/features/Stats/Info/hooks/useGetReleaseTimes.tsx @@ -20,6 +20,7 @@ import { DateTime } from 'luxon'; import { useApi } from '@backstage/core'; import { getReleaseCommitPairs } from '../helpers/getReleaseCommitPairs'; +import { getTagDate } from '../../helpers/getTagDate'; import { gitReleaseManagerApiRef } from '../../../../api/serviceApiRef'; import { useProjectContext } from '../../../../contexts/ProjectContext'; import { useReleaseStatsContext } from '../../contexts/ReleaseStatsContext'; @@ -80,19 +81,11 @@ export function useGetReleaseTimes() { const { baseVersion, startCommit, endCommit } = releaseCommitPairs[index]; const [ - { createdAt: startCommitCreatedAt }, - { createdAt: endCommitCreatedAt }, + { tagDate: startCommitCreatedAt }, + { tagDate: endCommitCreatedAt }, ] = await Promise.all([ - pluginApiClient.stats.getCommit({ - owner: project.owner, - repo: project.repo, - ref: startCommit.sha, - }), - pluginApiClient.stats.getCommit({ - owner: project.owner, - repo: project.repo, - ref: endCommit.sha, - }), + getTagDate({ pluginApiClient, project, tagSha: startCommit.sha }), + getTagDate({ pluginApiClient, project, tagSha: endCommit.sha }), ]); const releaseTime: ReleaseTime = { diff --git a/plugins/git-release-manager/src/features/Stats/helpers/getMappedReleases.test.tsx b/plugins/git-release-manager/src/features/Stats/helpers/getMappedReleases.test.tsx index 5bea396d5c..fd5b23beaf 100644 --- a/plugins/git-release-manager/src/features/Stats/helpers/getMappedReleases.test.tsx +++ b/plugins/git-release-manager/src/features/Stats/helpers/getMappedReleases.test.tsx @@ -38,24 +38,14 @@ describe('getMappedReleases', () => { "releases": Object { "1.0": Object { "baseVersion": "1.0", - "candidates": Array [ - Object { - "sha": "", - "tagName": "rc-1.0.0", - }, - ], + "candidates": Array [], "createdAt": "2021-01-01T10:11:12Z", "htmlUrl": "html_url", "versions": Array [], }, "1.1": Object { "baseVersion": "1.1", - "candidates": Array [ - Object { - "sha": "", - "tagName": "rc-1.1.0", - }, - ], + "candidates": Array [], "createdAt": "2021-01-01T10:11:12Z", "htmlUrl": "html_url", "versions": Array [], diff --git a/plugins/git-release-manager/src/features/Stats/helpers/getMappedReleases.tsx b/plugins/git-release-manager/src/features/Stats/helpers/getMappedReleases.tsx index 2cbea22664..cee64436a1 100644 --- a/plugins/git-release-manager/src/features/Stats/helpers/getMappedReleases.tsx +++ b/plugins/git-release-manager/src/features/Stats/helpers/getMappedReleases.tsx @@ -40,24 +40,18 @@ export function getMappedReleases({ return acc; } - const prefix = match[1] as 'rc' | 'version'; const baseVersion = project.versioningStrategy === 'semver' ? `${match[2]}.${match[3]}` : match[2]; if (!acc.releases[baseVersion]) { - const releaseEntry = { - tagName: release.tagName, - sha: '', - }; - acc.releases[baseVersion] = { baseVersion, createdAt: release.createdAt, htmlUrl: release.htmlUrl, - candidates: prefix === 'rc' ? [releaseEntry] : [], - versions: prefix === 'version' ? [releaseEntry] : [], + candidates: [], + versions: [], }; return acc; diff --git a/plugins/git-release-manager/src/features/Stats/helpers/getReleaseStats.test.tsx b/plugins/git-release-manager/src/features/Stats/helpers/getReleaseStats.test.tsx index 3b59cc4c46..6d0cb1ca3d 100644 --- a/plugins/git-release-manager/src/features/Stats/helpers/getReleaseStats.test.tsx +++ b/plugins/git-release-manager/src/features/Stats/helpers/getReleaseStats.test.tsx @@ -27,24 +27,15 @@ describe('getReleaseStats', () => { baseVersion: '1.0', createdAt: '2021-01-01T10:11:12Z', htmlUrl: 'html_url', - candidates: [ - { - tagName: 'rc-1.0.0', - sha: '', - }, - ], + candidates: [], versions: [], }, '1.1': { baseVersion: '1.1', createdAt: '2021-01-01T10:11:12Z', htmlUrl: 'html_url', - candidates: [ - { - tagName: 'rc-1.1.0', - sha: '', - }, - ], + candidates: [], + versions: [], }, }, @@ -96,10 +87,6 @@ describe('getReleaseStats', () => { "1.1": Object { "baseVersion": "1.1", "candidates": Array [ - Object { - "sha": "", - "tagName": "rc-1.1.0", - }, Object { "sha": "sha", "tagName": "rc-1.1.1", diff --git a/plugins/git-release-manager/src/features/Stats/helpers/getReleaseStats.tsx b/plugins/git-release-manager/src/features/Stats/helpers/getReleaseStats.tsx index 41ce41b1ac..fb3bad8d0c 100644 --- a/plugins/git-release-manager/src/features/Stats/helpers/getReleaseStats.tsx +++ b/plugins/git-release-manager/src/features/Stats/helpers/getReleaseStats.tsx @@ -55,18 +55,7 @@ export function getReleaseStats({ } const dest = release[prefix === 'rc' ? 'candidates' : 'versions']; - const releaseToEnrich = dest.find( - ({ tagName }) => tagName === tag.tagName, - ); - - if (releaseToEnrich) { - releaseToEnrich.sha = tag.sha; - } else { - dest.push({ - tagName: tag.tagName, - sha: tag.sha, - }); - } + dest.push(tag); return acc; }, diff --git a/plugins/git-release-manager/src/features/Stats/helpers/getTagDate.ts b/plugins/git-release-manager/src/features/Stats/helpers/getTagDate.ts new file mode 100644 index 0000000000..f0c3bcd445 --- /dev/null +++ b/plugins/git-release-manager/src/features/Stats/helpers/getTagDate.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { GitReleaseApi } from '../../../api/GitReleaseApiClient'; +import { Project } from '../../../contexts/ProjectContext'; + +interface GetTagDate { + pluginApiClient: GitReleaseApi; + project: Project; + tagSha: string; +} + +export const getTagDate = async ({ + pluginApiClient, + project, + tagSha, +}: GetTagDate) => { + const commitRes = await pluginApiClient.stats.getCommit({ + owner: project.owner, + repo: project.repo, + ref: tagSha, + }); + + return { + tagDate: commitRes.createdAt, + }; +}; diff --git a/plugins/git-release-manager/src/features/Stats/hooks/useGetTagDate.ts b/plugins/git-release-manager/src/features/Stats/hooks/useGetTagDate.ts new file mode 100644 index 0000000000..028b3a1929 --- /dev/null +++ b/plugins/git-release-manager/src/features/Stats/hooks/useGetTagDate.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useAsync } from 'react-use'; +import { useApi } from '@backstage/core'; + +import { getTagDate } from '../helpers/getTagDate'; +import { gitReleaseManagerApiRef } from '../../../api/serviceApiRef'; +import { GitReleaseManagerError } from '../../../errors/GitReleaseManagerError'; +import { ReleaseStats } from '../contexts/ReleaseStatsContext'; +import { UnboxArray } from '../../../types/helpers'; +import { useProjectContext } from '../../../contexts/ProjectContext'; + +export const useGetTagDate = ({ + tag, +}: { + tag: UnboxArray; +}) => { + const pluginApiClient = useApi(gitReleaseManagerApiRef); + const { project } = useProjectContext(); + + const tagDate = useAsync(async () => { + if (!tag) { + throw new GitReleaseManagerError('Missing tag details to get tag date'); + } + + return await getTagDate({ pluginApiClient, project, tagSha: tag.sha }); + }); + + return { + tagDate, + }; +}; diff --git a/plugins/git-release-manager/src/test-helpers/test-helpers.ts b/plugins/git-release-manager/src/test-helpers/test-helpers.ts index 886fad9de0..56b1d0214f 100644 --- a/plugins/git-release-manager/src/test-helpers/test-helpers.ts +++ b/plugins/git-release-manager/src/test-helpers/test-helpers.ts @@ -306,5 +306,11 @@ export const mockApiClient: GitReleaseApi = { getCommit: jest.fn(async () => ({ createdAt: '2021-01-01T10:11:12Z', })), + + getSingleTag: jest.fn(async () => ({ + date: '2021-04-29T12:48:30.120Z', + username: 'mock_usersingle_tag_name', + userEmail: 'mock_userEsingle_tag_mail', + })), }, };