From 09f8725349e2e7c596132bf738b9966d19974efe Mon Sep 17 00:00:00 2001 From: pookmish Date: Wed, 20 Mar 2024 10:04:14 -0700 Subject: [PATCH] Move tests and automation from CircleCI to Github Actions parallel/matrix (#1481) * Move tests and automation from CircleCI to Github Actions parallel/matrix. --- .circleci/config.yml | 219 +------------- .github/workflows/content-stage.yml | 25 +- .github/workflows/release.yml | 80 ++++- .github/workflows/sites-test.yml | 250 +++++++++++++++ blt/blt.yml | 2 +- blt/ci.blt.yml | 6 +- .../Plugin/Commands/HsCircleCiCommands.php | 285 ------------------ composer.json | 2 +- composer.lock | 16 +- docroot/sites/settings/ci.settings.php | 27 +- tests/codeception.dist.yml | 10 + 11 files changed, 409 insertions(+), 513 deletions(-) create mode 100644 .github/workflows/sites-test.yml delete mode 100644 blt/src/Blt/Plugin/Commands/HsCircleCiCommands.php diff --git a/.circleci/config.yml b/.circleci/config.yml index 56b96920a9..cb2f0ecc71 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,7 +22,6 @@ add_known_hosts: &add_known_hosts defaults: &defaults docker: - image: pookmish/drupal8ci:latest - - image: selenium/standalone-chrome:latest - image: circleci/mysql:5.7 environment: MYSQL_DATABASE: drupal @@ -56,126 +55,6 @@ disable_telemetry: &disable_telemetry run: name: Disable Telemetry command: vendor/bin/blt blt:telemetry:disable --no-interaction -#Jobs - -directory_setup: &directory_setup - <<: *defaults - steps: - - checkout - - restore_cache: *restore_cache - - run: - name: Composer setup - command: | - composer install --optimize-autoloader --no-interaction - composer dump-autoload - vendor/bin/blt blt:telemetry:disable --no-interaction - vendor/bin/blt settings --no-interaction - - save_cache: *save_cache - - persist_to_workspace: - root: . - paths: - - . - -### Job to run the update path and Codeception tests. -acceptance_first: &acceptance_first - <<: *defaults - steps: - - *add_ssh - - *add_known_hosts - - attach_workspace: - at: . - - *disable_telemetry - - run: - name: Run Acceptance tests - command: vendor/bin/blt circleci:codeception 0 - - store_test_results: - path: /var/www/html/artifacts - - store_artifacts: - path: /var/www/html/artifacts - -### Job to run the update path and Codeception tests. -acceptance_second: &acceptance_second - <<: *defaults - steps: - - *add_ssh - - *add_known_hosts - - attach_workspace: - at: . - - *disable_telemetry - - run: - name: Run Acceptance tests - command: vendor/bin/blt circleci:codeception 1 - - store_test_results: - path: /var/www/html/artifacts - - store_artifacts: - path: /var/www/html/artifacts - -## Job to run Unit and Kernel tests. -acceptance: &acceptance - <<: *defaults - steps: - - attach_workspace: - at: . - - *disable_telemetry - - run: - name: Run installation Acceptance tests - command: vendor/bin/blt circleci:codeception - - store_test_results: - path: /var/www/html/artifacts - - store_artifacts: - path: /var/www/html/artifacts - -phpunit_coverage: &phpunit_coverage - <<: *defaults - steps: - - attach_workspace: - at: . - - *disable_telemetry - - run: - name: Run PHPUnit Coverage Tests - command: | - dockerize -wait tcp://localhost:3306 -timeout 1m - apachectl stop; apachectl start - vendor/bin/blt tests:phpunit:coverage --no-interaction - - store_test_results: - path: artifacts/phpunit - - store_artifacts: - path: artifacts/phpunit - -## Job to deploy the current branch to Acquia hosting using BLT. -deploy_branch: &deploy_branch - <<: *defaults - steps: - - *add_ssh - - *add_known_hosts - - attach_workspace: - at: . - - *disable_telemetry - - run: - name: Deploying branch to Acquia - command: | - git config --global user.email "sws-developers@lists.stanford.edu" - git config --global user.name "CircleCI" - vendor/bin/blt deploy --no-interaction - -## Job to deploy the new tag to Acquia hosting using BLT. -deploy_tag: &deploy_tag - <<: *defaults - steps: - - *add_ssh - - *add_known_hosts - - checkout - - restore_cache: *restore_cache - - run: composer install --optimize-autoloader - - *disable_telemetry - - run: - name: Deploying Tag to Acquia - command: | - git config --global user.email "sws-developers@lists.stanford.edu" - git config --global user.name "CircleCI" - DATE=`date +%Y-%m-%d` - vendor/bin/blt deploy --tag=$(echo ${DATE}_${CIRCLE_TAG}) --commit-msg=$CIRCLE_TAG --no-interaction - vendor/bin/blt circleci:new-release-branch ${CIRCLE_TAG} update_dependencies: &update_dependencies <<: *defaults @@ -190,89 +69,30 @@ update_dependencies: &update_dependencies name: Update dependencies no_output_timeout: 30m command: | - git config --global user.email "sws-developers@lists.stanford.edu" - git config --global user.name "CircleCI" - vendor/bin/blt circleci:update $CIRCLE_BRANCH - vendor/bin/blt humsci:clean-backups + dockerize -wait tcp://localhost:3306 -timeout 1m && + apachectl stop && apachectl start && + git config --global user.email "sws-developers@lists.stanford.edu" && + git config --global user.name "CircleCI" && + blt drupal:install -n && + drush cim -y && + composer update -n && + drush updatedb -y && + drush config:export -y && + git add config composer.lock docroot && + git commit -m "Updated dependencies $DATE" && + git push origin $CIRCLE_BRANCH && + blt humsci:clean-backups && + blt humsci:clean-branches - save_cache: *save_cache -run-content-stage: &run-content-stage - docker: - - image: cimg/php:7.4 - steps: - - checkout - - run: composer install --optimize-autoloader - - *disable_telemetry - - run: vendor/bin/blt stage --no-interaction - - slack/notify: - event: fail - channel: C750VBZCZ - template: basic_fail_1 - - slack/notify: - event: pass - channel: C750VBZCZ - template: basic_success_1 - # Declare all the jobs we should run. jobs: run-updates: <<: *update_dependencies - run-setup: - <<: *directory_setup - run-acceptance-first: - <<: *acceptance_first - run-acceptance-second: - <<: *acceptance_second - run-acceptance: - <<: *acceptance - run-code-coverage: - <<: *phpunit_coverage - run-deploy-branch: - <<: *deploy_branch - run-deploy-tag: - <<: *deploy_tag - run-content-stage: - <<: *run-content-stage version: 2.1 -orbs: - slack: circleci/slack@4.4.2 # Declare a workflow that runs all of our jobs in parallel. workflows: - version: 2.1 - deploy_tag: - jobs: - # Tags are only created on successful code. Deploy the tag after creation. - # This will trigger after the release is created above. - - run-deploy-tag: - filters: - tags: - only: - - /.*/ - branches: - ignore: - - /.*/ - test_lint_deploy: - jobs: - - run-setup - - run-acceptance-first: - requires: - - run-setup - - run-acceptance-second: - requires: - - run-setup - - run-acceptance: - requires: - - run-setup - - run-code-coverage: - requires: - - run-setup - # If the above jobs complete successfully, deploy the branch. - - run-deploy-branch: - requires: - - run-acceptance-first - - run-acceptance-second - - run-acceptance dependency_updates: triggers: - schedule: @@ -283,14 +103,3 @@ workflows: - /10\..*-release/ jobs: - run-updates -# 'Stage Content from Production': -# jobs: -# - run-content-stage: -# context: slack-secrets -# triggers: -# - schedule: -# cron: "0 23 * * 3" -# filters: -# branches: -# only: -# - /develop/ diff --git a/.github/workflows/content-stage.yml b/.github/workflows/content-stage.yml index 0cb54e4b3a..6ba7c02ed8 100644 --- a/.github/workflows/content-stage.yml +++ b/.github/workflows/content-stage.yml @@ -5,14 +5,29 @@ on: jobs: Copy-Prod-Database-Down: runs-on: ubuntu-latest + container: + image: pookmish/drupal8ci:latest steps: - - name: Check out repository code - uses: actions/checkout@v3 - - run: composer update --optimize-autoloader - - run: vendor/bin/blt blt:telemetry:disable --no-interaction + - uses: actions/checkout@v4 + - name: Restore Cache + uses: actions/cache@v4 + with: + path: | + vendor + docroot/core + docroot/libraries + docroot/modules/contrib + key: 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + restore-keys: | + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}- + 1.x-${{ hashFiles('blt/blt.yml') }}- - name: Copy databases env: SLACK_NOTIFICATION_URL: ${{ secrets.SLACK_NOTIFICATION_URL }} ACQUIA_KEY: ${{ secrets.ACQUIA_KEY }} ACQUIA_SECRET: ${{ secrets.ACQUIA_SECRET }} - run: vendor/bin/blt stage --no-interaction + run: | + composer install -n && + blt blt:telemetry:disable --no-interaction && + blt stage --no-interaction diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4dafefb9ea..04cc7fcc2d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,16 +3,90 @@ name: Release on: pull_request: - types: closed - + types: [ closed ] jobs: build: runs-on: ubuntu-latest + permissions: write-all + if: github.event.pull_request.merged + container: + image: pookmish/drupal8ci:latest steps: - - name: Tag + - name: Get Next Release + id: tag uses: K-Phoen/semver-release-action@master with: + release_strategy: none release_branch: develop tag_format: "%major%.%minor%.%patch%" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Creating new release for ${{ steps.tag.outputs.tag }} + if: ${{ steps.tag.outputs.tag }} + uses: ncipollo/release-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + name: ${{ steps.tag.outputs.tag }} + tag: ${{ steps.tag.outputs.tag }} + commit: ${{ github.sha }} + generateReleaseNotes: true + makeLatest: true + - name: Install SSH key + if: ${{ steps.tag.outputs.tag }} + uses: shimataro/ssh-key-action@v2 + with: + key: ${{ secrets.SSH_KEY }} + name: id_rsa + known_hosts: ${{ secrets.KNOWN_HOSTS }} + if_key_exists: fail + - uses: actions/checkout@v4 + if: ${{ steps.tag.outputs.tag }} + with: + ref: ${{ github.sha }} + - name: Restore Cache + if: ${{ steps.tag.outputs.tag }} + uses: actions/cache@v4 + with: + path: | + vendor + docroot/core + docroot/libraries + docroot/modules/contrib + key: 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + restore-keys: | + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}- + 1.x-${{ hashFiles('blt/blt.yml') }}- + - name: Deploy Tag + if: ${{ steps.tag.outputs.tag }} + run: | + git config --system --add safe.directory '*' && + git config --global user.email "sws-developers@lists.stanford.edu" && + git config --global user.name "Github Actions" && + ssh-keyscan -t rsa svn-23450.prod.hosting.acquia.com >> /root/.ssh/known_hosts && + composer install -n && + blt blt:telemetry:disable --no-interaction && + DATE=$(date +'%Y-%m-%d') && + blt deploy --tag=$(echo $DATE_${{ steps.tag.outputs.tag }}) --commit-msg=${{ steps.tag.outputs.tag }} --no-interaction + - name: Get Next Release + if: ${{ steps.tag.outputs.tag }} + id: next_tag + run: | + NEXT_VERSION=$(echo ${{ steps.tag.outputs.tag }} | awk -F. -v OFS=. '{$NF += 1 ; print}') && + sed -i "s/^version:.*/version: $NEXT_VERSION/g" docroot/profiles/humsci/su_humsci_profile/su_humsci_profile.info.yml && + echo "version=$NEXT_VERSION" >> $GITHUB_OUTPUT + - name: Create Next Release + if: ${{ steps.tag.outputs.tag }} + uses: peter-evans/create-pull-request@v6 + with: + committer: Github Actions + author: Github Actions + commit-message: ${{ steps.next_tag.outputs.version }} + branch: ${{ steps.next_tag.outputs.version }}-release + base: develop + title: ${{ steps.next_tag.outputs.version }} + body: "# DO NOT DELETE" + - name: Push New Branch + if: ${{ steps.tag.outputs.tag }} + run: blt deploy -n diff --git a/.github/workflows/sites-test.yml b/.github/workflows/sites-test.yml new file mode 100644 index 0000000000..fb84d5fef4 --- /dev/null +++ b/.github/workflows/sites-test.yml @@ -0,0 +1,250 @@ +name: Unit and Acceptance Tests +on: push +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +jobs: + test_phpunit: + runs-on: ubuntu-latest + container: + image: pookmish/drupal8ci:latest + options: '--network-alias drupal8ci' + env: + REAL_AES_ENCRYPTION: ${{secrets.REAL_AES_ENCRYPTION}} + DRUPAL_DATABASE_NAME: drupal + DRUPAL_DATABASE_USERNAME: drupal + DRUPAL_DATABASE_PASSWORD: drupal + DRUPAL_DATABASE_HOST: mysql + services: + mysql: + image: mysql:5.7 + env: + MYSQL_DATABASE: drupal + MYSQL_USER: drupal + MYSQL_PASSWORD: drupal + MYSQL_ROOT_PASSWORD: drupal + ports: + - 33306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + steps: + - uses: actions/checkout@v4 + - name: Restore Cache + uses: actions/cache@v4 + with: + path: | + vendor + docroot/core + docroot/libraries + docroot/modules/contrib + key: 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + restore-keys: | + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}- + 1.x- + - run: git config --system --add safe.directory '*' + - name: Install Dependencies + run: | + mysql -h mysql -P 3306 -u root -pdrupal -e 'SET GLOBAL max_allowed_packet=67108864;' && + rm -rf /var/www/html && + ln -snf $GITHUB_WORKSPACE /var/www/html && + composer install -n && + vendor/bin/blt blt:telemetry:disable --no-interaction && + blt settings && + mkdir -p docroot/sites/default/files && + chmod -R 777 docroot/sites/default/files/ + - name: Codeception Tests + run: | + blt tests:phpunit:coverage --no-interaction + set_sites: + runs-on: ubuntu-latest + container: + image: pookmish/drupal8ci:latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + - name: Restore Cache + uses: actions/cache@v4 + with: + path: | + vendor + docroot/core + docroot/libraries + docroot/modules/contrib + key: 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + restore-keys: | + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}- + 1.x-${{ hashFiles('blt/blt.yml') }}- + - id: set-matrix + run: | + composer install -n && + vendor/bin/blt blt:telemetry:disable --no-interaction && + SITES=$(echo -n "$(blt blt:config:get multisites | shuf -n 10)" | jq -R -s -c 'split("\n") | sort') + echo "matrix={\"site\": $SITES}" >> $GITHUB_OUTPUT + test_existing_site: + needs: set_sites + strategy: + fail-fast: false + matrix: ${{fromJSON(needs.set_sites.outputs.matrix)}} + runs-on: ubuntu-latest + container: + image: pookmish/drupal8ci:latest + options: '--network-alias drupal8ci' + env: + REAL_AES_ENCRYPTION: ${{secrets.REAL_AES_ENCRYPTION}} + DRUPAL_DATABASE_NAME: drupal + DRUPAL_DATABASE_USERNAME: drupal + DRUPAL_DATABASE_PASSWORD: drupal + DRUPAL_DATABASE_HOST: mysql + services: + selenium: + image: selenium/standalone-chrome:115.0 + options: '--shm-size="2g"' + mysql: + image: mysql:5.7 + env: + MYSQL_DATABASE: drupal + MYSQL_USER: drupal + MYSQL_PASSWORD: drupal + MYSQL_ROOT_PASSWORD: drupal + ports: + - 33306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + steps: + - uses: actions/checkout@v4 + - name: Restore Cache + uses: actions/cache@v4 + with: + path: | + vendor + docroot/core + docroot/libraries + docroot/modules/contrib + key: 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + restore-keys: | + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}- + 1.x-${{ hashFiles('blt/blt.yml') }}- + - name: Install SSH key + uses: shimataro/ssh-key-action@v2 + with: + key: ${{ secrets.SSH_KEY }} + name: id_rsa + known_hosts: ${{ secrets.KNOWN_HOSTS }} + if_key_exists: fail + - run: git config --system --add safe.directory '*' + - name: Sync Database + run: | + mysql -h mysql -P 3306 -u root -pdrupal -e 'SET GLOBAL max_allowed_packet=67108864;' && + rm -rf /var/www/html && + ln -snf $GITHUB_WORKSPACE /var/www/html && + composer install -n && + vendor/bin/blt blt:telemetry:disable --no-interaction && + blt settings && + blt drupal:sync --site=${{ matrix.site }} -n + mkdir -p docroot/sites/default/files && + chmod -R 777 docroot/sites/default/files/ + - name: Codeception Tests ${{ matrix.site }} + run: | + apachectl stop + apachectl start + blt codeception --group=existingSite + test_new_site: + runs-on: ubuntu-latest + container: + image: pookmish/drupal8ci:latest + options: '--network-alias drupal8ci' + env: + REAL_AES_ENCRYPTION: ${{secrets.REAL_AES_ENCRYPTION}} + DRUPAL_DATABASE_NAME: drupal + DRUPAL_DATABASE_USERNAME: drupal + DRUPAL_DATABASE_PASSWORD: drupal + DRUPAL_DATABASE_HOST: mysql + services: + selenium: + image: selenium/standalone-chrome:115.0 + options: '--shm-size="2g"' + mysql: + image: mysql:5.7 + env: + MYSQL_DATABASE: drupal + MYSQL_USER: drupal + MYSQL_PASSWORD: drupal + MYSQL_ROOT_PASSWORD: drupal + ports: + - 33306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + steps: + - uses: actions/checkout@v4 + - name: Restore Cache + uses: actions/cache@v4 + with: + path: | + vendor + docroot/core + docroot/libraries + docroot/modules/contrib + key: 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + restore-keys: | + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}- + 1.x-${{ hashFiles('blt/blt.yml') }}- + - run: git config --system --add safe.directory '*' + - name: Install Site + run: | + mysql -h mysql -P 3306 -u root -pdrupal -e 'SET GLOBAL max_allowed_packet=67108864;' && + rm -rf /var/www/html && + ln -snf $GITHUB_WORKSPACE /var/www/html && + composer install -n && + vendor/bin/blt blt:telemetry:disable --no-interaction && + blt settings && + mkdir -p docroot/sites/default/files && + chmod -R 777 docroot/sites/default/files/ && + blt drupal:install -n + - name: Codeception Tests + run: | + apachectl stop + apachectl start + blt codeception --group=install + deploy_branch: + needs: + - test_phpunit + - set_sites + - test_existing_site + - test_new_site + runs-on: ubuntu-latest + container: + image: pookmish/drupal8ci:latest + options: '--network-alias drupal8ci' + steps: + - uses: actions/checkout@v4 + - name: Restore Cache + uses: actions/cache@v4 + with: + path: | + vendor + docroot/core + docroot/libraries + docroot/modules/contrib + key: 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + restore-keys: | + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}-${{ hashFiles('composer.lock') }} + 1.x-${{ hashFiles('blt/blt.yml') }}-${{ hashFiles('composer.json') }}- + 1.x-${{ hashFiles('blt/blt.yml') }}- + - name: Install SSH key + uses: shimataro/ssh-key-action@v2 + with: + key: ${{ secrets.SSH_KEY }} + name: id_rsa + known_hosts: ${{ secrets.KNOWN_HOSTS }} + if_key_exists: fail + - run: git config --system --add safe.directory '*' + - name: Deploy Branch + run: | + git config --global user.email "sws-developers@lists.stanford.edu" && + git config --global user.name "Github Actions" && + ssh-keyscan -t rsa svn-23450.prod.hosting.acquia.com >> /root/.ssh/known_hosts && + composer install -n && + blt blt:telemetry:disable --no-interaction && + blt deploy -n diff --git a/blt/blt.yml b/blt/blt.yml index c648ecc8f2..394c4c89b6 100644 --- a/blt/blt.yml +++ b/blt/blt.yml @@ -195,7 +195,7 @@ tests: reports: localDir: '${repo.root}/artifacts' codeception: - stanford_profile: + su_humsci_profile: suites: - acceptance - functional diff --git a/blt/ci.blt.yml b/blt/ci.blt.yml index adaf924b27..0afe7af460 100644 --- a/blt/ci.blt.yml +++ b/blt/ci.blt.yml @@ -19,8 +19,8 @@ project: drupal: db: - host: 127.0.0.1 + host: mysql port: 3306 - username: root - password: '' + username: drupal + password: drupal database: drupal diff --git a/blt/src/Blt/Plugin/Commands/HsCircleCiCommands.php b/blt/src/Blt/Plugin/Commands/HsCircleCiCommands.php deleted file mode 100644 index ad30d37bae..0000000000 --- a/blt/src/Blt/Plugin/Commands/HsCircleCiCommands.php +++ /dev/null @@ -1,285 +0,0 @@ -getSites(); - - if ($batch == 'install') { - $collection = $this->collectionBuilder(); - $this->prepEnvironment(); - $collection->addTask($this->blt()->arg('drupal:install')); - $collection->addTask($this->blt() - ->arg('codeception') - ->option('group', 'install', '=')); - return $collection->run(); - } - - $sites = array_chunk($sites, ceil(count($sites) / 2)); - if (!isset($sites[$batch])) { - throw new \Exception('Batch does not exist'); - } - $sites = array_combine($sites[$batch], $sites[$batch]); - $this->prepEnvironment(); - - $collection = $this->collectionBuilder(); - foreach (array_rand($sites, self::SITES_TO_TEST) as $site) { - $collection->addTaskList($this->syncAcquia($site)); - $collection->addTask($this->blt() - ->arg('codeception') - ->option('group', 'existingSite', '=')); - } - return $collection->run(); - } - - /** - * Update all dependencies and re-export the configuration. - * - * @command circleci:update - */ - public function updateDependencies($branch) { - $collection = $this->collectionBuilder(); - $this->prepEnvironment(); - $collection->addTask($this->blt()->arg('drupal:install')); - - $settings_file = $this->getConfigValue('docroot') . '/sites/settings/ci.settings.php'; - $collection->addTask($this->taskWriteToFile($settings_file) - ->line('$config["config_ignore.settings"]["ignored_config_entities"] = range(1, 100);') - ->line(PHP_EOL) - ->append()); - - $collection->addTask($this->taskDrush() - ->drush('config-import') - ->option('yes')); - $collection->addTask($this->taskComposerUpdate()->option('no-interaction')); - - $collection->addTask($this->taskDrush() - ->drush('updb') - ->option('yes') - ->drush('cache:rebuild') - ->drush('config:export') - ->option('yes')); - - $collection->addTask($this->taskGit()->exec("checkout $settings_file")); - - $collection->addTask($this->taskGitStack() - ->checkout($branch) - ->add('composer.lock config docroot') - ->commit('Updated dependencies ' . date('M j Y')) - ->push('origin', $branch)); - - return $collection->run(); - } - - /** - * Create a new branch for the next release. - * - * @param string $last_version - * Semver version. - * - * @command circleci:new-release-branch - */ - public function jobNewReleaseBranch(string $last_version) { - // Increment the last version by 1. - $new_version = $this->incrementVersion($last_version); - $this->yell("Creating new release: $new_version"); - - // Set module and profile version. Then update the changelog. - $this->setVersions($new_version); - - $new_branch = "$new_version-release"; - $message = "$new_version Release" . PHP_EOL . PHP_EOL . '# DO NOT DELETE'; - - // Create the new release branch in Github. - $tasks[] = $this->taskGitStack() - ->checkout("-b $new_branch"); - - $tasks[] = $this->taskGitStack() - ->add('-A') - ->commit("$new_version") - ->push('origin', $new_branch); - $tasks[] = $this->taskExec("gh pr create -B develop -b '$message' -f"); - $tasks[] = $this->blt()->arg('deploy'); - - $this->collectionBuilder()->addTaskList($tasks)->run(); - } - - /** - * Set the versions in the module & profile info files. - * - * @param string $version - * New version. - */ - protected function setVersions(string $version) { - // Update only profiles. - $dirs = [ - '*/profiles/humsci/su_*', - ]; - - foreach ($dirs as $dir) { - $modules = Finder::create() - ->files() - ->name('*.info.yml') - ->in($dir); - - /** @var \Symfony\Component\Finder\SplFileInfo $module */ - foreach ($modules as $module) { - // Don't need to update test modules. These inherit their versions. - if (strpos($module->getPath(), 'tests') !== FALSE) { - continue; - } - $info_file = Yaml::decode(file_get_contents($module->getRealPath())); - $info_file['version'] = $version; - file_put_contents($module->getRealPath(), Yaml::encode($info_file)); - } - } - } - - /** - * Perform some tasks to prepare the drupal environment. - */ - protected function prepEnvironment() { - $this->taskExec('dockerize -wait tcp://localhost:3306 -timeout 1m')->run(); - $this->taskExec('apachectl stop; apachectl start')->run(); - } - - /** - * Syncs the site to Acquia. - * - * We can't use drush sql-sync because it causes rsync issues when it tries - * to chown the files. - * - * @param string $site - * Machine name of the site to syn. - * - * @return \Robo\Task\Base\Exec[] - * Array of tasks. - */ - protected function syncAcquia($site = 'swshumsci') { - $tasks = []; - $tasks[] = $this->taskExec('mysql -u root -h 127.0.0.1 -e "CREATE DATABASE IF NOT EXISTS drupal"'); - - $docroot = $this->getConfigValue('docroot'); - - // To make things easy on setting up these tests, we'll just use the default - // directory for all site tests. But that means we need to bring over the - // site specific settings.php files too account for anything specific. - if ($site != 'default' && $site != 'swshusmci') { - $tasks[] = $this->taskFilesystemStack() - ->copy("$docroot/sites/$site/settings.php", "$docroot/sites/default/settings.php", TRUE); - } - - $tasks[] = $this->taskDrush() - ->alias('') - ->drush('sql-sync') - ->arg("@$site.prod") - ->arg('@self') - ->option('extra-dump', '--no-tablespaces --insert-ignore', '=') - ->option('structure-tables-key', 'lightweight') - ->option('create-db'); - - $tasks[] = $this->taskExecStack() - ->exec("rm -rf $docroot/sites/default/files"); - $tasks[] = $this->taskExecStack() - ->exec("mkdir $docroot/sites/default/files"); - $tasks[] = $this->taskExecStack()->exec("chmod 777 -R $docroot/sites/"); - $tasks[] = $this->blt()->arg('drupal:update'); - $tasks[] = $this->taskDrush() - ->drush('cache:rebuild'); - return $tasks; - } - - /** - * Return BLT. - * - * @return \Robo\Task\Base\Exec - * A drush exec command. - */ - protected function blt() { - return $this->taskExec('vendor/bin/blt') - ->option('no-interaction'); - } - - /** - * Advance to the next SemVer version. - * - * The behavior depends on the parameter $stage. - * - If $stage is empty, then the patch or minor version of $version is - * incremented - * - If $stage matches the current stage in the current version, then add - * one to the stage (e.g. alpha3 -> alpha4) - * - If $stage does not match the current stage in the current version, then - * reset to '1' (e.g. alpha4 -> beta1) - * - * Taken from consolidation/robo library. - * - * @param string $version - * A SemVer version. - * @param string $stage - * Release stage: dev, alpha, beta, rc or an empty string for stable. - * - * @return string - * New semver version. - */ - protected function incrementVersion($version, $stage = '') { - $stable = empty($stage); - - preg_match('/-([a-zA-Z]*)([0-9]*)/', $version, $match); - $match += ['', '', '']; - $versionStage = $match[1]; - $versionStageNumber = $match[2]; - if ($versionStage != $stage) { - $versionStageNumber = 0; - } - $version = preg_replace('/-.*/', '', $version); - $versionParts = explode('.', $version); - if ($stable) { - $versionParts[count($versionParts) - 1]++; - } - $version = implode('.', $versionParts); - if (!$stable) { - $version .= '-' . $stage; - if ($stage != 'dev') { - $versionStageNumber++; - $version .= $versionStageNumber; - } - } - return $version; - } - - /** - * Get all available sites in multisite setup. - * - * @return array - * Array of machine names for sites. - */ - protected function getSites() { - $sites = $this->getConfigValue('multisites'); - asort($sites); - return array_filter($sites, function ($site) { - return strpos($site, 'sandbox') === FALSE; - }); - } - -} diff --git a/composer.json b/composer.json index 3aed4fc4cb..c5be196d06 100644 --- a/composer.json +++ b/composer.json @@ -248,7 +248,7 @@ "https://www.drupal.org/project/google_analytics/issues/3373921": "https://www.drupal.org/files/issues/2023-08-07/google-analytics-issues-3373921-cannot-install-from-existing-config-11.patch" }, "drupal/hook_event_dispatcher": { - "https://www.drupal.org/project/hook_event_dispatcher/issues/3354751": "https://www.drupal.org/files/issues/2023-04-17/hook_event_dispatcher-4.x-3354751.patch" + "https://www.drupal.org/project/hook_event_dispatcher/issues/3354751": "https://git.drupalcode.org/project/hook_event_dispatcher/-/merge_requests/133.patch" }, "drupal/menu_block": { "https://www.drupal.org/project/menu_block/issues/3271218": "https://www.drupal.org/files/issues/2022-04-29/menu_block_rendered_empty-3271218-17.patch" diff --git a/composer.lock b/composer.lock index 7a7514f2a6..0539892ea8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b64fb2e68270728df32cb7eb2914818c", + "content-hash": "709631f80e51a0269df496bd0237c356", "packages": [ { "name": "acquia/blt", @@ -6725,17 +6725,17 @@ }, { "name": "drupal/hook_event_dispatcher", - "version": "4.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://git.drupalcode.org/project/hook_event_dispatcher.git", - "reference": "4.0.0" + "reference": "4.0.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/hook_event_dispatcher-4.0.0.zip", - "reference": "4.0.0", - "shasum": "9b11a07269ccf87e2c9b5e487aea3bcb425fcf5f" + "url": "https://ftp.drupal.org/files/projects/hook_event_dispatcher-4.0.1.zip", + "reference": "4.0.1", + "shasum": "a170035796c1f72f820bca5642f5de0117d51524" }, "require": { "drupal/core": "^10", @@ -6758,8 +6758,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "4.0.0", - "datestamp": "1709272506", + "version": "4.0.1", + "datestamp": "1710429583", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" diff --git a/docroot/sites/settings/ci.settings.php b/docroot/sites/settings/ci.settings.php index c3ac5dfb09..94d770e185 100644 --- a/docroot/sites/settings/ci.settings.php +++ b/docroot/sites/settings/ci.settings.php @@ -1,7 +1,32 @@ + [ + 'default' => + [ + 'database' => 'drupal', + 'username' => 'drupal', + 'password' => 'drupal', + 'host' => getenv('CIRCLECI') ? '127.0.0.1' : 'mysql', + 'port' => '3306', + 'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql', + 'driver' => 'mysql', + 'prefix' => '', + ], + ], +]; + +// On CircleCI we only do dependency updates. To help that work better, make sure +// the system doesn't ignore any configs. +if (getenv('CIRCLECI')) { + $config['config_ignore.settings']['ignored_config_entities'] = range(1, 100); +} + if (getenv('TUGBOAT_SERVICE')) { /** * Database configuration. @@ -24,7 +49,6 @@ ]; } - // Use development service parameters. $settings['container_yamls'][] = EnvironmentDetector::getRepoRoot() . '/docroot/sites/development.services.yml'; $settings['container_yamls'][] = EnvironmentDetector::getRepoRoot() . '/docroot/sites/blt.development.services.yml'; @@ -95,7 +119,6 @@ */ $settings['extension_discovery_scan_tests'] = FALSE; - /** * Configure static caches. * diff --git a/tests/codeception.dist.yml b/tests/codeception.dist.yml index 6ed76154a8..a4c0c77927 100644 --- a/tests/codeception.dist.yml +++ b/tests/codeception.dist.yml @@ -49,3 +49,13 @@ modules: cleanup_test: true cleanup_failed: false cleanup_suite: true +env: + ci: + modules: + config: + WebDriver: + url: 'http://drupal8ci/' + browser: chrome + host: selenium + port: 4444 + restart: true