Handle both tag and commit objects in Stats
Signed-off-by: Erik Engervall <erik.engervall@gmail.com>
This commit is contained in:
@@ -492,17 +492,21 @@ ${selectedPatchCommit.commit.message}`,
|
||||
getAllTags: async ({ owner, repo }) => {
|
||||
const { octokit } = await this.getOctokit();
|
||||
|
||||
const tags = await octokit.paginate(octokit.repos.listTags, {
|
||||
const tags = await octokit.paginate(octokit.git.listMatchingRefs, {
|
||||
owner,
|
||||
repo,
|
||||
ref: 'tags',
|
||||
per_page: 100,
|
||||
...DISABLE_CACHE,
|
||||
});
|
||||
|
||||
return tags.map(tag => ({
|
||||
tagName: tag.name,
|
||||
sha: tag.commit.sha,
|
||||
}));
|
||||
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 }) => {
|
||||
@@ -536,6 +540,7 @@ ${selectedPatchCommit.commit.message}`,
|
||||
date: singleTag.data.tagger.date,
|
||||
username: singleTag.data.tagger.name,
|
||||
userEmail: singleTag.data.tagger.email,
|
||||
objectSha: singleTag.data.object.sha,
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -780,7 +785,8 @@ export interface GitReleaseApi {
|
||||
) => Promise<
|
||||
Array<{
|
||||
tagName: string;
|
||||
sha: string;
|
||||
tagSha: string;
|
||||
tagType: 'tag' | 'commit';
|
||||
}>
|
||||
>;
|
||||
|
||||
@@ -804,6 +810,7 @@ export interface GitReleaseApi {
|
||||
date: string;
|
||||
username: string;
|
||||
userEmail: string;
|
||||
objectSha: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
+33
-11
@@ -25,11 +25,13 @@ describe('getReleaseCommitPairs', () => {
|
||||
candidates: [
|
||||
{
|
||||
tagName: 'rc-1.0.0',
|
||||
sha: 'sha-1.0.0',
|
||||
tagSha: 'sha-1.0.0',
|
||||
tagType: 'tag' as const,
|
||||
},
|
||||
{
|
||||
tagName: 'rc-1.0.1',
|
||||
sha: 'sha-1.0.1',
|
||||
tagSha: 'sha-1.0.1',
|
||||
tagType: 'tag' as const,
|
||||
},
|
||||
],
|
||||
versions: [],
|
||||
@@ -42,13 +44,15 @@ describe('getReleaseCommitPairs', () => {
|
||||
candidates: [
|
||||
{
|
||||
tagName: 'rc-2.0.0',
|
||||
sha: 'sha-2.0.0',
|
||||
tagSha: 'sha-2.0.0',
|
||||
tagType: 'tag' as const,
|
||||
},
|
||||
],
|
||||
versions: [
|
||||
{
|
||||
tagName: 'version-2.0.0',
|
||||
sha: 'sha-2.0.0',
|
||||
tagSha: 'sha-2.0.0',
|
||||
tagType: 'tag' as const,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -60,17 +64,20 @@ describe('getReleaseCommitPairs', () => {
|
||||
candidates: [
|
||||
{
|
||||
tagName: 'rc-3.0.1',
|
||||
sha: 'sha-3.0.1',
|
||||
tagSha: 'sha-3.0.1',
|
||||
tagType: 'tag' as const,
|
||||
},
|
||||
{
|
||||
tagName: 'rc-3.0.0',
|
||||
sha: 'sha-3.0.0',
|
||||
tagSha: 'sha-3.0.0',
|
||||
tagType: 'tag' as const,
|
||||
},
|
||||
],
|
||||
versions: [
|
||||
{
|
||||
tagName: 'version-3.0.1',
|
||||
sha: 'sha-3.0.1',
|
||||
tagSha: 'sha-3.0.1',
|
||||
tagType: 'tag' as const,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -92,14 +99,29 @@ describe('getReleaseCommitPairs', () => {
|
||||
Object {
|
||||
"releaseCommitPairs": Array [
|
||||
Object {
|
||||
"baseVersion": "3.0",
|
||||
"baseVersion": "2.0",
|
||||
"endCommit": Object {
|
||||
"sha": "sha-3.0.1",
|
||||
"tagName": "version-3.0.1",
|
||||
"tagName": "version-2.0.0",
|
||||
"tagSha": "sha-2.0.0",
|
||||
"tagType": "tag",
|
||||
},
|
||||
"startCommit": Object {
|
||||
"tagName": "rc-2.0.0",
|
||||
"tagSha": "sha-2.0.0",
|
||||
"tagType": "tag",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"baseVersion": "3.0",
|
||||
"endCommit": Object {
|
||||
"tagName": "version-3.0.1",
|
||||
"tagSha": "sha-3.0.1",
|
||||
"tagType": "tag",
|
||||
},
|
||||
"startCommit": Object {
|
||||
"sha": "sha-3.0.0",
|
||||
"tagName": "rc-3.0.0",
|
||||
"tagSha": "sha-3.0.0",
|
||||
"tagType": "tag",
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
+4
-17
@@ -28,32 +28,19 @@ export function getReleaseCommitPairs({
|
||||
const endTag = release.versions[0];
|
||||
|
||||
// Missing Release Candidate for unknown reason
|
||||
if (!startTag?.sha) {
|
||||
if (!startTag) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
// Missing Release Version (likely prerelease)
|
||||
if (!endTag?.sha) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
// First RC tag is pointing towards the same commit as the most
|
||||
// recent Version tag, meaning there haven't been any patches
|
||||
// and we thus cannot determine and difference in time
|
||||
if (startTag?.sha === endTag?.sha) {
|
||||
if (!endTag) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
return acc.concat({
|
||||
baseVersion: release.baseVersion,
|
||||
startCommit: {
|
||||
tagName: startTag.tagName,
|
||||
sha: startTag.sha,
|
||||
},
|
||||
endCommit: {
|
||||
tagName: endTag.tagName,
|
||||
sha: endTag.sha,
|
||||
},
|
||||
startCommit: { ...startTag },
|
||||
endCommit: { ...endTag },
|
||||
});
|
||||
},
|
||||
[],
|
||||
|
||||
@@ -20,20 +20,22 @@ 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';
|
||||
import { getTagDates } from '../../helpers/getTagDates';
|
||||
|
||||
export type ReleaseCommitPairs = Array<{
|
||||
baseVersion: string;
|
||||
startCommit: {
|
||||
tagName: string;
|
||||
sha: string;
|
||||
tagSha: string;
|
||||
tagType: 'tag' | 'commit';
|
||||
};
|
||||
endCommit: {
|
||||
tagName: string;
|
||||
sha: string;
|
||||
tagSha: string;
|
||||
tagType: 'tag' | 'commit';
|
||||
};
|
||||
}>;
|
||||
|
||||
@@ -56,17 +58,17 @@ export function useGetReleaseTimes() {
|
||||
const [progress, setProgress] = useState(0);
|
||||
const { releaseCommitPairs } = getReleaseCommitPairs({ releaseStats });
|
||||
|
||||
const [fnRes, run] = useAsyncFn(() => {
|
||||
const [releaseTimeResult, run] = useAsyncFn(() => {
|
||||
setProgress(0);
|
||||
return getAndSetReleaseTime(0);
|
||||
return getAndSetReleaseTime({ pairIndex: 0 });
|
||||
});
|
||||
|
||||
useAsync(async () => {
|
||||
if (averageReleaseTime.length === 0) return;
|
||||
if (releaseCommitPairs.length === averageReleaseTime.length) return;
|
||||
|
||||
await getAndSetReleaseTime(averageReleaseTime.length);
|
||||
}, [fnRes.value, averageReleaseTime]);
|
||||
await getAndSetReleaseTime({ pairIndex: averageReleaseTime.length });
|
||||
}, [releaseTimeResult.value, averageReleaseTime]);
|
||||
|
||||
useEffect(() => {
|
||||
const unboundedProgress = Math.round(
|
||||
@@ -77,16 +79,20 @@ export function useGetReleaseTimes() {
|
||||
setProgress(boundedProgress);
|
||||
}, [averageReleaseTime.length, releaseCommitPairs.length]);
|
||||
|
||||
async function getAndSetReleaseTime(index: number) {
|
||||
const { baseVersion, startCommit, endCommit } = releaseCommitPairs[index];
|
||||
async function getAndSetReleaseTime({ pairIndex }: { pairIndex: number }) {
|
||||
const { baseVersion, startCommit, endCommit } = releaseCommitPairs[
|
||||
pairIndex
|
||||
];
|
||||
|
||||
const [
|
||||
{ tagDate: startCommitCreatedAt },
|
||||
{ tagDate: endCommitCreatedAt },
|
||||
] = await Promise.all([
|
||||
getTagDate({ pluginApiClient, project, tagSha: startCommit.sha }),
|
||||
getTagDate({ pluginApiClient, project, tagSha: endCommit.sha }),
|
||||
]);
|
||||
const {
|
||||
startDate: startCommitCreatedAt,
|
||||
endDate: endCommitCreatedAt,
|
||||
} = await getTagDates({
|
||||
pluginApiClient,
|
||||
project,
|
||||
startTag: startCommit,
|
||||
endTag: endCommit,
|
||||
});
|
||||
|
||||
const releaseTime: ReleaseTime = {
|
||||
version: baseVersion,
|
||||
|
||||
@@ -21,22 +21,31 @@ import { Alert } from '@material-ui/lab';
|
||||
|
||||
import { CenteredCircularProgress } from '../../../../components/CenteredCircularProgress';
|
||||
import { ReleaseStats } from '../../contexts/ReleaseStatsContext';
|
||||
import { useGetCommit } from '../../hooks/useGetCommit';
|
||||
import { useAsync } from 'react-use';
|
||||
import { getTagDates } from '../../helpers/getTagDates';
|
||||
import { useProjectContext } from '../../../../contexts/ProjectContext';
|
||||
import { useApi } from '@backstage/core';
|
||||
import { gitReleaseManagerApiRef } from '../../../../api/serviceApiRef';
|
||||
import { getDecimalNumber } from '../../helpers/getDecimalNumber';
|
||||
|
||||
interface ReleaseTimeProps {
|
||||
releaseStat: ReleaseStats['releases']['0'];
|
||||
}
|
||||
|
||||
export function ReleaseTime({ releaseStat }: ReleaseTimeProps) {
|
||||
const firstCandidateSha = [...releaseStat.candidates].reverse()[0]?.sha;
|
||||
const { commit: releaseCut } = useGetCommit({ ref: firstCandidateSha });
|
||||
const pluginApiClient = useApi(gitReleaseManagerApiRef);
|
||||
const { project } = useProjectContext();
|
||||
|
||||
const mostRecentVersionSha = releaseStat.versions[0]?.sha;
|
||||
const { commit: releaseComplete } = useGetCommit({
|
||||
ref: mostRecentVersionSha,
|
||||
});
|
||||
const releaseTimes = useAsync(() =>
|
||||
getTagDates({
|
||||
pluginApiClient,
|
||||
project,
|
||||
startTag: [...releaseStat.candidates].reverse()[0],
|
||||
endTag: releaseStat.versions[0],
|
||||
}),
|
||||
);
|
||||
|
||||
if (releaseCut.loading || releaseComplete.loading) {
|
||||
if (releaseTimes.loading || releaseTimes.loading) {
|
||||
return (
|
||||
<Wrapper>
|
||||
<CenteredCircularProgress />
|
||||
@@ -44,19 +53,22 @@ export function ReleaseTime({ releaseStat }: ReleaseTimeProps) {
|
||||
);
|
||||
}
|
||||
|
||||
if (releaseCut.error) {
|
||||
if (releaseTimes.error) {
|
||||
return (
|
||||
<Alert severity="error">
|
||||
Failed to fetch the first Release Candidate commit (
|
||||
{releaseCut.error.message})
|
||||
{releaseTimes.error.message})
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
|
||||
const diff =
|
||||
releaseCut.value?.createdAt && releaseComplete.value?.createdAt
|
||||
? DateTime.fromISO(releaseComplete.value.createdAt)
|
||||
.diff(DateTime.fromISO(releaseCut.value.createdAt), ['days', 'hours'])
|
||||
const { days = 0, hours = 0 } =
|
||||
releaseTimes.value?.startDate && releaseTimes.value?.endDate
|
||||
? DateTime.fromISO(releaseTimes.value.endDate)
|
||||
.diff(DateTime.fromISO(releaseTimes.value.startDate), [
|
||||
'days',
|
||||
'hours',
|
||||
])
|
||||
.toObject()
|
||||
: { days: -1 };
|
||||
|
||||
@@ -71,8 +83,8 @@ export function ReleaseTime({ releaseStat }: ReleaseTimeProps) {
|
||||
>
|
||||
<Typography variant="body1">
|
||||
{releaseStat.versions.length === 0 ? '-' : 'Release completed '}
|
||||
{releaseComplete.value?.createdAt &&
|
||||
DateTime.fromISO(releaseComplete.value.createdAt)
|
||||
{releaseTimes.value?.endDate &&
|
||||
DateTime.fromISO(releaseTimes.value.endDate)
|
||||
.setLocale('sv-SE')
|
||||
.toFormat('yyyy-MM-dd')}
|
||||
</Typography>
|
||||
@@ -85,11 +97,13 @@ export function ReleaseTime({ releaseStat }: ReleaseTimeProps) {
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Typography variant="h5" color="secondary">
|
||||
{diff.days === -1 ? (
|
||||
<>Ongoing: {diff.days} days</>
|
||||
<Typography variant="h6" color="secondary">
|
||||
{days === -1 ? (
|
||||
<>Ongoing</>
|
||||
) : (
|
||||
<>Completed in: {diff.days} days</>
|
||||
<>
|
||||
Completed in: {days} days {getDecimalNumber(hours, 1)} hours
|
||||
</>
|
||||
)}
|
||||
</Typography>
|
||||
</Box>
|
||||
@@ -103,8 +117,8 @@ export function ReleaseTime({ releaseStat }: ReleaseTimeProps) {
|
||||
>
|
||||
<Typography variant="body1">
|
||||
Release Candidate created{' '}
|
||||
{releaseCut.value?.createdAt &&
|
||||
DateTime.fromISO(releaseCut.value.createdAt)
|
||||
{releaseTimes.value?.startDate &&
|
||||
DateTime.fromISO(releaseTimes.value.startDate)
|
||||
.setLocale('sv-SE')
|
||||
.toFormat('yyyy-MM-dd')}
|
||||
</Typography>
|
||||
|
||||
@@ -27,21 +27,15 @@ export interface ReleaseStats {
|
||||
baseVersion: string;
|
||||
createdAt: string | null;
|
||||
htmlUrl: string;
|
||||
|
||||
/**
|
||||
* Ordered from new to old
|
||||
*/
|
||||
candidates: {
|
||||
tagName: string;
|
||||
sha: string;
|
||||
tagSha: string;
|
||||
tagType: 'tag' | 'commit';
|
||||
}[];
|
||||
|
||||
/**
|
||||
* Ordered from new to old
|
||||
*/
|
||||
versions: {
|
||||
tagName: string;
|
||||
sha: string;
|
||||
tagSha: string;
|
||||
tagType: 'tag' | 'commit';
|
||||
}[];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -44,14 +44,18 @@ describe('getReleaseStats', () => {
|
||||
unmatchedTags: [],
|
||||
},
|
||||
allTags: [
|
||||
{ sha: 'sha', tagName: 'rc-1.0.0' },
|
||||
{ sha: 'sha', tagName: 'rc-1.0.1' },
|
||||
{ sha: 'sha', tagName: 'rc-1.0.2' },
|
||||
{ sha: 'sha', tagName: 'version-1.0.2' },
|
||||
{ sha: 'sha', tagName: 'rc-1.1.1' },
|
||||
{ tagType: 'tag' as const, tagSha: 'sha', tagName: 'rc-1.0.0' },
|
||||
{ tagType: 'tag' as const, tagSha: 'sha', tagName: 'rc-1.0.1' },
|
||||
{ tagType: 'tag' as const, tagSha: 'sha', tagName: 'rc-1.0.2' },
|
||||
{ tagType: 'tag' as const, tagSha: 'sha', tagName: 'version-1.0.2' },
|
||||
{ tagType: 'tag' as const, tagSha: 'sha', tagName: 'rc-1.1.1' },
|
||||
|
||||
{ sha: 'unmatchable', tagName: 'rc-1/2/3' },
|
||||
{ sha: 'unmappable', tagName: 'rc-123.123.123' },
|
||||
{ tagType: 'tag' as const, tagSha: 'unmatchable', tagName: 'rc-1/2/3' },
|
||||
{
|
||||
tagType: 'tag' as const,
|
||||
tagSha: 'unmappable',
|
||||
tagName: 'rc-123.123.123',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
@@ -63,24 +67,28 @@ describe('getReleaseStats', () => {
|
||||
"baseVersion": "1.0",
|
||||
"candidates": Array [
|
||||
Object {
|
||||
"sha": "sha",
|
||||
"tagName": "rc-1.0.0",
|
||||
"tagSha": "sha",
|
||||
"tagType": "tag",
|
||||
},
|
||||
Object {
|
||||
"sha": "sha",
|
||||
"tagName": "rc-1.0.1",
|
||||
"tagSha": "sha",
|
||||
"tagType": "tag",
|
||||
},
|
||||
Object {
|
||||
"sha": "sha",
|
||||
"tagName": "rc-1.0.2",
|
||||
"tagSha": "sha",
|
||||
"tagType": "tag",
|
||||
},
|
||||
],
|
||||
"createdAt": "2021-01-01T10:11:12Z",
|
||||
"htmlUrl": "html_url",
|
||||
"versions": Array [
|
||||
Object {
|
||||
"sha": "sha",
|
||||
"tagName": "version-1.0.2",
|
||||
"tagSha": "sha",
|
||||
"tagType": "tag",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -88,8 +96,9 @@ describe('getReleaseStats', () => {
|
||||
"baseVersion": "1.1",
|
||||
"candidates": Array [
|
||||
Object {
|
||||
"sha": "sha",
|
||||
"tagName": "rc-1.1.1",
|
||||
"tagSha": "sha",
|
||||
"tagType": "tag",
|
||||
},
|
||||
],
|
||||
"createdAt": "2021-01-01T10:11:12Z",
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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.getCommit({
|
||||
owner: project.owner,
|
||||
repo: project.repo,
|
||||
ref: tagSha,
|
||||
});
|
||||
|
||||
return {
|
||||
tagDate: commitRes.createdAt,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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 { GitReleaseManagerError } from '../../../errors/GitReleaseManagerError';
|
||||
import { Project } from '../../../contexts/ProjectContext';
|
||||
|
||||
interface GetTagDates {
|
||||
pluginApiClient: GitReleaseApi;
|
||||
project: Project;
|
||||
startTag: {
|
||||
tagSha: string;
|
||||
tagType: 'tag' | 'commit';
|
||||
};
|
||||
endTag: {
|
||||
tagSha: string;
|
||||
tagType: 'tag' | 'commit';
|
||||
};
|
||||
}
|
||||
|
||||
export const getTagDates = async ({
|
||||
pluginApiClient,
|
||||
project,
|
||||
startTag,
|
||||
endTag,
|
||||
}: GetTagDates) => {
|
||||
if (startTag.tagType === 'tag' && endTag.tagType === 'tag') {
|
||||
const [{ date: startDate }, { date: endDate }] = await Promise.all([
|
||||
pluginApiClient.stats.getSingleTag({
|
||||
owner: project.owner,
|
||||
repo: project.repo,
|
||||
tagSha: startTag.tagSha,
|
||||
}),
|
||||
pluginApiClient.stats.getSingleTag({
|
||||
owner: project.owner,
|
||||
repo: project.repo,
|
||||
tagSha: endTag.tagSha,
|
||||
}),
|
||||
]);
|
||||
|
||||
return {
|
||||
startDate,
|
||||
endDate,
|
||||
};
|
||||
}
|
||||
|
||||
if (startTag.tagType === 'commit' && endTag.tagType === 'commit') {
|
||||
const [
|
||||
{ createdAt: startDate },
|
||||
{ createdAt: endDate },
|
||||
] = await Promise.all([
|
||||
pluginApiClient.getCommit({
|
||||
owner: project.owner,
|
||||
repo: project.repo,
|
||||
ref: startTag.tagSha,
|
||||
}),
|
||||
pluginApiClient.getCommit({
|
||||
owner: project.owner,
|
||||
repo: project.repo,
|
||||
ref: endTag.tagSha,
|
||||
}),
|
||||
]);
|
||||
|
||||
return {
|
||||
startDate,
|
||||
endDate,
|
||||
};
|
||||
}
|
||||
|
||||
if (startTag.tagType === 'tag' && endTag.tagType === 'commit') {
|
||||
const [{ date: startDate }, { createdAt: endDate }] = await Promise.all([
|
||||
getCommitFromTag({ pluginApiClient, project, tag: startTag }),
|
||||
pluginApiClient.getCommit({
|
||||
owner: project.owner,
|
||||
repo: project.repo,
|
||||
ref: endTag.tagSha,
|
||||
}),
|
||||
]);
|
||||
|
||||
return {
|
||||
startDate,
|
||||
endDate,
|
||||
};
|
||||
}
|
||||
|
||||
if (startTag.tagType === 'commit' && endTag.tagType === 'tag') {
|
||||
const [{ createdAt: startDate }, { date: endDate }] = await Promise.all([
|
||||
pluginApiClient.getCommit({
|
||||
owner: project.owner,
|
||||
repo: project.repo,
|
||||
ref: startTag.tagSha,
|
||||
}),
|
||||
getCommitFromTag({ pluginApiClient, project, tag: endTag }),
|
||||
]);
|
||||
|
||||
return {
|
||||
startDate,
|
||||
endDate,
|
||||
};
|
||||
}
|
||||
|
||||
throw new GitReleaseManagerError(
|
||||
`Failed to get tag dates for tags with type "${startTag.tagType}" and "${endTag.tagType}"`,
|
||||
);
|
||||
};
|
||||
|
||||
async function getCommitFromTag({
|
||||
pluginApiClient,
|
||||
project,
|
||||
tag,
|
||||
}: {
|
||||
pluginApiClient: GetTagDates['pluginApiClient'];
|
||||
project: GetTagDates['project'];
|
||||
tag: GetTagDates['startTag'] | GetTagDates['endTag'];
|
||||
}) {
|
||||
const singleTag = await pluginApiClient.stats.getSingleTag({
|
||||
owner: project.owner,
|
||||
repo: project.repo,
|
||||
tagSha: tag.tagSha,
|
||||
});
|
||||
const startCommit = await pluginApiClient.getCommit({
|
||||
owner: project.owner,
|
||||
repo: project.repo,
|
||||
ref: singleTag.objectSha,
|
||||
});
|
||||
|
||||
return {
|
||||
date: startCommit.createdAt,
|
||||
};
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* 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 { gitReleaseManagerApiRef } from '../../../api/serviceApiRef';
|
||||
import { GitReleaseManagerError } from '../../../errors/GitReleaseManagerError';
|
||||
import { useProjectContext } from '../../../contexts/ProjectContext';
|
||||
|
||||
export const useGetCommit = ({ ref }: { ref?: string }) => {
|
||||
const pluginApiClient = useApi(gitReleaseManagerApiRef);
|
||||
const { project } = useProjectContext();
|
||||
|
||||
const commit = useAsync(async () => {
|
||||
if (!ref) {
|
||||
throw new GitReleaseManagerError('Missing ref to get commit');
|
||||
}
|
||||
|
||||
return pluginApiClient.getCommit({
|
||||
owner: project.owner,
|
||||
repo: project.repo,
|
||||
ref,
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
commit,
|
||||
};
|
||||
};
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* 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<ReleaseStats['releases']['0']['candidates']>;
|
||||
}) => {
|
||||
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,
|
||||
};
|
||||
};
|
||||
@@ -25,11 +25,13 @@ export const mockReleaseStats: ReleaseStats = {
|
||||
candidates: [
|
||||
{
|
||||
tagName: 'rc-1.0.1',
|
||||
sha: 'sha-1.0.1',
|
||||
tagSha: 'sha-1.0.1',
|
||||
tagType: 'tag',
|
||||
},
|
||||
{
|
||||
tagName: 'rc-1.0.0',
|
||||
sha: 'sha-1.0.0',
|
||||
tagSha: 'sha-1.0.0',
|
||||
tagType: 'tag',
|
||||
},
|
||||
],
|
||||
versions: [],
|
||||
@@ -41,25 +43,30 @@ export const mockReleaseStats: ReleaseStats = {
|
||||
candidates: [
|
||||
{
|
||||
tagName: 'rc-1.1.2',
|
||||
sha: 'sha-1.1.2',
|
||||
tagSha: 'sha-1.1.2',
|
||||
tagType: 'tag',
|
||||
},
|
||||
{
|
||||
tagName: 'rc-1.1.1',
|
||||
sha: 'sha-1.1.1',
|
||||
tagSha: 'sha-1.1.1',
|
||||
tagType: 'tag',
|
||||
},
|
||||
{
|
||||
tagName: 'rc-1.1.0',
|
||||
sha: 'sha-1.1.0',
|
||||
tagSha: 'sha-1.1.0',
|
||||
tagType: 'tag',
|
||||
},
|
||||
],
|
||||
versions: [
|
||||
{
|
||||
tagName: 'version-1.1.3',
|
||||
sha: 'sha-1.1.3',
|
||||
tagSha: 'sha-1.1.3',
|
||||
tagType: 'tag',
|
||||
},
|
||||
{
|
||||
tagName: 'version-1.1.2',
|
||||
sha: 'sha-1.1.2',
|
||||
tagSha: 'sha-1.1.2',
|
||||
tagType: 'tag',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -292,7 +292,8 @@ export const mockApiClient: GitReleaseApi = {
|
||||
getAllTags: jest.fn(async () => [
|
||||
{
|
||||
tagName: MOCK_RELEASE_CANDIDATE_TAG_NAME_CALVER,
|
||||
sha: 'mock_sha',
|
||||
tagSha: 'mock_sha',
|
||||
tagType: 'tag' as const,
|
||||
},
|
||||
]),
|
||||
|
||||
@@ -308,8 +309,9 @@ export const mockApiClient: GitReleaseApi = {
|
||||
|
||||
getSingleTag: jest.fn(async () => ({
|
||||
date: '2021-04-29T12:48:30.120Z',
|
||||
username: 'mock_usersingle_tag_name',
|
||||
userEmail: 'mock_userEsingle_tag_mail',
|
||||
username: 'mock_user_single_tag_name',
|
||||
userEmail: 'mock_user_single_tag_email',
|
||||
objectSha: 'mock_single_tag_object_sha',
|
||||
})),
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user