-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tooling: Introduce pre-commit CHANGELOG verification #13594
Conversation
So does this mean that every change in a commit must be accompanied by a change in the Assuming most merges of pulls happen via the github ui/ux I wonder if we should instead use the github checks api via a custom github app and it checks there is a changelog entry for the changed code. We probably could base a custom app off of something like this. We could then enforce blocking merges of pulls unless there is a changelog entry. If there are scenarios where a merge to master happens outside of the github ui then maybe we should investigate also doing a check similar to what you did in here but only on the merge commit to master? |
The problem is that Lerna is dumb, and can't differentiate this point. It sees a touched file, it's going to prompt for publishing a new version. It also can't be on the person doing the publish to follow back the un-logged change to its source. Presumably, if the file needed to be touched in a package, the change ought to be able to be described as standing on its own legs, as the modules themselves are meant to be standalone, not purely in service of some other thing.
I started down this path as well, even looking forward to things like actions to make these sorts of workflow automations easier / more integrated to GitHub. The problem I faced is: I really don't want to go through the trouble of begging for an app to be approved for use in the WordPress organization. Or at least, it seemed there were viable alternatives by starting this as either just a pre-commit check, or as a step in the existing Travis build. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will take a closer look tomorrow but I think this is exactly what we would need for start.
* | ||
* @type {Set} | ||
*/ | ||
const verified = new Set; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it okey to omit parentheses?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it okey to omit parentheses?
Yes:
new Foo
is equivalent tonew Foo()
, i.e. if no argument list is specified,Foo
is called without arguments.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new#Description
Though some people might argue it's better to just be consistent:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. I'm fine to leave it as is if JS is happy :)
bin/check-changelog.js
Outdated
* Example (Error): | ||
* | ||
* ``` | ||
* node bin/check-changelog.js /Gutenberg/packages/i18n/src/index.js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this comment correct? I would expect something containing Missing CHANGELOG.md entry for...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this comment correct? I would expect something containing
Missing CHANGELOG.md entry for...
It's an example of a failing call, so yes, it would log the message.
@@ -197,6 +199,9 @@ | |||
"*.js": [ | |||
"wp-scripts lint-js" | |||
], | |||
"packages/*/**": [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to verify my assumption, but it might not work as intended for PR that has multiple commits. Use case I'm about to test is as follows:
- add
CHANGELOG.md
changes upfront and commit - add code changes with another commit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is what actually happened:
⚠️ Missing CHANGELOG.md entry for compose package edits.
More information: https://github.com/WordPress/gutenberg/blob/master/packages/README.md#maintaining-changelogs
It works as expected based on the implementation but we need to find a way to improve it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment: https://github.com/WordPress/gutenberg/pull/13594/files#r252659482
It works fine for a single commit but fails when CHANGELOG.md
was already updated in one of the previous commits and isn't included in the commit with code changes.
Yes, I can see that being an issue. I'd justified it in my head as the sort of thing where the developer ought to always include the CHANGELOG with the change itself. It ties a bit into the noted "future goal" of allowing the file arguments to be optional and have the tool refer to the branch history instead if omitted. |
This was kind of what I was getting at in my earlier comment though. I think practically, while the initial change a developer commits could include the CHANGELOG entry, pulls often have fixes needed as a result of a review and this creates extra friction for those subsequent commits. |
This doesn't stop someone from bundling many changes in the same branch, or in the same commit, it just requires that the CHANGELOG for each touched package would be updated as part of the commit, which is the point of the change we're trying to make. @gziolo's example of preemptively updating a CHANGELOG in a separate, earlier commit is a very niche example; it's not something I'd expect anyone to be doing. |
It's extreme but very close to how I patch PRs when I spot mistakes after self-review on GitHub for newly pushed PR. |
Maybe I'm misreading, but is that not a commit which takes place after the original change, i.e. the exact thing this pull request would prevent from being allowed to happen? The problem workflow I see is if someone (a) edited a changelog, (b) committed it, and (c) made the change corresponding the changelog note in a subsequent separate commit. |
I think it's every workflow for the existing PR where you add a new commit which contains only code changes but no update to the changelog file. |
That is what this validation will catch and prevent from happening. The developer can then just add the CHANGELOG entry. What I meant by "problem" in my previous commit is one which leaves the developer in an awkward unresolvable (at least not without a few extra steps) scenario. |
Per previous comments and as discussed in this week's #core-js meeting, I've made improvements in a9514c7 to consider whether a previous commit would satisfy the requirement of a CHANGELOG revision having been made for an affected file. The changes here are also quite nice in letting the script be run directly, without arguments, as a verification of the current branch. In other words, this could be used without any additional changes as part of a Travis task for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like these changes 👍
8f181e8
to
5509cc4
Compare
`\u00A0\u00A0\u00A0More information: https://github.com/WordPress/gutenberg/blob/master/packages/README.md#maintaining-changelogs\n` | ||
); | ||
|
||
process.exit( 1 ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will exit as soon as it will find the first violation, there might be more than one if several packages are updated. I don't consider it as a blocker but sharing here so we could discuss whether we should make iterate further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will exit as soon as it will find the first violation, there might be more than one if several packages are updated. I don't consider it as a blocker but sharing here so we could discuss whether we should make iterate further.
I can probably improve this without too much trouble 👍
* | ||
* @type {string} | ||
*/ | ||
const base = exec( 'git merge-base master HEAD' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part is tricky and might cause a lot of confusion because we reference the local copy of master
branch. I run into this issue locally where my master
branch is out of date if you compare with the upstream. Therefore when I run this script I see missing CHANGELOG.md
files in folders that weren't updated in the branch where I tried to add a new commit. In fact, I wanted to add a new commit directly to this branch to verify how it would work with some flows. In my case git merge-base origin/master HEAD
solves the issue, but that might differ for forks and can be also changed to something else.
I'm also wondering if this isn't a temporary issue caused by the fact that we don't update changelog files in a way this should happen. My assumption is that it wouldn't be an issue when this change lands and folks update their master
to the latest version.
As a way to avoid so much confusion maybe we should include the note prompting to update master
to the latest version and try again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the up to date master
branch it works like a charm ✨
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part is tricky and might cause a lot of confusion because we reference the local copy of
master
branch. I run into this issue locally where mymaster
branch is out of date if you compare with the upstream.
Argh, I'd hoped to have found some reliable way here. The other trouble too with dealing with branches is that Travis does some funny things with branches, which makes using the git
command not as reliable (reference).
There's seemingly many ways to check for differences; I want to dig to see if there could be another option here, before resorting to the forced update prompt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jest supports something similar with the following flags:
- --changedSince - "Runs tests related to the changes since the provided branch. If the current branch has diverged from the given branch, then only changes made locally will be tested."
- --onlyChanged - "Attempts to identify which tests to run based on which files have changed in the current repository."
It might be a nice way to compare the approach they took.
It seems like we very rarely update the package changelogs and it's understandable since it's not enforced. I'd think that we should make a decision. Try to land this PR or abandon these package changelogs entirely. Maybe something for the next #core-js chat |
Lines 960 to 967 in 548e600
We use those CHANGELOG entries to automate version bumps for npm packages. It's very important for the tooling that might have breaking changes more often. I admit it's less of an issue for packages that contain components, but it still might be useful in some cases. |
@youknowriad I'm keen to revisit this. Especially as the project has matured, the need to effectively communicate changes in individual packages has become increasingly a concern of mine. But one thing which would be prudent is to try to consider just how we expect these to be used. I think there's a lot of important information that can be included in these CHANGELOGs, and it's for this reason we've thought it crucial they be updated. (Aside: Looking back at my original comment, I feel I could have been more clear with these reasons) On the consuming end, we might want to think more about: (a) if and how they get incorporated into the Gutenberg release notes, (b) how someone like a plugin author can use these notes to know about upcoming or past changes associated with a WordPress release. A CHANGELOG workflow may be familiar for someone consuming packages from NPM, and this is certainly a use-case we want to support via these updates. I think it's also fair to say that at the current moment, it's not necessarily the primary one motivating these changes (save for a few packages like Or, at least, in addressing the other concern about how this may be viewed as a burden for contributors who aren't currently used to this being part of the workflow, it would be easier to do so if we could can clearly demonstrate the value that they bring. I have a few more specific tactical remarks I have in mind here. I'll consider those in a separate comment. |
Clearly not a lot of urgency with this one, so will go ahead and close as stale. Future work could pick this back up, mindful of the fact that some of the git operations may need to be updated (e.g. references to "master" branch). |
This pull request seeks to explore adding a pre-commit script which verifies that the contents of the pending commit include a
CHANGELOG.md
revision if applicable (i.e. within a packages directory, and not considered as an "ignored" change by Lerna).Testing instructions:
With the branch checked out, verify a few combinations of commit attempts:
README.md
)packages/i18n/benchmark/index.js
), without CHANGELOGpackages/i18n/src/index.js
), without CHANGELOGpackages/i18n/src/index.js
), with CHANGELOGFuture tasks:
It would be difficult to integrate this into a build step in its current form, as the script expects to receive the changed file paths as arguments. It should be enhanced to also retrieve a list of changed files from the current branch history.
The current incarnation can serve as a good, less-disruptive initial workflow to allow for some flexibility in the risk of false positives.