From 84c274b737d44a23484b3c85a2b518d9063170d9 Mon Sep 17 00:00:00 2001 From: Stuart Clark Date: Fri, 25 Sep 2020 08:15:33 +1000 Subject: [PATCH] [#1] Added CI config/scripts. --- .circleci/build.sh | 66 ++++++++++++++++ .circleci/config.yml | 140 +++++++++++++++++++++++++++++++++ .circleci/deploy.sh | 58 ++++++++++++++ .circleci/lint.sh | 11 +++ .circleci/process-artifacts.sh | 11 +++ .circleci/test.sh | 25 ++++++ .gitignore | 1 + 7 files changed, 312 insertions(+) create mode 100755 .circleci/build.sh create mode 100644 .circleci/config.yml create mode 100755 .circleci/deploy.sh create mode 100755 .circleci/lint.sh create mode 100755 .circleci/process-artifacts.sh create mode 100755 .circleci/test.sh create mode 100644 .gitignore diff --git a/.circleci/build.sh b/.circleci/build.sh new file mode 100755 index 0000000..34489a8 --- /dev/null +++ b/.circleci/build.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +## +# Build. +# +# shellcheck disable=SC2015,SC2094 + +set -e + +echo "==> Validate composer" +composer validate --ansi --strict + +[ -d build ] && echo "==> Remove existing build directory" && chmod -Rf 777 build && rm -rf build + +# Allow installing custom version of Drupal core, but only coupled with +# drupal-project SHA (required to get correct dependencies). +if [ -n "${DRUPAL_PROJECT_SHA}" ] && [ -n "${DRUPAL_VERSION}" ] ; then + echo "==> Initialise Drupal site from the scaffold commit $DRUPAL_PROJECT_SHA" + + git clone -n https://github.com/drupal-composer/drupal-project.git build + git --git-dir=build/.git --work-tree=build checkout "${DRUPAL_PROJECT_SHA}" + rm -rf build/.git > /dev/null + + echo "==> Pin Drupal to a specific version" + sed_opts=(-i) && [ "$(uname)" == "Darwin" ] && sed_opts=(-i '') + sed "${sed_opts[@]}" 's|\(.*"drupal\/core"\): "\(.*\)",.*|\1: '"\"$DRUPAL_VERSION\",|" build/composer.json + cat build/composer.json + + echo "==> Install dependencies" + php -d memory_limit=-1 "$(command -v composer)" --working-dir=build install +else + echo "==> Initialise Drupal site from the latest scaffold" + php -d memory_limit=-1 "$(command -v composer)" create-project drupal-composer/drupal-project:8.x-dev build --no-interaction +fi + +echo "==> Install additional dev dependencies from module's composer.json" +cat <<< "$(jq --indent 4 -M -s '.[0] * .[1]' composer.json build/composer.json)" > build/composer.json +php -d memory_limit=-1 "$(command -v composer)" --working-dir=build update --lock + +echo "==> Install other dev dependencies" +cat <<< "$(jq --indent 4 '.extra["phpcodesniffer-search-depth"] = 10' build/composer.json)" > build/composer.json +php -d memory_limit=-1 "$(command -v composer)" --working-dir=build require --dev dealerdirect/phpcodesniffer-composer-installer + +echo "==> Start inbuilt PHP server in $(pwd)/build/web" +killall -9 php > /dev/null 2>&1 || true +nohup php -S localhost:8000 -t "$(pwd)/build/web" "$(pwd)/build/web/.ht.router.php" > /tmp/php.log 2>&1 & +sleep 4 # Waiting for the server to be ready. +netstat_opts='-tulpn'; [ "$(uname)" == "Darwin" ] && netstat_opts='-anv' || true; +netstat "${netstat_opts[@]}" | grep -q 8000 || (echo "ERROR: Unable to start inbuilt PHP server" && cat /tmp/php.log && exit 1) +curl -s -o /dev/null -w "%{http_code}" -L -I http://localhost:8000 | grep -q 200 || (echo "ERROR: Server is started, but site cannot be served" && exit 1) + +MODULE=$(basename -s .info.yml -- ./*.info.yml) +DB_FILE="${DB_FILE:-/tmp/site_${MODULE}.sqlite}" + +echo "==> Install Drupal into SQLite database ${DB_FILE}" +build/vendor/bin/drush -r build/web si "${DRUPAL_PROFILE:-standard}" -y --db-url "sqlite://${DB_FILE}" --account-name=admin install_configure_form.enable_update_status_module=NULL install_configure_form.enable_update_status_emails=NULL +build/vendor/bin/drush -r "$(pwd)/build/web" status + +echo "==> Symlink module code" +rm -rf build/web/modules/"${MODULE}"/* > /dev/null +mkdir -p "build/web/modules/${MODULE}" +ln -s "$(pwd)"/* build/web/modules/"${MODULE}" && rm build/web/modules/"${MODULE}"/build + +echo "==> Enable module ${MODULE}" +build/vendor/bin/drush -r build/web pm:enable "${MODULE}" -y +build/vendor/bin/drush -r build/web cr +build/vendor/bin/drush -r build/web -l http://localhost:8000 uli --no-browser diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..d65b58b --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,140 @@ +# @see https://github.com/integratedexperts/drupal_circleci +version: 2 +aliases: + # SSH deployment key fingerprint from CircleCI App -> Project -> Settings -> SSH Permissions. + # Replace the value for your project. + # - &deploy_ssh_fingerprint "" + - &container_config + working_directory: ~/project + docker: + - image: circleci/php:7.4-cli-browsers + +job-build: &job-build + steps: + - checkout + - run: | + sudo -E apt-get update && sudo -E apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev jq \ + && sudo -E docker-php-ext-install -j$(nproc) iconv \ + && if [ "$(php -r "echo PHP_MAJOR_VERSION;")" -gt 5 ] && [ "$(php -r "echo PHP_MINOR_VERSION;")" -gt 3 ] ; then sudo -E docker-php-ext-configure gd --with-freetype --with-jpeg; else sudo -E docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/; fi \ + && sudo -E docker-php-ext-install -j$(nproc) gd + - run: .circleci/build.sh + - run: .circleci/lint.sh + - run: .circleci/test.sh + - run: + command: .circleci/process-artifacts.sh + when: always + - store_test_results: + path: /tmp/test_results + when: always + - store_artifacts: + path: /tmp/artifacts + when: always + +jobs: + build-php-7.4: + <<: *container_config + <<: *job-build + + build-php-7.3: + <<: *container_config + docker: + - image: circleci/php:7.3-cli-browsers + <<: *job-build + + build-php-7.2: + <<: *container_config + docker: + - image: circleci/php:7.2-cli-browsers + <<: *job-build + + # @todo: Enable after Drupal core > 8.8.0 release, so that DRUPAL_VERSION + # would become 8.8.0. This is due to a core version < 8.8 does not support + # php 7.4. But we still want to provide the template for testing code with + # legacy cores. + # Also, enable in workflows below. + # build-php-7.4-legacy: + # <<: *container_config + # environment: + # DRUPAL_VERSION: 8.7.6 + # # Drupal project commit before moving 8.8.0. + # # https://github.com/drupal-composer/drupal-project/commit/53f6910c35db73d0b367d5b6f22be4af94dd1af3 + # DRUPAL_PROJECT_SHA: 53f6910c35db73d0b367d5b6f22be4af94dd1af3 + # <<: *job-build + + # build-php-7.3-legacy: + # <<: *container_config + # docker: + # - image: circleci/php:7.3-cli-browsers + # environment: + # DRUPAL_VERSION: 8.7.6 + # # Drupal project commit before moving 8.8.0. + # # https://github.com/drupal-composer/drupal-project/commit/53f6910c35db73d0b367d5b6f22be4af94dd1af3 + # DRUPAL_PROJECT_SHA: 53f6910c35db73d0b367d5b6f22be4af94dd1af3 + # <<: *job-build + + # build-php-7.2-legacy: + # <<: *container_config + # docker: + # - image: circleci/php:7.2-cli-browsers + # environment: + # DRUPAL_VERSION: 8.7.6 + # # Drupal project commit before moving 8.8.0. + # # https://github.com/drupal-composer/drupal-project/commit/53f6910c35db73d0b367d5b6f22be4af94dd1af3 + # DRUPAL_PROJECT_SHA: 53f6910c35db73d0b367d5b6f22be4af94dd1af3 + # <<: *job-build + + # deploy: + # <<: *container_config + # environment: + # DEPLOY_SSH_FINGERPRINT: *deploy_ssh_fingerprint + # steps: + # - checkout + # - add_ssh_keys: + # fingerprints: + # - *deploy_ssh_fingerprint + # - run: DEPLOY_BRANCH=${CIRCLE_BRANCH} .circleci/deploy.sh + +workflows: + version: 2 + main: + jobs: + - build-php-7.4: + filters: + tags: + only: /.*/ + - build-php-7.3: + filters: + tags: + only: /.*/ + - build-php-7.2: + filters: + tags: + only: /.*/ + # @todo: Enable after Drupal core version > 8.8.0 released. + # - build-php-7.4-legacy: + # filters: + # tags: + # only: /.*/ + # - build-php-7.3-legacy: + # filters: + # tags: + # only: /.*/ + # - build-php-7.2-legacy: + # filters: + # tags: + # only: /.*/ + # - deploy: + # requires: + # - build-php-7.4 + # - build-php-7.3 + # - build-php-7.2 + # # @todo: Enable after Drupal core version > 8.8.0 released. + # # - build-php-7.4-legacy + # # - build-php-7.3-legacy + # # - build-php-7.2-legacy + # filters: + # tags: + # only: /.*/ + # branches: + # # 7.x, 8.x, 7.x-1.x, 8.x-1.x, 7.x-2.x, 8.x-2.x, ci + # only: /^(?:7|8)\.x(?:\-[0-9]+\.x)?|ci$/ diff --git a/.circleci/deploy.sh b/.circleci/deploy.sh new file mode 100755 index 0000000..58b1702 --- /dev/null +++ b/.circleci/deploy.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +## +# Deploy code to a remote repository. +# +# - configures local git +# - adds deployment SSH key to SSH agent +# - force-pushes code to a remote code repository branch +# +# It is a good practice to create a separate Deployer user with own SSH key for +# every project. +# +# Add the following variables through CircleCI UI. +# DEPLOY_USER_NAME - name of the user who will be committing to a remote repository. +# DEPLOY_USER_EMAIL - email address of the user who will be committing to a remote repository. +# DEPLOY_REMOTE - remote repository to push code to. +# DEPLOY_PROCEED - set to 1 if the deployment should proceed. Useful for testing CI configuration before an actual code push. +# +# Other variables: +# DEPLOY_BRANCH - git branch to deploy. +# DEPLOY_SSH_FINGERPRINT - the fingerprint of the SSH key of the user on behalf of which the deployment is performed. + +set -e + +DEPLOY_USER_NAME="${DEPLOY_USER_NAME}" +DEPLOY_USER_EMAIL="${DEPLOY_USER_EMAIL}" +DEPLOY_REMOTE="${DEPLOY_REMOTE:-}" +DEPLOY_BRANCH="${DEPLOY_BRANCH:-}" +DEPLOY_SSH_FINGERPRINT="${DEPLOY_SSH_FINGERPRINT:-}" +DEPLOY_PROCEED="${DEPLOY_PROCEED:-0}" + +[ -z "${DEPLOY_USER_NAME}" ] && echo "ERROR: Missing required value for DEPLOY_USER_NAME" && exit 1 +[ -z "${DEPLOY_USER_EMAIL}" ] && echo "ERROR: Missing required value for DEPLOY_USER_EMAIL" && exit 1 +[ -z "${DEPLOY_REMOTE}" ] && echo "ERROR: Missing required value for DEPLOY_REMOTE" && exit 1 +[ -z "${DEPLOY_SSH_FINGERPRINT}" ] && echo "ERROR: Missing required value for DEPLOY_SSH_FINGERPRINT" && exit 1 + +[ "${DEPLOY_PROCEED}" != "1" ] && echo "==> Skipping deployment because \$DEPLOY_PROCEED is not set to 1" && exit 0 + +# Configure git and SSH to connect to remote servers for deployment. +mkdir -p "${HOME}/.ssh/" +echo -e "Host *\n\tStrictHostKeyChecking no\n" > "${HOME}/.ssh/config" +DEPLOY_SSH_FILE="${DEPLOY_SSH_FINGERPRINT//:}" +DEPLOY_SSH_FILE="${HOME}/.ssh/id_rsa_${DEPLOY_SSH_FILE//\"}" +[ ! -f "${DEPLOY_SSH_FILE}" ] && echo "ERROR: Unable to find Deploy SSH key file ${DEPLOY_SSH_FILE}" && exit 1 +if [ -z "${SSH_AGENT_PID}" ]; then eval "$(ssh-agent)"; fi +ssh-add -D > /dev/null +ssh-add "${DEPLOY_SSH_FILE}" + +[ "$(git config --global user.name)" == "" ] && echo "==> Configuring global git user name" && git config --global user.name "${DEPLOY_USER_NAME}" +[ "$(git config --global user.email)" == "" ] && echo "==> Configuring global git user email" && git config --global user.email "${DEPLOY_USER_EMAIL}" + +git config --global push.default matching + +echo "==> Adding remote ${DEPLOY_REMOTE}" +git remote add deployremote "${DEPLOY_REMOTE}" + +echo "==> Deploying to remote ${DEPLOY_REMOTE}" +# shellcheck disable=SC2086 +git push --force --tags deployremote ${DEPLOY_BRANCH} diff --git a/.circleci/lint.sh b/.circleci/lint.sh new file mode 100755 index 0000000..ce8d606 --- /dev/null +++ b/.circleci/lint.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +## +# Run lint checks. +# + +set -e + +MODULE=$(basename -s .info.yml -- ./*.info.yml) + +echo "==> Lint code" +build/vendor/bin/phpcs -s --standard=Drupal,DrupalPractice --extensions=module,php,install,inc,test,info.yml,js "build/web/modules/${MODULE}" diff --git a/.circleci/process-artifacts.sh b/.circleci/process-artifacts.sh new file mode 100755 index 0000000..1b78924 --- /dev/null +++ b/.circleci/process-artifacts.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +## +# Process test artifacts. +# +set -e + +if [ -d "$(pwd)/build/web/sites/simpletest/browser_output" ]; then + echo "==> Copying Simpletest test artifacts" + mkdir -p /tmp/artifacts/simpletest + cp -Rf "$(pwd)/build/web/sites/simpletest/browser_output/." /tmp/artifacts/simpletest +fi diff --git a/.circleci/test.sh b/.circleci/test.sh new file mode 100755 index 0000000..248fc75 --- /dev/null +++ b/.circleci/test.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +## +# Run tests. +# + +set -e + +MODULE=$(basename -s .info.yml -- ./*.info.yml) + +echo "==> Run tests" +[ ! -d tests ] && echo "==> No tests found. Skipping." && exit 0 + +mkdir -p /tmp/test_results/simpletest +rm -f /tmp/test.sqlite + +php ./build/web/core/scripts/run-tests.sh \ + --sqlite /tmp/test.sqlite \ + --dburl sqlite://localhost//tmp/test.sqlite \ + --url http://localhost:8000 \ + --non-html \ + --xml /tmp/test_results/simpletest \ + --color \ + --verbose \ + --suppress-deprecations \ + --module "${MODULE}" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build