提交 1a69af19 编写于 作者: T Tomas Vik

Merge branch '400-fix-ci-config-validation' into 'main'

fix: validate CI command didn't show validation result

See merge request gitlab-org/gitlab-vscode-extension!273
此差异已折叠。
const vscode = require('vscode');
const { gitExtensionWrapper } = require('./git/git_extension_wrapper');
const gitLabService = require('./gitlab_service');
import * as vscode from 'vscode';
import { gitExtensionWrapper } from './git/git_extension_wrapper';
import * as gitLabService from './gitlab_service';
const { showInformationMessage, showErrorMessage } = vscode.window;
async function validate() {
export async function validate(): Promise<void> {
const editor = vscode.window.activeTextEditor;
if (!editor) {
showInformationMessage('GitLab Workflow: No open file.');
await vscode.window.showInformationMessage('GitLab Workflow: No open file.');
return;
}
const content = editor.document.getText();
const response = await gitLabService.validateCIConfig(
gitExtensionWrapper.getActiveRepository().rootFsPath,
gitExtensionWrapper.getActiveRepository()!.rootFsPath,
content,
);
if (!response) {
showInformationMessage('GitLab Workflow: Failed to validate CI configuration.');
await vscode.window.showInformationMessage(
'GitLab Workflow: Failed to validate CI configuration.',
);
return;
}
const { status, errors, error } = response;
if (status === 'valid') {
showInformationMessage('GitLab Workflow: Your CI configuration is valid.');
await vscode.window.showInformationMessage('GitLab Workflow: Your CI configuration is valid.');
} else if (status === 'invalid') {
if (errors[0]) {
showErrorMessage(errors[0]);
await vscode.window.showErrorMessage(errors[0]);
}
showErrorMessage('GitLab Workflow: Invalid CI configuration.');
await vscode.window.showErrorMessage('GitLab Workflow: Invalid CI configuration.');
} else if (error) {
showErrorMessage(`GitLab Workflow: Failed to validate CI configuration. Reason: ${error}`);
await vscode.window.showErrorMessage(
`GitLab Workflow: Failed to validate CI configuration. Reason: ${error}`,
);
}
}
exports.validate = validate;
......@@ -484,25 +484,25 @@ export async function createSnippet(repositoryRoot: string, data: { id: number }
}
}
export async function validateCIConfig(repositoryRoot: string, content: string): Promise<boolean> {
let validCIConfig = null;
interface ValidationResponse {
status?: string;
errors: string[];
error: string;
}
export async function validateCIConfig(
repositoryRoot: string,
content: string,
): Promise<ValidationResponse | undefined> {
try {
const { response } = await fetch(repositoryRoot, '/ci/lint', 'POST', {
content,
});
validCIConfig = response;
return response;
} catch (e) {
handleError(new UserFriendlyError('Failed to validate CI configuration.', e));
return undefined;
}
return Boolean(validCIConfig);
}
interface Discussion {
notes: {
// eslint-disable-next-line camelcase
created_at: string;
}[];
}
export async function renderMarkdown(markdown: string, repositoryRoot: string) {
......
const sinon = require('sinon');
const assert = require('assert');
const vscode = require('vscode');
const { rest } = require('msw');
const { tokenService } = require('../../src/services/token_service');
const validCiLintResponse = require('./fixtures/rest/ci_lint_valid.json');
const invalidCiLintResponse = require('./fixtures/rest/ci_lint_invalid.json');
const { getServer } = require('./test_infrastructure/mock_server');
const { GITLAB_URL, API_URL_PREFIX } = require('./test_infrastructure/constants');
const {
createAndOpenFile,
closeAndDeleteFile,
getRepositoryRoot,
insertTextIntoActiveEditor,
} = require('./test_infrastructure/helpers');
const { validate } = require('../../src/ci_config_validator');
describe('Validate CI config', async () => {
let server;
let testFileUri;
const VALID_CI_CONFIG = [`test:`, ` stage: test`, ` script:`, ` - echo 1`].join(['\n']);
const INVALID_CI_CONFIG = [`test:`, ` stage: test`, ` scccript:`, ` - echo 1`].join(['\n']);
const sandbox = sinon.createSandbox();
before(async () => {
server = getServer([
rest.post(`${API_URL_PREFIX}/ci/lint`, (req, res, ctx) => {
switch (req.body.content) {
case VALID_CI_CONFIG:
return res(ctx.status(200), ctx.json(validCiLintResponse));
case INVALID_CI_CONFIG:
return res(ctx.status(200), ctx.json(invalidCiLintResponse));
default:
return res(ctx.status(500), ctx.text('No response for the config'));
}
}),
]);
await tokenService.setToken(GITLAB_URL, 'abcd-secret');
});
beforeEach(async () => {
server.resetHandlers();
testFileUri = vscode.Uri.parse(`${getRepositoryRoot()}/.gitlab-ci.yml`);
await createAndOpenFile(testFileUri);
});
afterEach(async () => {
sandbox.restore();
await closeAndDeleteFile(testFileUri);
});
after(async () => {
server.close();
await tokenService.setToken(GITLAB_URL, undefined);
});
it('shows info message for valid config', async () => {
const informationMessageMock = sandbox
.mock(vscode.window)
.expects('showInformationMessage')
.withArgs('GitLab Workflow: Your CI configuration is valid.')
.resolves();
await insertTextIntoActiveEditor(VALID_CI_CONFIG);
await validate();
informationMessageMock.verify();
});
it('shows error message for invalid config', async () => {
const errorMessages = [];
sandbox.stub(vscode.window, 'showErrorMessage').callsFake(async msg => {
errorMessages.push(msg);
});
await insertTextIntoActiveEditor(INVALID_CI_CONFIG);
await validate();
assert.deepStrictEqual(errorMessages, [
'jobs:test config contains unknown keys: scccript',
'GitLab Workflow: Invalid CI configuration.',
]);
});
});
{
"status": "invalid",
"errors": ["jobs:test config contains unknown keys: scccript"],
"warnings": []
}
{ "status": "valid", "errors": [], "warnings": [] }
......@@ -10,6 +10,14 @@ export const createAndOpenFile = async (testFileUri: vscode.Uri): Promise<void>
await vscode.window.showTextDocument(testFileUri);
};
export const insertTextIntoActiveEditor = async (text: string): Promise<void> => {
const editor = vscode.window.activeTextEditor;
assert(editor, 'no active editor');
await editor.edit(editBuilder => {
editBuilder.insert(editor.selection.start, text);
});
};
export const closeAndDeleteFile = async (testFileUri: vscode.Uri): Promise<void> => {
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
const edit = new vscode.WorkspaceEdit();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册