Problem/Motivation

As core moves to merge requests we need to move https://github.com/alexpott/d8githooks in core because committers will doing merges and potentially clicking on buttons in the gitlab UI.

Proposed resolution

Add the pre-commit hook to core in the form of shell script.

DrupalCI already has some codebase quality checks but these have several issues the biggest being that because they are controlled by DrupalCI it is very hard for the commands to change between 9.1.x and 9.2.x for example. We should run these things the same as everyone else (CircleCI, github actions, Travis CI) and have a script in core run them. That way this script can change over time and be different in different branches.

Remaining tasks

Tidy up the script.
Add better documentation.

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

@todo

CommentFileSizeAuthor
#55 interdiff_41_54.txt1.31 KBSpokje
#54 3178845-54-d89.patch13.25 KBSpokje
#54 3178845-54-d89.patch13.25 KBSpokje
#53 interdiff_41_53.txt1.36 KBSpokje
#53 3178845-53-d89.patch13.16 KBSpokje
#52 interdiff_41_52.txt1.36 KBSpokje
#52 3178845-52-d89.patch13.16 KBSpokje
#41 3178845-41.patch13.68 KBalexpott
#41 36-41-interdiff.txt3.05 KBalexpott
#36 3178845-36.patch13.72 KBalexpott
#36 33-36-interdiff.txt696 bytesalexpott
#33 3178845-33.patch13.72 KBalexpott
#33 32-33-interdiff.txt667 bytesalexpott
#33 3178845-33-will-fail.patch17.9 KBalexpott
#32 3178845-32.patch13.67 KBalexpott
#32 3178845-32-will-fail.patch17.85 KBalexpott
#32 31-32-interdiff.txt2.87 KBalexpott
#31 3178845-31.patch12.97 KBalexpott
#31 27-31-interdiff.txt2.13 KBalexpott
#27 3178845-27.patch12.82 KBalexpott
#27 3178845-27-will-fail.patch17 KBalexpott
#27 25-27-interdiff.txt831 bytesalexpott
#25 3178845-25.patch12.49 KBalexpott
#25 23-25-interdiff.txt599 bytesalexpott
#23 3178845-23.patch12.49 KBalexpott
#23 3178845-23-will-fail.patch16.67 KBalexpott
#23 16-23-interdiff.txt3.9 KBalexpott
#16 3178845-16.patch11.61 KBalexpott
#16 9-16-interdiff.txt1.14 KBalexpott
#9 3178845-9.patch11.45 KBalexpott
#9 3178845-9-test.patch15.63 KBalexpott
#9 8-9-interdiff.txt3.07 KBalexpott
#8 3178845-8.patch10.34 KBalexpott
#8 3178845-8-test.patch14.52 KBalexpott
#6 3178845-6.patch11.09 KBalexpott
#5 3178845-5.patch15.27 KBalexpott
#4 3178845-4.patch15.14 KBalexpott
#3 3178845-3-test.patch11.21 KBalexpott
#2 3178845-2.patch10.8 KBalexpott
#2 3178845-2-test.patch11.21 KBalexpott

Issue fork drupal-3178845

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

alexpott created an issue. See original summary.

alexpott’s picture

Here's a start

alexpott’s picture

Let's try again.

alexpott’s picture

Let's add some more things that fail...

alexpott’s picture

Improving the output a bit.

alexpott’s picture

And here's a patch that shouldn't fail.

alexpott’s picture

Title: Run same checks as committers do it DrupalCI » Run same checks as committers do on DrupalCI
alexpott’s picture

  • Cleaned up the shell script and made indentation consistent.
  • Removed vendor check because it does make sense.
  • Remove command_exists() check because it is not used
  • Added pass / fail message and end of file check loop
alexpott’s picture

  • Improve the utility of the script for everyone by adding a --cached mode to only check staged files.
  • Add back vendor check because now we have the staged file check it is useful

The last submitted patch, 8: 3178845-8.patch, failed testing. View results

jonathan1055’s picture

This looks interesting. Not sure if you are ready for questions/review yet, as it is clear WIP. But the first thing I noticed is that it appears that the phpcs section in the new script does not write anything in the dispatcher log. Is that intentional? At least, I could not find 'phpcs' in the log, nor was there any output in the artifacts.

