Discussion: custom configuration
z0al opened this issue ยท 33 comments
I would like to discuss what things I need to consider when supporting custom configuration files in the root repository directory.
More specifically, how can we support .commitlint.yml or .commitlint.json ? I can't see any way to support .js based config files
Any input is welcome!
cc @marionebl
I rolled this around a bit already here are my thoughts:
- Look up
.?commitlint.{js,yml.json}andpatternplateinpackage.jsonvia the Github API instead of FS - Load the contents of first match via Github API
3a).ymland.json: parse the files
3b).js: Idea: Run the script in a safe node sandbox with most features and APIs (e.g. require) disabled/limited - Resolve relative
.extendsand.parserPreset, goto 2 - Use absolute
.extendsand.parserPresetif they are found in a defined whitelist
cc @paulirish
@marionebl Thank you for sharing this
Look up .?commitlint.{js,yml.json} and patternplate in package.json via the Github API instead of FS
I have no idea what patternplate is and how it's related to commitlint?
Whoops, I meant commitlint, referring to the feature of cosmiconfig where config is read from a section in package.json
I do not have a good solution for making this work with things like commitlint-config-lerna though without cloning the repository.
I understand correctly now.sh is the primary deployment target for probot?
I think a command line approach ( like how bundlesize works) may fits things like commitlint-config-lerna
I understand correctly now.sh is the primary deployment target for probot?
I may only use now.sh - at least for now. Other services are forbidden in my country :/
Here is a another approach:
- Standalone CLI
Only runs in a CI (i.e. Travis, Circle .etc) environment. It executescommitlinttargeting the pre-cloned repo and send the report to our API endpoint! Done (similar to the way code coverage services like https://codecov.io work?) - The web service (the current bot)
Its only function is to analyze the report then update the PR status accordingly! it wouldn't be necessary listen to GitHub's webhooks anymore
What do you think?
Sounds like a very good idea! This would require json formatted output for commitlint and some tool to manage the transport to commitlint-bot right?
I'd add the complete resolved config to the json output. This way we could even cover @paulirish's use case of linting the PR title, using said resolved config from CI runs to check on title changes indicated by web hooks.
yo guys! haha it's another commitlint bot! :D
my project is, yah, only focused on the PR title and doesn't care about commits. As such, it wouldn't make sense to be a CLI that runs inside of CI (like codecov or bundlesize). Because a user needs to iterate on the PR title a few times to get it right.. so it needs to be webhook.
In mine, I pull the commitlint.config.js from the root of the repo: https://github.com/paulirish/commitlintbot/blob/9368713fa237a983155d9f57906d0797931e9063/index.js#L33-L37 a little janky but it works.
In mine, I pull the commitlint.config.js from the root of the repo
@paulirish umm, it may not work for commitlint-config-lerna though
It may also limit the possible supported scenarios?
However, you're right, running inside a CI wouldn't make sense if the user only wants title linting
I think we can have the cake and eat it, too - by taking up @ahmed-taj's idea to send information from CI to commitlint-bot.
I propose to not lint on CI, but let commitlint send the resolved config for a CI run to commitlint-bot.
Step by step this would work like this:
1. Linting a PR title
- PR is opened: commitlint-bot waits for resolved config to be sent
- CI runs commitlint (sans actual linting), sends fully resolved config to commitlint-bot. This may include stuff like the results of
commitlint-config-lerna. - Using the resolved config, commitlint-bot lints the given title
- On commits/history changes: Wait for new resolved config to be sent
- On title changes: Wait for any pending configs, then lint the title contents
2. Linting a PR commit range
- PR is opened: commitlint-bot waits for resolved config to be sent
- CI sends fully resolved commitlint config to commitlint-bot
- Using the resolved config, commitlint-bot lints al commits in the PR
- On commits/history changes: Wait for new resolved config to be sent, then lint
- On title changes: Nothing happens
On a side note: Would it make sense to check the current merge strategy of a PR (if possible) and automatically do the right thing, e.g.:
- Merge: Do not lint
- Rebase: Lint all commits
- Squash: Lint the PR title
@marionebl sounds very good ๐ , I think I will go with your proposal!
I will try to work on this in the next couple of days. Will open a WIP pull request.
On a side note: Would it make sense to check the current merge strategy of a PR (if possible)
AFAIK, GitHub doesn't provide an API for this, yet!
Oh, that needs an option in commitlint to output resolved config as a JSON. AFAIK commitlint doesn't support this yet!
@marionebl you can point me where to start to add this functionality to @commitlint/cli, I may give it a try!
@ahmed-taj Yeah, we'll have to add this as subcommand to commitlint/cli, e.g.:
commitlint config --resolve --json # machine output
commitlint config --resolve # human readable output, let's implement later Just before @commitlint/cli/src/cli.js#L80 something like this could go:
const configCommand = require('./commands/config');
const defaultCommand = require('./commands/default');
async function main(options) {
const raw = options.input;
const command = raw.length > 1 ? raw[0] : null;
// ...
switch(command) {
case 'config':
return configCommand(options);
default:
return defaultCommand(options);
}
}@ahmed-taj I noticed you went ahead and forked commitlint. Don't hesitate to contact me if you hit road blocks or just could do with some help.
Ping me e.g. on the commitlint channel in the devtools slack:
http://devtoolscommunity.herokuapp.com/
Hey @marionebl I appreciate it :)
Sadly, I can no longer use Slack
But I can open a work-in-progress pull request in your commitlint repo so we may continue discussion there
Ok, that's a bummer. What Messengers do you use? I am e.g. on Gitter. Can make IRC happen too.
Gitter sounds good, which channel?
I published a pre-release of the required commitlint functionality, you can pull it in via
npm install @commitlint/cli@next
Invoking commitlint config --format=json in a directory should produce stdout output like this. The example is produced by executing the prerelease version in the root of commitlint project.
commitlint config --json
{"extends":["./@commitlint/config-conventional","./@commitlint/config-lerna-scopes"],"rules":{"scope-enum":[2,"always",["commitlint-config-angular","commitlint-config-lerna-scopes","commitlint-config-patternplate","commitlint","cli","config-angular-type-enum","config-angular","config-conventional","config-lerna-scopes","config-patternplate","core","prompt-cli","prompt","travis-cli","babel-preset-commitlint","example-prompt","test","utils"]]},"parserPreset":{"name":"conventional-changelog-angular","path":"/Users/marneb/Documents/oss/commitlint/node_modules/conventional-changelog-angular/index.js","opts":{"headerPattern":{},"headerCorrespondence":["type","scope","subject"],"noteKeywords":["BREAKING CHANGE","BREAKING CHANGES"],"revertPattern":{},"revertCorrespondence":["header","hash"]}}}
Great work @marionebl
Invoking
commitlint config --jsonin a directory should ...
Plain --json doesn't work, you need to set the value to "format", i.e. --format=json
So, about the path key should be absolute?
I think the next step is to fully resolve the configs, so we end up having no need for extends part, right?
Great work @marionebl
Invoking commitlint config --json in a directory should ...
Plain --json doesn't work, you need to set the value to "format", i.e. --format=json
So, about the path key should be absolute?
Yep, sorry about that - I edited my comment to reflect this.
I think the next step is to fully resolve the configs, so we end up having no need for extends part, right?
The config actually is fully resolved (the extensions are expanded into .rules), the .extends key just isn't very useful yet.
The config actually is fully resolved (the extensions are expanded into .rules), the .extends key just isn't very useful yet.
Great! I may just ignore .extends for now.
We now have the "cake", let's eat it ;)
I think I start the logic on the bot side the next couple of days (when I have a final idea on how to "authorize" the upload request)
reading from .github/config.yml may also be a good idea :)
@ahmed-taj I can help if needed to run untrusted JS code on Node, as the vm Node module is not considered safe (see the node on the module page).
If the code does not contain any require or other APIs (pure, vanilla ECMAScript) we can make a lightweight isolated v8 VM using v8::Isolate.
A bit of a flyer, but how about a commitlint github action that just runs commitlint cli in the repo?
@bennypowers Yeah, that would be awesome.
I think about making one but didn't get early access to Github Actions yet.
See https://github.com/bennypowers/commitlint-gh-actions (untested.. not even sure if it will run) and conventional-changelog/commitlint#586
I've created a github action for this case, if you want to have a look: https://github.com/marketplace/actions/commit-linter
I tried using @bennypowers's action but got some issues and ended up creating another one, as explained here.
This one was made to not depend on the project's stack, so it comes with a set of shared configs available to use. The downside is that people can't use configs that come from a private npm package, but I think this is way less likely to happen. If someone needs that case, we can also create another commitlint action that depends on context (or maybe update Benny's one to do that).
Thanks @wagoid for publishing. Happy to take PRs, as I've not had the time to invest in this recently.