Skip to content

Commit

Permalink
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.
  • Loading branch information
vinokurig committed Nov 20, 2024
1 parent 642b542 commit 8bc391c
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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]: '[email protected]:user/repository.git',
});
const emptyStore = new FakeStoreBuilder().build();
renderComponent(emptyStore, searchParams, history);

await jest.advanceTimersByTimeAsync(MIN_STEP_DURATION_MS);

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

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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;
Expand Down Expand Up @@ -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.`,
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export type BrandingDocs = {
faq?: string;
storageTypes: string;
webSocketTroubleshooting: string;
startWorkspaceFromGit: string;
};

export type BrandingConfiguration = {
Expand Down Expand Up @@ -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 8bc391c

Please sign in to comment.