Please excuse me, and feel free not to answer in depth (or at all) if this is all still to be done.

alexpott’s picture

@jonathan1055 have a look at the output on https://www.drupal.org/pift-ci-job/1863285

CHECKING: core/lib/Drupal.php
----------------------------------------------------------------------------------------------------
[31m[1mgit pre-commit check failed:(B[m file core/lib/Drupal.php should be 644 not 755

FILE: /var/www/html/core/lib/Drupal.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 147 | ERROR | Content missing for @var tag in member variable
     |       | comment
----------------------------------------------------------------------

Time: 162ms; Memory: 6MB


core/lib/Drupal.php [31m[1mfailed(B[m
jonathan1055’s picture

Yes thanks, I did see that output. But when there is nothing produced (because phpcs passes everything) I could not see any evidence that is has actually been run. I was just thinking about some time in the future, when some bug stops the phpcs section from being triggered, it could be a while before it is noticed, if we get used to seeing no output and no record that it has been run (when all is passing). But this is a minor point, I did not want to distract you from the bigger tasks.

xjm’s picture

@jonathan1055 Making "Custom commands failed" actually raise a fail and mark the issue NW would be a Drupal infrastructure followup to this issue, I think. That said, committers would still not commit the patch with the "Custom commands failed" test result, and it's still a step up from where we are currently (where the error itself is only discovered when the committer goes to commit the patch on their local CLI).

Mixologic’s picture

The one thing I would suggest is that we dont keep this in core/scripts/ and actually start another scripts folder at the root of the project for development purposes.

Given that this script isnt intended to be part of the product, it also cordon's it off into an area that we can change, at will, without worry of whether or not somebody has come to rely on it.

alexpott’s picture

I think #15 is a good point but one we're not ready for yet. I've opened #3181570: Move scripts outside of /core/ that are not part of the end product. to discuss this further.

For now I'm moving the script to core/scripts/dev and adding an @internal to make very clear what the purpose and the promises of the script are.

xjm’s picture

Couple things in the patch seem like they might have been specific to running this in the actual commit workflow vs. on DrupalCI; questions below.

  1. +++ b/core/scripts/dev/commit-code-check.sh
    @@ -0,0 +1,313 @@
    +# cSpell:disable
    ...
    +# Set up variables to make coloured output simple.
    ...
    +  # For DrupalCI / default behaviour this is the list of all changes in the
    

    While it's fine to disable cspell on the file, we probably should still use core's standard AE spellings here?

  2. +++ b/core/scripts/dev/commit-code-check.sh
    @@ -0,0 +1,313 @@
    +  # Check staged files only.
    +  if git rev-parse --verify HEAD >/dev/null 2>&1
    

    Is this relevant for DrupalCI? (Or are the other cases?)

    Presumably the fail-patches prove that it works. It might be good to have a fail-patch that has a fail for each kind of check, just to make sure they're all running consistently. I read through https://www.drupal.org/pift-ci-job/1863278 and it seems to hit most of them, but not a PHPCS fail? Edit: It's there; just missed it searching the output for "PHPCS" because obviously the new yaml file is also being checked and passes.

  3. +++ b/core/scripts/dev/commit-code-check.sh
    @@ -0,0 +1,313 @@
    +# This script assumes that composer install and yarn install have already been
    +# run and all dependencies are updated.
    

    Can we guarantee this will always be the case on DrupalCI? I didn't realize yarn install would happen at all. What would a fail look like if they hadn't been?

xjm’s picture

Also, should we add documentation about how to run the thing locally?

xjm’s picture

+++ b/core/lib/Drupal.php
@@ -142,7 +144,7 @@ class Drupal {
-   * @var \Symfony\Component\DependencyInjection\ContainerInterface|null
+   * @var

So this was intended to be the PHPCS fail, but it didn't actually cause PHPCS to fail. Did PHPCS actually run? Or is this rule not enabled?

Never mind; I just didn't read far enough down in the result because of newlines. It is there.

xjm’s picture

Come to think of it, maybe it's worth retaining all the different logic for different git statuses so that it can be used locally (if we document it better).

xjm’s picture

Issue tags: +Needs change record

Also a CR.

xjm’s picture

Couple other thoughts:

  1. Do we expect the 80% usecase to be DrupalCI results, or results from running it locally? I'd expect the former. The color codes are nice on the CLI but pollute the DrupalCI result with what are, to the uninitiated, random characters.
  2. Similarly, for the DrupalCI case, could we omit outputting results for passing files? For a large patch, it's going to be hard to find the one coding standards error in the output for dozens of changed files. I don't know if the individual tools support this or not but it would help people understand the results (and avoid my mistake above).
alexpott’s picture

Thanks for the reviews.

#17.1 Fixed
#17.2 - as per #20 I think it is useful for people to be able to run these checks locally
#17.3 - yes we can - if they've not run DrupalCI does not work

Re #18 the command has help - I've added a message if this is run on DrupalCI and it fails to tell people how to reproduce the results locally.

Re #22.1 - I've added a special DrupalCI mode that no longer uses colour and I've added a DrupalCI issue so we can re-enable it - #3181869: Pift results should display console colors

Re #22.2 - I added this as a result on #13. However I agree that this is probably too verbose. I've trimmed the output a bit. It'd be nice to only show the fails in the error message but keep all the success messages in the log. Not sure yet how to achieve this. Or whether we want to block this on that. There are several options here:

  • Keep things as is - mix success and failure in the same output
  • Remove success out from DrupalCI until fixed - and open an @todo to add back the success output
  • Some other solution involving the the simpletest table that DrupalCI / PIFT uses for error reporting

I'm not sure which way to go. One problem is without the more verbose output to say which file is being tested it's a little tricky to parse the output so I think I'd leave things as is and then work on improving the reporting on Drupal.org

xjm’s picture

Priority: Normal » Major

Re: #18 I don't think a help flag in the script counts as documentation; the problem is that no one is going to find this to use it locally. I think the solution might actually be handbook documentation; maybe under https://www.drupal.org/docs/develop/standards or a level up? Then the CR could include a brief summary and link that handbook doc.

Bumping priority since this is a blocker for using merge requests for core. I debated on critical but there are technically two workarounds (simplest probably being committers downloading the plain diff and committing it that way, honestly).

+++ b/core/scripts/dev/commit-code-check.sh
@@ -68,6 +69,19 @@
+# Set up variables to make colored output simple. Color output is disable on

Typo: disabled.

alexpott’s picture

Fixing the typo.

Discussed this with @Mixologic. Turns out the approach is not going to work for Merge Requests because DrupalCI checks them out rather than applying them as a patch. So we need to detect this can change how we get the list of files. We're going to need to support both patches and MRs... fun.

alexpott’s picture

Okay I've worked out how to fix MR testing without any changes from DrupalCI. Atm I use PHP to do this but maybe doing something like

sed -n -E 's/^ *const VERSION = \'([0-9\.]*)-dev\';/\1/p' core/lib/Drupal.php

would be better... but sed is not the most portable thing.

alexpott’s picture

Can't prove that #27 works :( because in order for DrupalCI to use a changed drupalci.yml file it needs to detect it has changed... and that is broken atm. So if we committed this. It'd probably work but we can't prove that :(

Mixologic’s picture

Re: #28 That is only broken for right now for Merge Requests.

Everything in #27 worked as expected.

jonathan1055’s picture

Two minor grammar problems from the interdiff. It is worth getting these comments right.

+# If the FILES is empty the assume we're on a branch and we want to diff
+# against the Drupal branch. This always DrupalCI to do MR testing.

1. the assume -> then assume
2. "This always DrupalCI to do MR testing." is not a complete sentence. Is there a word missing?

alexpott’s picture

@jonathan1055 good point. I've fixed the comments and move things around a bit.

Also I think this points to the fact we might want to add a --branch option for human users in the future to make it really easy to run the checks locally when doing a merge request.... hmmm... actually writing that out makes me realise with should ship with that functionality.

alexpott’s picture

Adding branch functionality and using in the help message on DrupalCI so people using merge requests can reproduce the results locally.

alexpott’s picture

So the good news is now we get the same custom commands failed for MRs! yay.

I think the output on https://www.drupal.org/pift-ci-job/1887087 is pretty good. @Mixologic has raised some concerns. However it's not often that so many files fails and the most unclear part - the css and js build stuff is super rare. I think we could choose to iterate and improve on this once this lands.

alexpott’s picture

Created a change record - https://www.drupal.org/node/3185278

xjm’s picture

I think this is probably good to go, if we can get that handbook page somewhere?

alexpott’s picture

We should make the script executable.

I've created https://www.drupal.org/docs/develop/development-tools/running-core-devel... - feels a bit weird to maintain this and the CR - perhaps the CR should just point there so we only have one place to maintain.

catch’s picture

perhaps the CR should just point there so we only have one place to maintain.

+1.

alexpott’s picture

I updated the CR to point to the handbook page.

catch’s picture

Status: Needs review » Reviewed & tested by the community

Let's get this up and running - it's getting urgent with the number of merge requests against core.

lauriii’s picture

Status: Reviewed & tested by the community » Needs work

Mostly nitpicks that could be fixed on commit but thought it might be worthwhile fixing the file permission messages in a patch.

  1. +++ b/core/scripts/dev/commit-code-check.sh
    @@ -0,0 +1,365 @@
    +# - PHPCS checks php and yaml files.
    

    Nit: s/php/PHP, s/yaml/YAML

  2. +++ b/core/scripts/dev/commit-code-check.sh
    @@ -0,0 +1,365 @@
    +# - Eslint checks javascript files.
    

    Nit: s/javascript/JavaScript

  3. +++ b/core/scripts/dev/commit-code-check.sh
    @@ -0,0 +1,365 @@
    +# - Stylelint checks css files.
    

    Nit: s/css/CSS

  4. +++ b/core/scripts/dev/commit-code-check.sh
    @@ -0,0 +1,365 @@
    +        printf "${red}git pre-commit check failed:${reset} file $FILE should be 644 not $STAT\n"
    ...
    +    printf "${red}git pre-commit check failed:${reset} file in vendor directory being committed ($FILE)\n"
    ...
    +    printf "${red}git pre-commit check failed:${reset} file in core/node_modules directory being committed ($FILE)\n"
    

    Should we change the message to not mention git pre-commit check given that this is now run as part of the CI process?

  5. +++ b/core/scripts/dev/commit-code-check.sh
    @@ -0,0 +1,365 @@
    +    # Work out the root name of the Javascript so we can ensure that the ES6
    

    Nit: s/Javascript/JavaScript

alexpott’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
3.05 KB
13.68 KB

As #40 is all nits set back to rtbc.

I've not bothered to update the MR because there are no logic changes.

lauriii’s picture

Version: 9.2.x-dev » 9.1.x-dev

Committed 5486534 and pushed to 9.2.x. Thanks!

Leaving open for backport to 9.1.x.

  • lauriii committed 5486534 on 9.2.x
    Issue #3178845 by alexpott, xjm: Run same checks as committers do on...
alexpott’s picture

Title: Run same checks as committers do on DrupalCI » [backport] Run same checks as committers do on DrupalCI

I can't imagine we'd commit a fix to 9.1.x without committing it to 9.2.x first so as long as the patch has been run against 9.2.x... oh hmmm... that's actually a good reason to backport this to 9.1.x - because we file issues against 9.1.x and have test run against that branch. So yeah +1 from me for backport.

Once we have in 9.1.x we might consider adding this to 8.9.x albeit without cspell because that's a 9.1.x only check.

xjm’s picture

Adding credit for @Mixologic as well; while he didn't comment on the issue much he did help fix the approach for MRs.

xjm’s picture

Also made a couple improvements to the CR, including fixing a11y for the link (always use a meaningful link text, folks) as well as explaining what actually happens when the checks fail and how to find out what the failures are.

xjm’s picture

Oh and also +1 for the backport to at least 9.1.x. I'll ask @catch for thoughts on 8.9.x.

catch’s picture

So 9.2.x is the only branch where mistakes will accumulate (all previous branches are dead-ends), BUT 9.1.x is the canonical branch for docs now, so we should definitely backport it there (as well as the potential for tests to not run on 9.2.x at all). For 8.9.x it seems more likely we'll have diverging patches that need their own test run, and also people will probably continue to look at 8.9.x docs when working on 8.9.x sites in case the 9.x docs have changed. So... let's backport it to both IMO. If there is an unforseen problem, we can roll it back or deal with it when it comes up.

  • lauriii committed cbe7ab1 on 9.1.x
    Issue #3178845 by alexpott, xjm: Run same checks as committers do on...
lauriii’s picture

Version: 9.1.x-dev » 8.9.x-dev
Status: Reviewed & tested by the community » Needs work

Cherry-picked to 9.1.x. Based on #44 we need new patch for 8.9.x so moving back to needs work for that.

Spokje’s picture

Assigned: Unassigned » Spokje

Rolling 8.9.x patch

Spokje’s picture

Not sure what the state of the MR is, so adding this a POP (=Plain Ol' Patch) based on @laurii's commit

Spokje’s picture

FileSize
13.16 KB
1.36 KB

Let's try this then!
#IHateTestBot

Spokje’s picture

3rd time lucky!
#TestBotMightBeOK

Spokje’s picture

FileSize
1.31 KB

Who needs 3 attempts when you can use 4! 🤦

Spokje’s picture

Assigned: Spokje » Unassigned
Status: Needs work » Needs review

Seems to work and doing no spell checks.

Relevant console log for the 8.9.x patch:

00:01:35.371 ----------------   Starting container_command.commit-checks   ----------------
00:01:35.379 Directory created at /var/lib/drupalci/workspace/jenkins-drupal_patches-71626/ancillary/container_command.commit-checks
00:01:35.379 Container command.
00:01:35.379 core/scripts/dev/commit-code-check.sh --drupalci
00:01:35.946 
00:01:35.946 ----------------------------------------------------------------------------------------------------
00:01:35.946 Checking core/scripts/dev/commit-code-check.sh
00:01:35.946 
00:01:35.946 core/scripts/dev/commit-code-check.sh passed
00:01:35.946 
00:01:35.947 ----------------------------------------------------------------------------------------------------
00:01:35.947 Checking core/drupalci.yml
00:01:35.947 
00:01:36.105 PHPCS: core/drupalci.yml passed
00:01:36.105 core/drupalci.yml passed
00:01:36.105 
00:01:36.105 ----------------------------------------------------------------------------------------------------
00:01:36.120 ---------------- Finished container_command.commit-checks in 0.748 seconds ---------------- 

Compare to relevant console log from 9.2.x patch:

00:02:57.131 ----------------   Starting container_command.commit-checks   ----------------
00:02:57.138 Directory created at /var/lib/drupalci/workspace/jenkins-drupal_patches-71431/ancillary/container_command.commit-checks
00:02:57.138 Container command.
00:02:57.138 core/scripts/dev/commit-code-check.sh --drupalci
00:02:59.669 CSpell: Files checked: 2, Issues found: 0 in 0 files
00:02:59.689 
00:02:59.689 CSpell: passed
00:02:59.689 
00:02:59.689 ----------------------------------------------------------------------------------------------------
00:02:59.690 Checking core/scripts/dev/commit-code-check.sh
00:02:59.690 
00:02:59.690 core/scripts/dev/commit-code-check.sh passed
00:02:59.690 
00:02:59.690 ----------------------------------------------------------------------------------------------------
00:02:59.690 Checking core/drupalci.yml
00:02:59.690 
00:02:59.855 PHPCS: core/drupalci.yml passed
00:02:59.855 core/drupalci.yml passed
00:02:59.855 
00:02:59.855 ----------------------------------------------------------------------------------------------------
00:02:59.871 ---------------- Finished container_command.commit-checks in 2.739 seconds ---------------- 
alexpott’s picture

Status: Needs review » Reviewed & tested by the community

I've reviewed the interdiff for the Drupal 8 patch and it looks good. DrupalCI is also happy running the script. Therefore this is RTBC for the release managers to decide.

  • catch committed 9e6e2e5 on 8.9.x
    Issue #3178845 by alexpott, Spokje, xjm, lauriii, Mixologic: [backport]...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed the backport to 8.9.x, thanks! Let's see how this goes, can always roll back if there's a problem.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

catch’s picture

Title: [backport] Run same checks as committers do on DrupalCI » Run same checks as committers do on DrupalCI