diff --git a/.circleci/config.yml b/.circleci/config.yml index 99e73e2..80a1558 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,9 +7,9 @@ version: 2.1 # Orbs used in this pipeline ## orbs: - slack: circleci/slack@4.12.5 # Ref: https://github.com/mojaloop/ci-config/tree/master/slack-templates - pr-tools: mojaloop/pr-tools@0.1.10 # Ref: https://github.com/mojaloop/ci-config/ - gh: circleci/github-cli@2.2.0 + slack: circleci/slack@4.12.5 # Ref: https://github.com/mojaloop/ci-config/tree/master/slack-templates + pr-tools: mojaloop/pr-tools@0.1.10 # Ref: https://github.com/mojaloop/ci-config/ + gh: circleci/github-cli@2.2.0 ## # defaults @@ -29,91 +29,90 @@ defaults_awsCliDependencies: &defaults_awsCliDependencies | apk --no-cache add aws-cli defaults_license_scanner: &defaults_license_scanner - name: Install and set up license-scanner - command: | - git clone https://github.com/mojaloop/license-scanner /tmp/license-scanner - cd /tmp/license-scanner && make build default-files set-up + name: Install and set up license-scanner + command: | + git clone https://github.com/mojaloop/license-scanner /tmp/license-scanner + cd /tmp/license-scanner && make build default-files set-up defaults_npm_auth: &defaults_npm_auth - name: Update NPM registry auth token - command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc - + name: Update NPM registry auth token + command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc defaults_npm_publish_release: &defaults_npm_publish_release - name: Publish NPM $RELEASE_TAG artifact - command: | - source $BASH_ENV - echo "Publishing tag $RELEASE_TAG" - npm publish --tag $RELEASE_TAG --access public + name: Publish NPM $RELEASE_TAG artifact + command: | + source $BASH_ENV + echo "Publishing tag $RELEASE_TAG" + npm publish --tag $RELEASE_TAG --access public defaults_export_version_from_package: &defaults_export_version_from_package - name: Format the changelog into the github release body and get release tag - command: | - git diff --no-indent-heuristic master~1 HEAD CHANGELOG.md | sed -n '/^+[^+]/ s/^+//p' > /tmp/changes - echo 'export RELEASE_CHANGES=`cat /tmp/changes`' >> $BASH_ENV - echo 'export RELEASE_TAG=`cat package-lock.json | jq -r .version`' >> $BASH_ENV + name: Format the changelog into the github release body and get release tag + command: | + git diff --no-indent-heuristic master~1 HEAD CHANGELOG.md | sed -n '/^+[^+]/ s/^+//p' > /tmp/changes + echo 'export RELEASE_CHANGES=`cat /tmp/changes`' >> $BASH_ENV + echo 'export RELEASE_TAG=`cat package-lock.json | jq -r .version`' >> $BASH_ENV defaults_configure_git: &defaults_configure_git - name: Configure git - command: | - git config user.email ${GIT_CI_EMAIL} - git config user.name ${GIT_CI_USER} + name: Configure git + command: | + git config user.email ${GIT_CI_EMAIL} + git config user.name ${GIT_CI_USER} defaults_configure_nvm: &defaults_configure_nvm - name: Configure NVM - command: | - cd $HOME - - export ENV_DOT_PROFILE=$HOME/.profile - touch $ENV_DOT_PROFILE - - echo "1. Export env variable" - export NVM_DIR="$HOME/.nvm" - if [ -z "$NVMRC_VERSION" ]; then - echo "==> Configuring NVMRC_VERSION!" - export NVMRC_VERSION=$(cat $CIRCLE_WORKING_DIRECTORY/.nvmrc) - echo "export NVMRC_VERSION=$NVMRC_VERSION" >> $ENV_DOT_PROFILE - fi - - if [ -f "$NVM_DIR" ]; then - echo "==> $NVM_DIR exists. Skipping steps 2-4!" - else - echo "==> $NVM_DIR does not exists. Executing steps 2-4!" - - echo "2. Installing NVM" - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash - - echo "3. Executing $NVM_DIR/nvm.sh" - [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" - - # echo "4. Update $ENV_DOT_PROFILE" - # echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $ENV_DOT_PROFILE - # echo "export NVM_DIR=$NVM_DIR" >> $ENV_DOT_PROFILE - fi - - ## Ref: https://github.com/nvm-sh/nvm/issues/1102#issuecomment-550572252 - if [ ! -z "$NVM_ARCH_UNOFFICIAL_OVERRIDE" ]; then - echo "==> Handle NVM_ARCH_UNOFFICIAL_OVERRIDE=$NVM_ARCH_UNOFFICIAL_OVERRIDE!" - echo "nvm_get_arch() { nvm_echo \"${NVM_ARCH_UNOFFICIAL_OVERRIDE}\"; }" >> $ENV_DOT_PROFILE - echo "export NVM_NODEJS_ORG_MIRROR=https://unofficial-builds.nodejs.org/download/release" >> $ENV_DOT_PROFILE - source $ENV_DOT_PROFILE - fi - - echo "4. Installing Node version: $NVMRC_VERSION" - nvm install $NVMRC_VERSION - nvm alias default $NVMRC_VERSION - nvm use $NVMRC_VERSION - - cd $CIRCLE_WORKING_DIRECTORY + name: Configure NVM + command: | + cd $HOME + + export ENV_DOT_PROFILE=$HOME/.profile + touch $ENV_DOT_PROFILE + + echo "1. Export env variable" + export NVM_DIR="$HOME/.nvm" + if [ -z "$NVMRC_VERSION" ]; then + echo "==> Configuring NVMRC_VERSION!" + export NVMRC_VERSION=$(cat $CIRCLE_WORKING_DIRECTORY/.nvmrc) + echo "export NVMRC_VERSION=$NVMRC_VERSION" >> $ENV_DOT_PROFILE + fi + + if [ -f "$NVM_DIR" ]; then + echo "==> $NVM_DIR exists. Skipping steps 2-4!" + else + echo "==> $NVM_DIR does not exists. Executing steps 2-4!" + + echo "2. Installing NVM" + curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash + + echo "3. Executing $NVM_DIR/nvm.sh" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + + # echo "4. Update $ENV_DOT_PROFILE" + # echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $ENV_DOT_PROFILE + # echo "export NVM_DIR=$NVM_DIR" >> $ENV_DOT_PROFILE + fi + + ## Ref: https://github.com/nvm-sh/nvm/issues/1102#issuecomment-550572252 + if [ ! -z "$NVM_ARCH_UNOFFICIAL_OVERRIDE" ]; then + echo "==> Handle NVM_ARCH_UNOFFICIAL_OVERRIDE=$NVM_ARCH_UNOFFICIAL_OVERRIDE!" + echo "nvm_get_arch() { nvm_echo \"${NVM_ARCH_UNOFFICIAL_OVERRIDE}\"; }" >> $ENV_DOT_PROFILE + echo "export NVM_NODEJS_ORG_MIRROR=https://unofficial-builds.nodejs.org/download/release" >> $ENV_DOT_PROFILE + source $ENV_DOT_PROFILE + fi + + echo "4. Installing Node version: $NVMRC_VERSION" + nvm install $NVMRC_VERSION + nvm alias default $NVMRC_VERSION + nvm use $NVMRC_VERSION + + cd $CIRCLE_WORKING_DIRECTORY defaults_display_versions: &defaults_display_versions - name: Display Versions - command: | - echo "What is the active version of Nodejs?" - echo "node: $(node --version)" - echo "yarn: $(yarn --version)" - echo "npm: $(npm --version)" - echo "nvm: $(nvm --version)" + name: Display Versions + command: | + echo "What is the active version of Nodejs?" + echo "node: $(node --version)" + echo "yarn: $(yarn --version)" + echo "npm: $(npm --version)" + echo "nvm: $(nvm --version)" ## # Executors @@ -121,456 +120,477 @@ defaults_display_versions: &defaults_display_versions # CircleCI Executors ## executors: - default-docker: - working_directory: &WORKING_DIR /home/circleci/project - shell: "/bin/sh -leo pipefail" ## Ref: https://circleci.com/docs/env-vars/#alpine-linux - environment: - BASH_ENV: /etc/profile ## Ref: https://circleci.com/docs/env-vars/#alpine-linux - NVM_ARCH_UNOFFICIAL_OVERRIDE: x64-musl ## Ref: https://github.com/nvm-sh/nvm/issues/1102#issuecomment-550572252 - docker: - - image: node:lts-alpine # Ref: https://hub.docker.com/_/node?tab=tags&page=1&name=alpine - - default-machine: - working_directory: *WORKING_DIR - shell: "/bin/bash -leo pipefail" ## Ref: https://circleci.com/docs/env-vars/#alpine-linux - machine: - image: ubuntu-2204:2023.04.2 # Ref: https://circleci.com/developer/machine/image/ubuntu-2204 + default-docker: + working_directory: &WORKING_DIR /home/circleci/project + shell: "/bin/sh -leo pipefail" ## Ref: https://circleci.com/docs/env-vars/#alpine-linux + environment: + BASH_ENV: /etc/profile ## Ref: https://circleci.com/docs/env-vars/#alpine-linux + NVM_ARCH_UNOFFICIAL_OVERRIDE: x64-musl ## Ref: https://github.com/nvm-sh/nvm/issues/1102#issuecomment-550572252 + docker: + - image: node:lts-alpine # Ref: https://hub.docker.com/_/node?tab=tags&page=1&name=alpine + + default-machine: + working_directory: *WORKING_DIR + shell: "/bin/bash -leo pipefail" ## Ref: https://circleci.com/docs/env-vars/#alpine-linux + machine: + image: ubuntu-2204:2023.04.2 # Ref: https://circleci.com/developer/machine/image/ubuntu-2204 jobs: - setup: - executor: default-docker - steps: - - run: - name: Install general dependencies - command: *defaults_docker_Dependencies - - checkout - - run: - <<: *defaults_configure_nvm - - run: - <<: *defaults_display_versions - - run: - name: Update NPM install - command: npm ci - - save_cache: - key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} - paths: - - node_modules - - test-dependencies: - executor: default-docker - steps: - - run: - name: Install general dependencies - command: *defaults_docker_Dependencies - - checkout - - run: - <<: *defaults_configure_nvm - - run: - <<: *defaults_display_versions - - restore_cache: - key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} - - run: - name: Execute dependency tests - command: npm run dep:check - - test-lint: - executor: default-docker - steps: - - run: - name: Install general dependencies - command: *defaults_docker_Dependencies - - checkout - - run: - <<: *defaults_configure_nvm - - run: - <<: *defaults_display_versions - - restore_cache: - key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} - - run: - name: Execute lint tests - command: npm run lint - - test-unit: - executor: default-docker - steps: - - run: - name: Install general dependencies - command: *defaults_docker_Dependencies - - checkout - - run: - <<: *defaults_configure_nvm - - run: - <<: *defaults_display_versions - - restore_cache: - key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} - - run: - name: Create dir for test results - command: mkdir -p ./test/results - - run: - name: Execute unit tests - command: npm -s run test:xunit - - store_artifacts: - path: ./test/results - destination: test - - store_test_results: - path: ./test/results - - test-deprecations: - executor: default-docker - steps: - - run: - name: Checking if deprecated dependencies exist - command: node .circleci/deprecated-check.js - - test-coverage: - executor: default-docker - steps: - - run: - name: Install general dependencies - command: *defaults_docker_Dependencies - - run: - name: Install AWS CLI dependencies - command: *defaults_awsCliDependencies - - checkout - - run: - <<: *defaults_configure_nvm - - run: - <<: *defaults_display_versions - - restore_cache: - key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} - - run: - name: Execute code coverage check - command: npm -s run test:coverage-check - - store_artifacts: - path: coverage - destination: test - - store_test_results: - path: coverage - - vulnerability-check: - executor: default-docker - steps: - - run: - name: Install general dependencies - command: *defaults_docker_Dependencies - - checkout - - run: - <<: *defaults_configure_nvm - - run: - <<: *defaults_display_versions - - restore_cache: - key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} - - run: - name: Create dir for test results - command: mkdir -p ./audit/results - - run: - name: Check for new npm vulnerabilities - command: npm run audit:check --silent -- -o json > ./audit/results/auditResults.json - - store_artifacts: - path: ./audit/results - destination: audit - - audit-licenses: - executor: default-docker - steps: - - run: - name: Install general dependencies - command: *defaults_docker_Dependencies - - run: - <<: *defaults_display_versions - - run: - <<: *defaults_license_scanner - - checkout - - restore_cache: - key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} - - run: - name: Run the license-scanner - command: cd /tmp/license-scanner && pathToRepo=$CIRCLE_WORKING_DIRECTORY make run - - store_artifacts: - path: /tmp/license-scanner/results - destination: licenses - - release: - executor: default-docker - steps: - - run: - name: Install general dependencies - command: *defaults_docker_Dependencies - - checkout - - restore_cache: - keys: - - dependency-cache-{{ .Environment.CIRCLE_SHA1 }} - - run: - <<: *defaults_configure_git - - run: - name: Setup Slack config - command: | - echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV - echo "export SLACK_RELEASE_TYPE='GitHub Release'" >> $BASH_ENV - echo "export SLACK_RELEASE_TAG='${RELEASE_TAG} on ${CIRCLE_BRANCH} branch'" >> $BASH_ENV - echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV - echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV - - run: - name: Generate changelog and bump package version - command: npm run release -- --no-verify - - run: - name: Push the release - command: git push --follow-tags origin ${CIRCLE_BRANCH} - - slack/notify: - event: fail - template: SLACK_TEMP_RELEASE_FAILURE - - github-release: - executor: default-machine - shell: "/bin/bash -eo pipefail" - steps: - - run: - name: Install git - command: | - sudo apt-get update && sudo apt-get install -y git - - gh/install - - checkout - - run: - <<: *defaults_configure_git - - run: - name: Fetch updated release branch - command: | - git fetch origin - git checkout origin/${CIRCLE_BRANCH} - - run: - <<: *defaults_export_version_from_package - - run: - name: Check the release changes - command: | - echo "Changes are: ${RELEASE_CHANGES}" - - run: - name: Setup Slack config - command: | - echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV - echo "export SLACK_RELEASE_TYPE='Github Release'" >> $BASH_ENV - echo "export SLACK_RELEASE_TAG=v${RELEASE_TAG}" >> $BASH_ENV - echo "export SLACK_RELEASE_URL=https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/v${RELEASE_TAG}" >> $BASH_ENV - echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV - echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV - - run: - name: Create Release - command: | - gh release create "v${RELEASE_TAG}" --title "v${RELEASE_TAG} Release" --draft=false --notes "${RELEASE_CHANGES}" ./CHANGELOG.md - - slack/notify: - event: pass - template: SLACK_TEMP_RELEASE_SUCCESS - - slack/notify: - event: fail - template: SLACK_TEMP_RELEASE_FAILURE - - publish: - executor: default-docker - steps: - - run: - name: Install general dependencies - command: *defaults_docker_Dependencies - - checkout - - run: - name: Setup for LATEST release - command: | - echo "export RELEASE_TAG=$RELEASE_TAG_PROD" >> $BASH_ENV - echo "RELEASE_TAG=$RELEASE_TAG_PROD" - - PACKAGE_VERSION=$(cat package-lock.json | jq -r .version) - echo "export PACKAGE_VERSION=${PACKAGE_VERSION}" >> $BASH_ENV - echo "PACKAGE_VERSION=${PACKAGE_VERSION}" - - run: - name: Setup Slack config - command: | - echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV - echo "export SLACK_RELEASE_TYPE='NPM Release'" >> $BASH_ENV - echo "export SLACK_RELEASE_TAG=v${CIRCLE_TAG:1}" >> $BASH_ENV - echo "export SLACK_RELEASE_URL=https://www.npmjs.com/package/@mojaloop/${CIRCLE_PROJECT_REPONAME}/v/${CIRCLE_TAG:1}" >> $BASH_ENV - echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV - echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV - - run: - <<: *defaults_npm_auth - - run: - <<: *defaults_npm_publish_release - - slack/notify: - event: pass - template: SLACK_TEMP_RELEASE_SUCCESS - - slack/notify: - event: fail - template: SLACK_TEMP_RELEASE_FAILURE - - publish-snapshot: - executor: default-docker - steps: - - run: - name: Install general dependencies - command: *defaults_docker_Dependencies - - checkout - - run: - name: Setup for SNAPSHOT release - command: | - echo "export RELEASE_TAG=${RELEASE_TAG_SNAPSHOT}" >> $BASH_ENV - echo "RELEASE_TAG=${RELEASE_TAG_SNAPSHOT}" - - echo "Override package version: ${CIRCLE_TAG:1}" - npx standard-version --skip.tag --skip.commit --skip.changelog --release-as ${CIRCLE_TAG:1} - - PACKAGE_VERSION=$(cat package-lock.json | jq -r .version) - echo "export PACKAGE_VERSION=${PACKAGE_VERSION}" >> $BASH_ENV - echo "PACKAGE_VERSION=${PACKAGE_VERSION}" - - run: - name: Setup Slack config - command: | - echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV - echo "export SLACK_RELEASE_TYPE='NPM Snapshot'" >> $BASH_ENV - echo "export SLACK_RELEASE_TAG=v${CIRCLE_TAG:1}" >> $BASH_ENV - echo "export SLACK_RELEASE_URL=https://www.npmjs.com/package/@mojaloop/${CIRCLE_PROJECT_REPONAME}/v/${CIRCLE_TAG:1}" >> $BASH_ENV - echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV - echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV - - run: - <<: *defaults_npm_auth - - run: - <<: *defaults_npm_publish_release - - slack/notify: - event: pass - template: SLACK_TEMP_RELEASE_SUCCESS - - slack/notify: - event: fail - template: SLACK_TEMP_RELEASE_FAILURE + setup: + executor: default-docker + steps: + - run: + name: Install general dependencies + command: *defaults_docker_Dependencies + - checkout + - run: + <<: *defaults_configure_nvm + - run: + <<: *defaults_display_versions + - run: + name: Update NPM install + command: npm ci + - save_cache: + key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} + paths: + - node_modules + + test-dependencies: + executor: default-docker + steps: + - run: + name: Install general dependencies + command: *defaults_docker_Dependencies + - checkout + - run: + <<: *defaults_configure_nvm + - run: + <<: *defaults_display_versions + - restore_cache: + key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Execute dependency tests + command: npm run dep:check + + test-lint: + executor: default-docker + steps: + - run: + name: Install general dependencies + command: *defaults_docker_Dependencies + - checkout + - run: + <<: *defaults_configure_nvm + - run: + <<: *defaults_display_versions + - restore_cache: + key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Execute lint tests + command: npm run lint + + test-unit: + executor: default-docker + steps: + - run: + name: Install general dependencies + command: *defaults_docker_Dependencies + - checkout + - run: + <<: *defaults_configure_nvm + - run: + <<: *defaults_display_versions + - restore_cache: + key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Create dir for test results + command: mkdir -p ./test/results + - run: + name: Execute unit tests + command: npm -s run test:xunit + - store_artifacts: + path: ./test/results + destination: test + - store_test_results: + path: ./test/results + + test-deprecations: + executor: default-docker + steps: + - run: + name: Install general dependencies + command: *defaults_docker_Dependencies + - checkout + - run: + <<: *defaults_configure_nvm + - run: + <<: *defaults_display_versions + - restore_cache: + key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Checking if deprecated dependencies exist + command: node .circleci/deprecated-check.js + + test-coverage: + executor: default-docker + steps: + - run: + name: Install general dependencies + command: *defaults_docker_Dependencies + - run: + name: Install AWS CLI dependencies + command: *defaults_awsCliDependencies + - checkout + - run: + <<: *defaults_configure_nvm + - run: + <<: *defaults_display_versions + - restore_cache: + key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Execute code coverage check + command: npm -s run test:coverage-check + - store_artifacts: + path: coverage + destination: test + - store_test_results: + path: coverage + + vulnerability-check: + executor: default-docker + steps: + - run: + name: Install general dependencies + command: *defaults_docker_Dependencies + - checkout + - run: + <<: *defaults_configure_nvm + - run: + <<: *defaults_display_versions + - restore_cache: + key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Create dir for test results + command: mkdir -p ./audit/results + - run: + name: Check for new npm vulnerabilities + command: npm run audit:check --silent -- -o json > ./audit/results/auditResults.json + - store_artifacts: + path: ./audit/results + destination: audit + + audit-licenses: + executor: default-docker + steps: + - run: + name: Install general dependencies + command: *defaults_docker_Dependencies + - run: + <<: *defaults_display_versions + - run: + <<: *defaults_license_scanner + - checkout + - restore_cache: + key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Run the license-scanner + command: cd /tmp/license-scanner && pathToRepo=$CIRCLE_WORKING_DIRECTORY make run + - store_artifacts: + path: /tmp/license-scanner/results + destination: licenses + + release: + executor: default-docker + steps: + - run: + name: Install general dependencies + command: *defaults_docker_Dependencies + - checkout + - restore_cache: + keys: + - dependency-cache-{{ .Environment.CIRCLE_SHA1 }} + - run: + <<: *defaults_configure_git + - run: + name: Setup Slack config + command: | + echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV + echo "export SLACK_RELEASE_TYPE='GitHub Release'" >> $BASH_ENV + echo "export SLACK_RELEASE_TAG='${RELEASE_TAG} on ${CIRCLE_BRANCH} branch'" >> $BASH_ENV + echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV + echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV + - run: + name: Generate changelog and bump package version + command: npm run release -- --no-verify + - run: + name: Push the release + command: git push --follow-tags origin ${CIRCLE_BRANCH} + - slack/notify: + event: fail + template: SLACK_TEMP_RELEASE_FAILURE + + github-release: + executor: default-machine + shell: "/bin/bash -eo pipefail" + steps: + - run: + name: Install git + command: | + sudo apt-get update && sudo apt-get install -y git + - gh/install + - checkout + - run: + <<: *defaults_configure_git + - run: + name: Fetch updated release branch + command: | + git fetch origin + git checkout origin/${CIRCLE_BRANCH} + - run: + <<: *defaults_export_version_from_package + - run: + name: Check the release changes + command: | + echo "Changes are: ${RELEASE_CHANGES}" + - run: + name: Setup Slack config + command: | + echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV + echo "export SLACK_RELEASE_TYPE='Github Release'" >> $BASH_ENV + echo "export SLACK_RELEASE_TAG=v${RELEASE_TAG}" >> $BASH_ENV + echo "export SLACK_RELEASE_URL=https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/v${RELEASE_TAG}" >> $BASH_ENV + echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV + echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV + - run: + name: Create Release + command: | + gh release create "v${RELEASE_TAG}" --title "v${RELEASE_TAG} Release" --draft=false --notes "${RELEASE_CHANGES}" ./CHANGELOG.md + - slack/notify: + event: pass + template: SLACK_TEMP_RELEASE_SUCCESS + - slack/notify: + event: fail + template: SLACK_TEMP_RELEASE_FAILURE + + publish: + executor: default-docker + steps: + - run: + name: Install general dependencies + command: *defaults_docker_Dependencies + - checkout + - run: + name: Setup for LATEST release + command: | + echo "export RELEASE_TAG=$RELEASE_TAG_PROD" >> $BASH_ENV + echo "RELEASE_TAG=$RELEASE_TAG_PROD" + + PACKAGE_VERSION=$(cat package-lock.json | jq -r .version) + echo "export PACKAGE_VERSION=${PACKAGE_VERSION}" >> $BASH_ENV + echo "PACKAGE_VERSION=${PACKAGE_VERSION}" + - run: + name: Setup Slack config + command: | + echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV + echo "export SLACK_RELEASE_TYPE='NPM Release'" >> $BASH_ENV + echo "export SLACK_RELEASE_TAG=v${CIRCLE_TAG:1}" >> $BASH_ENV + echo "export SLACK_RELEASE_URL=https://www.npmjs.com/package/@mojaloop/${CIRCLE_PROJECT_REPONAME}/v/${CIRCLE_TAG:1}" >> $BASH_ENV + echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV + echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV + - run: + <<: *defaults_npm_auth + - run: + <<: *defaults_npm_publish_release + - slack/notify: + event: pass + template: SLACK_TEMP_RELEASE_SUCCESS + - slack/notify: + event: fail + template: SLACK_TEMP_RELEASE_FAILURE + + publish-snapshot: + executor: default-docker + steps: + - run: + name: Install general dependencies + command: *defaults_docker_Dependencies + - checkout + - run: + name: Setup for SNAPSHOT release + command: | + echo "export RELEASE_TAG=${RELEASE_TAG_SNAPSHOT}" >> $BASH_ENV + echo "RELEASE_TAG=${RELEASE_TAG_SNAPSHOT}" + + echo "Override package version: ${CIRCLE_TAG:1}" + npx standard-version --skip.tag --skip.commit --skip.changelog --release-as ${CIRCLE_TAG:1} + + PACKAGE_VERSION=$(cat package-lock.json | jq -r .version) + echo "export PACKAGE_VERSION=${PACKAGE_VERSION}" >> $BASH_ENV + echo "PACKAGE_VERSION=${PACKAGE_VERSION}" + - run: + name: Setup Slack config + command: | + echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV + echo "export SLACK_RELEASE_TYPE='NPM Snapshot'" >> $BASH_ENV + echo "export SLACK_RELEASE_TAG=v${CIRCLE_TAG:1}" >> $BASH_ENV + echo "export SLACK_RELEASE_URL=https://www.npmjs.com/package/@mojaloop/${CIRCLE_PROJECT_REPONAME}/v/${CIRCLE_TAG:1}" >> $BASH_ENV + echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV + echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV + - run: + <<: *defaults_npm_auth + - run: + <<: *defaults_npm_publish_release + - slack/notify: + event: pass + template: SLACK_TEMP_RELEASE_SUCCESS + - slack/notify: + event: fail + template: SLACK_TEMP_RELEASE_FAILURE workflows: - build_and_test: - jobs: - - pr-tools/pr-title-check: - context: org-global - - setup: - context: org-global - filters: - tags: - only: /.*/ - branches: - ignore: - - /feature*/ - - /bugfix*/ - - test-dependencies: - context: org-global - requires: - - setup - filters: - tags: - only: /.*/ - branches: - ignore: - - /feature*/ - - /bugfix*/ - - master - - test-lint: - context: org-global - requires: - - setup - filters: - tags: - only: /.*/ - branches: - ignore: - - /feature*/ - - /bugfix*/ - - test-unit: - context: org-global - requires: - - setup - filters: - tags: - only: /.*/ - branches: - ignore: - - /feature*/ - - /bugfix*/ - - test-coverage: - context: org-global - requires: - - setup - filters: - tags: - only: /.*/ - branches: - ignore: - - /feature*/ - - /bugfix*/ - - vulnerability-check: - context: org-global - requires: - - setup - filters: - tags: - only: /.*/ - branches: - ignore: - - /feature*/ - - /bugfix*/ - - audit-licenses: - context: org-global - requires: - - setup - filters: - tags: - only: /.*/ - branches: - ignore: - - /feature*/ - - /bugfix*/ - # New commits to master release automatically - - release: - context: org-global - requires: - - pr-tools/pr-title-check - - test-dependencies - - test-lint - - test-unit - - test-coverage - - vulnerability-check - - audit-licenses - filters: - branches: - only: - - master - - /release\/v.*/ - - github-release: - context: org-global - requires: - - release - filters: - branches: - only: - - master - - /release\/v.*/ - - publish: - context: org-global - requires: - - pr-tools/pr-title-check - - test-lint - - test-unit - - test-coverage - - vulnerability-check - - audit-licenses - filters: - tags: - only: /v[0-9]+(\.[0-9]+)*/ - branches: - ignore: - - /.*/ - - publish-snapshot: - context: org-global - requires: - - pr-tools/pr-title-check - - test-lint - - test-unit - - test-coverage - - vulnerability-check - - audit-licenses - filters: - tags: - only: /v[0-9]+(\.[0-9]+)*\-snapshot+((\.[0-9]+)?)/ - branches: - ignore: - - /.*/ + build_and_test: + jobs: + - pr-tools/pr-title-check: + context: org-global + - setup: + context: org-global + filters: + tags: + only: /.*/ + branches: + ignore: + - /feature*/ + - /bugfix*/ + - test-dependencies: + context: org-global + requires: + - setup + filters: + tags: + only: /.*/ + branches: + ignore: + - /feature*/ + - /bugfix*/ + - master + - test-lint: + context: org-global + requires: + - setup + filters: + tags: + only: /.*/ + branches: + ignore: + - /feature*/ + - /bugfix*/ + - test-unit: + context: org-global + requires: + - setup + filters: + tags: + only: /.*/ + branches: + ignore: + - /feature*/ + - /bugfix*/ + - test-deprecations: + context: org-global + requires: + - setup + filters: + tags: + only: /.*/ + branches: + ignore: + - /feature*/ + - /bugfix*/ + - test-coverage: + context: org-global + requires: + - setup + filters: + tags: + only: /.*/ + branches: + ignore: + - /feature*/ + - /bugfix*/ + - vulnerability-check: + context: org-global + requires: + - setup + filters: + tags: + only: /.*/ + branches: + ignore: + - /feature*/ + - /bugfix*/ + - audit-licenses: + context: org-global + requires: + - setup + filters: + tags: + only: /.*/ + branches: + ignore: + - /feature*/ + - /bugfix*/ + # New commits to master release automatically + - release: + context: org-global + requires: + - pr-tools/pr-title-check + - test-dependencies + - test-lint + - test-unit + - test-coverage + - vulnerability-check + - audit-licenses + filters: + branches: + only: + - master + - /release\/v.*/ + - github-release: + context: org-global + requires: + - release + filters: + branches: + only: + - master + - /release\/v.*/ + - publish: + context: org-global + requires: + - pr-tools/pr-title-check + - test-lint + - test-unit + - test-coverage + - vulnerability-check + - audit-licenses + filters: + tags: + only: /v[0-9]+(\.[0-9]+)*/ + branches: + ignore: + - /.*/ + - publish-snapshot: + context: org-global + requires: + - pr-tools/pr-title-check + - test-lint + - test-unit + - test-coverage + - vulnerability-check + - audit-licenses + filters: + tags: + only: /v[0-9]+(\.[0-9]+)*\-snapshot+((\.[0-9]+)?)/ + branches: + ignore: + - /.*/ diff --git a/.circleci/deprecated-check.js b/.circleci/deprecated-check.js index f0f87f5..8792d95 100644 --- a/.circleci/deprecated-check.js +++ b/.circleci/deprecated-check.js @@ -1,111 +1,98 @@ -const { exec } = require('child_process'); +const { spawnSync } = require('child_process'); -function execCommand(command) { - return new Promise((resolve, reject) => { - exec(command, (error, stdout, stderr) => { - //console.log(command); - if (error) { - reject(error.message); - } else if (stderr) { - reject(stderr); - } else { - resolve(stdout); - } - }); - }); +function execCommandSync(command) { + const [cmd, ...args] = command.split(' '); // Split command into executable and arguments + const result = spawnSync(cmd, args, { encoding: 'utf-8', shell: false }); + + if (result.error) { + throw result.error; // Handle system errors + } + if (result.status !== 0) { + throw new Error(result.stderr || `Command failed with exit code ${result.status}`); + } + return result.stdout; } -const dependencies_map = new Map(); +const dependenciesMap = new Map(); +const regex = /(?:@[\w-]+\/)?[\w.-]{1,100}@\d{1,10}\.\d{1,10}\.\d{1,10}(?:[-+][\w.-]{1,50})?/g; -async function checkDependencies(command) { +function checkDependencySync(dependency) { + if (dependenciesMap.has(dependency)) return; try { - const stdout = await execCommand(command); + const output = execCommandSync(`npm view ${dependency}`); + if (output.includes('DEPRECATED')) { + dependenciesMap.set(dependency, 'DEPRECATED'); + } else { + dependenciesMap.set(dependency, 'active'); + } + } catch (error) { + dependenciesMap.set(dependency, 'UNKNOWN'); + } +} - const result = stdout.trim().split("\n"); +function processLinesSync(lines) { + for (const line of lines) { + const trimmedLine = line.trim(); + const matches = trimmedLine.matchAll(regex); - for (let index = 0; index < result.length; index++) { - let line = result[index].trim(); - if(line.includes("UNMET OPTIONAL DEPENDENCY")){ - continue; - } - let dep = ""; - if(index===0){ - dep=line.split(" ")[0]; - } - else{ - arr=line.split(" "); - if(arr[arr.length-1]=="deduped" || arr[arr.length-1]=="overridden"){ - dep=arr[arr.length-2]; - } - else{ - dep=arr[arr.length-1]; - } - } - if(dep.includes(":")){ - dep=dep.split(":").pop(); - } - if (dependencies_map.has(dep)) { - continue; - } else { - try{ - const output = await execCommand(`npm view ${dep}`); - - if (output.includes("DEPRECATED")) { - dependencies_map.set(dep, "DEPRECATED"); - } else { - dependencies_map.set(dep, "active"); - } - } - catch(error){ - console.log(error); - } - } + for (const match of matches) { + const dependency = match[0]; + checkDependencySync(dependency); } + } +} - //console.log(dependencies_map); +function checkDependenciesSync(command) { + try { + const stdout = execCommandSync(command); + const lines = stdout.trim().split('\n'); + processLinesSync(lines); } catch (error) { - console.error(`Error: ${error}`); + + const errorLines = error.toString().trim().split('\n'); + processLinesSync(errorLines); // Process error lines as well } } -async function runDependencyCheck() { - - await checkDependencies('npm ls'); +function runDependencyCheckSync() { + console.log('Checking dependencies at root level...'); + checkDependenciesSync('npm ls'); - let dep_check = true; - counter=0; - dependencies_map.forEach((val, key) => { - if (val === "DEPRECATED") { + let deprecatedFound = false; + let counter = 0; + dependenciesMap.forEach((status, dependency) => { + if (status === 'DEPRECATED') { counter++; - dep_check = false; - console.log(counter+". "+key+" "+val); + deprecatedFound = true; + console.log(`${counter}. ${dependency} ${status}`); } }); - if (dep_check) { - console.log("\x1b[32mSUCCESS: All tests passed, no deprecated packages found at root level! Congos!!\n\x1b[0m") + if (deprecatedFound) { + console.log('\x1b[31mWARNING!! Deprecated results found at root level.\n\x1b[0m'); } else { - console.log("\x1b[31mWARNING!!Deprecated results found at root level.\n\x1b[0m"); + console.log('\x1b[32mSUCCESS: No deprecated packages found at root level! Congos!!\n\x1b[0m'); } - - await checkDependencies('npm ls --all'); - counter=0; - dependencies_map.forEach((val, key) => { - if (val === "DEPRECATED") { + console.log('Checking all dependencies (including transitive)...'); + checkDependenciesSync('npm ls --all'); + + deprecatedFound = false; + counter = 0; + dependenciesMap.forEach((status, dependency) => { + if (status === 'DEPRECATED') { counter++; - dep_check = false; - console.log(counter+". "+key+" "+val); + deprecatedFound = true; + console.log(`${counter}. ${dependency} ${status}`); } }); - if (dep_check) { - console.log("\x1b[32mSUCCESS: All tests passed, no deprecated packages found! Congos!!\x1b[0m") + if (deprecatedFound) { + console.log('\x1b[31mWARNING!! Deprecated results found in dependencies.\n\x1b[0m'); } else { - console.log("\x1b[31mWARINING!!Deprecated results found.\x1b[0m"); + console.log('\x1b[32mSUCCESS: No deprecated packages found! Congos!!\x1b[0m'); } } - -runDependencyCheck(); \ No newline at end of file +runDependencyCheckSync(); diff --git a/package-lock.json b/package-lock.json index 95cb83f..03ad3b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@mojaloop/ml-schema-transformer-lib": "^2.4.1", - "axios": "1.7.8", + "axios": "1.7.9", "axios-retry": "4.5.0", "base64url": "3.0.1", "fast-safe-stringify": "^2.1.1", @@ -1540,15 +1540,15 @@ } }, "node_modules/@mojaloop/ml-schema-transformer-lib/node_modules/@mojaloop/central-services-shared": { - "version": "18.11.2", - "resolved": "https://registry.npmjs.org/@mojaloop/central-services-shared/-/central-services-shared-18.11.2.tgz", - "integrity": "sha512-Ngsr9y2zpvPggEvMG5QjxV88wt9PkoGueoK7mSeGx/HZ1LGEN6TKYdEhkgBXdOrOtXnOwecFR8fyBY0rpz3saw==", + "version": "18.12.1", + "resolved": "https://registry.npmjs.org/@mojaloop/central-services-shared/-/central-services-shared-18.12.1.tgz", + "integrity": "sha512-+mLMgthhbg8VRVPZ9lpPuTWJ1Vy3l5gueTl7lY8MjbyZi/gWYNmppjgNxBCWwF+jRUx64ZDtqgbAbFmUY1YUhQ==", "license": "Apache-2.0", "dependencies": { "@hapi/catbox": "12.1.1", "@hapi/catbox-memory": "5.0.1", "@mojaloop/inter-scheme-proxy-cache-lib": "2.3.0", - "axios": "1.7.7", + "axios": "1.7.8", "clone": "2.1.2", "dotenv": "16.4.5", "env-var": "7.5.0", @@ -1625,9 +1625,9 @@ } }, "node_modules/@mojaloop/ml-schema-transformer-lib/node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz", + "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -2410,9 +2410,9 @@ } }, "node_modules/axios": { - "version": "1.7.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz", - "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -4875,9 +4875,10 @@ } }, "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -4898,7 +4899,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -4913,6 +4914,10 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/cookie": { @@ -9338,9 +9343,10 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" }, "node_modules/pause-stream": { "version": "0.0.11", diff --git a/package.json b/package.json index 55a60fb..70814e2 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ ], "dependencies": { "@mojaloop/ml-schema-transformer-lib": "^2.4.1", - "axios": "1.7.8", + "axios": "1.7.9", "axios-retry": "4.5.0", "base64url": "3.0.1", "fast-safe-stringify": "^2.1.1",