Skip to content
Snippets Groups Projects
Commit 38ee0bfe authored by joel.vonderwe's avatar joel.vonderwe Committed by michael.minelli
Browse files

Merge from origin

parent ced8bba1
No related branches found
No related tags found
No related merge requests found
...@@ -110,6 +110,13 @@ paths: ...@@ -110,6 +110,13 @@ paths:
type: boolean type: boolean
examples: examples:
- true - true
languages:
type: array
items: string
examples:
- - c
- cpp
- js
description: OK description: OK
default: default:
$ref: '#/components/responses/ERROR' $ref: '#/components/responses/ERROR'
...@@ -333,6 +340,16 @@ paths: ...@@ -333,6 +340,16 @@ paths:
type: boolean type: boolean
default: false default: false
description: Whether or not to use the Sonar integration to validate the assignment and exercise solutions description: Whether or not to use the Sonar integration to validate the assignment and exercise solutions
sonarGate:
type: string
default: ""
description: Sonar quality gate to use for the assignment
sonarProfiles:
type: string
default: "[]"
description: Sonar quality profiles for the assignment, as a JSON array of strings
examples:
- "[\"Sonar Way\", \"ArchWeb Way\"]"
language: language:
type: string type: string
default: other default: other
......
-- AlterTable
ALTER TABLE `Assignment` ADD COLUMN `sonarGate` VARCHAR(191) NULL,
ADD COLUMN `sonarProfiles` JSON NULL;
...@@ -48,6 +48,8 @@ model Assignment { ...@@ -48,6 +48,8 @@ model Assignment {
useSonar Boolean @default(false) useSonar Boolean @default(false)
sonarKey String? sonarKey String?
sonarCreationInfo Json? @db.Json sonarCreationInfo Json? @db.Json
sonarGate String?
sonarProfiles Json? @db.Json
exercises Exercise[] exercises Exercise[]
staff User[] staff User[]
......
...@@ -26,7 +26,7 @@ class AssignmentManager { ...@@ -26,7 +26,7 @@ class AssignmentManager {
async getByGitlabLink(gitlabLink: string, include: Prisma.AssignmentInclude | undefined = undefined): Promise<Assignment | undefined> { async getByGitlabLink(gitlabLink: string, include: Prisma.AssignmentInclude | undefined = undefined): Promise<Assignment | undefined> {
const nameInUrl = gitlabLink.replace('.git', '').split('/').pop()!; const nameInUrl = gitlabLink.replace('.git', '').split('/').pop()!;
console.log(nameInUrl);
const result = await db.assignment.findMany({ const result = await db.assignment.findMany({
where : { where : {
gitlabLink: { gitlabLink: {
...@@ -35,11 +35,12 @@ class AssignmentManager { ...@@ -35,11 +35,12 @@ class AssignmentManager {
}, },
include: include include: include
}) as Array<Assignment>; }) as Array<Assignment>;
console.log(result);
return result.length > 0 ? result[0] : undefined; return result.length > 0 ? result[0] : undefined;
} }
get(nameOrUrl: string, include: Prisma.AssignmentInclude | undefined = undefined): Promise<Assignment | undefined> { get(nameOrUrl: string, include: Prisma.AssignmentInclude | undefined = undefined): Promise<Assignment | undefined> {
console.log(nameOrUrl);
if ( nameOrUrl.includes('://') ) { if ( nameOrUrl.includes('://') ) {
return this.getByGitlabLink(nameOrUrl, include); return this.getByGitlabLink(nameOrUrl, include);
} else { } else {
......
...@@ -4,6 +4,10 @@ import axios, { AxiosInstance } from 'axios'; ...@@ -4,6 +4,10 @@ import axios, { AxiosInstance } from 'axios';
import Config from '../config/Config'; import Config from '../config/Config';
import SonarProjectCreation from '../shared/types/Sonar/SonarProjectCreation'; import SonarProjectCreation from '../shared/types/Sonar/SonarProjectCreation';
import https from 'https'; import https from 'https';
import GlobalHelper from '../helpers/GlobalHelper';
import DojoStatusCode from '../shared/types/Dojo/DojoStatusCode';
import express from 'express';
import GitlabRepository from '../shared/types/Gitlab/GitlabRepository';
class SonarManager { class SonarManager {
...@@ -59,6 +63,60 @@ class SonarManager { ...@@ -59,6 +63,60 @@ class SonarManager {
return await this.executePostRequest<SonarProjectCreation>(this.getApiUrl(SonarRoute.PROJECT_CREATE_GITLAB), formData) return await this.executePostRequest<SonarProjectCreation>(this.getApiUrl(SonarRoute.PROJECT_CREATE_GITLAB), formData)
} }
async addQualityGate(projectKey: string, qualityGate: string) {
const formData = new FormData();
formData.append('projectKey', projectKey);
formData.append('gateName', qualityGate);
return await this.executePostRequest<undefined>(this.getApiUrl(SonarRoute.PROJECT_ADD_GATE), formData);
}
async addQualityProfile(projectKey: string, qualityProfile: string, language: string) {
const formData = new FormData();
formData.append('project', projectKey);
formData.append('qualityProfile', qualityProfile);
formData.append('language', language);
return await this.executePostRequest<unknown>(this.getApiUrl(SonarRoute.PROJECT_ADD_PROFILE), formData);
}
async createProjectWithQualities(gitlabRepository: GitlabRepository, qualityGate: string | null, qualityProfiles: string[] | null, req: express.Request, res: express.Response) {
let sonarProject: SonarProjectCreation | undefined = undefined;
try {
sonarProject = await this.createProjectFromGitlab(gitlabRepository.id);
if (sonarProject == undefined) {
return await GlobalHelper.repositoryCreationError('Sonar error', undefined, req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, gitlabRepository);
}
} catch ( error ) {
return await GlobalHelper.repositoryCreationError('Sonar project creation error', error, req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_INTERNAL_ERROR, gitlabRepository);
}
// Add gate and profiles to sonar project
if ( qualityGate != undefined && qualityGate != "" ) {
try {
await this.addQualityGate(sonarProject.project.key, qualityGate);
} catch ( error ) {
return await GlobalHelper.repositoryCreationError('Sonar gate error', error, req, res, DojoStatusCode.ASSIGNMENT_SONAR_GATE_NOT_FOUND, DojoStatusCode.ASSIGNMENT_SONAR_GATE_NOT_FOUND, gitlabRepository);
}
}
if ( qualityProfiles != undefined && qualityProfiles.length > 0 ) {
for ( const profile of qualityProfiles ) {
try {
const [ lang, name ] = profile.split('/');
if (lang.trim() != '' && name.trim() != '') {
await this.addQualityProfile(sonarProject.project.key, name.trim(), lang.trim());
} else {
return await GlobalHelper.repositoryCreationError('Sonar profile invalid', undefined, req, res, DojoStatusCode.ASSIGNMENT_SONAR_PROFILE_NOT_FOUND, DojoStatusCode.ASSIGNMENT_SONAR_PROFILE_NOT_FOUND, gitlabRepository);
}
} catch ( error ) {
return await GlobalHelper.repositoryCreationError('Sonar profile not found', error, req, res, DojoStatusCode.ASSIGNMENT_SONAR_PROFILE_NOT_FOUND, DojoStatusCode.ASSIGNMENT_SONAR_PROFILE_NOT_FOUND, gitlabRepository);
}
}
}
return sonarProject;
}
async getLanguages() { async getLanguages() {
const resp = await this.executeGetRequest<{ languages: { key: string, name: string }[]}>(this.getApiUrl(SonarRoute.GET_LANGUAGES)) const resp = await this.executeGetRequest<{ languages: { key: string, name: string }[]}>(this.getApiUrl(SonarRoute.GET_LANGUAGES))
return resp.languages.map(l => l.key) return resp.languages.map(l => l.key)
......
...@@ -26,6 +26,7 @@ import SharedConfig from '../shared/config/SharedConfig.js'; ...@@ -26,6 +26,7 @@ import SharedConfig from '../shared/config/SharedConfig.js';
import SharedSonarManager from '../shared/managers/SharedSonarManager'; import SharedSonarManager from '../shared/managers/SharedSonarManager';
import SonarProjectCreation from '../shared/types/Sonar/SonarProjectCreation'; import SonarProjectCreation from '../shared/types/Sonar/SonarProjectCreation';
import SonarManager from '../managers/SonarManager'; import SonarManager from '../managers/SonarManager';
import { v4 as uuidv4 } from 'uuid';
class AssignmentRoutes implements RoutesManager { class AssignmentRoutes implements RoutesManager {
...@@ -143,7 +144,7 @@ class AssignmentRoutes implements RoutesManager { ...@@ -143,7 +144,7 @@ class AssignmentRoutes implements RoutesManager {
private async createAssignment(req: express.Request, res: express.Response) { private async createAssignment(req: express.Request, res: express.Response) {
const params: { const params: {
name: string, members: Array<Gitlab.UserSchema>, template: string, useSonar: string, language: string name: string, members: Array<Gitlab.UserSchema>, template: string, useSonar: string, sonarGate: string, sonarProfiles: string, language: string
} = req.body; } = req.body;
const useSonar = params.useSonar === 'true'; const useSonar = params.useSonar === 'true';
...@@ -197,7 +198,12 @@ class AssignmentRoutes implements RoutesManager { ...@@ -197,7 +198,12 @@ class AssignmentRoutes implements RoutesManager {
// Create Sonar project // Create Sonar project
let sonarProject: SonarProjectCreation | undefined = undefined; let sonarProject: SonarProjectCreation | undefined = undefined;
if ( useSonar ) { if ( useSonar ) {
sonarProject = await GlobalHelper.repoCreationFnExecCreator(req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_INTERNAL_ERROR, repository)(() => SonarManager.createProjectFromGitlab(repository.id), 'Sonar project creation error') as SonarProjectCreation; const profiles: string[] = JSON.parse(params.sonarProfiles);
sonarProject = await GlobalHelper.repoCreationFnExecCreator(req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_INTERNAL_ERROR, repository)(() => SonarManager.createProjectWithQualities(repository, params.sonarGate, profiles, req, res), 'Sonar project creation error') as SonarProjectCreation;
if ( sonarProject == undefined ) {
return;
}
} }
const assignment: Assignment = await repoCreationFnExec(() => db.assignment.create({ const assignment: Assignment = await repoCreationFnExec(() => db.assignment.create({
...@@ -212,6 +218,8 @@ class AssignmentRoutes implements RoutesManager { ...@@ -212,6 +218,8 @@ class AssignmentRoutes implements RoutesManager {
useSonar : useSonar, useSonar : useSonar,
sonarKey : sonarProject?.project.key, sonarKey : sonarProject?.project.key,
sonarCreationInfo : sonarProject?.project, sonarCreationInfo : sonarProject?.project,
sonarGate : params.sonarGate,
sonarProfiles : params.sonarProfiles,
language : Language[params.language as keyof typeof Language], language : Language[params.language as keyof typeof Language],
staff : { staff : {
connectOrCreate: [ ...params.members.map(gitlabUser => { connectOrCreate: [ ...params.members.map(gitlabUser => {
......
...@@ -270,8 +270,13 @@ class ExerciseRoutes implements RoutesManager { ...@@ -270,8 +270,13 @@ class ExerciseRoutes implements RoutesManager {
// Create Sonar project // Create Sonar project
let sonarProject: SonarProjectCreation | undefined = undefined; let sonarProject: SonarProjectCreation | undefined = undefined;
if ( assignment.useSonar ) { if ( assignment.useSonar && assignment.sonarProfiles != null ) {
sonarProject = await GlobalHelper.repoCreationFnExecCreator(req, res, DojoStatusCode.EXERCISE_CREATION_SONAR_ERROR, DojoStatusCode.EXERCISE_CREATION_INTERNAL_ERROR, repository)(() => SonarManager.createProjectFromGitlab(repository.id), 'Sonar project creation error') as SonarProjectCreation; const profiles: string[] = JSON.parse(assignment.sonarProfiles as string);
sonarProject = await GlobalHelper.repoCreationFnExecCreator(req, res, DojoStatusCode.EXERCISE_CREATION_SONAR_ERROR, DojoStatusCode.EXERCISE_CREATION_INTERNAL_ERROR, repository)(() => SonarManager.createProjectWithQualities(repository, assignment.sonarGate, profiles, req, res), 'Sonar project creation error') as SonarProjectCreation;
if ( sonarProject == undefined ) {
return;
}
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment