diff --git a/.gitignore b/.gitignore index 45de4116fd5ee5a5a2a2612157301ce75d7bffed..a5cafce8aaff50784bfa58d9c64c38392092c4e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ -.env - aws.xml workspace.xml +.gitlab-ci-local +Wiki/.idea ############################ MacOS # General @@ -184,11 +184,10 @@ web_modules/ .yarn-integrity # dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local +.env* +.flaskenv* +!.env.project +!.env.vault # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9e3ac9177517205ddc9034c3a05eefcd52eebd57..46b9417d91ca72665753b9af283498ad3ac10557 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,300 +1,8 @@ -variables: - GIT_SUBMODULE_STRATEGY: recursive - GIT_SUBMODULE_FORCE_HTTPS: "true" - SECURE_FILES_DOWNLOAD_PATH: './' +include: "NodeApp/.gitlab-ci/**.yml" - BIN_NAME: dojo - - MACOS_PKG_EXTENSION: '.pkg' - MACOS_PKG_BIN_NAME: "${BIN_NAME}${MACOS_PKG_EXTENSION}" - - WINDOWS_BIN_EXTENSION: '.exe' - WINDOWS_BIN_NAME: "${BIN_NAME}${WINDOWS_BIN_EXTENSION}" - - ARTIFACTS_FOLDER: /artifacts - - GITLAB_API_PROJECT_URL: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID} - - BIN_FOLDER_MACOS: $ARTIFACTS_FOLDER/macOS - BIN_FOLDER_LINUX: $ARTIFACTS_FOLDER/Linux - BIN_FOLDER_WINDOWS: $ARTIFACTS_FOLDER/Windows - - BIN_FOLDER_MACOS_ARM64: $BIN_FOLDER_MACOS/arm64 - BIN_FOLDER_MACOS_X64: $BIN_FOLDER_MACOS/x64 - - BIN_FILE_MACOS_ARM64: $BIN_FOLDER_MACOS_ARM64/$BIN_NAME - BIN_FILE_MACOS_X64: $BIN_FOLDER_MACOS_X64/$BIN_NAME - BIN_PKG_FILE_MACOS_ARM64: $BIN_FOLDER_MACOS_ARM64/$MACOS_PKG_BIN_NAME - BIN_PKG_FILE_MACOS_X64: $BIN_FOLDER_MACOS_X64/$MACOS_PKG_BIN_NAME - BIN_FILE_LINUX_ARM64: $BIN_FOLDER_LINUX/arm64/$BIN_NAME - BIN_FILE_LINUX_X64: $BIN_FOLDER_LINUX/x64/$BIN_NAME - BIN_FILE_WINDOWS_ARM64: $BIN_FOLDER_WINDOWS/arm64/$WINDOWS_BIN_NAME - BIN_FILE_WINDOWS_X64: $BIN_FOLDER_WINDOWS/x64/$WINDOWS_BIN_NAME - - VERSION_FILE: $ARTIFACTS_FOLDER/VERSION - VERSION_DEV_SUFFIX: '-dev' - - PROJECT_FOLDER: NodeApp - - PACKAGE_REGISTRY_URL: "${GITLAB_API_PROJECT_URL}/packages/generic/${BIN_NAME}" - - -.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: - - PACKAGE_URL_MACOS_ARM64_BIN="${PACKAGE_REGISTRY_URL}_macOS-arm64/${VERSION}/${BIN_NAME}" - - PACKAGE_URL_MACOS_X64_BIN="${PACKAGE_REGISTRY_URL}_macOS-x64/${VERSION}/${BIN_NAME}" - - PACKAGE_URL_MACOS_ARM64_PKG="${PACKAGE_REGISTRY_URL}_macOS-pkg-arm64/${VERSION}/${MACOS_PKG_BIN_NAME}" - - PACKAGE_URL_MACOS_X64_PKG="${PACKAGE_REGISTRY_URL}_macOS-pkg-x64/${VERSION}/${MACOS_PKG_BIN_NAME}" - - PACKAGE_URL_LINUX_ARM64_BIN="${PACKAGE_REGISTRY_URL}_Linux-arm64/${VERSION}/${BIN_NAME}" - - PACKAGE_URL_LINUX_X64_BIN="${PACKAGE_REGISTRY_URL}_Linux-x64/${VERSION}/${BIN_NAME}" - - PACKAGE_URL_WINDOWS_ARM64_BIN="${PACKAGE_REGISTRY_URL}_Windows-arm64/${VERSION}/${WINDOWS_BIN_NAME}" - - PACKAGE_URL_WINDOWS_X64_BIN="${PACKAGE_REGISTRY_URL}_Windows-x64/${VERSION}/${WINDOWS_BIN_NAME}" - -.build_cli: - script: - - cd NodeApp - # Download secure files - - curl --silent "https://gitlab.com/gitlab-org/incubation-engineering/mobile-devops/download-secure-files/-/raw/main/installer" | bash - - mv env_$VERSION .env - # Install dependencies - - npm install - - npm run build - # Build binaries - ## macOS - - npx pkg . -t node18-macos-arm64 --output $BIN_FILE_MACOS_ARM64 --no-bytecode --public-packages "*" --public - - npx pkg . -t node18-macos-x64 --output $BIN_FILE_MACOS_X64 --no-bytecode --public-packages "*" --public - ## Linux - - npx pkg . -t node18-linuxstatic-arm64 --output $BIN_FILE_LINUX_ARM64 --no-bytecode --public-packages "*" --public - - npx pkg . -t node18-linuxstatic-x64 --output $BIN_FILE_LINUX_X64 --no-bytecode --public-packages "*" --public - ## Windows - - npx pkg . -t node18-win-arm64 --output $BIN_FILE_WINDOWS_ARM64 --no-bytecode --public-packages "*" --public - - npx pkg . -t node18-win-x64 --output $BIN_FILE_WINDOWS_X64 --no-bytecode --public-packages "*" --public - -.sign_macos: - script: - # Sign excecutable - - codesign --force --options=runtime --entitlements ../../../Resources/macApp/Signing/entitlements.plist --sign $SIGN_DEV_ID_APP --keychain $SIGN_LOGIN_KEYCHAIN_PATH --timestamp ${BIN_NAME} - # Package and notarize the app - - xcrun notarytool store-credentials --apple-id $SIGN_APPLE_ID --team-id $SIGN_TEAM_ID --password $SIGN_APP_PASSWORD --keychain $SIGN_LOGIN_KEYCHAIN_PATH $SIGN_KEYCHAIN_PROFILE - - ditto ${BIN_NAME} ${BIN_NAME}_pkg/usr/local/bin/ - - productbuild --identifier $SIGN_IDENTIFIER --version $VERSION --sign $SIGN_DEV_ID_INST --keychain $SIGN_LOGIN_KEYCHAIN_PATH --timestamp --root ${BIN_NAME}_pkg / ${MACOS_PKG_BIN_NAME} - - xcrun notarytool submit ${BIN_NAME}.pkg --keychain $SIGN_LOGIN_KEYCHAIN_PATH --keychain-profile $SIGN_KEYCHAIN_PROFILE --wait - - xcrun stapler staple ${BIN_NAME}.pkg - #Clean folder - - rm -Rf ${BIN_NAME}_pkg - -.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 - - -stages: - - test - - build - - sign - - clean - - upload - - release - - -test:build: - stage: test - tags: - - build - image: node:latest - script: - - apt update - - apt install -y jq - - !reference [.get_version, script] - - !reference [.build_cli, script] - rules: - - if: '$CI_COMMIT_TAG =~ "/^$/" && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_COMMIT_BRANCH !~ /^v[0-9]+(\.[0-9]+)*$/' - -build:version: - stage: build - tags: - - build - image: node:latest - script: - - apt update - - apt install -y jq - - !reference [.get_version, script] - - mkdir -p $ARTIFACTS_FOLDER - - echo $VERSION > $VERSION_FILE - - !reference [.build_cli, script] - artifacts: - untracked: true - paths: - - $ARTIFACTS_FOLDER/* - expire_in: 1 hour - rules: - - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /^v[0-9]+(\.[0-9]+)*$/' - -sign:macos: - stage: sign - tags: - - macos_signing - dependencies: - - build:version - script: - - VERSION=$(cat $VERSION_FILE) - - security unlock-keychain -p $SIGN_KEYCHAIN_PASSWORD $SIGN_LOGIN_KEYCHAIN_PATH - - cd $BIN_FOLDER_MACOS_ARM64 - - !reference [.sign_macos, script] - - cd $BIN_FOLDER_MACOS_X64 - - !reference [.sign_macos, script] - artifacts: - paths: - - $ARTIFACTS_FOLDER/* - expire_in: 1 day - rules: - - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /^v[0-9]+(\.[0-9]+)*$/' - -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_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /^v[0-9]+(\.[0-9]+)*$/' - -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_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /^v[0-9]+(\.[0-9]+)*$/' - -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' - -upload:packages: - stage: upload - tags: - - gitlab_package - dependencies: - - sign:macos - image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest - script: - - !reference [.get_version, script] - - !reference [.get_packages_url, script] - #macOS - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_FILE_MACOS_ARM64} "${PACKAGE_URL_MACOS_ARM64_BIN}";' - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_FILE_MACOS_X64} "${PACKAGE_URL_MACOS_X64_BIN}";' - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_PKG_FILE_MACOS_ARM64} "${PACKAGE_URL_MACOS_ARM64_PKG}";' - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_PKG_FILE_MACOS_X64} "${PACKAGE_URL_MACOS_X64_PKG}";' - #Linux - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_FILE_LINUX_ARM64} "${PACKAGE_URL_LINUX_ARM64_BIN}";' - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_FILE_LINUX_X64} "${PACKAGE_URL_LINUX_X64_BIN}";' - #Windows - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_FILE_WINDOWS_ARM64} "${PACKAGE_URL_WINDOWS_ARM64_BIN}";' - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_FILE_WINDOWS_X64} "${PACKAGE_URL_WINDOWS_X64_BIN}";' - rules: - - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /^v[0-9]+(\.[0-9]+)*$/' - -release:gitlab: - stage: release - tags: - - release - image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest +lint_pass: + only: + variables: + - $FOO == "bar" script: - - !reference [.get_version, script] - - !reference [.get_packages_url, script] - - echo 'Running release_job' - # 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": "Windows (ARM64) binary", - "url": "'${PACKAGE_URL_WINDOWS_ARM64_BIN}'", - },{ - "name": "Windows (x64) binary", - "url": "'${PACKAGE_URL_WINDOWS_X64_BIN}'", - },{ - "name": "Linux (ARM64) binary", - "url": "'${PACKAGE_URL_LINUX_ARM64_BIN}'", - },{ - "name": "Linux (x64) binary", - "url": "'${PACKAGE_URL_LINUX_X64_BIN}'", - },{ - "name": "macOS (Intel) binary", - "url": "'${PACKAGE_URL_MACOS_X64_BIN}'", - },{ - "name": "macOS (Apple Silicon) binary", - "url": "'${PACKAGE_URL_MACOS_ARM64_BIN}'", - },{ - "name": "macOS (Intel) package", - "url": "'${PACKAGE_URL_MACOS_X64_PKG}'", - },{ - "name": "macOS (Apple Silicon) package", - "url": "'${PACKAGE_URL_MACOS_ARM64_PKG}'", - } - ] - } - }') - - > - 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_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /^v[0-9]+(\.[0-9]+)*$/' \ No newline at end of file + - echo diff --git a/CHANGELOG.md b/CHANGELOG.md index 619aa96399baa4168efc9ee2bc236f249f2664d1..1bc7131614fb2ae150155b19cdc4dd631d137e12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,24 @@ **β οΈ Deprecation:** --> -## 2.0.0 (?) +## 2.1.0 (?) + +### β¨ Feature +- Added pipeline badge to exercises +- Creation of Debian / Ubuntu deb packages + +### π¨ 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) ### β¨ Feature - Added license: AGPLv3 diff --git a/NodeApp/.env.vault b/NodeApp/.env.vault new file mode 100644 index 0000000000000000000000000000000000000000..f6d35a5f86ea190e012c9ec8d378bab125ef1e2f --- /dev/null +++ b/NodeApp/.env.vault @@ -0,0 +1,11 @@ +#/-------------------.env.vault---------------------/ +#/ cloud-agnostic vaulting standard / +#/ [how it works](https://dotenv.org/env-vault) / +#/--------------------------------------------------/ + +# development +DOTENV_VAULT_DEVELOPMENT="McsEkttfKr1Vl0q9g7z4+6IRodJFBiT+rZWlz8SH12VCeviOBsot3YnUku80PwUxI3MqaWKmw6WNL5eLxKLlo64coMfgdajaTcp9yOfK6CRfHfWdh3MCoAf8ZiqbJGkmaH2X8j2QcnzJ6C+v8S1ZPUxk49ug+6otlyKl8hnr9ECvNGFKJ+Xa5L7XzEo+IGIFDrEYDtxI2VyUOiwudRnP0WarU8KJNt28IZYz3M5zymdFFI8Wlcq2+KiOp/CjiKYDxALkcINGkffu1WIU/lS0WE1FVLbds2hMsGkB4LwT1Q1ASkmsVT/BIb/wRxamDmAN494cTgGqYdaM5IOCGt2BDtm2UJWFrM5txl/PKRrbgE8wjpIaSp5OQ33nRV2P1fGk38z3gYHVI3NG5SRzxZTo+D4lT9UdNmwWIzL6rXRfnJgUTwKhc0MBrl+giaIt3U8wzYB69/F5+thYruSJVir42/b+XpOWSovZTwYYcAO5dXML/24jR3eNMxTlcxVvXpdx/Eg8r5ZCHSsMVKCgmyfGA49xWGjaMqOiizu83mt9KhsXiRgaI1imKiOm85eK9CUkvfLTQo8ccK+RITMvLKtCZgirF4HLi7y5DVjvufhtjxxOXjknFmI3UJFmjU9cUAKC3ccsM9F8Pm4mo6XbcPjBXZdX/18gtlvxps5at1cH998F8ZPkoaEJGp7lCYlxXTEBHOxxCEd5DdUldhpbOUfSsYZHUuxiA1gqJvilok39bgxl1WpO6nPM7S0S0GaI1jGkPKOJ/gx1fBRY91sSQy9Qw/O3tBUId1Az0QZLQZ+gijr6kchd5aczHmIRa2z4AHCSbeuzmaGfP+4yh0M6FvPPCD4i" + +# production +DOTENV_VAULT_PRODUCTION="aWWYhhCla0zC0MtLgZl1O7b4j8q5ya47bbHgZZtNJzw1PrL1I/2axdy6atW3v1cstw2putaNl4Gc81IM3GUPHyP6dDod6L7AMmLXKwrQFoYUxz0Za8fWLpnx79nY6A/zNgwfBqEZ0NE5o/GFKCDRYsfA6UuX8f6jBN2lhVK9leMU5DRvEyPrhKV4KHDwjKSTuqNbkZNW/BwyTf9Fdrd/SgUjgWA5Rvrg6N3RSkcHsuHfrBXzuzFHUFjQyrDlfS+fmpHj6PN69HWwtG+OjpgPaLocZ3WN2cDnb9X+rhB1W0uTN9Y8gAJkddUw3Kynf7YXimEBxWwV3ltdftIPAIcnz5cOx6lbzwFrXPnl2FesjpFZ1G27rZVr61kSUiILjRbOg9KIEmSqJXFzUHEyX7FwEYWxHtm1jw+76ePTV5g+4yfIxx2Vjo78uUKreASwtlA6CnsnnkFKqqLE3LYtskI7SYq/2t/Y0UrFKOFrOiK3Y5Kza7rRfcZo5SoNGFcyBw+4/YV5Tk/8z4zhyt/6lzLTA/w/mNXv4KCKn2oRBIUOlaMClvfmA2pwCv7YgpCGAycj0qQkhNhhIkd2F3cuc0o+U1XnWiqlEIVX9Z40gnrzodTRBmdvjVNdQ79nMvEVsmzjwmhoAC62RnyEnMUBrE9XM3RvRFoYFThOd7RE5TxCmLjbZfyVYN58hufZZDFT3oPYzoT9rzur6nU0NqjfNNU6BfZK4L+qGBg=" + diff --git a/NodeApp/.gitignore b/NodeApp/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..797ca4d1e519b7f376d5d3f74b9564fe39bd2079 --- /dev/null +++ b/NodeApp/.gitignore @@ -0,0 +1,5 @@ + +.env* +.flaskenv* +!.env.project +!.env.vault \ No newline at end of file diff --git a/NodeApp/.gitlab-ci/00_vars.yml b/NodeApp/.gitlab-ci/00_vars.yml new file mode 100644 index 0000000000000000000000000000000000000000..b2f058ad22a29824086741b5e0199b107a698ee7 --- /dev/null +++ b/NodeApp/.gitlab-ci/00_vars.yml @@ -0,0 +1,54 @@ +variables: + GIT_SUBMODULE_STRATEGY: recursive + GIT_SUBMODULE_FORCE_HTTPS: "true" + SECURE_FILES_DOWNLOAD_PATH: './' + + PROJECT_NAME: DojoCLI + PROJECT_FOLDER: NodeApp + + RESOURCES_FOLDER: "${CI_PROJECT_DIR}/Resources" + + BIN_NAME: dojo + + PKG_EXTENSION_DEBIAN: '.deb' + PKG_EXTENSION_MACOS: '.pkg' + + PKG_BIN_NAME_DEBIAN: "${BIN_NAME}${PKG_EXTENSION_DEBIAN}" + PKG_BIN_NAME_MACOS: "${BIN_NAME}${PKG_EXTENSION_MACOS}" + + BIN_EXTENSION_WINDOWS: '.exe' + BIN_NAME_WINDOWS: "${BIN_NAME}${BIN_EXTENSION_WINDOWS}" + + ARTIFACTS_FOLDER: /artifacts + + GITLAB_API_PROJECT_URL: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID} + + BIN_FOLDER_MACOS: $ARTIFACTS_FOLDER/macOS + BIN_FOLDER_LINUX: $ARTIFACTS_FOLDER/Linux + BIN_FOLDER_WINDOWS: $ARTIFACTS_FOLDER/Windows + + BIN_FOLDER_LINUX_ARM64: $BIN_FOLDER_LINUX/arm64 + BIN_FOLDER_LINUX_X64: $BIN_FOLDER_LINUX/x64 + BIN_FOLDER_MACOS_ARM64: $BIN_FOLDER_MACOS/arm64 + BIN_FOLDER_MACOS_X64: $BIN_FOLDER_MACOS/x64 + BIN_FOLDER_WINDOWS_ARM64: $BIN_FOLDER_WINDOWS/arm64 + BIN_FOLDER_WINDOWS_X64: $BIN_FOLDER_WINDOWS/x64 + + BIN_FILE_MACOS_ARM64: $BIN_FOLDER_MACOS_ARM64/$BIN_NAME + BIN_FILE_MACOS_X64: $BIN_FOLDER_MACOS_X64/$BIN_NAME + BIN_FILE_LINUX_ARM64: $BIN_FOLDER_LINUX_ARM64/$BIN_NAME + BIN_FILE_LINUX_X64: $BIN_FOLDER_LINUX_X64/$BIN_NAME + BIN_FILE_WINDOWS_ARM64: $BIN_FOLDER_WINDOWS_ARM64/$BIN_NAME_WINDOWS + BIN_FILE_WINDOWS_X64: $BIN_FOLDER_WINDOWS_X64/$BIN_NAME_WINDOWS + + BIN_PKG_FILE_DEBIAN_ARM64: $BIN_FOLDER_LINUX_ARM64/$PKG_BIN_NAME_DEBIAN + BIN_PKG_FILE_DEBIAN_X64: $BIN_FOLDER_LINUX_X64/$PKG_BIN_NAME_DEBIAN + BIN_PKG_FILE_MACOS_ARM64: $BIN_FOLDER_MACOS_ARM64/$PKG_BIN_NAME_MACOS + BIN_PKG_FILE_MACOS_X64: $BIN_FOLDER_MACOS_X64/$PKG_BIN_NAME_MACOS + + VERSION_FILE: $ARTIFACTS_FOLDER/VERSION + VERSION_DEV_SUFFIX: '-dev' + + PACKAGE_REGISTRY_URL: "${GITLAB_API_PROJECT_URL}/packages/generic/${BIN_NAME}" + + WIKI_FOLDER: Wiki \ No newline at end of file diff --git a/NodeApp/.gitlab-ci/01_functions.yml b/NodeApp/.gitlab-ci/01_functions.yml new file mode 100644 index 0000000000000000000000000000000000000000..57b72e642b5194d76bb1a6176bd6a48ec9872b7f --- /dev/null +++ b/NodeApp/.gitlab-ci/01_functions.yml @@ -0,0 +1,108 @@ +.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_last_stable_version: + script: + # Get all releases of the project + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" "${GITLAB_API_PROJECT_URL}/releases" > releases.json' + + # Filter and select last package that don't contains "-dev" in its name + - LAST_STABLE_VERSION=`jq -r '[.[] | .name | select (contains("$VERSION_DEV_SUFFIX") | not)][0]' releases.json` + + +.get_packages_url: + script: + # Binaries + - PACKAGE_URL_MACOS_ARM64_BIN="${PACKAGE_REGISTRY_URL}_macOS-arm64/${VERSION}/${BIN_NAME}" + - PACKAGE_URL_MACOS_X64_BIN="${PACKAGE_REGISTRY_URL}_macOS-x64/${VERSION}/${BIN_NAME}" + - PACKAGE_URL_LINUX_ARM64_BIN="${PACKAGE_REGISTRY_URL}_Linux-arm64/${VERSION}/${BIN_NAME}" + - PACKAGE_URL_LINUX_X64_BIN="${PACKAGE_REGISTRY_URL}_Linux-x64/${VERSION}/${BIN_NAME}" + - PACKAGE_URL_WINDOWS_ARM64_BIN="${PACKAGE_REGISTRY_URL}_Windows-arm64/${VERSION}/${BIN_NAME_WINDOWS}" + - PACKAGE_URL_WINDOWS_X64_BIN="${PACKAGE_REGISTRY_URL}_Windows-x64/${VERSION}/${BIN_NAME_WINDOWS}" + + # Packages + - PACKAGE_URL_MACOS_ARM64_PKG="${PACKAGE_REGISTRY_URL}_macOS-pkg-arm64/${VERSION}/${PKG_BIN_NAME_MACOS}" + - PACKAGE_URL_MACOS_X64_PKG="${PACKAGE_REGISTRY_URL}_macOS-pkg-x64/${VERSION}/${PKG_BIN_NAME_MACOS}" + - PACKAGE_URL_DEBIAN_ARM64_PKG="${PACKAGE_REGISTRY_URL}_debian-pkg-arm64/${VERSION}/${PKG_BIN_NAME_DEBIAN}" + - PACKAGE_URL_DEBIAN_X64_PKG="${PACKAGE_REGISTRY_URL}_debian-pkg-x64/${VERSION}/${PKG_BIN_NAME_DEBIAN}" + + # Wiki + - WIKI_ARCHIVE_NAME="${PROJECT_NAME}_Wiki_${VERSION}.tar.xz" + - PACKAGE_URL_WIKI="${PACKAGE_REGISTRY_URL}_Wiki/${VERSION}/${WIKI_ARCHIVE_NAME}" + + +.build_cli: + script: + - cd "${PROJECT_FOLDER}" + + # Install dependencies + - npm install + + # Set version number shown in CLI + - sed -i -r "s/\{\{VERSION\}\}/${VERSION}/g" src/commander/CommanderApp.ts + + # Decrypt env vars for production + - | + 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 + + # Build + - npm run build + + # Build binaries + ## macOS + - npx pkg . -t node18-macos-arm64 --output $BIN_FILE_MACOS_ARM64 --no-bytecode --compress Brotli --public-packages "*" --public + - npx pkg . -t node18-macos-x64 --output $BIN_FILE_MACOS_X64 --no-bytecode --compress Brotli --public-packages "*" --public + + ## Linux + - npx pkg . -t node18-linuxstatic-arm64 --output $BIN_FILE_LINUX_ARM64 --no-bytecode --compress Brotli --public-packages "*" --public + - npx pkg . -t node18-linuxstatic-x64 --output $BIN_FILE_LINUX_X64 --no-bytecode --compress Brotli --public-packages "*" --public + + ## Windows + - npx pkg . -t node18-win-arm64 --output $BIN_FILE_WINDOWS_ARM64 --no-bytecode --compress Brotli --public-packages "*" --public + - npx pkg . -t node18-win-x64 --output $BIN_FILE_WINDOWS_X64 --no-bytecode --compress Brotli --public-packages "*" --public + + # Add execution rights to binaries + ## macOS + - chmod +x $BIN_FILE_MACOS_ARM64 + - chmod +x $BIN_FILE_MACOS_X64 + + ## Linux + - chmod +x $BIN_FILE_LINUX_ARM64 + - chmod +x $BIN_FILE_LINUX_X64 + + ## Windows + - chmod +x $BIN_FILE_WINDOWS_ARM64 + - chmod +x $BIN_FILE_WINDOWS_X64 + + +.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/NodeApp/.gitlab-ci/02_templates.yml b/NodeApp/.gitlab-ci/02_templates.yml new file mode 100644 index 0000000000000000000000000000000000000000..8bf24a6f5a203cdb1ea621d04d0091a785bbd960 --- /dev/null +++ b/NodeApp/.gitlab-ci/02_templates.yml @@ -0,0 +1,90 @@ +.pkg_and_sign:debian: + stage: pkg_and_sign + image: ubuntu:latest + tags: + - pkg + dependencies: + - build:version + script: + # Install dependencies + - apt update + - apt install -y dpkg jq curl build-essential + + # Get vars + - !reference [ .get_version, script ] + - !reference [ .get_last_stable_version, script ] + + - cd $BIN_FOLDER_DEBIAN_PKG_AND_SIGN + - PKG_BUILD_FOLDER_NAME="${BIN_NAME}_${VERSION}_${ARCH}" + + + # Pkg tree creation + - mkdir -p "${PKG_BUILD_FOLDER_NAME}/usr/local/bin/" + ## Copy binary + - cp -R ${BIN_NAME} "${PKG_BUILD_FOLDER_NAME}/usr/local/bin/" + ## Copy debian folder with package definition files + - cp -R "${RESOURCES_FOLDER}/Debian/pkg/DEBIAN" "${PKG_BUILD_FOLDER_NAME}" + + # Modify files + - cd "${PKG_BUILD_FOLDER_NAME}/DEBIAN" + ## control file + - sed -i -r "s%\{\{VERSION\}\}%${VERSION}%g" control + - sed -i -r "s%\{\{ARCH\}\}%${ARCH}%g" control + - sed -i -r "s%\{\{BIN_NAME\}\}%${BIN_NAME}%g" control + ## changelog file + - STABILITY=$([[ $IS_DEV == true ]] && echo 'unstable' || echo 'stable') + - PRIORITY=$([[ ${VERSION%.*} == ${LAST_STABLE_VERSION%.*} ]] && echo 'medium' || echo 'high') + - sed -i -r "s%\{\{VERSION\}\}%${VERSION}%g" changelog + - sed -i -r "s%\{\{BIN_NAME\}\}%${BIN_NAME}%g" changelog + - sed -i -r "s%\{\{DATE\}\}%$(date -R)%g" changelog + - sed -i -r "s%\{\{URL\}\}%${CI_PROJECT_URL}%g" changelog + - sed -i -r "s%\{\{STABILITY\}\}%${STABILITY}%g" changelog + - sed -i -r "s%\{\{PRIORITY\}\}%${PRIORITY}%g" changelog + ## copyright file + - sed -i -r "s%\{\{BIN_NAME\}\}%${BIN_NAME}%g" copyright + ## return to bin folder + - cd $BIN_FOLDER_DEBIAN_PKG_AND_SIGN + + # Build package + - dpkg-deb --build --root-owner-group -Z xz -z 9 ${PKG_BUILD_FOLDER_NAME} ${PKG_BIN_NAME_DEBIAN} + + # Clean folder + - rm -Rf ${PKG_BUILD_FOLDER_NAME} + artifacts: + paths: + - $ARTIFACTS_FOLDER/* + expire_in: 10 mins + rules: + - if: '$CI_COMMIT_REF_PROTECTED == "true"' + + +.pkg_and_sign:macos: + stage: pkg_and_sign + tags: + - macos_signing + dependencies: + - build:version + script: + - VERSION=$(cat $VERSION_FILE) + - security unlock-keychain -p $SIGN_KEYCHAIN_PASSWORD $SIGN_LOGIN_KEYCHAIN_PATH + + - cd $BIN_FOLDER_MACOS_PKG_AND_SIGN + + # Sign excecutable + - codesign --force --options=runtime --entitlements ../../../Resources/macOS/Signing/entitlements.plist --sign $SIGN_DEV_ID_APP --keychain $SIGN_LOGIN_KEYCHAIN_PATH --timestamp ${BIN_NAME} + + # Package and notarize the app + - xcrun notarytool store-credentials --apple-id $SIGN_APPLE_ID --team-id $SIGN_TEAM_ID --password $SIGN_APP_PASSWORD --keychain $SIGN_LOGIN_KEYCHAIN_PATH $SIGN_KEYCHAIN_PROFILE + - ditto ${BIN_NAME} ${BIN_NAME}_pkg/usr/local/bin/ + - productbuild --identifier $SIGN_IDENTIFIER --version $VERSION --sign $SIGN_DEV_ID_INST --keychain $SIGN_LOGIN_KEYCHAIN_PATH --timestamp --root ${BIN_NAME}_pkg / ${PKG_BIN_NAME_MACOS} + - xcrun notarytool submit ${BIN_NAME}.pkg --keychain $SIGN_LOGIN_KEYCHAIN_PATH --keychain-profile $SIGN_KEYCHAIN_PROFILE --wait + - xcrun stapler staple ${BIN_NAME}.pkg + + # Clean folder + - rm -Rf ${BIN_NAME}_pkg + artifacts: + paths: + - $ARTIFACTS_FOLDER/* + expire_in: 10 mins + rules: + - if: '$CI_COMMIT_REF_PROTECTED == "true"' \ No newline at end of file diff --git a/NodeApp/.gitlab-ci/03_stages.yml b/NodeApp/.gitlab-ci/03_stages.yml new file mode 100644 index 0000000000000000000000000000000000000000..c459c1651b62a43f93c894fd8b640bb8df071386 --- /dev/null +++ b/NodeApp/.gitlab-ci/03_stages.yml @@ -0,0 +1,7 @@ +stages: + - test + - build + - pkg_and_sign + - clean + - upload + - release \ No newline at end of file diff --git a/NodeApp/.gitlab-ci/04_stageTest.yml b/NodeApp/.gitlab-ci/04_stageTest.yml new file mode 100644 index 0000000000000000000000000000000000000000..6c87377ea87becfa1b5404aae476a1cc981c85a0 --- /dev/null +++ b/NodeApp/.gitlab-ci/04_stageTest.yml @@ -0,0 +1,14 @@ +test:build: + stage: test + tags: + - build + image: node:latest + script: + - apt update + - apt install -y jq + - !reference [ .get_version, script ] + + # Build + - !reference [ .build_cli, script ] + rules: + - if: '$CI_COMMIT_REF_PROTECTED != "true"' diff --git a/NodeApp/.gitlab-ci/05_stageBuild.yml b/NodeApp/.gitlab-ci/05_stageBuild.yml new file mode 100644 index 0000000000000000000000000000000000000000..2771ad328154f051d2b2356ce86715ff6b3e0f05 --- /dev/null +++ b/NodeApp/.gitlab-ci/05_stageBuild.yml @@ -0,0 +1,21 @@ +build:version: + stage: build + tags: + - build + image: node:latest + script: + - apt update + - apt install -y jq + - !reference [ .get_version, script ] + - mkdir -p $ARTIFACTS_FOLDER + - echo $VERSION > $VERSION_FILE + + # Build + - !reference [ .build_cli, script ] + artifacts: + untracked: true + paths: + - $ARTIFACTS_FOLDER/* + expire_in: 10 mins + rules: + - if: '$CI_COMMIT_REF_PROTECTED == "true"' diff --git a/NodeApp/.gitlab-ci/06_stagePkgAndSign.yml b/NodeApp/.gitlab-ci/06_stagePkgAndSign.yml new file mode 100644 index 0000000000000000000000000000000000000000..dfdc2bd0004724db8d53b42484432f7d5adadead --- /dev/null +++ b/NodeApp/.gitlab-ci/06_stagePkgAndSign.yml @@ -0,0 +1,14 @@ +pkg_and_sign:debian: + parallel: + matrix: + - ARCH: [ "arm64", "amd64" ] + before_script: + - BIN_FOLDER_DEBIAN_PKG_AND_SIGN=$([[ $ARCH == "arm64" ]] && echo ${BIN_FOLDER_LINUX_ARM64} || echo ${BIN_FOLDER_LINUX_X64}) + extends: .pkg_and_sign:debian + + +pkg_and_sign:macos: + parallel: + matrix: + - BIN_FOLDER_MACOS_PKG_AND_SIGN: [ "$BIN_FOLDER_MACOS_ARM64", "$BIN_FOLDER_MACOS_X64" ] + extends: .pkg_and_sign:macos \ No newline at end of file diff --git a/NodeApp/.gitlab-ci/07_stageClean.yml b/NodeApp/.gitlab-ci/07_stageClean.yml new file mode 100644 index 0000000000000000000000000000000000000000..4eef3851aaa4b5b47ef46f6f3efa81e95216f059 --- /dev/null +++ b/NodeApp/.gitlab-ci/07_stageClean.yml @@ -0,0 +1,48 @@ +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' \ No newline at end of file diff --git a/NodeApp/.gitlab-ci/08_stageUpload.yml b/NodeApp/.gitlab-ci/08_stageUpload.yml new file mode 100644 index 0000000000000000000000000000000000000000..9ebb3fdf89f0cd171cd0e878e04b9c560c2165ec --- /dev/null +++ b/NodeApp/.gitlab-ci/08_stageUpload.yml @@ -0,0 +1,52 @@ +upload:packages: + stage: upload + tags: + - gitlab_package + dependencies: + - pkg_and_sign:macos + - pkg_and_sign:debian + image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest + script: + - !reference [ .get_version, script ] + - !reference [ .get_packages_url, script ] + + # macOS + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_FILE_MACOS_ARM64} "${PACKAGE_URL_MACOS_ARM64_BIN}";' + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_FILE_MACOS_X64} "${PACKAGE_URL_MACOS_X64_BIN}";' + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_PKG_FILE_MACOS_ARM64} "${PACKAGE_URL_MACOS_ARM64_PKG}";' + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_PKG_FILE_MACOS_X64} "${PACKAGE_URL_MACOS_X64_PKG}";' + + # Linux + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_FILE_LINUX_ARM64} "${PACKAGE_URL_LINUX_ARM64_BIN}";' + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_FILE_LINUX_X64} "${PACKAGE_URL_LINUX_X64_BIN}";' + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_PKG_FILE_DEBIAN_ARM64} "${PACKAGE_URL_DEBIAN_ARM64_PKG}";' + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_PKG_FILE_DEBIAN_X64} "${PACKAGE_URL_DEBIAN_X64_PKG}";' + + # Windows + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_FILE_WINDOWS_ARM64} "${PACKAGE_URL_WINDOWS_ARM64_BIN}";' + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${BIN_FILE_WINDOWS_X64} "${PACKAGE_URL_WINDOWS_X64_BIN}";' + rules: + - if: '$CI_COMMIT_REF_PROTECTED == "true"' + + +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"' \ No newline at end of file diff --git a/NodeApp/.gitlab-ci/09_stageRelease.yml b/NodeApp/.gitlab-ci/09_stageRelease.yml new file mode 100644 index 0000000000000000000000000000000000000000..ef93e4ed4185c81107861e8ca5110368e5c6c434 --- /dev/null +++ b/NodeApp/.gitlab-ci/09_stageRelease.yml @@ -0,0 +1,114 @@ +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: + stage: release + tags: + - release + image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest + script: + - !reference [ .get_version, script ] + - !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": "Windows (ARM64) binary", + "url": "'${PACKAGE_URL_WINDOWS_ARM64_BIN}'", + },{ + "name": "Windows (x64) binary", + "url": "'${PACKAGE_URL_WINDOWS_X64_BIN}'", + },{ + "name": "Linux (ARM64) binary", + "url": "'${PACKAGE_URL_LINUX_ARM64_BIN}'", + },{ + "name": "Linux (x64) binary", + "url": "'${PACKAGE_URL_LINUX_X64_BIN}'", + },{ + "name": "Debian / Ubuntu (ARM64) package", + "url": "'${PACKAGE_URL_DEBIAN_ARM64_PKG}'", + },{ + "name": "Debian / Ubuntu (x64) package", + "url": "'${PACKAGE_URL_DEBIAN_X64_PKG}'", + },{ + "name": "macOS (Intel) binary", + "url": "'${PACKAGE_URL_MACOS_X64_BIN}'", + },{ + "name": "macOS (Apple Silicon) binary", + "url": "'${PACKAGE_URL_MACOS_ARM64_BIN}'", + },{ + "name": "macOS (Intel) package", + "url": "'${PACKAGE_URL_MACOS_X64_PKG}'", + },{ + "name": "macOS (Apple Silicon) package", + "url": "'${PACKAGE_URL_MACOS_ARM64_PKG}'", + },{ + "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 diff --git a/NodeApp/.idea/DojoCLI.iml b/NodeApp/.idea/DojoCLI.iml index 24643cc37449b4bde54411a80b8ed61258225e34..d47865a1c8d932c244bdb1f09d5eb3295d5dc715 100644 --- a/NodeApp/.idea/DojoCLI.iml +++ b/NodeApp/.idea/DojoCLI.iml @@ -6,6 +6,9 @@ <excludeFolder url="file://$MODULE_DIR$/temp" /> <excludeFolder url="file://$MODULE_DIR$/tmp" /> </content> + <content url="file://$MODULE_DIR$/.gitlab-ci-local"> + <excludeFolder url="file://$MODULE_DIR$/.gitlab-ci-local" /> + </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> </component> diff --git a/NodeApp/package-lock.json b/NodeApp/package-lock.json index 6b5fe0f904508e058062b4ebf9303340638b61a5..6d9c32798aafb2306f209eb808b9ce5398711637 100644 --- a/NodeApp/package-lock.json +++ b/NodeApp/package-lock.json @@ -1,12 +1,12 @@ { "name": "dojo_cli", - "version": "1.0.1", + "version": "2.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dojo_cli", - "version": "1.0.1", + "version": "2.1.0", "dependencies": { "ajv": "^8.12.0", "appdata-path": "^1.0.0", @@ -33,6 +33,7 @@ "@types/jsonwebtoken": "^8.5.9", "@types/node": "^18.17.2", "@types/tar-stream": "^2.2.2", + "dotenv-vault": "^1.25.0", "pkg": "^5.8.1", "tiny-typed-emitter": "^2.1.0", "ts-node": "^10.9.1", @@ -226,6 +227,432 @@ "node": ">= 8" } }, + "node_modules/@oclif/core": { + "version": "1.26.2", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-1.26.2.tgz", + "integrity": "sha512-6jYuZgXvHfOIc9GIaS4T3CIKGTjPmfAxuMcbCbMRKJJl4aq/4xeRlEz0E8/hz8HxvxZBGvN2GwAUHlrGWQVrVw==", + "dev": true, + "dependencies": { + "@oclif/linewrap": "^1.0.0", + "@oclif/screen": "^3.0.4", + "ansi-escapes": "^4.3.2", + "ansi-styles": "^4.3.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.10.0", + "debug": "^4.3.4", + "ejs": "^3.1.6", + "fs-extra": "^9.1.0", + "get-package-type": "^0.1.0", + "globby": "^11.1.0", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.14.1", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.33", + "password-prompt": "^1.1.2", + "semver": "^7.3.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "tslib": "^2.4.1", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oclif/core/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@oclif/core/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@oclif/core/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@oclif/linewrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz", + "integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw==", + "dev": true + }, + "node_modules/@oclif/plugin-help": { + "version": "5.2.19", + "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-5.2.19.tgz", + "integrity": "sha512-gf6/dFtzMJ8RA4ovlBCBGJsZsd4jPXhYWJho+Gh6KmA+Ev9LupoExbE0qT+a2uHJyHEvIg4uX/MBW3qdERD/8g==", + "dev": true, + "dependencies": { + "@oclif/core": "^2.15.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/plugin-help/node_modules/@oclif/core": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-2.15.0.tgz", + "integrity": "sha512-fNEMG5DzJHhYmI3MgpByTvltBOMyFcnRIUMxbiz2ai8rhaYgaTHMG3Q38HcosfIvtw9nCjxpcQtC8MN8QtVCcA==", + "dev": true, + "dependencies": { + "@types/cli-progress": "^3.11.0", + "ansi-escapes": "^4.3.2", + "ansi-styles": "^4.3.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.12.0", + "debug": "^4.3.4", + "ejs": "^3.1.8", + "get-package-type": "^0.1.0", + "globby": "^11.1.0", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.14.1", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.33", + "password-prompt": "^1.1.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "ts-node": "^10.9.1", + "tslib": "^2.5.0", + "widest-line": "^3.1.0", + "wordwrap": "^1.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oclif/plugin-help/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@oclif/plugin-not-found": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@oclif/plugin-not-found/-/plugin-not-found-2.4.1.tgz", + "integrity": "sha512-LqW7qpw5Q8ploRiup2jEIMQJXcxHP1tpwj45GApKQMe7GRdGdRdjBT9Tu+U2tdEgMqgMplAIhOsYCx2nc2nMSw==", + "dev": true, + "dependencies": { + "@oclif/core": "^2.15.0", + "chalk": "^4", + "fast-levenshtein": "^3.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/plugin-not-found/node_modules/@oclif/core": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-2.15.0.tgz", + "integrity": "sha512-fNEMG5DzJHhYmI3MgpByTvltBOMyFcnRIUMxbiz2ai8rhaYgaTHMG3Q38HcosfIvtw9nCjxpcQtC8MN8QtVCcA==", + "dev": true, + "dependencies": { + "@types/cli-progress": "^3.11.0", + "ansi-escapes": "^4.3.2", + "ansi-styles": "^4.3.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.12.0", + "debug": "^4.3.4", + "ejs": "^3.1.8", + "get-package-type": "^0.1.0", + "globby": "^11.1.0", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.14.1", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.33", + "password-prompt": "^1.1.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "ts-node": "^10.9.1", + "tslib": "^2.5.0", + "widest-line": "^3.1.0", + "wordwrap": "^1.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oclif/plugin-not-found/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@oclif/plugin-update": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@oclif/plugin-update/-/plugin-update-3.2.3.tgz", + "integrity": "sha512-JVKwp4ysG9GU4RmG59MZYMunz8onRI+wEQzJThyYkUFd0VfZviYt2FHsyoNtxi30l0tInC8APgKp1pCCO4e+FQ==", + "dev": true, + "dependencies": { + "@oclif/core": "^2.11.8", + "chalk": "^4", + "cross-spawn": "^7.0.3", + "debug": "^4.3.1", + "filesize": "^6.1.0", + "fs-extra": "^9.0.1", + "http-call": "^5.3.0", + "inquirer": "^8.2.6", + "lodash.throttle": "^4.1.1", + "log-chopper": "^1.0.2", + "semver": "^7.5.4", + "tar-fs": "^2.1.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/plugin-update/node_modules/@oclif/core": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-2.15.0.tgz", + "integrity": "sha512-fNEMG5DzJHhYmI3MgpByTvltBOMyFcnRIUMxbiz2ai8rhaYgaTHMG3Q38HcosfIvtw9nCjxpcQtC8MN8QtVCcA==", + "dev": true, + "dependencies": { + "@types/cli-progress": "^3.11.0", + "ansi-escapes": "^4.3.2", + "ansi-styles": "^4.3.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.12.0", + "debug": "^4.3.4", + "ejs": "^3.1.8", + "get-package-type": "^0.1.0", + "globby": "^11.1.0", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.14.1", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.33", + "password-prompt": "^1.1.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "ts-node": "^10.9.1", + "tslib": "^2.5.0", + "widest-line": "^3.1.0", + "wordwrap": "^1.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oclif/plugin-update/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@oclif/plugin-update/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@oclif/plugin-update/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@oclif/plugin-warn-if-update-available": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@oclif/plugin-warn-if-update-available/-/plugin-warn-if-update-available-2.1.0.tgz", + "integrity": "sha512-liTWd/qSIqALsikr88CAB9o2xGFt0LdT5REbhxtrx16/trRmkxQ+0RHK1FieGZAzEENx/4D3YcC/Y67a0uyO0g==", + "dev": true, + "dependencies": { + "@oclif/core": "^2.15.0", + "chalk": "^4.1.0", + "debug": "^4.1.0", + "http-call": "^5.2.2", + "lodash.template": "^4.5.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/plugin-warn-if-update-available/node_modules/@oclif/core": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-2.15.0.tgz", + "integrity": "sha512-fNEMG5DzJHhYmI3MgpByTvltBOMyFcnRIUMxbiz2ai8rhaYgaTHMG3Q38HcosfIvtw9nCjxpcQtC8MN8QtVCcA==", + "dev": true, + "dependencies": { + "@types/cli-progress": "^3.11.0", + "ansi-escapes": "^4.3.2", + "ansi-styles": "^4.3.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.12.0", + "debug": "^4.3.4", + "ejs": "^3.1.8", + "get-package-type": "^0.1.0", + "globby": "^11.1.0", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.14.1", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.33", + "password-prompt": "^1.1.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "ts-node": "^10.9.1", + "tslib": "^2.5.0", + "widest-line": "^3.1.0", + "wordwrap": "^1.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oclif/plugin-warn-if-update-available/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@oclif/plugin-warn-if-update-available/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@oclif/screen": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-3.0.6.tgz", + "integrity": "sha512-nEv7dFPxCrWrvK6dQ8zya0/Kb54EXVcwIKV9capjSa89ZDoOo+qH0YSo4/eQVECXgW3eUvgKLDIcIt62YBk0HA==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -250,6 +677,15 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "node_modules/@types/cli-progress": { + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.2.tgz", + "integrity": "sha512-Yt/8rEJalfa9ve2SbfQnwFHrc9QF52JIZYHW3FDaTMpkCvnns26ueKiPHDxyJ0CS//IqjMINTx7R5Xa7k7uFHQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/fs-extra": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.1.tgz", @@ -409,6 +845,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true + }, "node_modules/appdata-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/appdata-path/-/appdata-path-1.0.0.tgz", @@ -420,6 +862,15 @@ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -429,6 +880,15 @@ "node": ">=8" } }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", @@ -463,6 +923,12 @@ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -524,6 +990,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -564,6 +1040,15 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, + "node_modules/byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -575,6 +1060,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -601,6 +1099,33 @@ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true }, + "node_modules/clean-stack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", + "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clean-stack/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cli-boxes": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", @@ -623,6 +1148,18 @@ "node": ">=8" } }, + "node_modules/cli-progress": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz", + "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==", + "dev": true, + "dependencies": { + "string-width": "^4.2.3" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/cli-spinners": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", @@ -736,6 +1273,21 @@ "node": ">=16" } }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -748,6 +1300,20 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -855,6 +1421,38 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, + "node_modules/dotenv-vault": { + "version": "1.25.0", + "resolved": "https://registry.npmjs.org/dotenv-vault/-/dotenv-vault-1.25.0.tgz", + "integrity": "sha512-+3isN+iq0E5VE+pfluBcNYb2qFf/Zu5q44Neh3Bazl82vk86xdUbI2z2cYHgJq5bMgRW1kUOaGWsgXjYlGUhng==", + "dev": true, + "dependencies": { + "@oclif/core": "^1", + "@oclif/plugin-help": "^5.2.11", + "@oclif/plugin-not-found": "^2.3.24", + "@oclif/plugin-update": "^3.1.16", + "@oclif/plugin-warn-if-update-available": "^2.0.40", + "axios": "^0.27.2", + "chalk": "^4.1.2", + "dotenv": "^16.3.1" + }, + "bin": { + "dotenv-vault": "bin/run" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/dotenv-vault/node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -863,6 +1461,21 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -882,6 +1495,21 @@ "once": "^1.4.0" } }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-ex/node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -899,6 +1527,19 @@ "node": ">=0.8.0" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -947,6 +1588,24 @@ "node": ">=8.6.0" } }, + "node_modules/fast-levenshtein": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", + "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "dev": true, + "dependencies": { + "fastest-levenshtein": "^1.0.7" + } + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -975,6 +1634,45 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/filesize": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.4.0.tgz", + "integrity": "sha512-mjFIpOHC4jbfcTfoh4rkWpI31mF7viw9ikj/JyLoKzqlwG/YsefKfvYlYhdYdg/9mtK2z1AzgN/0LvVQ3zdlSQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1098,6 +1796,15 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", @@ -1161,6 +1868,23 @@ "node": ">=8" } }, + "node_modules/http-call": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/http-call/-/http-call-5.3.0.tgz", + "integrity": "sha512-ahwimsC23ICE4kPl9xTBjKB4inbRaeLyZeRunC/1Jy/Z6X8tv22MEAjK+KBOMSVLaqXPTTmd8638waVIKLGx2w==", + "dev": true, + "dependencies": { + "content-type": "^1.0.4", + "debug": "^4.1.1", + "is-retry-allowed": "^1.1.0", + "is-stream": "^2.0.0", + "parse-json": "^4.0.0", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/http-status-codes": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz", @@ -1179,6 +1903,15 @@ "node": ">= 6" } }, + "node_modules/hyperlinker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", + "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -1218,6 +1951,15 @@ "node": ">= 4" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -1230,9 +1972,9 @@ "dev": true }, "node_modules/inquirer": { - "version": "8.2.5", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", - "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -1248,12 +1990,25 @@ "string-width": "^4.1.0", "strip-ansi": "^6.0.0", "through": "^2.3.6", - "wrap-ansi": "^7.0.0" + "wrap-ansi": "^6.0.1" }, "engines": { "node": ">=12.0.0" } }, + "node_modules/inquirer/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/into-stream": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", @@ -1287,6 +2042,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1333,6 +2103,15 @@ "node": ">=0.12.0" } }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -1355,12 +2134,61 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -1373,6 +2201,12 @@ "node": ">=4" } }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -1450,6 +2284,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", + "dev": true + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -1485,6 +2325,43 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", + "dev": true + }, + "node_modules/log-chopper": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-chopper/-/log-chopper-1.0.2.tgz", + "integrity": "sha512-tEWS6Fb+Xv0yLChJ6saA1DP3H1yPL0PfiIN7SDJ+U/CyP+fD4G/dhKfow+P5UuJWi6BdE4mUcPkJclGXCWxDrg==", + "dev": true, + "dependencies": { + "byline": "5.x" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -1592,6 +2469,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -1647,6 +2536,15 @@ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", "dev": true }, + "node_modules/natural-orderby": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", + "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/node-abi": { "version": "3.45.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.45.0.tgz", @@ -1694,6 +2592,15 @@ } } }, + "node_modules/object-treeify": { + "version": "1.1.33", + "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", + "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1764,6 +2671,38 @@ "node": ">=8" } }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/password-prompt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.3.tgz", + "integrity": "sha512-HkrjG2aJlvF0t2BMH0e2LB/EHf3Lcq3fNMzy4GYHcQblAvOl+QQji1Lx7WRBMqpVK8p+KR7bCg7oqAMXtdgqyw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.2", + "cross-spawn": "^7.0.3" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -2005,6 +2944,15 @@ "node": ">= 6" } }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "dependencies": { + "esprima": "~4.0.0" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -2152,6 +3100,27 @@ "semver": "bin/semver" } }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -2219,6 +3188,29 @@ "node": ">=8" } }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -2327,6 +3319,19 @@ "node": ">=8" } }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -2574,6 +3579,21 @@ "webidl-conversions": "^3.0.0" } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", @@ -2619,6 +3639,12 @@ "node": ">= 6.4.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/NodeApp/package.json b/NodeApp/package.json index eb095058924ef551b7734599bd77cf4621dca7de..8f1ea6b3241f7a2cf8854af300f796178bce933c 100644 --- a/NodeApp/package.json +++ b/NodeApp/package.json @@ -1,6 +1,6 @@ { "name" : "dojo_cli", - "version" : "2.0.0", + "version" : "2.1.0", "main" : "dist/app.js", "bin" : { "dojo": "./dist/app.js" @@ -17,6 +17,7 @@ "node18-macos-x64", "node18-linux-arm64", "node18-linux-x64", + "node18-win-arm64", "node18-win-x86" ] }, @@ -48,6 +49,7 @@ "@types/jsonwebtoken": "^8.5.9", "@types/node" : "^18.17.2", "@types/tar-stream" : "^2.2.2", + "dotenv-vault" : "^1.25.0", "pkg" : "^5.8.1", "tiny-typed-emitter" : "^2.1.0", "ts-node" : "^10.9.1", diff --git a/NodeApp/src/app.ts b/NodeApp/src/app.ts index 543bc0594fc11b97e98fa5bb50265662b27bf65d..ea7d4ef9a1c6eb8f15517b3df0a0bb2cf56a6dbd 100644 --- a/NodeApp/src/app.ts +++ b/NodeApp/src/app.ts @@ -1,7 +1,10 @@ // Read from the .env file // ATTENTION : This lines MUST be the first of this file (except for the path import) const path = require('node:path'); -require('dotenv').config({ path: path.join(__dirname, '../.env') }); +require('dotenv').config({ + path : path.join(__dirname, '../.env'), + DOTENV_KEY: 'dotenv://:key_fc323d8e0a02349342f1c6a119bb38495958ce3a43a87d19a3f674b7e2896dcb@dotenv.local/vault/.env.vault?environment=development' + }); require('./shared/helpers/TypeScriptExtensions'); // ATTENTION : This line MUST be the second of this file diff --git a/NodeApp/src/commander/CommanderApp.ts b/NodeApp/src/commander/CommanderApp.ts index a6002b0a382a5b6d9f54f5825dfa21b7235f7549..91ba8fe932cea2e6085cf4ff554d030589cf7771 100644 --- a/NodeApp/src/commander/CommanderApp.ts +++ b/NodeApp/src/commander/CommanderApp.ts @@ -12,7 +12,7 @@ class CommanderApp { this.program .name('dojo') .description('CLI of the Dojo application') - .version('2.0.0') + .version('{{VERSION}}') .showHelpAfterError() .configureHelp({ showGlobalOptions: true, diff --git a/NodeApp/src/commander/exercise/ExerciseRunCommand.ts b/NodeApp/src/commander/exercise/ExerciseRunCommand.ts index 7fdd21b620679f37d5919171a3ae6c1e5320ce33..9eb4d8da5a2ec909018a15e052142adc6bcacf09 100644 --- a/NodeApp/src/commander/exercise/ExerciseRunCommand.ts +++ b/NodeApp/src/commander/exercise/ExerciseRunCommand.ts @@ -86,7 +86,7 @@ class ExerciseRunCommand extends CommanderCommand { spinner.succeed(`The exercise folder contains all the needed files`); } - // dojo.assignment validity + // dojo_assignment.json validity { const spinner: ora.Ora = ora({ text : `Checking ${ Config.assignment.filename } file`, diff --git a/Resources/Debian/pkg/DEBIAN/changelog b/Resources/Debian/pkg/DEBIAN/changelog new file mode 100644 index 0000000000000000000000000000000000000000..1203451e322bd3645b1c54f5481127e52d3375af --- /dev/null +++ b/Resources/Debian/pkg/DEBIAN/changelog @@ -0,0 +1,5 @@ +{{BIN_NAME}} ({{VERSION}}) {{STABILITY}}; urgency={{URGENCY}} + + * See on gitlab: {{URL}}/-/blob/main/CHANGELOG.md + + -- MichaΓ«l Minelli <dojo@minelli.me> {{DATE}} \ No newline at end of file diff --git a/Resources/Debian/pkg/DEBIAN/compat b/Resources/Debian/pkg/DEBIAN/compat new file mode 100644 index 0000000000000000000000000000000000000000..f599e28b8ab0d8c9c57a486c89c4a5132dcbd3b2 --- /dev/null +++ b/Resources/Debian/pkg/DEBIAN/compat @@ -0,0 +1 @@ +10 diff --git a/Resources/Debian/pkg/DEBIAN/control b/Resources/Debian/pkg/DEBIAN/control new file mode 100644 index 0000000000000000000000000000000000000000..8f5ce246d783bcfdd48f6d6db7bb5eda7a886eed --- /dev/null +++ b/Resources/Debian/pkg/DEBIAN/control @@ -0,0 +1,47 @@ +Source: {{BIN_NAME}} +Version: {{VERSION}} +Standards-Version: {{VERSION}} +Section: education +Priority: optional +Maintainer: MichaΓ«l Minelli <dojo@minelli.me> +Package: {{BIN_NAME}} +Architecture: {{ARCH}} +Description: Dojo: a platform to practice programming + The Dojo platform is an online tool built to help practice programming by + allowing users to propose assignments and perform them as exercises. + . + The tool is very flexible and allows for proposing exercises for any language + and does not impose any limitation on a framework to be heavily relying + on Docker and Gitlab. These tools used in combination allow for automatic + correction of assignments in order to give immediate feedback to users + performing exercises. Solved exercises can then be shared among the community + of users such that they can inspire other users or give hints on ways to solve + a given exercise. + . + The two major concepts of the platform are the **assignments** and the **exercises**. + . + The principal way to interact with the Dojo platform is currently the `dojo` CLI. + . + . + ## The assignment + . + An assignment is written by a user that wants to propose an exercise. It is typically + composed of a written description of the work to be performed, and tests that must be + passed once the exercise is successfully performed (and some configuration files for + the infrastructure of the tests such as docker files). At its core, an assignment is + nothing else than a git repository that can be forked in the form of an exercise and + modified using standard git commands. + . + In the future a dependency tree of assignments can be created, as well as tagging for + filtering purposes. + . + . + ## The exercise + . + An exercise is an instance of an assignment which the learner will modify in order to + make it pass the automatic tests. It can be run locally on any user's machine using the + dojo CLI. When the exercise is completed it is pushed on the dojo where the CI/CD tools + of Gitlab can evaluate it automatically and notify the dojo platform of the result. The + exercises can then be shared with other users in order to propose a wide variety of + solutions and can be a base for discussion among users and with teachers. + For a more detailed description please see the CLI documentation: https://gitedu.hesge.ch/dojo_project/projects/ui/dojocli/-/wikis/home diff --git a/Resources/Debian/pkg/DEBIAN/copyright b/Resources/Debian/pkg/DEBIAN/copyright new file mode 100644 index 0000000000000000000000000000000000000000..e3a927e86f8a990b5f89b2657cdb2f3cde4aae9c --- /dev/null +++ b/Resources/Debian/pkg/DEBIAN/copyright @@ -0,0 +1,573 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: {{BIN_NAME}} +Upstream-Contact: MichaΓ«l Minelli <dojo@minelli.me> +Source: https://gitedu.hesge.ch/dojo_project/projects/ui/dojocli.git + +Files: * +Copyright: + Development by: + * MichaΓ«l Minelli <dojo@minelli.me> + * Orestis Malaspinas <orestis.malaspinas@hesge.ch> +License: AGPL-3 + +License: AGPL-3 + GNU AFFERO GENERAL PUBLIC LICENSE + . + Version 3, 19 November 2007 + . + Copyright Β© 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies of this license + document, but changing it is not allowed. + Preamble + . + The GNU Affero General Public License is a free, copyleft license for + software and other kinds of works, specifically designed to ensure + cooperation with the community in the case of network server software. + . + The licenses for most software and other practical works are designed to + take away your freedom to share and change the works. By contrast, our + General Public Licenses are intended to guarantee your freedom to share and + change all versions of a program--to make sure it remains free software for + all its users. + . + When we speak of free software, we are referring to freedom, not price. Our + General Public Licenses are designed to make sure that you have the freedom + to distribute copies of free software (and charge for them if you wish), + that you receive source code or can get it if you want it, that you can + change the software or use pieces of it in new free programs, and that you + know you can do these things. + . + Developers that use our General Public Licenses protect your rights with two + steps: (1) assert copyright on the software, and (2) offer you this License + which gives you legal permission to copy, distribute and/or modify the + software. + . + A secondary benefit of defending all users' freedom is that improvements + made in alternate versions of the program, if they receive widespread use, + become available for other developers to incorporate. Many developers of + free software are heartened and encouraged by the resulting cooperation. + However, in the case of software used on network servers, this result may + fail to come about. The GNU General Public License permits making a modified + version and letting the public access it on a server without ever releasing + its source code to the public. + . + The GNU Affero General Public License is designed specifically to ensure + that, in such cases, the modified source code becomes available to the + community. It requires the operator of a network server to provide the + source code of the modified version running there to the users of that + server. Therefore, public use of a modified version, on a publicly + accessible server, gives the public access to the source code of the + modified version. + . + An older license, called the Affero General Public License and published by + Affero, was designed to accomplish similar goals. This is a different + license, not a version of the Affero GPL, but Affero has released a new + version of the Affero GPL which permits relicensing under this license. + . + The precise terms and conditions for copying, distribution and modification + follow. + TERMS AND CONDITIONS + 0. Definitions. + . + "This License" refers to version 3 of the GNU Affero General Public License. + . + "Copyright" also means copyright-like laws that apply to other kinds of + works, such as semiconductor masks. + . + "The Program" refers to any copyrightable work licensed under this License. + Each licensee is addressed as "you". "Licensees" and "recipients" may be + individuals or organizations. + . + To "modify" a work means to copy from or adapt all or part of the work in a + fashion requiring copyright permission, other than the making of an exact + copy. The resulting work is called a "modified version" of the earlier work + or a work "based on" the earlier work. + . + A "covered work" means either the unmodified Program or a work based on the + Program. + . + To "propagate" a work means to do anything with it that, without permission, + would make you directly or secondarily liable for infringement under + applicable copyright law, except executing it on a computer or modifying a + private copy. Propagation includes copying, distribution (with or without + modification), making available to the public, and in some countries other + activities as well. + . + To "convey" a work means any kind of propagation that enables other parties + to make or receive copies. Mere interaction with a user through a computer + network, with no transfer of a copy, is not conveying. + . + An interactive user interface displays "Appropriate Legal Notices" to the + extent that it includes a convenient and prominently visible feature that + (1) displays an appropriate copyright notice, and (2) tells the user that + there is no warranty for the work (except to the extent that warranties are + provided), that licensees may convey the work under this License, and how to + view a copy of this License. If the interface presents a list of user + commands or options, such as a menu, a prominent item in the list meets this + criterion. + 1. Source Code. + . + The "source code" for a work means the preferred form of the work for making + modifications to it. "Object code" means any non-source form of a work. + . + A "Standard Interface" means an interface that either is an official + standard defined by a recognized standards body, or, in the case of + interfaces specified for a particular programming language, one that is + widely used among developers working in that language. + . + The "System Libraries" of an executable work include anything, other than + the work as a whole, that (a) is included in the normal form of packaging a + Major Component, but which is not part of that Major Component, and (b) + serves only to enable use of the work with that Major Component, or to + implement a Standard Interface for which an implementation is available to + the public in source code form. A "Major Component", in this context, means + a major essential component (kernel, window system, and so on) of the + specific operating system (if any) on which the executable work runs, or a + compiler used to produce the work, or an object code interpreter used to run + it. + . + The "Corresponding Source" for a work in object code form means all the + source code needed to generate, install, and (for an executable work) run + the object code and to modify the work, including scripts to control those + activities. However, it does not include the work's System Libraries, or + general-purpose tools or generally available free programs which are used + unmodified in performing those activities but which are not part of the + work. For example, Corresponding Source includes interface definition files + associated with source files for the work, and the source code for shared + libraries and dynamically linked subprograms that the work is specifically + designed to require, such as by intimate data communication or control flow + between those subprograms and other parts of the work. + . + The Corresponding Source need not include anything that users can regenerate + automatically from other parts of the Corresponding Source. + . + The Corresponding Source for a work in source code form is that same work. + 2. Basic Permissions. + . + All rights granted under this License are granted for the term of copyright + on the Program, and are irrevocable provided the stated conditions are met. + This License explicitly affirms your unlimited permission to run the + unmodified Program. The output from running a covered work is covered by + this License only if the output, given its content, constitutes a covered + work. This License acknowledges your rights of fair use or other equivalent, + as provided by copyright law. + . + You may make, run and propagate covered works that you do not convey, + without conditions so long as your license otherwise remains in force. You + may convey covered works to others for the sole purpose of having them make + modifications exclusively for you, or provide you with facilities for + running those works, provided that you comply with the terms of this License + in conveying all material for which you do not control copyright. Those thus + making or running the covered works for you must do so exclusively on your + behalf, under your direction and control, on terms that prohibit them from + making any copies of your copyrighted material outside their relationship + with you. + . + Conveying under any other circumstances is permitted solely under the + conditions stated below. Sublicensing is not allowed; section 10 makes it + unnecessary. + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + . + No covered work shall be deemed part of an effective technological measure + under any applicable law fulfilling obligations under article 11 of the WIPO + copyright treaty adopted on 20 December 1996, or similar laws prohibiting or + restricting circumvention of such measures. + . + When you convey a covered work, you waive any legal power to forbid + circumvention of technological measures to the extent such circumvention is + effected by exercising rights under this License with respect to the covered + work, and you disclaim any intention to limit operation or modification of + the work as a means of enforcing, against the work's users, your or third + parties' legal rights to forbid circumvention of technological measures. + 4. Conveying Verbatim Copies. + . + You may convey verbatim copies of the Program's source code as you receive + it, in any medium, provided that you conspicuously and appropriately publish + on each copy an appropriate copyright notice; keep intact all notices + stating that this License and any non-permissive terms added in accord with + section 7 apply to the code; keep intact all notices of the absence of any + warranty; and give all recipients a copy of this License along with the + Program. + . + You may charge any price or no price for each copy that you convey, and you + may offer support or warranty protection for a fee. + 5. Conveying Modified Source Versions. + . + You may convey a work based on the Program, or the modifications to produce + it from the Program, in the form of source code under the terms of section + 4, provided that you also meet all of these conditions: + . + a) The work must carry prominent notices stating that you modified it, + and giving a relevant date. + b) The work must carry prominent notices stating that it is released + under this License and any conditions added under section 7. This + requirement modifies the requirement in section 4 to "keep intact all + notices". + c) You must license the entire work, as a whole, under this License to + anyone who comes into possession of a copy. This License will therefore + apply, along with any applicable section 7 additional terms, to the whole of + the work, and all its parts, regardless of how they are packaged. This + License gives no permission to license the work in any other way, but it + does not invalidate such permission if you have separately received it. + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your work need not + make them do so. + . + A compilation of a covered work with other separate and independent works, + which are not by their nature extensions of the covered work, and which are + not combined with it such as to form a larger program, in or on a volume of + a storage or distribution medium, is called an "aggregate" if the + compilation and its resulting copyright are not used to limit the access or + legal rights of the compilation's users beyond what the individual works + permit. Inclusion of a covered work in an aggregate does not cause this + License to apply to the other parts of the aggregate. + 6. Conveying Non-Source Forms. + . + You may convey a covered work in object code form under the terms of + sections 4 and 5, provided that you also convey the machine-readable + Corresponding Source under the terms of this License, in one of these ways: + . + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the Corresponding + Source fixed on a durable physical medium customarily used for software + interchange. + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a written offer, + valid for at least three years and valid for as long as you offer spare + parts or customer support for that product model, to give anyone who + possesses the object code either (1) a copy of the Corresponding Source for + all the software in the product that is covered by this License, on a + durable physical medium customarily used for software interchange, for a + price no more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the Corresponding Source from a + network server at no charge. + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This alternative is + allowed only occasionally and noncommercially, and only if you received the + object code with such an offer, in accord with subsection 6b. + d) Convey the object code by offering access from a designated place + (gratis or for a charge), and offer equivalent access to the Corresponding + Source in the same way through the same place at no further charge. You need + not require recipients to copy the Corresponding Source along with the + object code. If the place to copy the object code is a network server, the + Corresponding Source may be on a different server (operated by you or a + third party) that supports equivalent copying facilities, provided you + maintain clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the Corresponding + Source, you remain obligated to ensure that it is available for as long as + needed to satisfy these requirements. + e) Convey the object code using peer-to-peer transmission, provided you + inform other peers where the object code and Corresponding Source of the + work are being offered to the general public at no charge under subsection + 6d. + . + A separable portion of the object code, whose source code is excluded from + the Corresponding Source as a System Library, need not be included in + conveying the object code work. + . + A "User Product" is either (1) a "consumer product", which means any + tangible personal property which is normally used for personal, family, or + household purposes, or (2) anything designed or sold for incorporation into + a dwelling. In determining whether a product is a consumer product, doubtful + cases shall be resolved in favor of coverage. For a particular product + received by a particular user, "normally used" refers to a typical or common + use of that class of product, regardless of the status of the particular + user or of the way in which the particular user actually uses, or expects or + is expected to use, the product. A product is a consumer product regardless + of whether the product has substantial commercial, industrial or + non-consumer uses, unless such uses represent the only significant mode of + use of the product. + . + "Installation Information" for a User Product means any methods, procedures, + authorization keys, or other information required to install and execute + modified versions of a covered work in that User Product from a modified + version of its Corresponding Source. The information must suffice to ensure + that the continued functioning of the modified object code is in no case + prevented or interfered with solely because modification has been made. + . + If you convey an object code work under this section in, or with, or + specifically for use in, a User Product, and the conveying occurs as part of + a transaction in which the right of possession and use of the User Product + is transferred to the recipient in perpetuity or for a fixed term + (regardless of how the transaction is characterized), the Corresponding + Source conveyed under this section must be accompanied by the Installation + Information. But this requirement does not apply if neither you nor any + third party retains the ability to install modified object code on the User + Product (for example, the work has been installed in ROM). + . + The requirement to provide Installation Information does not include a + requirement to continue to provide support service, warranty, or updates for + a work that has been modified or installed by the recipient, or for the User + Product in which it has been modified or installed. Access to a network may + be denied when the modification itself materially and adversely affects the + operation of the network or violates the rules and protocols for + communication across the network. + . + Corresponding Source conveyed, and Installation Information provided, in + accord with this section must be in a format that is publicly documented + (and with an implementation available to the public in source code form), + and must require no special password or key for unpacking, reading or + copying. + 7. Additional Terms. + . + "Additional permissions" are terms that supplement the terms of this License + by making exceptions from one or more of its conditions. Additional + permissions that are applicable to the entire Program shall be treated as + though they were included in this License, to the extent that they are valid + under applicable law. If additional permissions apply only to part of the + Program, that part may be used separately under those permissions, but the + entire Program remains governed by this License without regard to the + additional permissions. + . + When you convey a copy of a covered work, you may at your option remove any + additional permissions from that copy, or from any part of it. (Additional + permissions may be written to require their own removal in certain cases + when you modify the work.) You may place additional permissions on material, + added by you to a covered work, for which you have or can give appropriate + copyright permission. + . + Notwithstanding any other provision of this License, for material you add to + a covered work, you may (if authorized by the copyright holders of that + material) supplement the terms of this License with terms: + . + a) Disclaiming warranty or limiting liability differently from the terms + of sections 15 and 16 of this License; or + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal Notices + displayed by works containing it; or + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in reasonable + ways as different from the original version; or + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + e) Declining to grant rights under trademark law for use of some trade + names, trademarks, or service marks; or + f) Requiring indemnification of licensors and authors of that material + by anyone who conveys the material (or modified versions of it) with + contractual assumptions of liability to the recipient, for any liability + that these contractual assumptions directly impose on those licensors and + authors. + . + All other non-permissive additional terms are considered "further + restrictions" within the meaning of section 10. If the Program as you + received it, or any part of it, contains a notice stating that it is + governed by this License along with a term that is a further restriction, + you may remove that term. If a license document contains a further + restriction but permits relicensing or conveying under this License, you may + add to a covered work material governed by the terms of that license + document, provided that the further restriction does not survive such + relicensing or conveying. + . + If you add terms to a covered work in accord with this section, you must + place, in the relevant source files, a statement of the additional terms + that apply to those files, or a notice indicating where to find the + applicable terms. + . + Additional terms, permissive or non-permissive, may be stated in the form of + a separately written license, or stated as exceptions; the above + requirements apply either way. + 8. Termination. + . + You may not propagate or modify a covered work except as expressly provided + under this License. Any attempt otherwise to propagate or modify it is void, + and will automatically terminate your rights under this License (including + any patent licenses granted under the third paragraph of section 11). + . + However, if you cease all violation of this License, then your license from + a particular copyright holder is reinstated (a) provisionally, unless and + until the copyright holder explicitly and finally terminates your license, + and (b) permanently, if the copyright holder fails to notify you of the + violation by some reasonable means prior to 60 days after the cessation. + . + Moreover, your license from a particular copyright holder is reinstated + permanently if the copyright holder notifies you of the violation by some + reasonable means, this is the first time you have received notice of + violation of this License (for any work) from that copyright holder, and you + cure the violation prior to 30 days after your receipt of the notice. + . + Termination of your rights under this section does not terminate the + licenses of parties who have received copies or rights from you under this + License. If your rights have been terminated and not permanently reinstated, + you do not qualify to receive new licenses for the same material under + section 10. + 9. Acceptance Not Required for Having Copies. + . + You are not required to accept this License in order to receive or run a + copy of the Program. Ancillary propagation of a covered work occurring + solely as a consequence of using peer-to-peer transmission to receive a copy + likewise does not require acceptance. However, nothing other than this + License grants you permission to propagate or modify any covered work. These + actions infringe copyright if you do not accept this License. Therefore, by + modifying or propagating a covered work, you indicate your acceptance of + this License to do so. + 10. Automatic Licensing of Downstream Recipients. + . + Each time you convey a covered work, the recipient automatically receives a + license from the original licensors, to run, modify and propagate that work, + subject to this License. You are not responsible for enforcing compliance by + third parties with this License. + . + An "entity transaction" is a transaction transferring control of an + organization, or substantially all assets of one, or subdividing an + organization, or merging organizations. If propagation of a covered work + results from an entity transaction, each party to that transaction who + receives a copy of the work also receives whatever licenses to the work the + party's predecessor in interest had or could give under the previous + paragraph, plus a right to possession of the Corresponding Source of the + work from the predecessor in interest, if the predecessor has it or can get + it with reasonable efforts. + . + You may not impose any further restrictions on the exercise of the rights + granted or affirmed under this License. For example, you may not impose a + license fee, royalty, or other charge for exercise of rights granted under + this License, and you may not initiate litigation (including a cross-claim + or counterclaim in a lawsuit) alleging that any patent claim is infringed by + making, using, selling, offering for sale, or importing the Program or any + portion of it. + 11. Patents. + . + A "contributor" is a copyright holder who authorizes use under this License + of the Program or a work on which the Program is based. The work thus + licensed is called the contributor's "contributor version". + . + A contributor's "essential patent claims" are all patent claims owned or + controlled by the contributor, whether already acquired or hereafter + acquired, that would be infringed by some manner, permitted by this License, + of making, using, or selling its contributor version, but do not include + claims that would be infringed only as a consequence of further modification + of the contributor version. For purposes of this definition, "control" + includes the right to grant patent sublicenses in a manner consistent with + the requirements of this License. + . + Each contributor grants you a non-exclusive, worldwide, royalty-free patent + license under the contributor's essential patent claims, to make, use, sell, + offer for sale, import and otherwise run, modify and propagate the contents + of its contributor version. + . + In the following three paragraphs, a "patent license" is any express + agreement or commitment, however denominated, not to enforce a patent (such + as an express permission to practice a patent or covenant not to sue for + patent infringement). To "grant" such a patent license to a party means to + make such an agreement or commitment not to enforce a patent against the + party. + . + If you convey a covered work, knowingly relying on a patent license, and the + Corresponding Source of the work is not available for anyone to copy, free + of charge and under the terms of this License, through a publicly available + network server or other readily accessible means, then you must either (1) + cause the Corresponding Source to be so available, or (2) arrange to deprive + yourself of the benefit of the patent license for this particular work, or + (3) arrange, in a manner consistent with the requirements of this License, + to extend the patent license to downstream recipients. "Knowingly relying" + means you have actual knowledge that, but for the patent license, your + conveying the covered work in a country, or your recipient's use of the + covered work in a country, would infringe one or more identifiable patents + in that country that you have reason to believe are valid. + . + If, pursuant to or in connection with a single transaction or arrangement, + you convey, or propagate by procuring conveyance of, a covered work, and + grant a patent license to some of the parties receiving the covered work + authorizing them to use, propagate, modify or convey a specific copy of the + covered work, then the patent license you grant is automatically extended to + all recipients of the covered work and works based on it. + . + A patent license is "discriminatory" if it does not include within the scope + of its coverage, prohibits the exercise of, or is conditioned on the + non-exercise of one or more of the rights that are specifically granted + under this License. You may not convey a covered work if you are a party to + an arrangement with a third party that is in the business of distributing + software, under which you make payment to the third party based on the + extent of your activity of conveying the work, and under which the third + party grants, to any of the parties who would receive the covered work from + you, a discriminatory patent license (a) in connection with copies of the + covered work conveyed by you (or copies made from those copies), or (b) + primarily for and in connection with specific products or compilations that + contain the covered work, unless you entered into that arrangement, or that + patent license was granted, prior to 28 March 2007. + . + Nothing in this License shall be construed as excluding or limiting any + implied license or other defenses to infringement that may otherwise be + available to you under applicable patent law. + 12. No Surrender of Others' Freedom. + . + If conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot convey a + covered work so as to satisfy simultaneously your obligations under this + License and any other pertinent obligations, then as a consequence you may + not convey it at all. For example, if you agree to terms that obligate you + to collect a royalty for further conveying from those to whom you convey the + Program, the only way you could satisfy both those terms and this License + would be to refrain entirely from conveying the Program. + 13. Remote Network Interaction; Use with the GNU General Public License. + . + Notwithstanding any other provision of this License, if you modify the + Program, your modified version must prominently offer all users interacting + with it remotely through a computer network (if your version supports such + interaction) an opportunity to receive the Corresponding Source of your + version by providing access to the Corresponding Source from a network + server at no charge, through some standard or customary means of + facilitating copying of software. This Corresponding Source shall include + the Corresponding Source for any work covered by version 3 of the GNU + General Public License that is incorporated pursuant to the following + paragraph. + . + Notwithstanding any other provision of this License, you have permission to + link or combine any covered work with a work licensed under version 3 of the + GNU General Public License into a single combined work, and to convey the + resulting work. The terms of this License will continue to apply to the part + which is the covered work, but the work with which it is combined will + remain governed by version 3 of the GNU General Public License. + 14. Revised Versions of this License. + . + The Free Software Foundation may publish revised and/or new versions of the + GNU Affero General Public License from time to time. Such new versions will + be similar in spirit to the present version, but may differ in detail to + address new problems or concerns. + . + Each version is given a distinguishing version number. If the Program + specifies that a certain numbered version of the GNU Affero General Public + License "or any later version" applies to it, you have the option of + following the terms and conditions either of that numbered version or of any + later version published by the Free Software Foundation. If the Program does + not specify a version number of the GNU Affero General Public License, you + may choose any version ever published by the Free Software Foundation. + . + If the Program specifies that a proxy can decide which future versions of + the GNU Affero General Public License can be used, that proxy's public + statement of acceptance of a version permanently authorizes you to choose + that version for the Program. + . + Later license versions may give you additional or different permissions. + However, no additional obligations are imposed on any author or copyright + holder as a result of your choosing to follow a later version. + 15. Disclaimer of Warranty. + . + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE + LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR + OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, + EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. + SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY + SERVICING, REPAIR OR CORRECTION. + 16. Limitation of Liability. + . + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL + ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE + PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY + GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE + OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA + OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD + PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), + EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGES. + 17. Interpretation of Sections 15 and 16. + . + If the disclaimer of warranty and limitation of liability provided above + cannot be given local legal effect according to their terms, reviewing + courts shall apply local law that most closely approximates an absolute + waiver of all civil liability in connection with the Program, unless a + warranty or assumption of liability accompanies a copy of the Program in + return for a fee. \ No newline at end of file diff --git a/Resources/Debian/pkg/DEBIAN/rules b/Resources/Debian/pkg/DEBIAN/rules new file mode 100755 index 0000000000000000000000000000000000000000..7903e6f86e772cbcd0b480b198a49be5443852f4 --- /dev/null +++ b/Resources/Debian/pkg/DEBIAN/rules @@ -0,0 +1,17 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#DH_VERBOSE = 1 + +# see FEATURE AREAS in dpkg-buildflags(1) +#export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# see ENVIRONMENT in dpkg-buildflags(1) +# package maintainers to append CFLAGS +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +# package maintainers to append LDFLAGS +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + + +%: + dh $@ \ No newline at end of file diff --git a/Resources/Debian/pkg/usr/local/bin/.gitkeep b/Resources/Debian/pkg/usr/local/bin/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Resources/macApp/Signing/entitlements.plist b/Resources/macOS/Signing/entitlements.plist similarity index 100% rename from Resources/macApp/Signing/entitlements.plist rename to Resources/macOS/Signing/entitlements.plist diff --git a/Wiki/0-Dojo-presentation.md b/Wiki/0-Dojo-presentation.md new file mode 100644 index 0000000000000000000000000000000000000000..6b57243843561093f1e74debe2fcfc426fb7ba16 --- /dev/null +++ b/Wiki/0-Dojo-presentation.md @@ -0,0 +1,37 @@ +# Dojo: a platform to practice programming + +The dojo platform is an online tool built to help practice programming by +allowing users to propose assignments and perform them as exercises. + +The tool is very flexible and allows for proposing exercises for any language +and does not impose any limitation on a framework to be heavily relying +on Docker and Gitlab. These tools used in combination allow for automatic +correction of assignments in order to give immediate feedback to users +performing exercises. Solved exercises can then be shared among the community +of users such that they can inspire other users or give hints on ways to solve +a given exercise. + +The two major concepts of the platform are the **assignments** and the **exercises**. + +The principal way to interact with the Dojo platform is currently the `dojo` CLI. + +## The assignment + +An assignment is written by a user that wants to propose an exercise. It is typically composed of a written description of the work to be performed, +and tests that must be passed once the exercise is successfully performed (and some configuration files for the infrastructure of the tests +such as docker files). At its core, an assignment is +nothing else than a git repository that can be forked in the form of an exercise and modified using standard git commands. +For a more detailed description please see the [CLI documentation](home). +An assignment can be proposed by any user. + +In the future a dependency tree of assignments can be created, as well as tagging for filtering purposes. + +## The exercise + +An exercise is an instance of an assignment which the learner will modify in order to make it pass the automatic tests. +It can be run locally on any user's machine using the dojo CLI. When the exercise is completed +it is pushed on the dojo where the CI/CD tools of Gitlab can evaluate it automatically and +notify the dojo platform of the result. The exercises can then be shared with other users +in order to propose a wide variety of solutions and can be a base for discussion among users +and with teachers. +For a more detailed description please see the [CLI documentation](home). \ No newline at end of file diff --git a/Wiki/Tutorials/0-Exercise-perform.md b/Wiki/Tutorials/0-Exercise-perform.md new file mode 100644 index 0000000000000000000000000000000000000000..e2ca1b442ba52137db823f1bd62b38b6a31ab1c0 --- /dev/null +++ b/Wiki/Tutorials/0-Exercise-perform.md @@ -0,0 +1,154 @@ +# How to perform an exercise + +In this tutorial we quickly explain the workflow for performing an exercise by a student (or a professor). +The exercise is based on the `c_hello_world` assignment created in [assignment creation](1-Assignment-creation) tutorial. + +## Exercise "creation" + +To perform an exercise the student must first create the exercise. Under the hood, this operation consist in making +a fork of a published assignment in the student's namespace. + +This is performed by the following `dojo` command: +```bash +$ dojo exercise create --assignment c_hello_world +``` +```console +Please wait while we verify and retrieve data... +βΉ Checking Dojo session: + β The session is valid + β Student permissions +βΉ Checking Gitlab token: + β Read access + β Write access +βΉ Checking assignment: + β Assignment "c_hello_world" exists + β Assignment "c_hello_world" is published +Please wait while we are creating the exercise... +β Exercise successfully created + βΉ Id: 8d3f53a0-0d32-4455-a251-e1a1c5a97c6a + βΉ Name: DojoEx - c_hello_world - orestis.malaspin - 1 + βΉ Web URL: https://gitedu.hesge.ch/dojo/exercise/dojo-ex_c_hello_world_8d3f53a0-0d32-4455-a251-e1a1c5a97c6a + βΉ HTTP Repo: https://gitedu.hesge.ch/dojo/exercise/dojo-ex_c_hello_world_8d3f53a0-0d32-4455-a251-e1a1c5a97c6a.git + βΉ SSH Repo: ssh://git@ssh.hesge.ch:10572/dojo/exercise/dojo-ex_c_hello_world_8d3f53a0-0d32-4455-a251-e1a1c5a97c6a.git +``` + +## To perform the exercise + +The exercise is nothing else than a git repository so the workflow is pretty straightforward. + +1. Clone the repository (see the repo link above) +```bash +$ git clone ssh://git@ssh.hesge.ch:10572/dojo/exercise/dojo-ex_c_hello_world_8d3f53a0-0d32-4455-a251-e1a1c5a97c6a.git +``` +```console +Cloning into 'dojo-ex_c_hello_world_8d3f53a0-0d32-4455-a251-e1a1c5a97c6a'... +remote: Enumerating objects: 33, done. +remote: Counting objects: 100% (33/33), done. +remote: Compressing objects: 100% (26/26), done. +remote: Total 33 (delta 6), reused 16 (delta 3), pack-reused 0 +Receiving objects: 100% (33/33), 7.32 KiB | 7.32 MiB/s, done. +Resolving deltas: 100% (6/6), done. +``` +2. Read the `README.md` file to understand what is expected by the teacher. +3. Modify/create the appropriate code. +4. (Optional but recommended) Execute the pipeline locally +```bash +$ dojo exercise run +``` +```console +Please wait while we are checking and creating dependencies... + βΉ Checking exercise content: + β The exercise folder contains all the needed files + β The dojo_assignment.json file is valid + β The Docker deamon is running +Please wait while we are running the exercise... + β Docker Compose file run successfully + β Linked services logs acquired + β Containers stopped and removed +Please wait while we are checking the results... + β Results file found + β Results file is valid + β Results folder size is in bounds + + ββββββββββββββββββββββββββββββββββββββββββββββ Results βββββββββββββββββββββββββββββββββββββββββββββββ + β β + β Global result : β Failure β + β β + β Execution exit code : 0 β + β β + β Execution results folder : /home/student/DojoExecutions/dojo_execLogs_2023-08-30T18_58_05_764Z β + β β + ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ +``` +Currently the exercise is a failure which is sad but expected since there was no modification in any file. +One can see that we have access to a `results` folder in `/home/student/DojoExecutions/dojo_execLogs_2023-08-30T18_58_05_764Z`. +This directory contains the output of the pipeline execution +```console +/home/student/DojoExecutions/dojo_execLogs_2023-08-30T18_58_05_764Z +βββ Dojo +β βββ dockerComposeLogs.txt +β βββ results.json +βββ Exercise + βββ diff_output.txt + +2 directories, 3 files +``` +In particular one can find the output the teacher wanted us (students) to see in the `Exercise` folder. +It contains any output file that can be used for debugging for example. In this case it contains +```console +< ./hello_world +< (null) +\ No newline at end of file +--- +> Hello world! +\ No newline at end of file +``` +One can see that there is an `Hello world!` expected and that no `Hello world!` was provided by our program. +One can also see the complete +logs of the `docker compose` command in `Dojo/dockerComposeLogs.txt` which may (or may not) +provide additional informations. + +In order to complete this assignment we have to modify the `src/function.c` file such that it becomes +```c +#include "function.h" + +char *hello_world() +{ + return "Hello world!"; +} +``` +Rerunning the pipeline now yields +```bash +$ dojo exercise run +``` +```console +Please wait while we are checking and creating dependencies... + βΉ Checking exercise content: + β The exercise folder contains all the needed files + β The dojo_assignment.json file is valid + β The Docker deamon is running +Please wait while we are running the exercise... + β Docker Compose file run successfully + β Linked services logs acquired + β Containers stopped and removed +Please wait while we are checking the results... + β Results file found + β Results file is valid + β Results folder size is in bounds + + ββββββββββββββββββββββββββββββββββββββββββββββ Results βββββββββββββββββββββββββββββββββββββββββββββββ + β β + β Global result : β Success β + β β + β Execution exit code : 0 β + β β + β Execution results folder : /home/student/DojoExecutions/dojo_execLogs_2023-08-30T19_20_25_104Z β + β β + ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ +``` +5. Now that we are happy with the state of our exercise, we can commit and push our modifications and +the exercise will be run through the Gitlab CI pipeline and one can see the "official" result +of our exercise. + +It is not necessary to have a successful pipeline to commit and push the code. We can do it at any time +which is particularly useful when doing long assignments that take many iterations to finish. diff --git a/Wiki/Tutorials/1-Assignment-creation.md b/Wiki/Tutorials/1-Assignment-creation.md new file mode 100644 index 0000000000000000000000000000000000000000..16441292665f46c699b6d6fb419dd9129f430504 --- /dev/null +++ b/Wiki/Tutorials/1-Assignment-creation.md @@ -0,0 +1,414 @@ +# How to create an assignment + +We will describe how to create a very simple assignment with dojo. + +Here we will build a `Hello world!` in the C programming language. We will describe how one must +modify the default template to have an exercise. + +The exercise will be to fill a function to return the `Hello world!` string. +The output of the function will be printed on the standard output. +The structure will be provided to the students as well as a very simple `Makefile` +to compile and run the code. + +The success or failure of this assignment will be tested by comparing the output +of our program with an the expected output (the famous `Hello world!`). + +To build this exercise we need to perform several steps that will be described below in great details. + +## Empty assignment creation + +First create a new assignment with the command +```bash +$ dojo assignment create --name c_hello_world +``` +```console +Please wait while we verify and retrieve data... +βΉ Checking Dojo session: + β The session is valid + β Teaching staff permissions +βΉ Checking Gitlab token: + β Read access + β Write access +β Assignment name "c_hello_world" is available +Please wait while we are creating the assignment... +β Assignment successfully created + βΉ Name: c_hello_world + βΉ Web URL: https://gitedu.hesge.ch/dojo/assignment/c_hello_world + βΉ HTTP Repo: https://gitedu.hesge.ch/dojo/assignment/c_hello_world.git + βΉ SSH Repo: ssh://git@ssh.hesge.ch:10572/dojo/assignment/c_hello_world.git +``` + +## Clone the assignment locally + +The assignment is nothing more than a git repository. We just clone it and start +modifying it +```bash +$ git clone ssh://git@ssh.hesge.ch:10572/dojo/assignment/c_hello_world.git +``` +```console +Cloning into 'c_hello_world'... +remote: Enumerating objects: 18, done. +remote: Counting objects: 100% (18/18), done. +remote: Compressing objects: 100% (12/12), done. +remote: Total 18 (delta 3), reused 18 (delta 3), pack-reused 0 +Receiving objects: 100% (18/18), 4.37 KiB | 4.37 MiB/s, done. +Resolving deltas: 100% (3/3), done. +``` +The `c_hello_world` assignment has now the following structure +```bash +$ tree c_hello_world/ +``` +```console +c_hello_world/ +βββ docker-compose.yml +βββ Dockerfile +βββ dojo.assignment +βββ README.md +``` + +## Build the development environment + +In order to execute a C program we need a working compiler and `make`. In order to +produce a special result file to be parsed by the `dojo` tool to produce nicely formatted output +we will use `jq`, a command-line json creation/edition/reding tool. Our `Dockerfile` +contains +```dockerfile +FROM ubuntu:latest +RUN apt update && apt install gcc make jq -y +COPY . / +ENTRYPOINT ["./run.sh"] +``` +We see that we start by installing the required packages on top of the latest Ubuntu image. +We then proceed to copy the complete assignment into the docker container, finall we run +a yet to be created `run.sh` script. + +We can test our `Dockerfile` by running the command +```bash +$ docker compose run --build hello_world +``` +```console +[+] Building 20.5s (8/8) FINISHED + => [hello_world internal] load build definition from Dockerfile + => => transferring dockerfile: 134B + => [hello_world internal] load .dockerignore + => => transferring context: 2B + => [hello_world internal] load metadata for docker.io/library/ubuntu:latest + => CACHED [hello_world 1/3] FROM docker.io/library/ubuntu:latest@sha256:ec050c32e4a6085b423d36ecd025c0d3ff00c38ab93a3d71a460ff1c44fa6d77 + => [hello_world internal] load build context + => => transferring context: 39.87kB + => [hello_world 2/3] RUN apt update && apt install gcc make jq -y + => [hello_world 3/3] COPY . / + => [hello_world] exporting to image + => => exporting layers + => => writing image sha256:4b561113c7123da08206a2cf2642cb4f331670fe44350646437eaa78e44aff3a + => => naming to docker.io/library/c_hello_world-hello_world +ERRO[0021] error waiting for container: +Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "./run.sh": stat ./run.sh: no such file or directory: unknown +``` +We see an error at the end of the command which is perfectly normal. We did not create the `run.sh` file et (let's leave that for later). + +We then need to focus on the `docker-compose.yml` file which will take care of all the hard work +needed if complex workflows are required. Here it is as simple as possible and should contain +```yml +services: + hello_world: + container_name: hello_world + build: + context: ./ + dockerfile: Dockerfile + volumes: + - hello_world_volume:/result # <hello_world_volume> must be the same as below but + # the name may be arbitrary. This volume must be + # present in the dojo_assignment.json file under the field + # "result": { + # "volume": "hello_world_volume", + # ... + # } +volumes: + hello_world_volume: +``` +In this file, we see the definition of a `hello_world_volume` this is an arbitrary name and can be changed but it +must be coherent in this file and in the `dojo_assignment.json` file (more on this later configuration file in [The dojo configuration file](#the-dojo-configuration-file)). +This volume is responsible of mounting `/result/` directory which will contain all +the output generated by our assignment (again the name can be changed). In particular +in this director e will be required to create a `dojo_assignment.json` file +that contains at least if the assignment was successfully performed (more on that at the end of the [Creating the assignment files](#creating-the-assignment-files) section). + +## The dojo configuration file + +The `dojo_assignment.json` file contains the general configuration of the assignment. +The important configuration parameters are: +- the *immutable files* which are files that will be overwritten when the compilation pipeline is run (even if the student +modifies these files the modifications will not be taken into account), +- the *results* which is the volume corresponding to the `docker-compose.yml` file. + +In its default form `dojo_assignment.json` file contains +```json +{ + "dojoAssignmentVersion": 1, + "version": 1, + "immutable": [ + { + "description": "Dockerfile of the unique container", + "path": "Dockerfile", + "isDirectory": false + } + ], + "result": { + "container": "hello_world", + "volume": "hello_world_volume" + } +} +``` +Here we see only one immutable file which is the `Dockerfile` (the `isDirectory` field is `false` but it is possible to make +complete directories immutable) and we see that: +* the value of the `container` field (`hello_world`) corresponds to +the value of the `container_name` field in the `docker-compose.yml` file, +* the value of the `volume` field (`hello_world_volume`) corresponds to the `volumes` field in the `docker-compose.yml` file. + +This file will be completed in [The immutable files](#the-immutable-files) sectino with the files of our assignment that will be +created in the [next section](#creating-the-assignment-files). + +## Creating the assignment files + +For this assignment we will create the following files with the following content: + +- `src/Makefile` +```makefile +CC:=gcc +CFLAGS:=-Wall -Wextra -Wpedantic -fsanitize=address -Werror -g +LDFLAGS:=-fsanitize=address + +hello_world: hello_world.o function.o + gcc -o $@ $^ $(LDFLAGS) + +hello_world.o: function.h + +function.o: function.h + +run: hello_world + ./hello_world + +clean: + rm -f *.o hello_world +``` +- `src/hello_world.c` +```c +#include <stdio.h> +#include <stdlib.h> +#include "function.h" + +int main() +{ + printf("%s", hello_world()); + return EXIT_SUCCESS; +} +``` +- `src/function.h` +```c +#ifndef _FUNCTION_H_ +#define _FUNCTION_H_ + +char *hello_world(); + +#endif +``` +- `src/function.c` +```c +#include "function.h" + +char *hello_world() +{ + // TODO: Replace 0 here to return "Hello world!" + return 0; +} +``` +- `src/expected_output.txt` +``` +Hello world! +``` + +These files will be used to create an executable that will be run by the custom execution script, `run.sh`, see the `Dockerfile` in +the [Build the environment](#build-the-development-environment) section. + +All these files have arbitrary names and it's completely up to the teacher to make a coherent exercise. + +The only missing file is `run.sh` (do not forget to make it executable, `chmod +x run.sh`) that contains the following code +```bash +#!/bin/bash + +echo "Starting tests." + +GLOBAL_SUCCESS=false + +make -C src clean -s +make -C src -s +if [ $? -eq 0 ]; then + make run -C src > src/output.txt -s + if [ $? -eq 0 ]; then + diff --color src/output.txt src/expected_output.txt > result/diff_output.txt + if [ $? -ne 0 ]; then + echo "Output is wrong:"; + cat result/diff_output.txt + else + echo "All tests were a complete success" + GLOBAL_SUCCESS=true + fi + + else + echo "Execution failed"; + fi +else + echo "Compilation failed." +fi + +jq --null-input --arg success $GLOBAL_SUCCESS \ + '{"success": $success | test("true")}' > /result/results.json +``` +Here one can see the creation of two different files that are located in the `result` directory: +- `result/results.json` +- `result/diff_output.txt` +The `results.json` is mandatory to be created and must at least contain the +`success` field must be `true` or `false` and determines whether the +assignment is a success or a failure. The other files present in the `result` folder +can be retrieved by the students. + +To test if everything works according to plan, one can again use the command +```bash +$ docker compose run --build hello_world +``` +```console +[+] Building 1.8s (8/8) FINISHED + => [hello_world internal] load build definition from Dockerfile + => => transferring dockerfile: 134B + => [hello_world internal] load .dockerignore + => => transferring context: 2B + => [hello_world internal] load metadata for docker.io/library/ubuntu:latest + => [hello_world 1/3] FROM docker.io/library/ubuntu:latest@sha256:ec050c32e4a6085b423d36ecd025c0d3ff00c38ab93 + => [hello_world internal] load build context + => => transferring context: 3.23kB + => CACHED [hello_world 2/3] RUN apt update && apt install gcc make jq -y + => [hello_world 3/3] COPY . / + => [hello_world] exporting to image + => => exporting layers + => => writing image sha256:5499aa3aa0b2f2021584dbf46b4b05ab83dc0a5ad4d6c81a3466c56673c3f562 + => => naming to docker.io/library/c_hello_world-hello_world +Starting tests. +Output is wrong: +1c1 +< (null) +\ No newline at end of file +--- +> Hello world! +\ No newline at end of file +``` +where we see that the execution fails. This will be improved in the future and the actual execution as expected to be +run by the students will be added. + +## The immutable files + +There is only one file that should be modified by the students in this example: the `function.c` file. Therefore we can safely +add all the created files in the `src` except `src/function.c` which is precisely +the file that the student must modify, as well as the `run.sh` file. The `dojo_assignment.json` file becomes +```json +{ + "dojoAssignmentVersion": 1, + "version": 1, + "immutable": [ + { + "description": "Dockerfile of the unique container", + "path": "Dockerfile", + "isDirectory": false + }, + { + "description": "The entry point of the Dockerfile", + "path": "run.sh", + "isDirectory": false + }, + { + "description": "The makefile for compilation/execution purposes", + "path": "src/Makefile", + "isDirectory": false + }, + { + "description": "Entry point of the code", + "path": "src/hello_world.c", + "isDirectory": false + }, + { + "description": "The header file fot the program's assignment", + "path": "src/function.h", + "isDirectory": false + }, + { + "description": "The expected output file for comparing with the actual output", + "path": "src/expected_output.txt", + "isDirectory": false + } + ], + "result": { + "container": "hello_world", + "volume": "hello_world_volume" + } +} +``` + +## The `README.md` file + +The `README.md` file is used to provide informations on the assignment and the way the teacher wants students to accomplish +the assignment and its content is completely free. It is recommended to use the `Markdown` syntax as the +file extension suggests. + +In this assignment the `README.md` file reads +```markdown +# Hello world! + +C'est le premier vrai exercice jamais créé sur le Dojo! + +Il sert de tutoriel pour crΓ©er un exercice simple en C. + +## But + +Le but est de faire afficher "Hello world!" Γ notre programme en C. + +Pour ce faire, il faut modifier le fichier `src/function.c` sous la ligne +annotΓ©e avec `TODO`. Bonne chance! +``` + +## Publish the work + +Now that the assignment is ready, we must publish it. First add/commit/push all the +files needed for your exercise. In this case, it should be: +```console +c_hello_world/ +βββ docker-compose.yml +βββ Dockerfile +βββ dojo_assignment.json +βββ README.md +βββ run.sh +βββ src + βββ expected_output.txt + βββ function.c + βββ function.h + βββ hello_world.c + βββ Makefile +``` +Then one must *publish* the assignment for the students to be able to perform to get the exercise. + +```bash +$ dojo assignment publish c_hello_world +``` +```console +? Are you sure you want to publish this assignment? Yes +Please wait while we verify and retrieve data... +βΉ Checking Dojo session: + β The session is valid +βΉ Checking assignment: + βΉ c_hello_world + β The assignment exists + β You are in the staff of this assignment +Please wait while we publish the assignment... +β Assignment c_hello_world successfully published +``` + +The assignment is now ready to be performed by students! diff --git a/Wiki/UserDocumentation/0-Installation.md b/Wiki/UserDocumentation/0-Installation.md new file mode 100644 index 0000000000000000000000000000000000000000..da20cbbb4580d83e64ec251bdef712c5cddecb32 --- /dev/null +++ b/Wiki/UserDocumentation/0-Installation.md @@ -0,0 +1,38 @@ +# Installation of the Dojo CLI + +1. Download the latest stable version (without "-dev" suffix) from the releases: <https://gitedu.hesge.ch/dojo_project/projects/ui/dojocli/-/releases> + + + +1. Download the executable corresponding to your OS and architecture. + - βΉοΈ For these OS you can use specific packaged release that install the binary at the right place (so you can ignore the next point). + - **Debian / Ubuntu** : You can use the `deb` package named `Debian / Ubuntu (YOUR_ARCH) package`. + - **macOS**: You can use the `pkg` version named `macOS (YOUR_ARCH) package`. + +2. Put it in your path. For + - For exemple: + - βΉοΈ **Linux**: `$HOME/.local/bin` + - βΉοΈ **macOS**: `/usr/local/bin` + +3. Verify your installation is working correctly by calling the `dojo` CLI. +```bash +dojo +``` +```console +Usage: dojo [options] [command] + +CLI of the Dojo application + +Options: + -h, --help display help for command + -H, --host <string> override the Dojo API endpoint (default: "https://rdps.hesge.ch/dojo/api") + -V, --version output the version number + +Commands: + assignment manage an assignment + exercise manage an exercise + help [command] display help for command + session manage Dojo and Gitlab sessions +``` + +As you can see calling the `dojo` command shows the help menu. \ No newline at end of file diff --git a/Wiki/UserDocumentation/1-Authentification.md b/Wiki/UserDocumentation/1-Authentification.md new file mode 100644 index 0000000000000000000000000000000000000000..8b1f285d7df035ef9c8eb78da4dba8f26708d69b --- /dev/null +++ b/Wiki/UserDocumentation/1-Authentification.md @@ -0,0 +1,49 @@ +# Authentication to the Dojo + +The authentication is done in two steps: login into the dojo app and into https://gitedu.hesge.ch (through an API token). + +1. Login into the dojo application: +```bash +dojo session application login --user <email> +``` +```console +? Please enter your password [hidden] +Please wait while we are logging in you to Dojo... +β Logged in + β Teaching staff permissions + β Student permissions +``` + +2. Register the API token (see below) for Gitlab +```bash +dojo session gitlab login <token> +``` +```console +Please wait while we are testing your Gitlab token... +βΉ Checking Gitlab token: + β Read access + β Write access +``` +The API token can be created by (see <https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html> for more informations): + +- Logging into <https://gitedu.hesge.ch> +- **Preferences -> Access Tokens** +- Give a name to your token and a validity +- Tick the **api** box +- Click the **Create personal access token** + +3. Test if it is working +```bash +dojo session test +``` +```console +βΉ Checking Dojo session: + β The session is valid + β Teaching staff permissions + β Student permissions +βΉ Checking Gitlab token: + β Read access + β Write access +``` + +Good news. You can use the Dojo! diff --git a/Wiki/UserDocumentation/2-Assignment-creation.md b/Wiki/UserDocumentation/2-Assignment-creation.md new file mode 100644 index 0000000000000000000000000000000000000000..15c7392aaaa51cc1a762e9c2e0600ecf4577ae1d --- /dev/null +++ b/Wiki/UserDocumentation/2-Assignment-creation.md @@ -0,0 +1,66 @@ +# Assignment creation + +The assignment is created by a member of the teaching staff and is the basis for students to perform their exercise. + +1. To create an assignment +```bash +dojo assignment create --name <unique_name> +``` +```console +Please wait while we verify and retrieve data... +βΉ Checking Dojo session: + β The session is valid + β Teaching staff permissions +βΉ Checking Gitlab token: + β Read access + β Write access +β Assignment name "unique_name" is available +Please wait while we are creating the assignment... +β Assignment successfully created + βΉ Name: unique_name + βΉ Web URL: https://gitedu.hesge.ch/dojo/assignment/unique_name + βΉ HTTP Repo: https://gitedu.hesge.ch/dojo/assignment/unique_name.git + βΉ SSH Repo: ssh://git@ssh.hesge.ch:10572/dojo/assignment/unique_name.git +``` +where `<unique_name>` is the name of the assignment. By default only the creator of the exercise is added to +the assignment (which is just a git repository with some configuration files in it). +There are several other options that can be provided: +```bash +dojo assignment create --name <unique_name> --template <url> +``` +where `<url>` is the url of the template repository one may want to use as a basis for the assignment- +```bash +dojo assignment create --name <unique_name> --members_username <usernames> +``` +where `<usernames>` is a list of gitedu usernames that will be given the same permissions as the +user creating the assignment. + +As usual one can show the help menu by typing +```bash +dojo assignment create --help +``` +Or you may just enter (`--help` is implicit in most commands) +```bash +dojo assignment create +``` +2. Clone the repository of the assignment that was just created: +```bash +git clone ssh://git@ssh.hesge.ch:10572/dojo/assignment/unique_name.git +``` +3. Modify the `unique_name` assignment as you want (modify the Dockerfile, docker-compose.yml files, add a readme, source code, compilation tools, etc.). Commit and push our work (soonβ’ more details will be provided on how to create assignment). +4. Once the assignment is done it must be published to be available to students: +```bash +dojo assignment publish unique_name +``` +```console +? Are you sure you want to publish this assignment? Yes +Please wait while we verify and retrieve data... +βΉ Checking Dojo session: + β The session is valid +βΉ Checking assignment: + βΉ unique_name + β The assignment exists + β You are in the staff of this assignment +Please wait while we publish the assignment... +β Assignment unique_name successfully published +``` \ No newline at end of file diff --git a/Wiki/UserDocumentation/3-Exercise-creation.md b/Wiki/UserDocumentation/3-Exercise-creation.md new file mode 100644 index 0000000000000000000000000000000000000000..29817fb37e5441833e1c0da61b9f41557d6d0c2e --- /dev/null +++ b/Wiki/UserDocumentation/3-Exercise-creation.md @@ -0,0 +1,74 @@ +# Exercise creation + +The exercise is an instance of a **published assignment** to be performed by students (or group of students). + +1. Create an exercise +```bash +dojo exercise create --assignment unique_name +``` +```console +Please wait while we verify and retrieve data... +βΉ Checking Dojo session: + β The session is valid + β Student permissions +βΉ Checking Gitlab token: + β Read access + β Write access +βΉ Checking assignment: + β Assignment "unique_name" exists + β Assignment "unique_name" is published +Please wait while we are creating the exercise... +β Exercise successfully created + βΉ Id: some-long-hash + βΉ Name: DojoEx - unique_name - your.name + βΉ Web URL: https://gitedu.hesge.ch/dojo/exercise/dojo-ex_unique_name_some-long-hash + βΉ HTTP Repo: https://gitedu.hesge.ch/dojo/exercise/dojo-ex_unique_name_some-long-hash.git + βΉ SSH Repo: ssh://git@ssh.hesge.ch:10572/dojo/exercise/dojo-ex_unique_name_some-long-hash.git +``` +**Tips**: You cas use the --members_username or --members_id options to add other students of the group to the exercise. +2. Make changes and try solving the exercise. +3. The complete tests can be run with the following command. +```bash +dojo exercise run +``` +```console +Please wait while we are checking and creating dependencies... + βΉ Checking exercise content: + β The exercise folder contains all the needed files + β The dojo_assignment.json file is valid + β The Docker deamon is running +Please wait while we are running the exercise... + β Docker Compose file run successfully + β Linked services logs acquired + β Containers stopped and removed +Please wait while we are checking the results... + β Results file found + β Results file is valid + β Results folder size is in bounds + + ββββββββββββββββββββββββββββββββββββββββββββββ Results βββββββββββββββββββββββββββββββββββββββββββββββ + β β + β Global result : β Success β + β β + β Execution exit code : 0 β + β β + β Tests passed : 3 β + β Tests failed : 1 β + β β + β Tests : β + β - β ListeOrdonnee β + β - β ListeVide β + β - β ListeOrdreInverse β + β - β ListeRandom β + β β + β Execution results folder : /home/username/DojoExecutions/dojo_execLogs_2023-08-21T21_33_38_684Z β + β β + ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ +``` +This command runs the exercise in the current directory or in the path provided by the `--path` option. + +4. Once confident enough in the solution, one can commit/push the solution. +This triggers the CI/CD pipeline on gitedu. In the CI/CD all immutable files are overwritten and +the docker-compose is executed (only logs from the current container are given) then other logs +are retrieved from the other images that may be used. The error code of the docker container is retrieved. + diff --git a/Wiki/figures/releases.png b/Wiki/figures/releases.png new file mode 100644 index 0000000000000000000000000000000000000000..8950a930ee305be9aeb50317502a57d90ce2d853 Binary files /dev/null and b/Wiki/figures/releases.png differ diff --git a/Wiki/home.md b/Wiki/home.md new file mode 100644 index 0000000000000000000000000000000000000000..90b298e88fc361293cfa24c148149689e3cd9fa6 --- /dev/null +++ b/Wiki/home.md @@ -0,0 +1,25 @@ +# Documentation of the `dojo` CLI utility + +In this wiki you will find the documentation related to the `dojo` CLI. + +## Dojo Project +The dojo platform is an online tool built to help practice programming by allowing users to propose assignments and perform them as exercises. + +The two major concepts of the platform are the **assignments** (provided by teaching staff) and the **exercises** (performed by students). + +More details here : [Dojo detailed presentation](0-Dojo-presentation) + +## User documentation + +* [Installation of the CLI](UserDocumentation/0-Installation) +* [Authentification](UserDocumentation/1-Authentification) +* [Assignment creation](UserDocumentation/2-Assignment-creation) +* [Exercice creation](UserDocumentation/3-Exercise-creation) + +## Tutorials / Exemples + +### Students / Everyone +* [How to perform an exercise](Tutorials/0-Exercise-perform) + +### Teaching staff +* [How to create and publish an assignment](Tutorials/1-Assignment-creation)