Merge pull request #2049 from balena-io/refresh-contributing

Update the CONTRIBUTING.md document
This commit is contained in:
bulldozer-balena[bot] 2020-10-02 08:49:00 +00:00 committed by GitHub
commit 568fcb9759
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,10 +2,12 @@
balenaCLI is an open source project and your contribution is welcome!
* Install the dependencies listed in the [NPM Installation](./INSTALL.md#npm-installation)
section of the `INSTALL.md` file. Check the section [Additional
Dependencies](./INSTALL.md#additional-dependencies) too.
* Clone the `balena-cli` repository, `cd` to it and run `npm install`.
* Install the dependencies listed in the [NPM Installation
section](./INSTALL-ADVANCED.md#npm-installation) section of the installation instructions. Check
the section [Additional Dependencies](./INSTALL-ADVANCED.md#additional-dependencies) too.
* 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`
(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
When using `./bin/balena-dev` with oclif-converted commands, it is currently necessary to manually
edit the `oclif` section of `package.json` to replace `./build` with `./lib` as follows:
When using `./bin/balena-dev`, it is currently necessary to manually edit the `oclif` section of
`package.json` to replace `./build` with `./lib` as follows:
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
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
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
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
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:
* Selected sections of the README file.
* The CLI's command documentation in source code (both Capitano and oclif commands), for example:
* `lib/actions/build.coffee`
* [Selected
sections](https://github.com/balena-io/balena-cli/blob/v12.23.0/automation/capitanodoc/capitanodoc.ts#L199-L204)
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`
The README file is manually edited, but subsections are automatically extracted for inclusion 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).
The `INSTALL.md` and `TROUBLESHOOTING.md` files are also manually edited.
The `INSTALL*.md` and `TROUBLESHOOTING.md` files are also manually edited.
## Windows
Please note that `npm run build:installer` (which generates the `.exe` executable installer on
Windows) specifically requires [MSYS2](https://www.msys2.org/) to be installed. Other than that,
the 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
they also run on a standard Windows Command Prompt.
The `npm run build:installer` script (which generates the `.exe` executable installer on Windows)
specifically requires [MSYS2](https://www.msys2.org/) to be installed. Other than that, the
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 changes are made to npm scripts in `package.json`,
check that they also run on a standard Windows Command Prompt.
## Updating the 'npm-shrinkwrap.json' file
The `npm-shrinkwrap.json` file is used to control package dependencies, as documented at
https://docs.npmjs.com/files/shrinkwrap.json.
While developing, the `package.json` file is often modified by, or before, running `npm install`
in order to add, remove or modify dependencies. When `npm install` is executed, it automatically
updates the `npm-shrinkwrap.json` file as well, **taking into account not only the `package.json`
file but also the current state of the `node_modules` folder in your computer.**
Changes to `npm-shrinkwrap.json` can be automatically merged by git during operations like
`rebase`, `pull` and `cherry-pick`, but in some cases this results in suboptimal dependency
resolution (the `node_modules` folder may end up larger than necessary, with consequences to CLI
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
operations like `rebase`, `cherry-pick` and `pull`. But git's automated merge is not the
recommended way of updating the `npm-shrinkwrap.json` file, because it does not take into account
duplicates or conflicts in the dependency tree, or indeed the state of the `package.json` file
(which may have just been merged). You can improve this by installing the npm merge driver with:
```sh
git checkout master -- npm-shrinkwrap.json
rm -rf node_modules
npm install # update npm-shrinkwrap.json to satisfy changes to package.json
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
```
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
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, 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 implementation of new features. Historically, the CLI was originally written in
[CoffeeScript](https://coffeescript.org), but all CoffeeScript code was migrated to either
Javascript or Typescript.
the implementation of new features.
Similarly, [Capitano](https://github.com/balena-io/capitano) was originally adopted as the CLI's
framework, but later we decided to take advantage of [oclif](https://oclif.io/)'s features such
as native installers for Windows, macOS and Linux, and support for custom flag parsing (for
example, we're still battling with Capitano's behavior of dropping leading zeros of arguments that
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.
Of historical interest, the CLI was originally written in [CoffeeScript](https://coffeescript.org)
and used the [Capitano](https://github.com/balena-io/capitano) framework. All CoffeeScript code was
migrated to either Javascript or Typescript, and Capitano was replaced with oclif. A few file or
variable names still refer to this legacy, for example `automation/capitanodoc/capitanodoc.ts`.
## Programming style
@ -138,29 +160,6 @@ to oclif.
reformats the code. Beyond that, we have a preference for Javascript promises over callbacks, and for
`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
One thing that most CLI bugs have in common is the absence of test cases exercising the broken