From b7a7fde69544525c7fd37540a12a32d2252fa857 Mon Sep 17 00:00:00 2001 From: Matt Poole Date: Thu, 17 Oct 2024 16:36:16 -0400 Subject: [PATCH 1/4] DIGITAL-36: Added validation package and github action to run it. --- .github/workflows/run-validation.yml | 67 ++++++++++++++++++++++++++++ composer.json | 3 +- composer.lock | 53 +++++++++++++++++++++- composer.log | 1 + robo.yml | 24 ++++++++++ 5 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/run-validation.yml create mode 100644 robo.yml diff --git a/.github/workflows/run-validation.yml b/.github/workflows/run-validation.yml new file mode 100644 index 0000000..54951fe --- /dev/null +++ b/.github/workflows/run-validation.yml @@ -0,0 +1,67 @@ +name: Run validation with RoboValidate + +on: + # Run on any branch so validate branch can always run. + push: + # Commit message validation requires a target branch which is only available in a PR. + pull_request: + +jobs: + validate: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + tools: composer:v2 + # https://github.com/shivammathur/setup-php?tab=readme-ov-file#disable-coverage + coverage: none + + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache Composer dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer + + - name: Install Composer dependencies and initialize Robo + run: | + composer install --ignore-platform-reqs --optimize-autoloader --no-progress --no-ansi + # If a Robo command exits with a failure and a RoboFile.php does not exist + # a warning about 'Robo is not initialized here. Please run `robo init` to create a new RoboFile.' + # will be created, which might make users think that is what the error was caused by. + if [ ! -f "RoboFile.php" ]; then + vendor/bin/robo init + fi + + - name: Validate a change to any branch + if: github.event_name == 'push' + run: | + # Initialize status variables to 0 + status1=0 + status2=0 + status3=0 + + # Run all commands and capture their exit statuses + vendor/bin/robo validate:branch-name || status1=$? || status1=0 + vendor/bin/robo validate:composer-lock || status3=$? || status3=0 + vendor/bin/robo validate:coding-standards || status2=$? || status2=0 + + # Exit with a non-zero status if any command failed + if [ "$status1" -ne 0 ] || [ "$status2" -ne 0 ] || [ "$status3" -ne 0 ]; then + exit 1 + fi + + - name: Validate pull requests + if: github.event_name == 'pull_request' + run: | + vendor/bin/robo validate:commit-messages --target-branch="${{ github.base_ref }}" --current-branch="${{ github.head_ref }}" diff --git a/composer.json b/composer.json index bc09e7e..7cff450 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,8 @@ "drush/drush": "^12.5", "league/commonmark": "^2.5", "mattsqd/drupal-env": "dev-main", - "mattsqd/drupal-env-lando": "dev-main" + "mattsqd/drupal-env-lando": "dev-main", + "mattsqd/robovalidate": "@alpha" }, "conflict": { "drupal/drupal": "*" diff --git a/composer.lock b/composer.lock index 4b35db0..0473f73 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": "c09325fc5ce8d438b5d896382459119e", + "content-hash": "a0cdbb65e9f93a9932dc2395b10df5e2", "packages": [ { "name": "asm89/stack-cors", @@ -4100,6 +4100,54 @@ }, "time": "2024-07-31T19:04:40+00:00" }, + { + "name": "mattsqd/robovalidate", + "version": "1.4.0-alpha", + "source": { + "type": "git", + "url": "https://github.com/mattsqd/robovalidate.git", + "reference": "db39f0605b1a1a2d94f36a57e07237d0f2326217" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mattsqd/robovalidate/zipball/db39f0605b1a1a2d94f36a57e07237d0f2326217", + "reference": "db39f0605b1a1a2d94f36a57e07237d0f2326217", + "shasum": "" + }, + "require": { + "consolidation/robo": "^3.0.9 || ^4.0.1", + "php": ">=8.0.17" + }, + "require-dev": { + "composer/composer": "^2.5", + "squizlabs/php_codesniffer": "^3.6" + }, + "suggest": { + "squizlabs/php_codesniffer": "Recommended if wanting to validate coding standards." + }, + "type": "robo-tasks", + "autoload": { + "psr-4": { + "RoboValidate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "mattsqd", + "email": "mattsqd@users.noreply.github.com" + } + ], + "description": "A group of Robo commands that run various validation tasks on local environments or pipelines", + "support": { + "issues": "https://github.com/mattsqd/robovalidate/issues", + "source": "https://github.com/mattsqd/robovalidate/tree/1.4.0-alpha" + }, + "time": "2024-07-31T17:51:40+00:00" + }, { "name": "mck89/peast", "version": "v1.16.3", @@ -13633,7 +13681,8 @@ "drupal/scheduler_content_moderation_integration": 10, "drupal/uswds_templates": 20, "mattsqd/drupal-env": 20, - "mattsqd/drupal-env-lando": 20 + "mattsqd/drupal-env-lando": 20, + "mattsqd/robovalidate": 15 }, "prefer-stable": true, "prefer-lowest": false, diff --git a/composer.log b/composer.log index 65747ff..fb31c54 100644 --- a/composer.log +++ b/composer.log @@ -19,3 +19,4 @@ ae2759e9c45acbf0d8378d04e842d0a8|Matt Poole|develop|Tue Jul 2 13:45:43 EDT 2024 8a86ff66fb8673b6889c9c4b0ab02673|Christian Medders|feature/config-content-types|Fri Oct 11 10:58:09 EDT 2024|./composer.sh require drupal/field_group 4df8b37fbf31532557c120dddc00593b|Cathy Baptista|feature/dg-26-add-paragraphs-to-content-types|Fri Oct 11 12:00:34 EDT 2024|./composer.sh require drupal/paragraphs 834a753fafaa65adba97795d28e5f6b0|Christian Medders|feature/dg-25-enable-auto-complete|Tue Oct 15 14:25:50 EDT 2024|./composer.sh require drupal/inline_entity_form:^3.0@RC +85ee634efd1237c31d3f2d88c373a543|Matt Poole|feature/DIGITAL-36-validate-action|Thu Oct 17 16:16:53 EDT 2024|./composer.sh require mattsqd/robovalidate:@alpha diff --git a/robo.yml b/robo.yml new file mode 100644 index 0000000..0bb4757 --- /dev/null +++ b/robo.yml @@ -0,0 +1,24 @@ +# Automatically Generated from 'robo validate:init-robo-yml'. +# See ./vendor/mattsqd/robovalidate/robo.example.yml for additional context. +command: + validate: + options: + project-id: DIGITAL + branch-name: + options: + # These refer to all the possible branch names. There are 4 different types and they will be + # described below. If you'd like to override any of these, you must put all back in that you'd like to + # use, they will not be merged together. + valid-branch-names: + # Matches a branch named 'develop'. + - 'explicit|develop' + # Matches a branch named 'main'. + - 'explicit|main' + # Matches a custom regular expression found in $pattern. + - 'custom|' + # Matches a branch like: hotfix/2.1.3. + - 'semantic|hotfix' + # Matches a branch like (the last number MUST be a 0): release/2.1.0. + - 'semantic_end_0|release' + # Matches a branch named 'stage' (MOD FROM DEFAULTS). + - 'explicit|stage' From e98fb83ebc9445943dcf60c4ebcf2aa9300f8af1 Mon Sep 17 00:00:00 2001 From: Matt Poole Date: Thu, 17 Oct 2024 16:52:41 -0400 Subject: [PATCH 2/4] DIGITAL-36: Make the theme add .min as a suffix for JS and CSS compiled so that they would be skipped by coding standards. --- web/themes/custom/digital_gov/digital_gov.libraries.yml | 8 ++++---- .../custom/digital_gov/gulp-includes/gulp/scripts.js | 2 ++ .../custom/digital_gov/gulp-includes/gulp/styles.js | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/web/themes/custom/digital_gov/digital_gov.libraries.yml b/web/themes/custom/digital_gov/digital_gov.libraries.yml index ec22e65..1436797 100644 --- a/web/themes/custom/digital_gov/digital_gov.libraries.yml +++ b/web/themes/custom/digital_gov/digital_gov.libraries.yml @@ -1,9 +1,9 @@ # Main theme library. global: js: - static/dist/js/main.js: { minified: true } - static/dist/js/uswds.js: {} - static/dist/js/uswds-init.js: {} + static/dist/js/main.min.js: { minified: true } + static/dist/js/uswds.min.js: { minified: true } + static/dist/js/uswds-init.min.js: { minified: true } css: base: - static/dist/styles.css: { minified: true } + static/dist/styles.min.css: { minified: true } diff --git a/web/themes/custom/digital_gov/gulp-includes/gulp/scripts.js b/web/themes/custom/digital_gov/gulp-includes/gulp/scripts.js index d96b363..a32c8c7 100644 --- a/web/themes/custom/digital_gov/gulp-includes/gulp/scripts.js +++ b/web/themes/custom/digital_gov/gulp-includes/gulp/scripts.js @@ -1,6 +1,7 @@ const { src, dest, series } = require("gulp"); const webpack = require("webpack-stream"); const compiler = require("webpack"); +const rename = require("gulp-rename"); const TerserPlugin = require('terser-webpack-plugin'); // Directories @@ -55,6 +56,7 @@ function compile() { compiler ) ) + .pipe(rename({ suffix: ".min" })) .pipe(dest(JS_DEST, { sourcemaps: true })); } diff --git a/web/themes/custom/digital_gov/gulp-includes/gulp/styles.js b/web/themes/custom/digital_gov/gulp-includes/gulp/styles.js index 9631426..d40fd6f 100644 --- a/web/themes/custom/digital_gov/gulp-includes/gulp/styles.js +++ b/web/themes/custom/digital_gov/gulp-includes/gulp/styles.js @@ -106,6 +106,7 @@ function buildSass() { return ( src([`${PROJECT_SASS_SRC}/**/*.scss`]) .pipe(sourcemaps.init({ largeFile: true })) + .pipe(rename({ suffix: ".min" })) .pipe( sass({ includePaths: [ From c622e84d26ed29a1e782bce55a751034f71a8787 Mon Sep 17 00:00:00 2001 From: Matt Poole Date: Thu, 17 Oct 2024 16:58:18 -0400 Subject: [PATCH 3/4] DIGITAL-36: Coding standards. --- .../custom/convert_text/src/ConvertText.php | 20 +++++++++---------- .../convert_text/src/Form/ConvertTextForm.php | 4 ++-- .../custom/digital_gov/digital_gov.theme | 5 +++++ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/web/modules/custom/convert_text/src/ConvertText.php b/web/modules/custom/convert_text/src/ConvertText.php index a1b274e..115706d 100644 --- a/web/modules/custom/convert_text/src/ConvertText.php +++ b/web/modules/custom/convert_text/src/ConvertText.php @@ -22,7 +22,7 @@ class ConvertText { * @return string * The converted text. */ - static protected function convertText(string $source_text, string $field_type): string { + protected static function convert(string $source_text, string $field_type): string { // Start by removing space before and after. $source_text = trim($source_text); // Remove extra spaces before new lines. @@ -30,7 +30,7 @@ static protected function convertText(string $source_text, string $field_type): switch ($field_type) { case 'plain_text': - return html_entity_decode($source_text,ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 , 'UTF-8'); + return html_entity_decode($source_text, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8'); case 'html': $converter = new CommonMarkConverter(); @@ -49,23 +49,23 @@ static protected function convertText(string $source_text, string $field_type): * The original source value. * * @return string - * The converted text. + * The converted text. */ - static public function plainText(string $source_text): string { - return self::convertText($source_text, 'plain_text'); + public static function plainText(string $source_text): string { + return self::convert($source_text, 'plain_text'); } /** * Gets text ready to be stored in html text fields. * * @var string $source_text - * The original source value. + * The original source value. * * @return string - * The converted text. + * The converted text. */ - static public function htmlText(string $source_text): string { - return self::convertText($source_text, 'html'); + public static function htmlText(string $source_text): string { + return self::convert($source_text, 'html'); } -} \ No newline at end of file +} diff --git a/web/modules/custom/convert_text/src/Form/ConvertTextForm.php b/web/modules/custom/convert_text/src/Form/ConvertTextForm.php index 39a067f..015af1c 100644 --- a/web/modules/custom/convert_text/src/Form/ConvertTextForm.php +++ b/web/modules/custom/convert_text/src/Form/ConvertTextForm.php @@ -4,9 +4,9 @@ namespace Drupal\convert_text\Form; -use Drupal\convert_text\ConvertText; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; +use Drupal\convert_text\ConvertText; /** * Provides a Convert Text form. @@ -57,7 +57,7 @@ public function buildForm(array $form, FormStateInterface $form_state): array { 'reset' => [ '#type' => 'submit', '#value' => $this->t('Reset'), - ] + ], ]; return $form; diff --git a/web/themes/custom/digital_gov/digital_gov.theme b/web/themes/custom/digital_gov/digital_gov.theme index 63a6942..41fa202 100644 --- a/web/themes/custom/digital_gov/digital_gov.theme +++ b/web/themes/custom/digital_gov/digital_gov.theme @@ -1,5 +1,10 @@ Date: Mon, 21 Oct 2024 13:18:07 -0400 Subject: [PATCH 4/4] DIGITAL-36: Added validation help to CONTRIBUTING.md. --- CONTRIBUTING.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f51e9f7..2427729 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,8 +40,22 @@ Simply edit or add new content, then run `./robo.sh drupal-project:export-conten ## Validation -We will soon have validation on branches, commits, composer.lock, and code. I'm waiting until our move to Jira. + * Uses [RoboValidate](https://github.com/mattsqd/robovalidate) to run the various validations. + * Can be run manually locally via: `./robo.sh validate:all` + * Is run when any branch is pushed to GitHub via GitHub Actions. Validation on Git commits is only run remotely when a pull request is made so that only new commits are checked. -To start: -* Follow Drupal & DrupalPractice coding standards. -* Create feature branches in the form `feature/short-description` +### Branch Names + +All branches created towards tasks should be in the form `feature/DIGITAL-X-Y`. `X` is the Jira ticket number and `Y` is a short description in lower case separated by dashes. + +### Commits + +Commit messages must be in the form: `DIGITAL-X:YZ`. `X` is the Jira ticket number, `Y` is a space and `Z` is a short description of the work done. + +### Coding Standards + +See the [coding standards](https://www.drupal.org/docs/develop/standards) documentation for Drupal. The project validates against the `Drupal` and `DrupalPractice` documentation. + +#### IDE + +[Enable coding standards help in your IDE](https://www.drupal.org/docs/extending-drupal/contributed-modules/contributed-module-documentation/coder/installing-coder#s-ide-and-editor-configuration) so you're not surprised by a bunch of errors when you push up.