Update the CONTRIBUTING.md document

Change-type: patch
This commit is contained in:
Paulo Castro 2020-09-28 14:47:02 +01:00
parent 1acf342fb0
commit 48076464da

View File

@ -2,10 +2,12 @@
balenaCLI is an open source project and your contribution is welcome! balenaCLI is an open source project and your contribution is welcome!
* Install the dependencies listed in the [NPM Installation](./INSTALL.md#npm-installation) * Install the dependencies listed in the [NPM Installation
section of the `INSTALL.md` file. Check the section [Additional section](./INSTALL-ADVANCED.md#npm-installation) section of the installation instructions. Check
Dependencies](./INSTALL.md#additional-dependencies) too. the section [Additional Dependencies](./INSTALL-ADVANCED.md#additional-dependencies) too.
* Clone the `balena-cli` repository, `cd` to it and run `npm install`. * Clone the `balena-cli` repository (or a [forked
repo](https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/fork-a-repo),
if you are not in the balena team), `cd` to it and run `npm install`.
* Build the CLI with `npm run build` or `npm test`, and execute it with `./bin/balena` * Build the CLI with `npm run build` or `npm test`, and execute it with `./bin/balena`
(on a Windows command prompt, you may need to run `node .\bin\balena`). (on a Windows command prompt, you may need to run `node .\bin\balena`).
@ -21,8 +23,8 @@ this will only help if you add some test cases for your new code!
## ./bin/balena-dev and oclif ## ./bin/balena-dev and oclif
When using `./bin/balena-dev` with oclif-converted commands, it is currently necessary to manually When using `./bin/balena-dev`, it is currently necessary to manually edit the `oclif` section of
edit the `oclif` section of `package.json` to replace `./build` with `./lib` as follows: `package.json` to replace `./build` with `./lib` as follows:
Change from: Change from:
``` ```
@ -44,7 +46,7 @@ And then remember to change it back before pushing the pull request. This is obv
and inconvenient, and improvement suggestions are welcome: is there a better solution than and inconvenient, and improvement suggestions are welcome: is there a better solution than
automatically editing `package.json`? It is doable, if it is what needs to be done. automatically editing `package.json`? It is doable, if it is what needs to be done.
## Semantic versioning and commit messages ## Semantic versioning, commit messages and the ChangeLog
The CLI version numbering adheres to [Semantic Versioning](http://semver.org/). The following The CLI version numbering adheres to [Semantic Versioning](http://semver.org/). The following
header/row is required in the body of a commit message, and will cause the CI build to fail if absent: header/row is required in the body of a commit message, and will cause the CI build to fail if absent:
@ -56,7 +58,29 @@ Change-type: patch|minor|major
Version numbers and commit messages are automatically added to the `CHANGELOG.md` file by the CI Version numbers and commit messages are automatically added to the `CHANGELOG.md` file by the CI
build flow, after a pull request is merged. It should not be manually edited. build flow, after a pull request is merged. It should not be manually edited.
## Editing documentation files (CHANGELOG, README, website...) If `package.json` is updated for dependencies listed in the `repo.yml` file (like `balena-sdk`),
the commit message body should include a line in the following format:
```
Update balena-sdk from 12.0.0 to 12.1.0
```
This allows the CI to produce nested change logs (with expandable arrows), pulling in commit
messages from the upstream repositories. The following npm script can be used to automatically
produce a commit with a suitable commit message:
```
npm run update balena-sdk ^12.1.0
```
The script will create a new branch (only if `master` is currently checked out), run `npm update`
with the given target version and commit the `package.json` and `npm-shrinkwrap.json` files. The
script by default will set the `Change-type` to `patch` or `minor`, depending on the semver change
of the updated dependency. For a `major` change type, it can specified as an extra argument:
```
npm run update balena-sdk ^12.14.0 patch
npm run update balena-sdk ^13.0.0 major
```
## Editing documentation files (README, INSTALL, Reference website...)
The `doc/cli.markdown` file is automatically generated by running `npm run build:doc` (which also The `doc/cli.markdown` file is automatically generated by running `npm run build:doc` (which also
runs as part of `npm run build`). That file is then pulled by scripts in the runs as part of `npm run build`). That file is then pulled by scripts in the
@ -65,72 +89,70 @@ Documentation page](https://www.balena.io/docs/reference/cli/).
The content sources for the auto generation of `doc/cli.markdown` are: The content sources for the auto generation of `doc/cli.markdown` are:
* Selected sections of the README file. * [Selected
* The CLI's command documentation in source code (both Capitano and oclif commands), for example: sections](https://github.com/balena-io/balena-cli/blob/v12.23.0/automation/capitanodoc/capitanodoc.ts#L199-L204)
* `lib/actions/build.coffee` of the README file.
* The CLI's command documentation in source code (`/lib/actions-oclif/` folder), for example:
* `lib/actions-oclif/push.ts`
* `lib/actions-oclif/env/add.ts` * `lib/actions-oclif/env/add.ts`
The README file is manually edited, but subsections are automatically extracted for inclusion in The README file is manually edited, but subsections are automatically extracted for inclusion in
`doc/cli.markdown` by the `getCapitanoDoc()` function in `doc/cli.markdown` by the `getCapitanoDoc()` function in
[`automation/capitanodoc/capitanodoc.ts`](https://github.com/balena-io/balena-cli/blob/master/automation/capitanodoc/capitanodoc.ts). [`automation/capitanodoc/capitanodoc.ts`](https://github.com/balena-io/balena-cli/blob/master/automation/capitanodoc/capitanodoc.ts).
The `INSTALL.md` and `TROUBLESHOOTING.md` files are also manually edited. The `INSTALL*.md` and `TROUBLESHOOTING.md` files are also manually edited.
## Windows ## Windows
Please note that `npm run build:installer` (which generates the `.exe` executable installer on The `npm run build:installer` script (which generates the `.exe` executable installer on Windows)
Windows) specifically requires [MSYS2](https://www.msys2.org/) to be installed. Other than that, specifically requires [MSYS2](https://www.msys2.org/) to be installed. Other than that, the
the standard Command Prompt or PowerShell can be used (though MSYS2 is still handy, as it provides standard Command Prompt or PowerShell can be used (though MSYS2 is still handy, as it provides
'git' and a number of common unix utilities). If you make changes to `package.json` scripts, check 'git' and a number of common unix utilities). If changes are made to npm scripts in `package.json`,
they also run on a standard Windows Command Prompt. check that they also run on a standard Windows Command Prompt.
## Updating the 'npm-shrinkwrap.json' file ## Updating the 'npm-shrinkwrap.json' file
The `npm-shrinkwrap.json` file is used to control package dependencies, as documented at The `npm-shrinkwrap.json` file is used to control package dependencies, as documented at
https://docs.npmjs.com/files/shrinkwrap.json. https://docs.npmjs.com/files/shrinkwrap.json.
While developing, the `package.json` file is often modified by, or before, running `npm install` Changes to `npm-shrinkwrap.json` can be automatically merged by git during operations like
in order to add, remove or modify dependencies. When `npm install` is executed, it automatically `rebase`, `pull` and `cherry-pick`, but in some cases this results in suboptimal dependency
updates the `npm-shrinkwrap.json` file as well, **taking into account not only the `package.json` resolution (the `node_modules` folder may end up larger than necessary, with consequences to CLI
file but also the current state of the `node_modules` folder in your computer.** load time too). For this reason, the recommended way to update `npm-shrinkwrap.json` is to run
`npm install`, possibly alongside `npm dedupe` as well. The following commands can be used to
fix shrinkwrap issues and optimize the dependencies:
Meanwhile, as a text (JSON) file, `git` is capable of merging the `npm-shrinkwrap.json` file during ```sh
operations like `rebase`, `cherry-pick` and `pull`. But git's automated merge is not the git checkout master -- npm-shrinkwrap.json
recommended way of updating the `npm-shrinkwrap.json` file, because it does not take into account rm -rf node_modules
duplicates or conflicts in the dependency tree, or indeed the state of the `package.json` file npm install # update npm-shrinkwrap.json to satisfy changes to package.json
(which may have just been merged). You can improve this by installing the npm merge driver with: npm dedupe # deduplicate dependencies from npm-shrinkwrap.json
npm install # re-add optional dependencies removed by dedupe
git add npm-shrinkwrap.json # add it for committing (solve merge errors)
``` ```
Note that `npm dedupe` should always be followed by `npm install`, as shown above, even if
`npm install` had already been executed before `npm dedupe`.
Optionally, these steps may be automated by installing the
[npm-merge-driver](https://www.npmjs.com/package/npm-merge-driver):
```sh
npx npm-merge-driver install -g npx npm-merge-driver install -g
``` ```
Whether or not there is a merge error, the following commands are the recommended way of updating
and committing the `npm-shrinkwrap.json` file:
```bash
$ npm install # fetch the latest modules update the npm-shrinkwrap.json file
$ npm dedupe # deduplicate dependencies from the npm-shrinkwrap.json file
$ npm install # re-add optional dependencies for other platforms that may have been removed by dedupe
$ git add npm-shrinkwrap.json # add it for committing (solve merge errors)
```
## TypeScript and oclif ## TypeScript and oclif
The CLI currently contains a mix of plain JavaScript and The CLI currently contains a mix of plain JavaScript and
[TypeScript](https://www.typescriptlang.org/) code. The goal is to have all code written in [TypeScript](https://www.typescriptlang.org/) code. The goal is to have all code written in
Typescript, in order to take advantage of static typing and formal programming interfaces. Typescript, in order to take advantage of static typing and formal programming interfaces.
The migration towards Typescript is taking place gradually, as part of maintenance work or The migration towards Typescript is taking place gradually, as part of maintenance work or
the implementation of new features. Historically, the CLI was originally written in the implementation of new features.
[CoffeeScript](https://coffeescript.org), but all CoffeeScript code was migrated to either
Javascript or Typescript.
Similarly, [Capitano](https://github.com/balena-io/capitano) was originally adopted as the CLI's Of historical interest, the CLI was originally written in [CoffeeScript](https://coffeescript.org)
framework, but later we decided to take advantage of [oclif](https://oclif.io/)'s features such and used the [Capitano](https://github.com/balena-io/capitano) framework. All CoffeeScript code was
as native installers for Windows, macOS and Linux, and support for custom flag parsing (for migrated to either Javascript or Typescript, and Capitano was replaced with oclif. A few file or
example, we're still battling with Capitano's behavior of dropping leading zeros of arguments that variable names still refer to this legacy, for example `automation/capitanodoc/capitanodoc.ts`.
look like integers, such as some abbreviated UUIDs). Again, the migration is taking place
gradually, with some CLI commands parsed by oclif and others by Capitano. A simple command line
pre-parsing takes place in `preparser.ts`, to decide whether to route full parsing to Capitano or
to oclif.
## Programming style ## Programming style
@ -138,29 +160,6 @@ to oclif.
reformats the code. Beyond that, we have a preference for Javascript promises over callbacks, and for reformats the code. Beyond that, we have a preference for Javascript promises over callbacks, and for
`async/await` over `.then()`. `async/await` over `.then()`.
## Updating upstream dependencies
In order to get proper nested changelogs, when updating upstream modules that are in the repo.yml
(like the balena-sdk), the commit body has to contain a line with the following format:
```
Update balena-sdk from 12.0.0 to 12.1.0
```
Since this is error prone, it's suggested to use the following npm script:
```
npm run update balena-sdk ^12.1.0
```
This will create a new branch (only if you are currently on master), run `npm update` with the
version you provided as a target and commit the package.json & npm-shrinkwrap.json. The script by
default will set the `Change-type` to `patch` or `minor`, depending on the semver change of the
updated dependency, but if you need to use a different one (eg `major`) you can specify it as an
extra argument:
```
npm run update balena-sdk ^12.14.0 patch
npm run update balena-sdk ^13.0.0 major
```
## Common gotchas ## Common gotchas
One thing that most CLI bugs have in common is the absence of test cases exercising the broken One thing that most CLI bugs have in common is the absence of test cases exercising the broken