Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve the Devfile is not reachable warning for SSH urls (#1259)
Browse files Browse the repository at this point in the history
If the devfile resolve request fails with the devfile not found error, check if the url is an SSH url. If so, interrupt the workspace start with a new warning that describes the problem of the devfile resolve via a private repository SSH url.
vinokurig committed Nov 20, 2024
1 parent 642b542 commit 1b1c554
Showing 3 changed files with 91 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */

import { FACTORY_LINK_ATTR } from '@eclipse-che/common';
import { AlertVariant } from '@patternfly/react-core';
import { cleanup, screen, waitFor } from '@testing-library/react';
import userEvent, { UserEvent } from '@testing-library/user-event';
import { createMemoryHistory, MemoryHistory } from 'history';
@@ -709,6 +710,7 @@ describe('Creating steps, fetching a devfile', () => {
[FACTORY_URL_ATTR]: factoryUrl,
});

mockIsOAuthResponse.mockReturnValue(false);
mockRequestFactoryResolver.mockRejectedValue('Could not reach devfile');

spyWindowLocation = createWindowLocationSpy(host, protocol);
@@ -751,6 +753,46 @@ describe('Creating steps, fetching a devfile', () => {
expect(mockOpenOAuthPage).not.toHaveBeenCalled();
expect(mockOnError).not.toHaveBeenCalled();
});

it('should show warning on SSH url', async () => {
const expectAlertItem = expect.objectContaining({
title: 'Warning',
variant: AlertVariant.warning,
children: (
<ExpandableWarning
textBefore="Devfile resolve from a privatre repositry via an SSH url is not supported."
errorMessage="Could not reach devfile"
textAfter="Apply a Personal Access Token to fetch the devfile.yaml content."
/>
),
actionCallbacks: [
expect.objectContaining({
title: 'Continue with default devfile',
callback: expect.any(Function),
}),
expect.objectContaining({
title: 'Reload',
callback: expect.any(Function),
}),
expect.objectContaining({
title: 'Open Documentation page',
callback: expect.any(Function),
}),
],
});
searchParams = new URLSearchParams({
[FACTORY_URL_ATTR]: 'git@github.com:user/repository.git',
});
const emptyStore = new MockStoreBuilder().build();
renderComponent(emptyStore, searchParams, location);

await jest.advanceTimersByTimeAsync(MIN_STEP_DURATION_MS);

await waitFor(() => expect(mockOnNextStep).not.toHaveBeenCalled);

expect(mockOpenOAuthPage).not.toHaveBeenCalled();
expect(mockOnError).toHaveBeenCalledWith(expectAlertItem);
});
});
});

Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@ import { AlertItem } from '@/services/helpers/types';
import { isOAuthResponse, OAuthService } from '@/services/oauth';
import SessionStorageService, { SessionStorageKey } from '@/services/session-storage';
import { AppState } from '@/store';
import { selectBranding } from '@/store/Branding/selectors';
import { factoryResolverActionCreators, selectFactoryResolver } from '@/store/FactoryResolver';
import { selectAllWorkspaces } from '@/store/Workspaces/selectors';

@@ -52,6 +53,13 @@ export class UnsupportedGitProviderError extends Error {
}
}

export class SSHPrivateRepositoryUrlError extends Error {
constructor(message: string) {
super(message);
this.name = 'UnsupportedGitProviderError';
}
}

const RELOADS_LIMIT = 2;
type ReloadsInfo = {
[url: string]: number;
@@ -179,6 +187,10 @@ class CreatingStepFetchDevfile extends ProgressStep<Props, State> {
this.clearStepError();
}

protected handleOpenDocumentationPage(): void {
window.open(this.props.branding.docs.startWorkspaceFromGit, '_blank');
}

protected handleTimeout(): void {
const timeoutError = new Error(
`Devfile hasn't been resolved in the last ${TIMEOUT_TO_RESOLVE_SEC} seconds.`,
@@ -220,7 +232,11 @@ class CreatingStepFetchDevfile extends ProgressStep<Props, State> {
errorMessage === 'Failed to fetch devfile' ||
errorMessage.startsWith('Could not reach devfile')
) {
throw new UnsupportedGitProviderError(errorMessage);
if (sourceUrl.startsWith('git@')) {
throw new SSHPrivateRepositoryUrlError(errorMessage);
} else {
throw new UnsupportedGitProviderError(errorMessage);
}
}
throw e;
}
@@ -365,6 +381,34 @@ class CreatingStepFetchDevfile extends ProgressStep<Props, State> {
],
};
}
if (error instanceof SSHPrivateRepositoryUrlError) {
return {
key,
title: 'Warning',
variant: AlertVariant.warning,
children: (
<ExpandableWarning
textBefore="Devfile resolve from a privatre repositry via an SSH url is not supported."
errorMessage={helpers.errors.getMessage(error)}
textAfter="Apply a Personal Access Token to fetch the devfile.yaml content."
/>
),
actionCallbacks: [
{
title: 'Continue with default devfile',
callback: () => this.handleDefaultDevfile(key),
},
{
title: 'Reload',
callback: () => this.handleRestart(key),
},
{
title: 'Open Documentation page',
callback: () => this.handleOpenDocumentationPage(),
},
],
};
}
return {
key,
title: 'Failed to create the workspace',
@@ -417,6 +461,7 @@ class CreatingStepFetchDevfile extends ProgressStep<Props, State> {
const mapStateToProps = (state: AppState) => ({
allWorkspaces: selectAllWorkspaces(state),
factoryResolver: selectFactoryResolver(state),
branding: selectBranding(state),
});

const connector = connect(mapStateToProps, factoryResolverActionCreators, null, {
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@ export type BrandingDocs = {
faq?: string;
storageTypes: string;
webSocketTroubleshooting: string;
startWorkspaceFromGit: string;
};

export type BrandingConfiguration = {
@@ -83,6 +84,8 @@ export const BRANDING_DEFAULT: BrandingData = {
'https://www.eclipse.org/che/docs/stable/end-user-guide/url-parameter-for-the-workspace-storage/',
webSocketTroubleshooting:
'https://www.eclipse.org/che/docs/stable/end-user-guide/troubleshooting-network-problems/',
startWorkspaceFromGit:
'https://eclipse.dev/che/docs/stable/end-user-guide/starting-a-workspace-from-a-git-repository-url/',
},
configuration: {},
};

0 comments on commit 1b1c554

Please sign in to comment.