diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..565a2005c8711d59ae247e836a0f8958128b5484 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,8 @@ +include: "AssignmentChecker/.gitlab-ci/**.yml" + +lint_pass: + only: + variables: + - $FOO == "bar" + script: + - echo \ No newline at end of file diff --git a/AssignmentChecker/.gitlab-ci/00_vars.yml b/AssignmentChecker/.gitlab-ci/00_vars.yml new file mode 100644 index 0000000000000000000000000000000000000000..0af94a753b6ffab5f8892ded39d9b10a92f8e05c --- /dev/null +++ b/AssignmentChecker/.gitlab-ci/00_vars.yml @@ -0,0 +1,22 @@ +variables: + GIT_SUBMODULE_STRATEGY: recursive + GIT_SUBMODULE_FORCE_HTTPS: "true" + + DOCKER_HOST: tcp://docker:2375 + DOCKER_TLS_CERTDIR: + DOCKER_DRIVER: overlay2 + + PROJECT_NAME: DojoAssignmentChecker + + VERSION_DEV_SUFFIX: '-dev' + + GITLAB_API_PROJECT_URL: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID} + + DOCKERFILE: Dockerfile_AssignmentChecker + DOCKER_PLATFORMS: linux/amd64,linux/arm64/v8 + + PROJECT_FOLDER: AssignmentChecker + + PACKAGE_REGISTRY_URL: "${GITLAB_API_PROJECT_URL}/packages/generic/${PROJECT_NAME}" + + WIKI_FOLDER: Wiki \ No newline at end of file diff --git a/AssignmentChecker/.gitlab-ci/01_functions.yml b/AssignmentChecker/.gitlab-ci/01_functions.yml new file mode 100644 index 0000000000000000000000000000000000000000..e77ccd8adc262354fa3941e9db0b2ad25228e9e9 --- /dev/null +++ b/AssignmentChecker/.gitlab-ci/01_functions.yml @@ -0,0 +1,81 @@ +.get_version: + script: + - 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 '') + + +.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}" + + +.init_dind_script: + script: + # Install dependencies + - apk update + - apk add git + - apk add jq + - apk add curl + + # Init docker buildx + - docker login -u $DOCKER_REGISTRY_USER -p $DOCKER_REGISTRY_PASSWORD $DOCKER_REGISTRY + - docker buildx create --use + + # Get version from package.json + - !reference [ .get_version, script ] + - CONTAINER_IMAGE=$DOCKER_REGISTRY_IMAGE:$VERSION + + +.build_script: + script: + - !reference [ .init_dind_script, script ] + - mkdir -p $ARTIFACTS_FOLDER + + # Decrypt env vars for production + - apk add npm sed + - cd $PROJECT_FOLDER + - sed -i -r "s/\{\{VERSION\}\}/${VERSION}/g" src/app.ts + - | + if [ $CI_COMMIT_REF_PROTECTED == "true" ]; then + echo "Decrypt production env vars" + sed -i -r "s/(DOTENV_KEY[ ]*:[ ]*[\'\"\`])[^'\"\`]*([\'\"\`])([ ]*\,)?//g" src/app.ts + sed -i -r "s/,[\ \n]*\}/\}/g" src/app.ts + npx dotenv-vault local decrypt "${DOTENV_PROD_KEY}" > .env + + fi + - cd .. + + # Need to build for each platform separately because of multi-stage builds (docker buildx don't use cache same way as docker build) + - > + platform_array=$(echo $DOCKER_PLATFORMS | tr "," "\n"); + for platform in $platform_array; do + echo "Buildind for : $platform" + docker buildx build --pull --platform $platform --file $DOCKERFILE --tag $CONTAINER_IMAGE . + done + + +.clean_release: + script: + # Delete release if it already exists + - '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) + - '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 \ No newline at end of file diff --git a/AssignmentChecker/.gitlab-ci/03_stages.yml b/AssignmentChecker/.gitlab-ci/03_stages.yml new file mode 100644 index 0000000000000000000000000000000000000000..1b20f1ed1fa05c19ee6d8145ccd33bcc39c85d9d --- /dev/null +++ b/AssignmentChecker/.gitlab-ci/03_stages.yml @@ -0,0 +1,6 @@ +stages: + - test + - build + - clean + - upload + - release \ No newline at end of file diff --git a/AssignmentChecker/.gitlab-ci/04_stageTest.yml b/AssignmentChecker/.gitlab-ci/04_stageTest.yml new file mode 100644 index 0000000000000000000000000000000000000000..a1b564295624124e216ae7bba18ac6950590eccb --- /dev/null +++ b/AssignmentChecker/.gitlab-ci/04_stageTest.yml @@ -0,0 +1,12 @@ +test:build: + stage: test + tags: + - build + - dind + image: docker:latest + services: + - docker:dind + script: + - !reference [ .build_script, script ] + rules: + - if: '$CI_COMMIT_TAG =~ "/^$/" && $CI_COMMIT_REF_PROTECTED != "true"' \ No newline at end of file diff --git a/AssignmentChecker/.gitlab-ci/05_stageBuild.yml b/AssignmentChecker/.gitlab-ci/05_stageBuild.yml new file mode 100644 index 0000000000000000000000000000000000000000..e2acdd1042c77d84b45e63e3b8b2cdaf217d92bc --- /dev/null +++ b/AssignmentChecker/.gitlab-ci/05_stageBuild.yml @@ -0,0 +1,15 @@ +build:version: + stage: build + tags: + - build + - dind + image: docker:latest + services: + - docker:dind + script: + - !reference [ .build_script, script ] + + # Here docker buildx can use cached images created in previous step + - docker buildx build --platform $DOCKER_PLATFORMS --file $DOCKERFILE --push --tag $CONTAINER_IMAGE . + rules: + - if: '$CI_COMMIT_REF_PROTECTED == "true"' \ No newline at end of file diff --git a/AssignmentChecker/.gitlab-ci/06_stageClean.yml b/AssignmentChecker/.gitlab-ci/06_stageClean.yml new file mode 100644 index 0000000000000000000000000000000000000000..f8b6dba94adccbefeda89205f59a704b7f6d3875 --- /dev/null +++ b/AssignmentChecker/.gitlab-ci/06_stageClean.yml @@ -0,0 +1,75 @@ +clean:release: + stage: clean + tags: + - gitlab_clean + image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest + script: + - !reference [ .get_version, script ] + - !reference [ .clean_release, script ] + rules: + - 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: + 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_release, script ] + rules: + - 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' + + +clean:dev:dockerhub: + stage: clean + tags: + - clean + - dind + image: docker:latest + services: + - docker:dind + script: + - !reference [ .init_dind_script, script ] + - VERSION="${VERSION}${VERSION_DEV_SUFFIX}" + + # Remove dev tag + ## Login to dockerhub (get JWT token) + - GET_TOKEN_DATA=$(jq --null-input --arg username "$DOCKER_REGISTRY_USER" --arg password "$DOCKER_REGISTRY_PASSWORD" '{"username":$username,"password":$password}') + - > + TOKEN=`curl --data "${GET_TOKEN_DATA}" \ + --header "Content-Type: application/json" \ + --header "JOB-TOKEN: $CI_JOB_TOKEN" \ + "https://hub.docker.com/v2/users/login/" | jq -r .token` + + ## Delete tag + - 'curl --header "Authorization: JWT ${TOKEN}" --request DELETE "https://hub.docker.com/v2/repositories/${DOCKER_REGISTRY_IMAGE}/tags/${VERSION}/"' + rules: + - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' \ No newline at end of file diff --git a/AssignmentChecker/.gitlab-ci/07_stageUpload.yml b/AssignmentChecker/.gitlab-ci/07_stageUpload.yml new file mode 100644 index 0000000000000000000000000000000000000000..4c9bd456380ebbbbaa2e0498321c89e76427e16c --- /dev/null +++ b/AssignmentChecker/.gitlab-ci/07_stageUpload.yml @@ -0,0 +1,22 @@ +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 + - mkdir -p $ARTIFACTS_FOLDER + - 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"' \ No newline at end of file diff --git a/AssignmentChecker/.gitlab-ci/08_stageRelease.yml b/AssignmentChecker/.gitlab-ci/08_stageRelease.yml new file mode 100644 index 0000000000000000000000000000000000000000..325d173cd88c4336e573d1dd33f6ffbe7745c653 --- /dev/null +++ b/AssignmentChecker/.gitlab-ci/08_stageRelease.yml @@ -0,0 +1,103 @@ +release:dockerhub:latest: + stage: release + tags: + - release + - dind + image: docker:latest + services: + - docker:dind + script: + - !reference [ .init_dind_script, script ] + + # Push latest tag + - docker buildx imagetools create $CONTAINER_IMAGE --tag $DOCKER_REGISTRY_IMAGE:latest + rules: + - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + + +release:wiki: + stage: release + tags: + - release + image: alpine:latest + script: + - apk update + - apk add git + - apk add jq + + - !reference [ .get_version, script ] + + # 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: + stage: release + tags: + - release + image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest + script: + - !reference [ .get_version, script ] + - echo 'Running release_job' + - !reference [ .get_packages_url, script ] + + # Extract description from 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` + - 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) + - > + 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, + "description": $description, + "tag_name": $tag_name, + "ref": $ref, + "assets": { + "links": [ + { + "name": "Wiki", + "url": "'${PACKAGE_URL_WIKI}'", + } + ] + } + }') + - > + curl --data "${RELEASE_DATA}" \ + --header "Content-Type: application/json" \ + --header "JOB-TOKEN: $CI_JOB_TOKEN" \ + --request POST "${GITLAB_API_PROJECT_URL}/releases" + rules: + - if: '$CI_COMMIT_REF_PROTECTED == "true"' \ No newline at end of file