Continue renaming code from GitHub to Git

Signed-off-by: Erik Engervall <erik.engervall@gmail.com>
This commit is contained in:
Erik Engervall
2021-04-29 12:02:05 +02:00
parent 66918b71fb
commit 19e6ebc1f2
38 changed files with 230 additions and 225 deletions
+9 -9
View File
@@ -1,4 +1,4 @@
# GitHub Release Manager (GRM)
# Git Release Manager (GRM)
## Overview
@@ -6,17 +6,17 @@
Does it build and ship your code? **No**.
What `GRM` does is manage your **[releases](https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository)** on GitHub, building and shipping is entirely up to you as a developer to handle in your CI.
What `GRM` does is manage your Git **[releases](https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository)**, building and shipping is entirely up to you as a developer to handle in your CI.
`GRM` is built with industry standards in mind and the flow is as follows:
![](./src/features/Info/flow.png)
> **GitHub**: The source control system where releases reside in a practical sense. Read more about [GitHub releases](https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository). (Note that this plugin works just as well with GitHub Enterprise.)
> **Git**: The source control system where releases reside in a practical sense. Read more about [Git releases](https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository). (Note that this plugin works just as well with any system implementing `Git`.)
>
> **Release Candidate (RC)**: A GitHub pre-release intended primarily for internal testing
> **Release Candidate (RC)**: A Git pre-release intended primarily for internal testing
>
> **Release Version**: A GitHub release intended for end users
> **Release Version**: A Git release intended for end users
Looking at the flow above, a common release lifecycle could be:
@@ -24,7 +24,7 @@ Looking at the flow above, a common release lifecycle could be:
- `GRM`
1. Creates a release branch `rc/<version>`
1. Creates Release Candidate tag `rc-<version>`
1. Creates a GitHub prerelease with Release Candidate tag
1. Creates a Git prerelease with Release Candidate tag
- Your CI
1. Detects the new tag by matching the git reference `refs/tags/rc-.*`
1. Builds and deploys to staging environment for testing
@@ -32,14 +32,14 @@ Looking at the flow above, a common release lifecycle could be:
- `GRM`
1. The selected commit is cherry-picked to the release branch
1. The release tag is bumped
1. Updates GitHub release's tag and description with the patch's details
1. Updates Git release's tag and description with the patch's details
- Your CI
1. Detects the new tag by matching the git reference `refs/tags/(rc|version)-.*` (Release Versions are patchable as well)
1. Builds and deploys to staging (or production if Release Version) for testing
- User presses **Promote Release Candidate to Release Version**
- `GRM`
1. Creates Release Version tag `version-<version>`
1. Promotes the GitHub release by removing the prerelease flag
1. Promotes the Git release by removing the prerelease flag
- Your CI
1. Detects the new tag by matching the git reference `refs/tags/version-.*`
1. Builds and deploys to production for testing
@@ -48,7 +48,7 @@ Looking at the flow above, a common release lifecycle could be:
### Importing
The plugin exports a single full-page extension `GitHubReleaseManagerPage`, which one can add to an app like a usual top-level tool on a dedicated route.
The plugin exports a single full-page extension `GitReleaseManagerPage`, which one can add to an app like a usual top-level tool on a dedicated route.
### Configuration
+5 -8
View File
@@ -18,14 +18,11 @@ import React from 'react';
import { createDevApp } from '@backstage/dev-utils';
import { Box, Typography } from '@material-ui/core';
import {
gitHubReleaseManagerPlugin,
GitHubReleaseManagerPage,
} from '../src/plugin';
import { gitReleaseManagerPlugin, GitReleaseManagerPage } from '../src/plugin';
import { InfoCardPlus } from '../src/components/InfoCardPlus';
createDevApp()
.registerPlugin(gitHubReleaseManagerPlugin)
.registerPlugin(gitReleaseManagerPlugin)
.addPage({
title: 'Dynamic',
path: '/dynamic',
@@ -36,7 +33,7 @@ createDevApp()
<Typography>Configure plugin via select inputs</Typography>
</InfoCardPlus>
<GitHubReleaseManagerPage />
<GitReleaseManagerPage />
</Box>
),
})
@@ -53,7 +50,7 @@ createDevApp()
</Typography>
</InfoCardPlus>
<GitHubReleaseManagerPage
<GitReleaseManagerPage
project={{
owner: 'eengervall-playground',
repo: 'RMaaS-semver',
@@ -74,7 +71,7 @@ createDevApp()
<Typography>Success callbacks can also be added</Typography>
</InfoCardPlus>
<GitHubReleaseManagerPage
<GitReleaseManagerPage
project={{
owner: 'eengervall-playground',
repo: 'playground-semver',
@@ -27,7 +27,7 @@ import {
} from './types/types';
import { Features } from './features/Features';
import { CenteredCircularProgress } from './components/CenteredCircularProgress';
import { githubReleaseManagerApiRef } from './api/serviceApiRef';
import { gitReleaseManagerApiRef } from './api/serviceApiRef';
import { InfoCardPlus } from './components/InfoCardPlus';
import { isProjectValid } from './helpers/isProjectValid';
import { ProjectContext, Project } from './contexts/ProjectContext';
@@ -35,7 +35,7 @@ import { RepoDetailsForm } from './features/RepoDetailsForm/RepoDetailsForm';
import { useQueryHandler } from './hooks/useQueryHandler';
import { useStyles } from './styles/styles';
export interface GitHubReleaseManagerProps {
interface GitReleaseManagerProps {
project?: Omit<Project, 'isProvidedViaProps'>;
features?: {
info?: Pick<ComponentConfig<void>, 'omit'>;
@@ -46,8 +46,8 @@ export interface GitHubReleaseManagerProps {
};
}
export function GitHubReleaseManager(props: GitHubReleaseManagerProps) {
const pluginApiClient = useApi(githubReleaseManagerApiRef);
export function GitReleaseManager(props: GitReleaseManagerProps) {
const pluginApiClient = useApi(gitReleaseManagerApiRef);
const classes = useStyles();
const { getParsedQuery } = useQueryHandler();
@@ -83,7 +83,7 @@ export function GitHubReleaseManager(props: GitHubReleaseManagerProps) {
return (
<ProjectContext.Provider value={{ project }}>
<div className={classes.root}>
<ContentHeader title="GitHub Release Manager" />
<ContentHeader title="Git Release Manager" />
<InfoCardPlus>
<RepoDetailsForm username={usernameResponse.value.username} />
@@ -16,7 +16,7 @@
import { ConfigReader, OAuthApi } from '@backstage/core';
import { PluginApiClient } from './PluginApiClient';
import { GitReleaseApiClient } from './PluginApiClient';
describe('PluginApiClient', () => {
it('should return the default plugin api client', () => {
@@ -24,10 +24,13 @@ describe('PluginApiClient', () => {
const githubAuthApi: OAuthApi = {
getAccessToken: jest.fn(),
};
const pluginApiClient = new PluginApiClient({ configApi, githubAuthApi });
const pluginApiClient = new GitReleaseApiClient({
configApi,
githubAuthApi,
});
expect(pluginApiClient).toMatchInlineSnapshot(`
PluginApiClient {
GitReleaseApiClient {
"baseUrl": "https://api.github.com",
"createRc": Object {
"createRef": [Function],
@@ -23,7 +23,7 @@ import { DISABLE_CACHE } from '../constants/constants';
import { Project } from '../contexts/ProjectContext';
import { SemverTagParts } from '../helpers/tagParts/getSemverTagParts';
export class PluginApiClient implements IPluginApiClient {
export class GitReleaseApiClient implements GitReleaseApi {
private readonly githubAuthApi: OAuthApi;
private readonly baseUrl: string;
readonly host: string;
@@ -774,7 +774,7 @@ type CreateTempCommit = (
tagParts: SemverTagParts | CalverTagParts;
releaseBranchTree: string;
selectedPatchCommit: UnboxArray<
UnboxReturnedPromise<IPluginApiClient['getRecentCommits']>
UnboxReturnedPromise<GitReleaseApi['getRecentCommits']>
>;
} & OwnerRepo,
) => Promise<{
@@ -812,7 +812,7 @@ type CreateCherryPickCommit = (
args: {
bumpedTag: string;
selectedPatchCommit: UnboxArray<
UnboxReturnedPromise<IPluginApiClient['getRecentCommits']>
UnboxReturnedPromise<GitReleaseApi['getRecentCommits']>
>;
mergeTree: string;
releaseBranchSha: string;
@@ -827,7 +827,7 @@ type ReplaceTempCommit = (
args: {
releaseBranchName: string;
cherryPickCommit: UnboxReturnedPromise<
IPluginApiClient['patch']['createCherryPickCommit']
GitReleaseApi['patch']['createCherryPickCommit']
>;
} & OwnerRepo,
) => Promise<{
@@ -924,7 +924,7 @@ type GetCommit = (
}>;
export type GetCommitResult = UnboxReturnedPromise<GetCommit>;
export interface IPluginApiClient {
export interface GitReleaseApi {
getHost: GetHost;
getRepoPath: GetRepoPath;
getOwners: GetOwners;
@@ -14,11 +14,11 @@
* limitations under the License.
*/
import { githubReleaseManagerApiRef } from './serviceApiRef';
import { gitReleaseManagerApiRef } from './serviceApiRef';
describe('githubReleaseManagerApiRef', () => {
describe('gitReleaseManagerApiRef', () => {
it('should work', () => {
const result = githubReleaseManagerApiRef;
const result = gitReleaseManagerApiRef;
expect(result).toMatchInlineSnapshot(`
ApiRefImpl {
@@ -16,9 +16,9 @@
import { createApiRef } from '@backstage/core';
import { IPluginApiClient } from './PluginApiClient';
import { GitReleaseApi } from './PluginApiClient';
export const githubReleaseManagerApiRef = createApiRef<IPluginApiClient>({
export const gitReleaseManagerApiRef = createApiRef<GitReleaseApi>({
id: 'plugin.git-release-manager.service',
description: 'Used by the Git Release Manager plugin to make requests',
});
@@ -22,7 +22,7 @@ import DynamicFeedIcon from '@material-ui/icons/DynamicFeed';
import GitHubIcon from '@material-ui/icons/GitHub';
import LocalOfferIcon from '@material-ui/icons/LocalOffer';
import { GitHubReleaseManagerError } from '../errors/GitHubReleaseManagerError';
import { GitReleaseManagerError } from '../errors/GitReleaseManagerError';
import { TEST_IDS } from '../test-helpers/test-ids';
interface DifferProps {
@@ -115,6 +115,6 @@ function Icon({ icon }: IconProps) {
);
default:
throw new GitHubReleaseManagerError('Invalid Differ icon');
throw new GitReleaseManagerError('Invalid Differ icon');
}
}
@@ -17,7 +17,7 @@
import { createContext, useContext } from 'react';
import { VERSIONING_STRATEGIES } from '../constants/constants';
import { GitHubReleaseManagerError } from '../errors/GitHubReleaseManagerError';
import { GitReleaseManagerError } from '../errors/GitReleaseManagerError';
export interface Project {
/**
@@ -57,7 +57,7 @@ export const useProjectContext = () => {
const { project } = useContext(ProjectContext) ?? {};
if (!project) {
throw new GitHubReleaseManagerError('project not found');
throw new GitReleaseManagerError('project not found');
}
return {
@@ -16,7 +16,7 @@
import { createContext, useContext } from 'react';
import { GitHubReleaseManagerError } from '../errors/GitHubReleaseManagerError';
import { GitReleaseManagerError } from '../errors/GitReleaseManagerError';
export const RefetchContext = createContext<
| {
@@ -30,7 +30,7 @@ export const useRefetchContext = () => {
const refetch = useContext(RefetchContext);
if (!refetch) {
throw new GitHubReleaseManagerError('refetch not found');
throw new GitReleaseManagerError('refetch not found');
}
return {
@@ -14,10 +14,10 @@
* limitations under the License.
*/
export class GitHubReleaseManagerError extends Error {
export class GitReleaseManagerError extends Error {
constructor(message: string) {
super(message);
this.name = 'GitHubReleaseManagerError';
this.name = 'GitReleaseManagerError';
}
}
@@ -19,15 +19,15 @@ import { render } from '@testing-library/react';
import {
mockCalverProject,
mockNextGitHubInfoSemver,
mockNextGitInfoSemver,
mockReleaseBranch,
mockReleaseCandidateCalver,
mockReleaseVersionCalver,
mockSemverProject,
} from '../../test-helpers/test-helpers';
import { CreateRc } from './CreateRc';
import { CreateReleaseCandidate } from './CreateReleaseCandidate';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { useCreateRc } from './hooks/useCreateRc';
import { useCreateReleaseCandidate } from './hooks/useCreateReleaseCandidate';
import { useProjectContext } from '../../contexts/ProjectContext';
jest.mock('../../contexts/ProjectContext', () => ({
@@ -35,23 +35,23 @@ jest.mock('../../contexts/ProjectContext', () => ({
project: mockCalverProject,
})),
}));
jest.mock('../../helpers/getRcGitHubInfo', () => ({
getRcGitHubInfo: () => mockNextGitHubInfoSemver,
jest.mock('../../helpers/getReleaseCandidateGitInfo', () => ({
getReleaseCandidateGitInfo: () => mockNextGitInfoSemver,
}));
jest.mock('./hooks/useCreateRc', () => ({
useCreateRc: () =>
jest.mock('./hooks/useCreateReleaseCandidate', () => ({
useCreateReleaseCandidate: () =>
({
run: jest.fn(),
responseSteps: [],
progress: 0,
runInvoked: false,
} as ReturnType<typeof useCreateRc>),
} as ReturnType<typeof useCreateReleaseCandidate>),
}));
describe('CreateRc', () => {
describe('CreateReleaseCandidate', () => {
it('should display CTA', () => {
const { getByTestId } = render(
<CreateRc
<CreateReleaseCandidate
defaultBranch="mockDefaultBranch"
latestRelease={mockReleaseCandidateCalver}
releaseBranch={mockReleaseBranch}
@@ -67,7 +67,7 @@ describe('CreateRc', () => {
});
const { getByTestId } = render(
<CreateRc
<CreateReleaseCandidate
defaultBranch="mockDefaultBranch"
latestRelease={mockReleaseVersionCalver}
releaseBranch={mockReleaseBranch}
@@ -32,16 +32,16 @@ import {
} from '../../api/PluginApiClient';
import { ComponentConfigCreateRc } from '../../types/types';
import { Differ } from '../../components/Differ';
import { getRcGitHubInfo } from '../../helpers/getRcGitHubInfo';
import { getReleaseCandidateGitInfo } from '../../helpers/getReleaseCandidateGitInfo';
import { InfoCardPlus } from '../../components/InfoCardPlus';
import { ResponseStepDialog } from '../../components/ResponseStepDialog/ResponseStepDialog';
import { SEMVER_PARTS } from '../../constants/constants';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { useCreateRc } from './hooks/useCreateRc';
import { useCreateReleaseCandidate } from './hooks/useCreateReleaseCandidate';
import { useProjectContext } from '../../contexts/ProjectContext';
import { useStyles } from '../../styles/styles';
interface CreateRcProps {
interface CreateReleaseCandidateProps {
defaultBranch: GetRepositoryResult['defaultBranch'];
latestRelease: GetLatestReleaseResult;
releaseBranch: GetBranchResult | null;
@@ -60,32 +60,37 @@ const InfoCardPlusWrapper = ({ children }: { children: React.ReactNode }) => {
);
};
export const CreateRc = ({
export const CreateReleaseCandidate = ({
defaultBranch,
latestRelease,
releaseBranch,
successCb,
}: CreateRcProps) => {
}: CreateReleaseCandidateProps) => {
const { project } = useProjectContext();
const classes = useStyles();
const [semverBumpLevel, setSemverBumpLevel] = useState<'major' | 'minor'>(
SEMVER_PARTS.minor,
);
const [nextGitHubInfo, setNextGitHubInfo] = useState(
getRcGitHubInfo({ latestRelease, project, semverBumpLevel }),
const [releaseCandidateGitInfo, setReleaseCandidateGitInfo] = useState(
getReleaseCandidateGitInfo({ latestRelease, project, semverBumpLevel }),
);
useEffect(() => {
setNextGitHubInfo(
getRcGitHubInfo({ latestRelease, project, semverBumpLevel }),
setReleaseCandidateGitInfo(
getReleaseCandidateGitInfo({ latestRelease, project, semverBumpLevel }),
);
}, [semverBumpLevel, setNextGitHubInfo, latestRelease, project]);
}, [semverBumpLevel, setReleaseCandidateGitInfo, latestRelease, project]);
const { progress, responseSteps, run, runInvoked } = useCreateRc({
const {
progress,
responseSteps,
run,
runInvoked,
} = useCreateReleaseCandidate({
defaultBranch,
latestRelease,
nextGitHubInfo,
releaseCandidateGitInfo,
project,
successCb,
});
@@ -99,15 +104,15 @@ export const CreateRc = ({
);
}
if (nextGitHubInfo.error !== undefined) {
if (releaseCandidateGitInfo.error !== undefined) {
return (
<InfoCardPlusWrapper>
<Alert severity="error">
{nextGitHubInfo.error.title && (
<AlertTitle>{nextGitHubInfo.error.title}</AlertTitle>
{releaseCandidateGitInfo.error.title && (
<AlertTitle>{releaseCandidateGitInfo.error.title}</AlertTitle>
)}
{nextGitHubInfo.error.subtitle}
{releaseCandidateGitInfo.error.subtitle}
</Alert>
</InfoCardPlusWrapper>
);
@@ -115,7 +120,7 @@ export const CreateRc = ({
const tagAlreadyExists =
latestRelease !== null &&
latestRelease.tagName === nextGitHubInfo.rcReleaseTag;
latestRelease.tagName === releaseCandidateGitInfo.rcReleaseTag;
const conflictingPreRelease =
latestRelease !== null && latestRelease.prerelease;
@@ -159,7 +164,7 @@ export const CreateRc = ({
{tagAlreadyExists && (
<Alert className={classes.paragraph} severity="warning">
There's already a tag named{' '}
<strong>{nextGitHubInfo.rcReleaseTag}</strong>
<strong>{releaseCandidateGitInfo.rcReleaseTag}</strong>
</Alert>
)}
</>
@@ -169,7 +174,7 @@ export const CreateRc = ({
<Differ
icon="branch"
current={releaseBranch?.name}
next={nextGitHubInfo.rcBranch}
next={releaseCandidateGitInfo.rcBranch}
/>
</Typography>
@@ -177,7 +182,7 @@ export const CreateRc = ({
<Differ
icon="tag"
current={latestRelease?.tagName}
next={nextGitHubInfo.rcReleaseTag}
next={releaseCandidateGitInfo.rcReleaseTag}
/>
</Typography>
</div>
@@ -21,25 +21,25 @@ import {
mockApiClient,
mockCalverProject,
mockDefaultBranch,
mockNextGitHubInfoCalver,
mockNextGitInfoCalver,
mockReleaseVersionCalver,
} from '../../../test-helpers/test-helpers';
import { useCreateRc } from './useCreateRc';
import { useCreateReleaseCandidate } from './useCreateReleaseCandidate';
jest.mock('@backstage/core', () => ({
useApi: () => mockApiClient,
createApiRef: jest.fn(),
}));
describe('useCreateRc', () => {
describe('useCreateReleaseCandidate', () => {
beforeEach(jest.clearAllMocks);
it('should return the expected responseSteps and progress', async () => {
const { result } = renderHook(() =>
useCreateRc({
useCreateReleaseCandidate({
defaultBranch: mockDefaultBranch,
latestRelease: mockReleaseVersionCalver,
nextGitHubInfo: mockNextGitHubInfoCalver,
releaseCandidateGitInfo: mockNextGitInfoCalver,
project: mockCalverProject,
}),
);
@@ -54,10 +54,10 @@ describe('useCreateRc', () => {
it('should return the expected responseSteps and progress (with successCb)', async () => {
const { result } = renderHook(() =>
useCreateRc({
useCreateReleaseCandidate({
defaultBranch: mockDefaultBranch,
latestRelease: mockReleaseVersionCalver,
nextGitHubInfo: mockNextGitHubInfoCalver,
releaseCandidateGitInfo: mockNextGitInfoCalver,
project: mockCalverProject,
successCb: jest.fn(),
}),
@@ -23,35 +23,35 @@ import {
GetRepositoryResult,
} from '../../../api/PluginApiClient';
import { CardHook, ComponentConfigCreateRc } from '../../../types/types';
import { getRcGitHubInfo } from '../../../helpers/getRcGitHubInfo';
import { githubReleaseManagerApiRef } from '../../../api/serviceApiRef';
import { GitHubReleaseManagerError } from '../../../errors/GitHubReleaseManagerError';
import { getReleaseCandidateGitInfo } from '../../../helpers/getReleaseCandidateGitInfo';
import { gitReleaseManagerApiRef } from '../../../api/serviceApiRef';
import { GitReleaseManagerError } from '../../../errors/GitReleaseManagerError';
import { Project } from '../../../contexts/ProjectContext';
import { useResponseSteps } from '../../../hooks/useResponseSteps';
interface CreateRC {
interface UseCreateReleaseCandidate {
defaultBranch: GetRepositoryResult['defaultBranch'];
latestRelease: GetLatestReleaseResult;
nextGitHubInfo: ReturnType<typeof getRcGitHubInfo>;
releaseCandidateGitInfo: ReturnType<typeof getReleaseCandidateGitInfo>;
project: Project;
successCb?: ComponentConfigCreateRc['successCb'];
}
export function useCreateRc({
export function useCreateReleaseCandidate({
defaultBranch,
latestRelease,
nextGitHubInfo,
releaseCandidateGitInfo,
project,
successCb,
}: CreateRC): CardHook<void> {
const pluginApiClient = useApi(githubReleaseManagerApiRef);
}: UseCreateReleaseCandidate): CardHook<void> {
const pluginApiClient = useApi(gitReleaseManagerApiRef);
if (nextGitHubInfo.error) {
throw new GitHubReleaseManagerError(
if (releaseCandidateGitInfo.error) {
throw new GitReleaseManagerError(
`Unexpected error: ${
nextGitHubInfo.error.title
? `${nextGitHubInfo.error.title} (${nextGitHubInfo.error.subtitle})`
: nextGitHubInfo.error.subtitle
releaseCandidateGitInfo.error.title
? `${releaseCandidateGitInfo.error.title} (${releaseCandidateGitInfo.error.subtitle})`
: releaseCandidateGitInfo.error.subtitle
}`,
);
}
@@ -98,12 +98,12 @@ export function useCreateRc({
owner: project.owner,
repo: project.repo,
mostRecentSha: latestCommitRes.value.latestCommit.sha,
targetBranch: nextGitHubInfo.rcBranch,
targetBranch: releaseCandidateGitInfo.rcBranch,
})
.catch(error => {
if (error?.body?.message === 'Reference already exists') {
throw new GitHubReleaseManagerError(
`Branch "${nextGitHubInfo.rcBranch}" already exists: .../tree/${nextGitHubInfo.rcBranch}`,
throw new GitReleaseManagerError(
`Branch "${releaseCandidateGitInfo.rcBranch}" already exists: .../tree/${releaseCandidateGitInfo.rcBranch}`,
);
}
throw error;
@@ -130,7 +130,7 @@ export function useCreateRc({
const previousReleaseBranch = latestRelease
? latestRelease.targetCommitish
: defaultBranch;
const nextReleaseBranch = nextGitHubInfo.rcBranch;
const nextReleaseBranch = releaseCandidateGitInfo.rcBranch;
const comparison = await pluginApiClient.createRc
.getComparison({
owner: project.owner,
@@ -173,16 +173,16 @@ export function useCreateRc({
.createRelease({
owner: project.owner,
repo: project.repo,
rcReleaseTag: nextGitHubInfo.rcReleaseTag,
releaseName: nextGitHubInfo.releaseName,
rcBranch: nextGitHubInfo.rcBranch,
rcReleaseTag: releaseCandidateGitInfo.rcReleaseTag,
releaseName: releaseCandidateGitInfo.releaseName,
rcBranch: releaseCandidateGitInfo.rcBranch,
releaseBody: getComparisonRes.value.releaseBody,
})
.catch(asyncCatcher);
addStepToResponseSteps({
message: `Created Release Candidate "${createReleaseResult.name}"`,
secondaryMessage: `with tag "${nextGitHubInfo.rcReleaseTag}"`,
secondaryMessage: `with tag "${releaseCandidateGitInfo.rcReleaseTag}"`,
link: createReleaseResult.htmlUrl,
});
@@ -66,7 +66,7 @@ describe('Features', () => {
class="MuiTypography-root MuiTypography-body1"
>
<strong>
GitHub
Git
</strong>
: The source control system where releases reside in a practical sense. Read more about
@@ -75,9 +75,9 @@ describe('Features', () => {
href="https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository"
target="_blank"
>
GitHub releases
Git releases
</a>
. (Note that this plugin works just as well with GitHub Enterprise.)
.
</p>
<p
class="MuiTypography-root MuiTypography-body1"
@@ -85,12 +85,11 @@ describe('Features', () => {
<strong>
Release Candidate
</strong>
: A GitHub
: A Git
<i>
prerelease
</i>
intended primarily for internal testing
intended primarily for internal testing
</p>
<p
class="MuiTypography-root MuiTypography-body1"
@@ -98,7 +97,7 @@ describe('Features', () => {
<strong>
Release Version
</strong>
: A GitHub release intended for end users
: A Git release intended for end users
</p>
</div>
`);
@@ -14,19 +14,19 @@
* limitations under the License.
*/
import React, { useState } from 'react';
import React, { useState, ComponentProps } from 'react';
import { Alert, AlertTitle } from '@material-ui/lab';
import { ErrorBoundary, useApi } from '@backstage/core';
import { CenteredCircularProgress } from '../components/CenteredCircularProgress';
import { CreateRc } from './CreateRc/CreateRc';
import { githubReleaseManagerApiRef } from '../api/serviceApiRef';
import { GitHubReleaseManagerProps } from '../GitHubReleaseManager';
import { CreateReleaseCandidate } from './CreateReleaseCandidate/CreateReleaseCandidate';
import { GitReleaseManager } from '../GitReleaseManager';
import { gitReleaseManagerApiRef } from '../api/serviceApiRef';
import { Info } from './Info/Info';
import { Patch } from './Patch/Patch';
import { PromoteRc } from './PromoteRc/PromoteRc';
import { RefetchContext } from '../contexts/RefetchContext';
import { useGetGitHubBatchInfo } from '../hooks/useGetGitHubBatchInfo';
import { useGetGitBatchInfo } from '../hooks/useGetGitBatchInfo';
import { useProjectContext } from '../contexts/ProjectContext';
import { useVersioningStrategyMatchesRepoTags } from '../hooks/useVersioningStrategyMatchesRepoTags';
import { validateTagName } from '../helpers/tagParts/validateTagName';
@@ -34,43 +34,43 @@ import { validateTagName } from '../helpers/tagParts/validateTagName';
export function Features({
features,
}: {
features: GitHubReleaseManagerProps['features'];
features: ComponentProps<typeof GitReleaseManager>['features'];
}) {
const pluginApiClient = useApi(githubReleaseManagerApiRef);
const pluginApiClient = useApi(gitReleaseManagerApiRef);
const { project } = useProjectContext();
const [refetchTrigger, setRefetchTrigger] = useState(0);
const { gitHubBatchInfo } = useGetGitHubBatchInfo({
const { gitBatchInfo } = useGetGitBatchInfo({
pluginApiClient,
project,
refetchTrigger,
});
const { versioningStrategyMatches } = useVersioningStrategyMatchesRepoTags({
latestReleaseTagName: gitHubBatchInfo.value?.latestRelease?.tagName,
latestReleaseTagName: gitBatchInfo.value?.latestRelease?.tagName,
project,
repositoryName: gitHubBatchInfo.value?.repository.name,
repositoryName: gitBatchInfo.value?.repository.name,
});
if (gitHubBatchInfo.error) {
if (gitBatchInfo.error) {
return (
<Alert severity="error">
Error occured while fetching information for "{project.owner}/
{project.repo}" ({gitHubBatchInfo.error.message})
{project.repo}" ({gitBatchInfo.error.message})
</Alert>
);
}
if (gitHubBatchInfo.loading) {
if (gitBatchInfo.loading) {
return <CenteredCircularProgress />;
}
if (gitHubBatchInfo.value === undefined) {
if (gitBatchInfo.value === undefined) {
return (
<Alert severity="error">Failed to fetch latest GitHub release</Alert>
);
}
if (!gitHubBatchInfo.value.repository.pushPermissions) {
if (!gitBatchInfo.value.repository.pushPermissions) {
return (
<Alert severity="error">
You lack push permissions for repository "{project.owner}/{project.repo}
@@ -81,7 +81,7 @@ export function Features({
const { tagNameError } = validateTagName({
project,
tagName: gitHubBatchInfo.value.latestRelease?.tagName,
tagName: gitBatchInfo.value.latestRelease?.tagName,
});
if (tagNameError) {
return (
@@ -95,20 +95,20 @@ export function Features({
return (
<RefetchContext.Provider value={{ refetchTrigger, setRefetchTrigger }}>
<ErrorBoundary>
{gitHubBatchInfo.value.latestRelease && !versioningStrategyMatches && (
{gitBatchInfo.value.latestRelease && !versioningStrategyMatches && (
<Alert severity="warning" style={{ marginBottom: 20 }}>
Versioning mismatch, expected {project.versioningStrategy} version,
got "{gitHubBatchInfo.value.latestRelease.tagName}"
got "{gitBatchInfo.value.latestRelease.tagName}"
</Alert>
)}
{!gitHubBatchInfo.value.latestRelease && (
{!gitBatchInfo.value.latestRelease && (
<Alert severity="info" style={{ marginBottom: 20 }}>
This repository doesn't have any releases yet
</Alert>
)}
{!gitHubBatchInfo.value.releaseBranch && (
{!gitBatchInfo.value.releaseBranch && (
<Alert severity="info" style={{ marginBottom: 20 }}>
This repository doesn't have any release branches
</Alert>
@@ -116,32 +116,32 @@ export function Features({
{!features?.info?.omit && (
<Info
latestRelease={gitHubBatchInfo.value.latestRelease}
releaseBranch={gitHubBatchInfo.value.releaseBranch}
latestRelease={gitBatchInfo.value.latestRelease}
releaseBranch={gitBatchInfo.value.releaseBranch}
statsEnabled={features?.stats?.omit !== true}
/>
)}
{!features?.createRc?.omit && (
<CreateRc
latestRelease={gitHubBatchInfo.value.latestRelease}
releaseBranch={gitHubBatchInfo.value.releaseBranch}
defaultBranch={gitHubBatchInfo.value.repository.defaultBranch}
<CreateReleaseCandidate
latestRelease={gitBatchInfo.value.latestRelease}
releaseBranch={gitBatchInfo.value.releaseBranch}
defaultBranch={gitBatchInfo.value.repository.defaultBranch}
successCb={features?.createRc?.successCb}
/>
)}
{!features?.promoteRc?.omit && (
<PromoteRc
latestRelease={gitHubBatchInfo.value.latestRelease}
latestRelease={gitBatchInfo.value.latestRelease}
successCb={features?.promoteRc?.successCb}
/>
)}
{!features?.patch?.omit && (
<Patch
latestRelease={gitHubBatchInfo.value.latestRelease}
releaseBranch={gitHubBatchInfo.value.releaseBranch}
latestRelease={gitBatchInfo.value.latestRelease}
releaseBranch={gitBatchInfo.value.releaseBranch}
successCb={features?.patch?.successCb}
/>
)}
@@ -51,25 +51,24 @@ export const Info = ({
<Typography variant="h6">Terminology</Typography>
<Typography>
<strong>GitHub</strong>: The source control system where releases
reside in a practical sense. Read more about{' '}
<strong>Git</strong>: The source control system where releases reside
in a practical sense. Read more about{' '}
<Link
href="https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository"
target="_blank"
>
GitHub releases
Git releases
</Link>
. (Note that this plugin works just as well with GitHub Enterprise.)
.
</Typography>
<Typography>
<strong>Release Candidate</strong>: A GitHub <i>prerelease</i>{' '}
intended primarily for internal testing
<strong>Release Candidate</strong>: A Git <i>prerelease</i> intended
primarily for internal testing
</Typography>
<Typography>
<strong>Release Version</strong>: A GitHub release intended for end
users
<strong>Release Version</strong>: A Git release intended for end users
</Typography>
</Box>
@@ -77,7 +76,7 @@ export const Info = ({
<Typography variant="h6">Flow</Typography>
<Typography className={classes.paragraph}>
GitHub Release Manager is built with a specific flow in mind. For
Git Release Manager is built with a specific flow in mind. For
example, it assumes your project is configured to react to tags
prefixed with <b>rc</b> or <b>version</b>.
</Typography>
@@ -42,8 +42,8 @@ import { CalverTagParts } from '../../helpers/tagParts/getCalverTagParts';
import { CenteredCircularProgress } from '../../components/CenteredCircularProgress';
import { ComponentConfigPatch } from '../../types/types';
import { Differ } from '../../components/Differ';
import { githubReleaseManagerApiRef } from '../../api/serviceApiRef';
import { GitHubReleaseManagerError } from '../../errors/GitHubReleaseManagerError';
import { gitReleaseManagerApiRef } from '../../api/serviceApiRef';
import { GitReleaseManagerError } from '../../errors/GitReleaseManagerError';
import { ResponseStepDialog } from '../../components/ResponseStepDialog/ResponseStepDialog';
import { SemverTagParts } from '../../helpers/tagParts/getSemverTagParts';
import { TEST_IDS } from '../../test-helpers/test-ids';
@@ -66,11 +66,11 @@ export const PatchBody = ({
successCb,
tagParts,
}: PatchBodyProps) => {
const pluginApiClient = useApi(githubReleaseManagerApiRef);
const pluginApiClient = useApi(gitReleaseManagerApiRef);
const { project } = useProjectContext();
const [checkedCommitIndex, setCheckedCommitIndex] = useState(-1);
const githubDataResponse = useAsync(async () => {
const gitDataResponse = useAsync(async () => {
const [
recentCommitsOnDefaultBranch,
recentCommitsOnReleaseBranch,
@@ -109,15 +109,15 @@ export const PatchBody = ({
);
}
if (githubDataResponse.error) {
if (gitDataResponse.error) {
return (
<Alert data-testid={TEST_IDS.patch.error} severity="error">
Unexpected error: {githubDataResponse.error.message}
Unexpected error: {gitDataResponse.error.message}
</Alert>
);
}
if (githubDataResponse.loading) {
if (gitDataResponse.loading) {
return <CenteredCircularProgress data-testid={TEST_IDS.patch.loading} />;
}
@@ -133,7 +133,7 @@ export const PatchBody = ({
severity="info"
>
<AlertTitle>
The current GitHub release is a <b>Release Version</b>
The current Git release is a <b>Release Version</b>
</AlertTitle>
It's still possible to patch it, but be extra mindful of changes
</Alert>
@@ -147,16 +147,16 @@ export const PatchBody = ({
}
function CommitList() {
if (!githubDataResponse.value?.recentCommitsOnDefaultBranch) {
if (!gitDataResponse.value?.recentCommitsOnDefaultBranch) {
return null;
}
return (
<List>
{githubDataResponse.value.recentCommitsOnDefaultBranch.map(
{gitDataResponse.value.recentCommitsOnDefaultBranch.map(
(commit, index) => {
// FIXME: Performance improvement opportunity: Convert to object lookup
const commitExistsOnReleaseBranch = !!githubDataResponse.value?.recentCommitsOnReleaseBranch.find(
const commitExistsOnReleaseBranch = !!gitDataResponse.value?.recentCommitsOnReleaseBranch.find(
releaseBranchCommit =>
releaseBranchCommit.sha === commit.sha ||
releaseBranchCommit.commit.message.includes(commit.sha), // The selected patch commit's sha is included in the commit message
@@ -277,11 +277,11 @@ export const PatchBody = ({
color="primary"
onClick={() => {
const selectedPatchCommit =
githubDataResponse.value?.recentCommitsOnDefaultBranch[
gitDataResponse.value?.recentCommitsOnDefaultBranch[
checkedCommitIndex
];
if (!selectedPatchCommit) {
throw new GitHubReleaseManagerError(
throw new GitReleaseManagerError(
'Could not find selected patch commit',
);
}
@@ -24,7 +24,7 @@ import {
} from '../../../api/PluginApiClient';
import { CalverTagParts } from '../../../helpers/tagParts/getCalverTagParts';
import { ComponentConfigPatch, CardHook } from '../../../types/types';
import { githubReleaseManagerApiRef } from '../../../api/serviceApiRef';
import { gitReleaseManagerApiRef } from '../../../api/serviceApiRef';
import { Project } from '../../../contexts/ProjectContext';
import { SemverTagParts } from '../../../helpers/tagParts/getSemverTagParts';
import { useResponseSteps } from '../../../hooks/useResponseSteps';
@@ -45,7 +45,7 @@ export function usePatch({
tagParts,
successCb,
}: Patch): CardHook<GetRecentCommitsResultSingle> {
const pluginApiClient = useApi(githubReleaseManagerApiRef);
const pluginApiClient = useApi(gitReleaseManagerApiRef);
const {
responseSteps,
addStepToResponseSteps,
@@ -46,9 +46,7 @@ export const PromoteRc = ({ latestRelease, successCb }: PromoteRcProps) => {
className={classes.paragraph}
severity="warning"
>
<AlertTitle>
Latest GitHub release is not a Release Candidate
</AlertTitle>
<AlertTitle>Latest Git release is not a Release Candidate</AlertTitle>
One can only promote Release Candidates to Release Versions
</Alert>
);
@@ -20,7 +20,7 @@ import { useApi } from '@backstage/core';
import { CardHook, ComponentConfigPromoteRc } from '../../../types/types';
import { GetLatestReleaseResult } from '../../../api/PluginApiClient';
import { githubReleaseManagerApiRef } from '../../../api/serviceApiRef';
import { gitReleaseManagerApiRef } from '../../../api/serviceApiRef';
import { useProjectContext } from '../../../contexts/ProjectContext';
import { useResponseSteps } from '../../../hooks/useResponseSteps';
@@ -35,7 +35,7 @@ export function usePromoteRc({
releaseVersion,
successCb,
}: PromoteRc): CardHook<void> {
const pluginApiClient = useApi(githubReleaseManagerApiRef);
const pluginApiClient = useApi(gitReleaseManagerApiRef);
const { project } = useProjectContext();
const {
responseSteps,
@@ -27,14 +27,14 @@ import {
import { useApi } from '@backstage/core';
import { CenteredCircularProgress } from '../../components/CenteredCircularProgress';
import { githubReleaseManagerApiRef } from '../../api/serviceApiRef';
import { gitReleaseManagerApiRef } from '../../api/serviceApiRef';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { useFormClasses } from './styles';
import { useProjectContext } from '../../contexts/ProjectContext';
import { useQueryHandler } from '../../hooks/useQueryHandler';
export function Owner({ username }: { username: string }) {
const pluginApiClient = useApi(githubReleaseManagerApiRef);
const pluginApiClient = useApi(gitReleaseManagerApiRef);
const { project } = useProjectContext();
const formClasses = useFormClasses();
const navigate = useNavigate();
@@ -27,14 +27,14 @@ import {
import { useApi } from '@backstage/core';
import { CenteredCircularProgress } from '../../components/CenteredCircularProgress';
import { githubReleaseManagerApiRef } from '../../api/serviceApiRef';
import { gitReleaseManagerApiRef } from '../../api/serviceApiRef';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { useFormClasses } from './styles';
import { useProjectContext } from '../../contexts/ProjectContext';
import { useQueryHandler } from '../../hooks/useQueryHandler';
export function Repo() {
const pluginApiClient = useApi(githubReleaseManagerApiRef);
const pluginApiClient = useApi(gitReleaseManagerApiRef);
const { project } = useProjectContext();
const navigate = useNavigate();
const formClasses = useFormClasses();
@@ -20,7 +20,7 @@ import { DateTime } from 'luxon';
import { useApi } from '@backstage/core';
import { getReleaseCommitPairs } from '../helpers/getReleaseCommitPairs';
import { githubReleaseManagerApiRef } from '../../../../api/serviceApiRef';
import { gitReleaseManagerApiRef } from '../../../../api/serviceApiRef';
import { useProjectContext } from '../../../../contexts/ProjectContext';
import { useReleaseStatsContext } from '../../contexts/ReleaseStatsContext';
@@ -46,7 +46,7 @@ type ReleaseTime = {
};
export function useGetReleaseTimes() {
const pluginApiClient = useApi(githubReleaseManagerApiRef);
const pluginApiClient = useApi(gitReleaseManagerApiRef);
const { project } = useProjectContext();
const { releaseStats } = useReleaseStatsContext();
const [averageReleaseTime, setAverageReleaseTime] = useState<ReleaseTime[]>(
@@ -16,7 +16,7 @@
import { createContext, useContext } from 'react';
import { GitHubReleaseManagerError } from '../../../errors/GitHubReleaseManagerError';
import { GitReleaseManagerError } from '../../../errors/GitReleaseManagerError';
export interface ReleaseStats {
unmappableTags: string[];
@@ -55,7 +55,7 @@ export const useReleaseStatsContext = () => {
const { releaseStats } = useContext(ReleaseStatsContext) ?? {};
if (!releaseStats) {
throw new GitHubReleaseManagerError('releaseStats not found');
throw new GitReleaseManagerError('releaseStats not found');
}
return {
@@ -17,17 +17,17 @@
import { useAsync } from 'react-use';
import { useApi } from '@backstage/core';
import { githubReleaseManagerApiRef } from '../../../api/serviceApiRef';
import { GitHubReleaseManagerError } from '../../../errors/GitHubReleaseManagerError';
import { gitReleaseManagerApiRef } from '../../../api/serviceApiRef';
import { GitReleaseManagerError } from '../../../errors/GitReleaseManagerError';
import { useProjectContext } from '../../../contexts/ProjectContext';
export const useGetCommit = ({ ref }: { ref?: string }) => {
const pluginApiClient = useApi(githubReleaseManagerApiRef);
const pluginApiClient = useApi(gitReleaseManagerApiRef);
const { project } = useProjectContext();
const commit = useAsync(async () => {
if (!ref) {
throw new GitHubReleaseManagerError('Missing ref to get commit');
throw new GitReleaseManagerError('Missing ref to get commit');
}
return pluginApiClient.stats.getCommit({
@@ -17,11 +17,11 @@
import { useApi } from '@backstage/core';
import { useAsync } from 'react-use';
import { githubReleaseManagerApiRef } from '../../../api/serviceApiRef';
import { gitReleaseManagerApiRef } from '../../../api/serviceApiRef';
import { useProjectContext } from '../../../contexts/ProjectContext';
export const useGetStats = () => {
const pluginApiClient = useApi(githubReleaseManagerApiRef);
const pluginApiClient = useApi(gitReleaseManagerApiRef);
const { project } = useProjectContext();
const stats = useAsync(async () => {
@@ -22,9 +22,9 @@ import {
mockReleaseVersionSemver,
mockSemverProject,
} from '../test-helpers/test-helpers';
import { getRcGitHubInfo } from './getRcGitHubInfo';
import { getReleaseCandidateGitInfo } from './getReleaseCandidateGitInfo';
describe('getRcGitHubInfo', () => {
describe('getReleaseCandidateGitInfo', () => {
describe('DateTime', () => {
it('should format dates as expected', () => {
const formattedDate = DateTime.now().toFormat('yyyy.MM.dd');
@@ -36,7 +36,7 @@ describe('getRcGitHubInfo', () => {
describe('calver', () => {
it('should return correct GitHub info', () => {
expect(
getRcGitHubInfo({
getReleaseCandidateGitInfo({
project: mockCalverProject,
latestRelease: mockReleaseVersionCalver,
semverBumpLevel: 'minor',
@@ -55,7 +55,7 @@ describe('getRcGitHubInfo', () => {
describe('semver', () => {
it("should return correct GitHub info when there's previous releases", () => {
expect(
getRcGitHubInfo({
getReleaseCandidateGitInfo({
project: mockSemverProject,
latestRelease: mockReleaseVersionSemver,
semverBumpLevel: 'minor',
@@ -71,7 +71,7 @@ describe('getRcGitHubInfo', () => {
it("should return correct GitHub info when there's no previous release", () => {
expect(
getRcGitHubInfo({
getReleaseCandidateGitInfo({
project: mockSemverProject,
latestRelease: null,
semverBumpLevel: 'minor',
@@ -22,7 +22,7 @@ import { getSemverTagParts } from './tagParts/getSemverTagParts';
import { Project } from '../contexts/ProjectContext';
import { SEMVER_PARTS } from '../constants/constants';
export const getRcGitHubInfo = ({
export const getReleaseCandidateGitInfo = ({
project,
latestRelease,
semverBumpLevel,
@@ -14,13 +14,13 @@
* limitations under the License.
*/
import { GitHubReleaseManagerError } from '../errors/GitHubReleaseManagerError';
import { GitReleaseManagerError } from '../errors/GitReleaseManagerError';
export function getShortCommitHash(hash: string) {
const shortCommitHash = hash.substr(0, 7);
if (shortCommitHash.length < 7) {
throw new GitHubReleaseManagerError(
throw new GitReleaseManagerError(
'Invalid shortCommitHash: less than 7 characters',
);
}
@@ -18,12 +18,12 @@ import { renderHook, act } from '@testing-library/react-hooks';
import { waitFor } from '@testing-library/react';
import { mockApiClient, mockSemverProject } from '../test-helpers/test-helpers';
import { useGetGitHubBatchInfo } from './useGetGitHubBatchInfo';
import { useGetGitBatchInfo } from './useGetGitBatchInfo';
describe('useGetGitHubBatchInfo', () => {
describe('useGetHubBatchInfo', () => {
it('should handle repositories with releases', async () => {
const { result } = renderHook(() =>
useGetGitHubBatchInfo({
useGetGitBatchInfo({
pluginApiClient: mockApiClient,
project: mockSemverProject,
refetchTrigger: 1337,
@@ -31,10 +31,10 @@ describe('useGetGitHubBatchInfo', () => {
);
await act(async () => {
await waitFor(() => result.current.gitHubBatchInfo !== undefined);
await waitFor(() => result.current.gitBatchInfo !== undefined);
});
expect(result.current.gitHubBatchInfo).toMatchInlineSnapshot(`
expect(result.current.gitBatchInfo).toMatchInlineSnapshot(`
Object {
"loading": false,
"value": Object {
@@ -73,7 +73,7 @@ describe('useGetGitHubBatchInfo', () => {
(mockApiClient.getLatestRelease as jest.Mock).mockResolvedValueOnce(null);
const { result } = renderHook(() =>
useGetGitHubBatchInfo({
useGetGitBatchInfo({
pluginApiClient: mockApiClient,
project: mockSemverProject,
refetchTrigger: 1337,
@@ -81,10 +81,10 @@ describe('useGetGitHubBatchInfo', () => {
);
await act(async () => {
await waitFor(() => result.current.gitHubBatchInfo !== undefined);
await waitFor(() => result.current.gitBatchInfo !== undefined);
});
expect(result.current.gitHubBatchInfo).toMatchInlineSnapshot(`
expect(result.current.gitBatchInfo).toMatchInlineSnapshot(`
Object {
"loading": false,
"value": Object {
@@ -16,21 +16,21 @@
import { useAsync } from 'react-use';
import { IPluginApiClient } from '../api/PluginApiClient';
import { GitReleaseApi } from '../api/PluginApiClient';
import { Project } from '../contexts/ProjectContext';
interface GetGitHubBatchInfo {
interface GetGitBatchInfo {
project: Project;
pluginApiClient: IPluginApiClient;
pluginApiClient: GitReleaseApi;
refetchTrigger: number;
}
export const useGetGitHubBatchInfo = ({
export const useGetGitBatchInfo = ({
project,
pluginApiClient,
refetchTrigger,
}: GetGitHubBatchInfo) => {
const gitHubBatchInfo = useAsync(async () => {
}: GetGitBatchInfo) => {
const gitBatchInfo = useAsync(async () => {
const [repository, latestRelease] = await Promise.all([
pluginApiClient.getRepository({ ...project }),
pluginApiClient.getLatestRelease({ ...project }),
@@ -57,6 +57,6 @@ export const useGetGitHubBatchInfo = ({
}, [project, refetchTrigger]);
return {
gitHubBatchInfo,
gitBatchInfo,
};
};
+3 -3
View File
@@ -15,7 +15,7 @@
*/
export {
gitHubReleaseManagerPlugin,
GitHubReleaseManagerPage,
githubReleaseManagerApiRef,
gitReleaseManagerPlugin,
GitReleaseManagerPage,
gitReleaseManagerApiRef,
} from './plugin';
@@ -20,9 +20,9 @@ describe('git-release-manager', () => {
it('should export plugin & friends', () => {
expect(Object.keys(plugin)).toMatchInlineSnapshot(`
Array [
"githubReleaseManagerApiRef",
"gitHubReleaseManagerPlugin",
"GitHubReleaseManagerPage",
"gitReleaseManagerApiRef",
"gitReleaseManagerPlugin",
"GitReleaseManagerPage",
]
`);
});
+8 -8
View File
@@ -22,26 +22,26 @@ import {
createRoutableExtension,
} from '@backstage/core';
import { githubReleaseManagerApiRef } from './api/serviceApiRef';
import { PluginApiClient } from './api/PluginApiClient';
import { gitReleaseManagerApiRef } from './api/serviceApiRef';
import { GitReleaseApiClient } from './api/PluginApiClient';
import { rootRouteRef } from './routes';
export { githubReleaseManagerApiRef };
export { gitReleaseManagerApiRef };
export const gitHubReleaseManagerPlugin = createPlugin({
export const gitReleaseManagerPlugin = createPlugin({
id: 'git-release-manager',
routes: {
root: rootRouteRef,
},
apis: [
createApiFactory({
api: githubReleaseManagerApiRef,
api: gitReleaseManagerApiRef,
deps: {
configApi: configApiRef,
githubAuthApi: githubAuthApiRef,
},
factory: ({ configApi, githubAuthApi }) => {
return new PluginApiClient({
return new GitReleaseApiClient({
configApi,
githubAuthApi,
});
@@ -50,10 +50,10 @@ export const gitHubReleaseManagerPlugin = createPlugin({
],
});
export const GitHubReleaseManagerPage = gitHubReleaseManagerPlugin.provide(
export const GitReleaseManagerPage = gitReleaseManagerPlugin.provide(
createRoutableExtension({
component: () =>
import('./GitHubReleaseManager').then(m => m.GitHubReleaseManager),
import('./GitReleaseManager').then(m => m.GitReleaseManager),
mountPoint: rootRouteRef,
}),
);
@@ -18,11 +18,11 @@ import {
GetBranchResult,
GetLatestReleaseResult,
GetRecentCommitsResultSingle,
IPluginApiClient,
GitReleaseApi,
} from '../api/PluginApiClient';
import { CalverTagParts } from '../helpers/tagParts/getCalverTagParts';
import { Project } from '../contexts/ProjectContext';
import { getRcGitHubInfo } from '../helpers/getRcGitHubInfo';
import { getReleaseCandidateGitInfo } from '../helpers/getReleaseCandidateGitInfo';
const mockOwner = 'mock_owner';
const mockRepo = 'mock_repo';
@@ -59,13 +59,17 @@ export const mockSearchSemver = `?versioningStrategy=${mockSemverProject.version
export const mockDefaultBranch = 'mock_defaultBranch';
export const mockNextGitHubInfoSemver: ReturnType<typeof getRcGitHubInfo> = {
export const mockNextGitInfoSemver: ReturnType<
typeof getReleaseCandidateGitInfo
> = {
rcBranch: MOCK_RELEASE_BRANCH_NAME_SEMVER,
rcReleaseTag: MOCK_RELEASE_CANDIDATE_TAG_NAME_SEMVER,
releaseName: MOCK_RELEASE_NAME_SEMVER,
};
export const mockNextGitHubInfoCalver: ReturnType<typeof getRcGitHubInfo> = {
export const mockNextGitInfoCalver: ReturnType<
typeof getReleaseCandidateGitInfo
> = {
rcBranch: MOCK_RELEASE_BRANCH_NAME_CALVER,
rcReleaseTag: MOCK_RELEASE_CANDIDATE_TAG_NAME_CALVER,
releaseName: MOCK_RELEASE_NAME_CALVER,
@@ -168,7 +172,7 @@ export const mockSelectedPatchCommit = createMockRecentCommit({
/**
* MOCK API CLIENT
*/
export const mockApiClient: IPluginApiClient = {
export const mockApiClient: GitReleaseApi = {
getHost: jest.fn(() => 'github.com'),
getRepoPath: jest.fn(() => `${mockOwner}/${mockRepo}`),
@@ -72,7 +72,7 @@ export const TEST_IDS = {
icons: {
tag: 'grm--differ--icons--tag',
branch: 'grm--differ--icons--branch',
github: 'grm--differ--icons--github',
github: 'grm--differ--icons--git',
slack: 'grm--differ--icons--slack',
versioning: 'grm--differ--icons--versioning',
},