From 9eb102a06670b4bb276e2c3452fd0e8f036e7439 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Minelli?= <michael@minelli.me>
Date: Fri, 13 Oct 2023 14:40:11 +0200
Subject: [PATCH] AssignmentRoutes => Add ci on assignment creation

---
 ExpressAPI/assets/assignment_gitlab_ci.yml | 26 ++++++++++
 ExpressAPI/src/routes/AssignmentRoutes.ts  | 60 +++++++++++++++++-----
 2 files changed, 72 insertions(+), 14 deletions(-)
 create mode 100644 ExpressAPI/assets/assignment_gitlab_ci.yml

diff --git a/ExpressAPI/assets/assignment_gitlab_ci.yml b/ExpressAPI/assets/assignment_gitlab_ci.yml
new file mode 100644
index 0000000..ad20a04
--- /dev/null
+++ b/ExpressAPI/assets/assignment_gitlab_ci.yml
@@ -0,0 +1,26 @@
+###################################################################################################################
+# DO NOT MODIFY THIS FILE
+# This file is the ci/cd pipeline that will be used to test your assignment
+###################################################################################################################
+
+variables:
+    GIT_SUBMODULE_STRATEGY: recursive
+    GIT_SUBMODULE_FORCE_HTTPS: "true"
+    DOCKER_HOST: tcp://docker:2375
+    DOCKER_TLS_CERTDIR:
+    DOCKER_DRIVER: overlay2
+
+stages:
+    - dojo
+
+dojo:
+    stage: dojo
+    tags:
+        - dojo_assignment
+    services:
+        - docker:dind
+    image:
+        name: dojohesso/dojo_assignment_checker:latest
+    script:
+        - dojo_assignment_checker
+    allow_failure: false
\ No newline at end of file
diff --git a/ExpressAPI/src/routes/AssignmentRoutes.ts b/ExpressAPI/src/routes/AssignmentRoutes.ts
index af42e42..bd191b0 100644
--- a/ExpressAPI/src/routes/AssignmentRoutes.ts
+++ b/ExpressAPI/src/routes/AssignmentRoutes.ts
@@ -20,16 +20,25 @@ import db                             from '../helpers/DatabaseHelper';
 import { Assignment }                 from '../types/DatabaseTypes';
 import AssignmentManager              from '../managers/AssignmentManager';
 import GitlabVisibility               from '../shared/types/Gitlab/GitlabVisibility';
+import fs                             from 'fs';
+import path                           from 'path';
 
 
 class AssignmentRoutes implements RoutesManager {
     private readonly assignmentValidator: ExpressValidator.Schema = {
-        name       : {
-            trim: true, notEmpty: true
-        }, members : {
-            trim: true, notEmpty: true, customSanitizer: DojoValidators.jsonSanitizer
-        }, template: {
-            trim: true, custom: DojoValidators.templateUrlValidator, customSanitizer: DojoValidators.templateUrlSanitizer
+        name    : {
+            trim    : true,
+            notEmpty: true
+        },
+        members : {
+            trim           : true,
+            notEmpty       : true,
+            customSanitizer: DojoValidators.jsonSanitizer
+        },
+        template: {
+            trim           : true,
+            custom         : DojoValidators.templateUrlValidator,
+            customSanitizer: DojoValidators.templateUrlSanitizer
         }
     };
 
@@ -78,6 +87,8 @@ class AssignmentRoutes implements RoutesManager {
             repository = await GitlabManager.createRepository(params.name, Config.assignment.default.description.replace('{{ASSIGNMENT_NAME}}', params.name), Config.assignment.default.visibility, Config.assignment.default.initReadme, Config.gitlab.group.assignments, Config.assignment.default.sharedRunnersEnabled, Config.assignment.default.wikiEnabled, params.template);
 
             await GitlabManager.protectBranch(repository.id, '*', true, GitlabAccessLevel.DEVELOPER, GitlabAccessLevel.DEVELOPER, GitlabAccessLevel.OWNER);
+
+            await GitlabManager.addRepositoryBadge(repository.id, Config.gitlab.badges.pipeline.link, Config.gitlab.badges.pipeline.imageUrl, 'Pipeline Status');
         } catch ( error ) {
             if ( error instanceof AxiosError ) {
                 if ( error.response?.data.message.name && error.response.data.message.name == 'has already been taken' ) {
@@ -91,6 +102,18 @@ class AssignmentRoutes implements RoutesManager {
             return res.status(StatusCodes.INTERNAL_SERVER_ERROR).send();
         }
 
+        try {
+            await GitlabManager.createFile(repository.id, '.gitlab-ci.yml', fs.readFileSync(path.join(__dirname, '../../assets/assignment_gitlab_ci.yml'), 'base64'), 'Add .gitlab-ci.yml (DO NOT MODIFY THIS FILE)');
+        } catch ( error ) {
+            logger.error(error);
+
+            if ( error instanceof AxiosError ) {
+                return res.status(error.response?.status ?? HttpStatusCode.InternalServerError).send();
+            }
+
+            return res.status(StatusCodes.INTERNAL_SERVER_ERROR).send();
+        }
+
         try {
             await Promise.all(params.members.map(member => member.id).map(async (memberId: number): Promise<GitlabMember | false> => {
                 try {
@@ -102,12 +125,20 @@ class AssignmentRoutes implements RoutesManager {
 
             const assignment: Assignment = await db.assignment.create({
                                                                           data: {
-                                                                              name: repository.name, gitlabId: repository.id, gitlabLink: repository.web_url, gitlabCreationInfo: repository as unknown as Prisma.JsonObject, gitlabLastInfo: repository as unknown as Prisma.JsonObject, gitlabLastInfoDate: new Date(), staff: {
+                                                                              name              : repository.name,
+                                                                              gitlabId          : repository.id,
+                                                                              gitlabLink        : repository.web_url,
+                                                                              gitlabCreationInfo: repository as unknown as Prisma.JsonObject,
+                                                                              gitlabLastInfo    : repository as unknown as Prisma.JsonObject,
+                                                                              gitlabLastInfoDate: new Date(),
+                                                                              staff             : {
                                                                                   connectOrCreate: [ ...params.members.map(gitlabUser => {
                                                                                       return {
-                                                                                          create  : {
-                                                                                              gitlabId: gitlabUser.id, firstname: gitlabUser.name
-                                                                                          }, where: {
+                                                                                          create: {
+                                                                                              gitlabId : gitlabUser.id,
+                                                                                              firstname: gitlabUser.name
+                                                                                          },
+                                                                                          where : {
                                                                                               gitlabId: gitlabUser.id
                                                                                           }
                                                                                       };
@@ -133,11 +164,12 @@ class AssignmentRoutes implements RoutesManager {
                 await GitlabManager.changeRepositoryVisibility(req.boundParams.assignment!.gitlabId, publish ? GitlabVisibility.INTERNAL : GitlabVisibility.PRIVATE);
 
                 await db.assignment.update({
-                                               where  : {
+                                               where: {
                                                    name: req.boundParams.assignment!.name
-                                               }, data: {
-                        published: publish
-                    }
+                                               },
+                                               data : {
+                                                   published: publish
+                                               }
                                            });
 
                 req.session.sendResponse(res, StatusCodes.OK);
-- 
GitLab