Skip to content
Snippets Groups Projects
Commit d7409df1 authored by michael.minelli's avatar michael.minelli
Browse files

Merge branch 'v2.1.0' into main

parents 7884e53c a0c9351c
No related branches found
No related tags found
No related merge requests found
Pipeline #26521 passed
.env
aws.xml aws.xml
workspace.xml workspace.xml
...@@ -184,11 +182,10 @@ web_modules/ ...@@ -184,11 +182,10 @@ web_modules/
.yarn-integrity .yarn-integrity
# dotenv environment variable files # dotenv environment variable files
.env .env*
.env.development.local .flaskenv*
.env.test.local !.env.project
.env.production.local !.env.vault
.env.local
# parcel-bundler cache (https://parceljs.org/) # parcel-bundler cache (https://parceljs.org/)
.cache .cache
......
...@@ -3,29 +3,61 @@ variables: ...@@ -3,29 +3,61 @@ variables:
GIT_SUBMODULE_FORCE_HTTPS: "true" GIT_SUBMODULE_FORCE_HTTPS: "true"
SECURE_FILES_DOWNLOAD_PATH: './' SECURE_FILES_DOWNLOAD_PATH: './'
PROJECT_NAME: DojoBackendAPI
VERSION_DEV_SUFFIX: '-dev' VERSION_DEV_SUFFIX: '-dev'
GITLAB_API_PROJECT_URL: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID} GITLAB_API_PROJECT_URL: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}
PROJECT_FOLDER: ExpressAPI PROJECT_FOLDER: ExpressAPI
PACKAGE_REGISTRY_URL: "${GITLAB_API_PROJECT_URL}/packages/generic/${PROJECT_NAME}"
WIKI_FOLDER: Wiki
.get_version: .get_version:
script: script:
- IS_DEV=$([[ $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH ]] && echo false || echo true) - IS_DEV=$([[ $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH ]] && echo false || echo true)
- VERSION=$(jq -r .version $PROJECT_FOLDER/package.json)$([[ $IS_DEV == true ]] && echo $VERSION_DEV_SUFFIX || echo '') - VERSION=$(jq -r .version $PROJECT_FOLDER/package.json)$([[ $IS_DEV == true ]] && echo $VERSION_DEV_SUFFIX || echo '')
.get_packages_url:
script:
# Wiki
- WIKI_ARCHIVE_NAME="${PROJECT_NAME}_Wiki_${VERSION}.tar.xz"
- PACKAGE_URL_WIKI="${PACKAGE_REGISTRY_URL}_Wiki/${VERSION}/${WIKI_ARCHIVE_NAME}"
.clean_release: .clean_release:
script: script:
# Delete release if it already exists # Delete release if it already exists
- 'curl --request DELETE --header "JOB-TOKEN: $CI_JOB_TOKEN" "${GITLAB_API_PROJECT_URL}/releases/${VERSION}"' - 'curl --request DELETE --header "JOB-TOKEN: $CI_JOB_TOKEN" "${GITLAB_API_PROJECT_URL}/releases/${VERSION}"'
# Delete tag if it already exists (use private-token because job-token don't have permission to delete tags) # Delete tag if it already exists (use private-token because job-token don't have permission to delete tags)
- 'curl --request DELETE --header "PRIVATE-TOKEN: $GITLAB_PROJECT_ACCESS_TOKEN" "${GITLAB_API_PROJECT_URL}/repository/tags/${VERSION}"' - 'curl --request DELETE --header "PRIVATE-TOKEN: $GITLAB_PROJECT_ACCESS_TOKEN" "${GITLAB_API_PROJECT_URL}/repository/tags/${VERSION}"'
.clean_packages:
script:
# Get all packages of the project
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" "${GITLAB_API_PROJECT_URL}/packages" > gitlabPackages.json'
# Filter and select packages to delete (based on version)
- packagesToDelete=`jq -r '.[] | select(.version=="'${VERSION}'") | ._links.delete_api_path' gitlabPackages.json`
# Delete packages by calling Gitlab API
- >
for deletePath in $packagesToDelete; do
echo "Deleting package at path : ${deletePath}"
curl --request DELETE --header "JOB-TOKEN: $CI_JOB_TOKEN" "${deletePath}"
done
stages: stages:
- test - test
- clean - clean
- upload
- release - release
...@@ -41,6 +73,7 @@ test:build: ...@@ -41,6 +73,7 @@ test:build:
rules: rules:
- if: '$CI_COMMIT_TAG =~ "/^$/"' - if: '$CI_COMMIT_TAG =~ "/^$/"'
clean:release: clean:release:
stage: clean stage: clean
tags: tags:
...@@ -50,7 +83,20 @@ clean:release: ...@@ -50,7 +83,20 @@ clean:release:
- !reference [.get_version, script] - !reference [.get_version, script]
- !reference [.clean_release, script] - !reference [.clean_release, script]
rules: rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /^v[0-9]+(\.[0-9]+)*$/' - if: '$CI_COMMIT_REF_PROTECTED == "true"'
clean:packages:
stage: clean
tags:
- gitlab_clean
image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest
script:
- !reference [.get_version, script]
- !reference [.clean_packages, script]
rules:
- if: '$CI_COMMIT_REF_PROTECTED == "true"'
clean:dev:release: clean:dev:release:
stage: clean stage: clean
...@@ -64,6 +110,90 @@ clean:dev:release: ...@@ -64,6 +110,90 @@ clean:dev:release:
rules: rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
clean:dev:packages:
stage: clean
tags:
- gitlab_clean
image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest
script:
- !reference [.get_version, script]
- VERSION="${VERSION}${VERSION_DEV_SUFFIX}"
- !reference [.clean_packages, script]
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
upload:packages:wiki:
stage: upload
tags:
- gitlab_package
image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest
script:
# Install dependencies
- apk update
- apk add xz
- !reference [.get_version, script]
- !reference [.get_packages_url, script]
# Create archive
- WIKI_ARCHIVE_PATH="${ARTIFACTS_FOLDER}/${WIKI_ARCHIVE_NAME}"
- tar -v -c -C "${CI_PROJECT_DIR}/${WIKI_FOLDER}" -J -f "${WIKI_ARCHIVE_PATH}" . # Ubuntu: tar --verbose --create --cd wiki-test-2 --xz --file file.tar.bz2
# Send package
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${WIKI_ARCHIVE_PATH} "${PACKAGE_URL_WIKI}";'
rules:
- if: '$CI_COMMIT_REF_PROTECTED == "true"'
release:wiki:
stage: release
tags:
- release
image: alpine:latest
script:
- !reference [.get_version, script]
- apk update
- apk add git
# Define URL for the wiki in terms of project-agnostic predefined variables
- WIKI_URL="${CI_SERVER_PROTOCOL}://project_${CI_PROJECT_ID}_bot:${GITLAB_PROJECT_ACCESS_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/${CI_PROJECT_PATH}.wiki.git"
# Clone this project's wiki under /tmp
- rm -rf "/tmp/${CI_PROJECT_NAME}.wiki"
- cd /tmp
- git clone "${WIKI_URL}"
# Enter the cloned repo
- cd "${CI_PROJECT_NAME}.wiki"
# Update the file
- mv .git/ ../
- rm -rf ./*
- mv ../.git/ ./
- cp "${CI_PROJECT_DIR}/.gitignore" .
- cp -R "${CI_PROJECT_DIR}/${WIKI_FOLDER}/." .
# Set committer info
- git config user.name "$GITLAB_USER_NAME"
- git config user.email "$GITLAB_USER_EMAIL"
# Commit the gitignore file
- git add ".gitignore"
- git commit -m "Add gitignore file" || true
# Commit the file
- git add .
- git commit -m "${VERSION}" || true
# Push the change back to the master branch of the wiki
- git push origin "HEAD:main"
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
release:gitlab: release:gitlab:
stage: release stage: release
tags: tags:
...@@ -71,18 +201,29 @@ release:gitlab: ...@@ -71,18 +201,29 @@ release:gitlab:
image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest
script: script:
- !reference [.get_version, script] - !reference [.get_version, script]
- !reference [.get_packages_url, script]
- echo 'Running release_job' - echo 'Running release_job'
# Extract description from CHANGELOG.md # Extract description from CHANGELOG.md
- CHANGELOG_LINE_START=`awk '/##\ [0-9]+\.[0-9]+\.[0-9]+/{print NR; exit;}' CHANGELOG.md` - CHANGELOG_LINE_START=`awk '/##\ [0-9]+\.[0-9]+\.[0-9]+/{print NR; exit;}' CHANGELOG.md`
- CHANGELOG_LINE_END=`awk '/##\ [0-9]+\.[0-9]+\.[0-9]+/{ count++; if(count>1) {print NR; exit;}}' CHANGELOG.md` - CHANGELOG_LINE_END=`awk '/##\ [0-9]+\.[0-9]+\.[0-9]+/{ count++; if(count>1) {print NR; exit;}}' CHANGELOG.md`
- DESCRIPTION=`awk 'NR > '$CHANGELOG_LINE_START' && NR < '$CHANGELOG_LINE_END'' CHANGELOG.md` - DESCRIPTION=`awk 'NR > '$CHANGELOG_LINE_START' && NR < '$CHANGELOG_LINE_END'' CHANGELOG.md`
# Create Release (can't be done by release_step of gitlab image because it don't have access to env var defined in script_step) # Create Release (can't be done by release_step of gitlab image because it don't have access to env var defined in script_step)
- > - >
RELEASE_DATA=$(jq --null-input --arg version "$VERSION" --arg description "# Changelog (version $VERSION) $DESCRIPTION" --arg tag_name "$VERSION" --arg ref "$CI_COMMIT_SHORT_SHA" '{ RELEASE_DATA=$(jq --null-input --arg version "$VERSION" --arg description "# Changelog (version $VERSION) $DESCRIPTION" --arg tag_name "$VERSION" --arg ref "$CI_COMMIT_SHORT_SHA" '{
"name": $version, "name": $version,
"description": $description, "description": $description,
"tag_name": $tag_name, "tag_name": $tag_name,
"ref": $ref "ref": $ref,
"assets": {
"links": [
{
"name": "Wiki",
"url": "'${PACKAGE_URL_WIKI}'",
}
]
}
}') }')
- > - >
curl --data "${RELEASE_DATA}" \ curl --data "${RELEASE_DATA}" \
...@@ -90,4 +231,4 @@ release:gitlab: ...@@ -90,4 +231,4 @@ release:gitlab:
--header "JOB-TOKEN: $CI_JOB_TOKEN" \ --header "JOB-TOKEN: $CI_JOB_TOKEN" \
--request POST "${GITLAB_API_PROJECT_URL}/releases" --request POST "${GITLAB_API_PROJECT_URL}/releases"
rules: rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /^v[0-9]+(\.[0-9]+)*$/' - if: '$CI_COMMIT_REF_PROTECTED == "true"'
...@@ -14,6 +14,22 @@ ...@@ -14,6 +14,22 @@
**⚠️ Deprecation:** **⚠️ Deprecation:**
--> -->
## 2.1.0 (?)
### ✨ Feature
- Added pipeline badge to exercises
### 🎨 Interface
- **💥 Breaking:** Renamed `dojo.enonce` (or `dojo.assignment`) file to `dojo_assignment.json`
### 🔨 Internal / Developers
- Deploy Wiki on Gitlab (on push to `main`) from files of `Wiki` folder
- Migration from .env files stored in Gitlab Secure Files to usage of `dotenv-vault` (locally)
### 📚 Documentation
- Added Wiki base
## 2.0.0 (2023-09-15) ## 2.0.0 (2023-09-15)
### ✨ Feature ### ✨ Feature
......
#/-------------------.env.vault---------------------/
#/ cloud-agnostic vaulting standard /
#/ [how it works](https://dotenv.org/env-vault) /
#/--------------------------------------------------/
# development
DOTENV_VAULT_DEVELOPMENT="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"
# production
DOTENV_VAULT_PRODUCTION="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"
.env*
.flaskenv*
!.env.project
!.env.vault
\ No newline at end of file
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"node_modules", "node_modules",
"prisma", "prisma",
"src", "src",
".env" ".env.vault"
], ],
"verbose": true, "verbose": true,
"ext" : ".ts,.js", "ext" : ".ts,.js",
......
This diff is collapsed.
{ {
"name" : "dojo_backend_api", "name" : "dojo_backend_api",
"description" : "Backend API for the Dojo Project", "description" : "Backend API for the Dojo Project",
"version" : "2.0.0", "version" : "2.1.0",
"license" : "", "license" : "",
"author" : "Michaël Minelli <michael-jean.minelli@hesge.ch>", "author" : "Michaël Minelli <michael-jean.minelli@hesge.ch>",
"main" : "app.js", "main" : "app.js",
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
"bcryptjs" : "^2.4.3", "bcryptjs" : "^2.4.3",
"compression" : "^1.7.4", "compression" : "^1.7.4",
"cors" : "^2.8.5", "cors" : "^2.8.5",
"dotenv" : "^16.0.3", "dotenv" : "^16.3.1",
"express" : "^4.18.2", "express" : "^4.18.2",
"express-validator": "^7.0.1", "express-validator": "^7.0.1",
"form-data" : "^4.0.0", "form-data" : "^4.0.0",
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
"@types/parse-link-header": "^2.0.1", "@types/parse-link-header": "^2.0.1",
"@types/tar-stream" : "^2.2.2", "@types/tar-stream" : "^2.2.2",
"@types/uuid" : "^9.0.2", "@types/uuid" : "^9.0.2",
"dotenv-vault" : "^1.25.0",
"nodemon" : "^3.0.1", "nodemon" : "^3.0.1",
"prisma" : "^5.1.1", "prisma" : "^5.1.1",
"ts-node" : "^10.9.1", "ts-node" : "^10.9.1",
......
require('dotenv').config(); // ATTENTION : This line MUST be the first of this file // Read from the .env file
require('./shared/helpers/TypeScriptExtensions'); // ATTENTION : This line MUST be the second of this file // ATTENTION : This lines MUST be the first of this file (except for the path import)
const path = require('node:path');
if ( process.env.NODE_ENV && process.env.NODE_ENV === 'production' ) {
require('dotenv').config();
} else {
require('dotenv').config({ path: path.join(__dirname, '../.env.keys') });
require('dotenv').config({ DOTENV_KEY: process.env.DOTENV_KEY_DEVELOPMENT });
}
require('./shared/helpers/TypeScriptExtensions'); // ATTENTION : This line MUST be after the dotenv.config() calls
import WorkerRole from './process/WorkerRole'; import WorkerRole from './process/WorkerRole';
import ClusterManager from './process/ClusterManager'; import ClusterManager from './process/ClusterManager';
......
...@@ -4,6 +4,9 @@ import fs from 'fs'; ...@@ -4,6 +4,9 @@ import fs from 'fs';
import { Exercise } from '../types/DatabaseTypes'; import { Exercise } from '../types/DatabaseTypes';
type ConfigGitlabBadge = { link: string, imageUrl: string }
class Config { class Config {
public readonly api: { public readonly api: {
port: number port: number
...@@ -18,7 +21,7 @@ class Config { ...@@ -18,7 +21,7 @@ class Config {
}; };
public gitlab: { public gitlab: {
apiURL: string; urls: Array<string>; account: { id: number; username: string; token: string; }; group: { root: number; templates: number; assignments: number; exercises: number; }; apiURL: string; urls: Array<string>; account: { id: number; username: string; token: string; }; group: { root: number; templates: number; assignments: number; exercises: number; }, badges: { pipeline: ConfigGitlabBadge }
}; };
public assignment: { public assignment: {
...@@ -50,6 +53,10 @@ class Config { ...@@ -50,6 +53,10 @@ class Config {
id: Number(process.env.GITLAB_DOJO_ACCOUNT_ID || 0), username: process.env.GITLAB_DOJO_ACCOUNT_USERNAME || '', token: process.env.GITLAB_DOJO_ACCOUNT_TOKEN || '' id: Number(process.env.GITLAB_DOJO_ACCOUNT_ID || 0), username: process.env.GITLAB_DOJO_ACCOUNT_USERNAME || '', token: process.env.GITLAB_DOJO_ACCOUNT_TOKEN || ''
}, group : { }, group : {
root: Number(process.env.GITLAB_GROUP_ROOT_ID || 0), templates: Number(process.env.GITLAB_GROUP_TEMPLATES_ID || 0), assignments: Number(process.env.GITLAB_GROUP_ASSIGNMENTS_ID || 0), exercises: Number(process.env.GITLAB_GROUP_EXERCISES_ID || 0) root: Number(process.env.GITLAB_GROUP_ROOT_ID || 0), templates: Number(process.env.GITLAB_GROUP_TEMPLATES_ID || 0), assignments: Number(process.env.GITLAB_GROUP_ASSIGNMENTS_ID || 0), exercises: Number(process.env.GITLAB_GROUP_EXERCISES_ID || 0)
}, badges: {
pipeline: {
link: process.env.GITLAB_BADGE_PIPELINE_LINK || '', imageUrl: process.env.GITLAB_BADGE_PIPELINE_IMAGE_URL || ''
}
} }
}; };
......
...@@ -111,6 +111,16 @@ class GitlabManager { ...@@ -111,6 +111,16 @@ class GitlabManager {
return response.data; return response.data;
} }
async addRepositoryBadge(repoId: number, linkUrl: string, imageUrl: string, name: string): Promise<GitlabMember> {
const response = await axios.post<GitlabMember>(this.getApiUrl(GitlabRoute.REPOSITORY_BADGES_ADD).replace('{{id}}', String(repoId)), {
link_url : linkUrl,
image_url: imageUrl,
name : name
});
return response.data;
}
async checkTemplateAccess(idOrNamespace: string, req: express.Request): Promise<StatusCodes> { async checkTemplateAccess(idOrNamespace: string, req: express.Request): Promise<StatusCodes> {
// Get the Gitlab project and check if it have public or internal visibility // Get the Gitlab project and check if it have public or internal visibility
try { try {
......
...@@ -87,6 +87,8 @@ class ExerciseRoutes implements RoutesManager { ...@@ -87,6 +87,8 @@ class ExerciseRoutes implements RoutesManager {
await GitlabManager.addRepositoryVariable(repository.id, 'DOJO_SECRET', secret, false, true); await GitlabManager.addRepositoryVariable(repository.id, 'DOJO_SECRET', secret, false, true);
await GitlabManager.addRepositoryVariable(repository.id, 'DOJO_RESULTS_FOLDER', Config.exercise.pipelineResultsFolder, false, false); await GitlabManager.addRepositoryVariable(repository.id, 'DOJO_RESULTS_FOLDER', Config.exercise.pipelineResultsFolder, false, false);
await GitlabManager.addRepositoryBadge(repository.id, Config.gitlab.badges.pipeline.link, Config.gitlab.badges.pipeline.imageUrl, 'Pipeline Status');
break; break;
} catch ( error ) { } catch ( error ) {
if ( error instanceof AxiosError ) { if ( error instanceof AxiosError ) {
......
Subproject commit 8d7e3ca0cca10e874ac48e19e47da8a1491ccba7 Subproject commit 6cff19278f7fa9664793e1d7826d2596597ac080
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment