We’ve decided to use PlantUML in order to generate diagrams for documentation purposes. In order to keep the generated diagrams in sync with their source files we’ve set up two kinds of automations:
A pre-commit git hook has been set up which executes the following tasks:
We’ve also created a setup script that should be run after cloning the repository in order to install the git hooks.
A GitHub action has been set up in order to safely check server-side that the diagrams generation is correct and if it’s not then regenerate them.
The action runs only if something has changed in the diagram directory.
On every tag push a GitHub action is run which:
On every push on the main branch GitHub action is run which:
We decided to use a custom GitHub action to publish out GH pages since the “automatic” method required our doc files to reside in specific folders, but we needed those files to be inside the .profile folder in order to show them as our organization README.
Every rule described below must be applied both to the server and the client repositories unless otherwise specified by them.
It has been decided to adopt GitFlow as branching model. Releases will be published from the main branch.
In order to build high quality software brach protection rules have been applied to the main and develop branches resulting in the following constraints:
Many CI workflows run only on pull requests since these cannot be skipped in the process.
The semantic-release workflow automates the versioning and publishing process for the GitHub repository and NPM package. It analyzes commit messages and it determines the appropriate version number and publishes the new release automatically, eliminating the need for manual version management. This workflow runs automatically on pushes to the main branch.
Moreover the release of an NPM package allows to distribute the package more easily because, for example, with just the command npm install @domoticasw/server it is possible to install the latest version of the server package without having to specify the version number or anything else.
The NPM token is an authentication key used to publish packages the NPM registry. It allows semantic-release to authenticate with NPM and push the new package version, it is stored as a GitHub Actions secret to prevent unauthorized access.
Since semantic release is being adopted it has been decided to use commitlint in order to enforce conventional commit messages (both in the client and server repositories).
DomoticASW commitlint github action is run in a github workflow on every pull request in order to prohibit invalid commit messages.
It works by running commitlint verifying all the commits from the pull request base up to its head.
Executing commitlint only on the remote means that the developer will discover that the commit messages he wrote were wrong only after pushing them, and to fix the problem he would be forced to reword the commits and push again.
To avoid this problem a pre-commit git hook have been written under the hooks directory both in the server and in the client. It must be installed through the setup.sh script which can be found in the root of both the repositories.
Note:
Running commitlint on the remote is kept as a safety measure since there’s no way to trust the developer that he will install the git hook.
It has been decided to extract the semantic-release workflow and the commitlint workflow into two different github actions of the organization so that they can be resued both from the server and the client.
We used git submodules to link the client repository within the server repository. This approach allows us to maintain a clear separation between the two repositories while still being able to serve the client from within the server.
A limitation of this method is that the submodule points to a specific commit of the client repository. As a result, updates to the client repository are not automatically reflected in the server repository and must be manually updated.
We set up prettier and two npm scripts:
format: formats every file in the src folder (is expected to be run by the developer)format-check: checks that every file in the src folder is correctly formatted, it is run by both:
It is useful, especially for development (we use it in our demo), to distribute the Server (which also includes the Client) as a Docker image. The image is built on a two stage Dockerfile in order to reduce the image size as much as possible.
The image is built by means of a GitHub action which:
latest and <release-version>We set up Renovate through the Mend.io GitHub App in order to automate our dependency updates.
Our global renovate configuration is the default one while the server has a simple renovate.json configuration file which:
main and develop branchesThe last two rules aim to reduce the number of merge conflict between main and develop while still allowing the main branch to be automatically updated (mostly for security patches).
For the client CI has been decided to just test that the code passes the lint and compiles. Automated tests are not possible due to being just the GUI of the wep app.
We decided not to enable renovate on the Client as we do not have any automated UI tests and therefore we cannot trust any dependency update to be made automatically.
Each emulated device is conveniently packaged as a Docker image in order to use it for development and in the demo.
Each device image is built and published by a GitHub action that is based on the suggested one by the Docker documentation (any modification will be specified per-device).
In order to keep the image as lean and optimized as possible it was decided to rely upon the sbt-native-packager sbt plugin which allows to automatically build a Docker image of the project.
This is the action used to build and publish the image. The main changes to the one mentioned above are:
The Dockerfile is based on the template suggested by the Gleam documentation.
This is the action used to build and publish the image. The main changes to the one mentioned above are:
In order to keep the image as lean and optimized as possible it was decided to rely upon the sbt-native-packager sbt plugin which allows to automatically build a Docker image of the project.
This is the action used to build and publish the image. The main changes to the one mentioned above are:
In order to keep the image as lean and optimized as possible it was decided to rely upon the sbt-native-packager sbt plugin which allows to automatically build a Docker image of the project.
This is the action used to build and publish the image. The main changes to the one mentioned above are:
This is the action used to build and publish the image. The main changes to the one mentioned above are:
This is the action used to build and publish the image. The main changes to the one mentioned above are:
This is the action used to build and publish the image. The main changes to the one mentioned above are:
main branch or after a release tag starting with vThis is the action used to build and publish the image. The main changes to the one mentioned above are:
main branch or after a release tag starting with v