The aim of this document is to present the OperatorFabric community, its code of conduct and to welcome contributors!

First, thank you for your interest !

We can’t stress enough that feedback, discussions, questions and contributions to OperatorFabric are very much appreciated. However, because the project is still in its early stages, we’re not fully equipped for any of it yet, so please bear with us while the contribution process and tooling are sorted out.

This project is governed by the OperatorFabric Technical Charter.

This project applies the LF Energy Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to opfab_AT_lists.lfenergy.org.

1. License and Developer Certificate of Origin

OperatorFabric is an open source project licensed under the Mozilla Public License 2.0. By contributing to OperatorFabric, you accept and agree to the terms and conditions for your present and future contributions submitted to OperatorFabric.

The project also uses a mechanism known as a Developer Certificate of Origin (DCO) to ensure that we are legally allowed to distribute all the code and assets for the project. A DCO is a legally binding statement that asserts that you are the author of your contribution, and that you wish to allow OperatorFabric to use your work.

Contributors sign-off that they adhere to these requirements by adding a Signed-off-by line to commit messages. All commits to any repository of the OperatorFabric organization have to be signed-off like this:

This is my commit message.

Signed-off-by: John Doe <john.doe@email-provider.com>

You can write it manually but Git has a -s command line option to append it automatically to your commit message:

$ git commit -s -m 'This is my commit message'

Most IDEs can also take care of this for you.

A check will be performed during the integration, making sure all commits in the Pull Request contain a valid Signed-off-by line.

These processes and templates have been adapted from the ones defined by the PowSyBl project.

2. Reporting Bugs or Vulnerabilities and Suggesting Enhancements

Anyone is welcome to report bugs and suggest enhancements or new features by opening a GitHub issue on this repository. Vulnerabilities can be reported publicly in the same way.

3. Contributing Code or Documentation

3.1. Contribution Workflow

The project started out using a Feature Branch workflow, but as the project team grew and we needed to manage support to previous releases we decided to switch to a workflow based on the Git Flow workflow, starting after version 1.3.0.RELEASE.

The principles for this workflow were first described in the blog post linked above, and this document attempts to summarize how we adapted it to our project. Statements in quotes are from the original blog post.

In this document, "repository version" refers to the version defined in the VERSION file at the root of the project, which is a parameter for certain build tasks and for our CICD pipeline.

3.1.1. Principles

3.1.1.1. develop branch

The role of the develop branch is quite similar to that of the master branch in our previous "Feature Branch" workflow.

The develop branch is where feature branches are branched off from, and where they’re merged back to. This way, the HEAD of the develop branch "always reflects a state with the latest delivered development changes for the next release".

The repository version on the develop branch should always be SNAPSHOT.

The daily CRON GitHub Action generating the documentation and docker images for the SNAPSHOT version are run from this branch (see our CICD documentation for details).

3.1.1.2. master branch

"When the source code in the develop branch reaches a stable point and is ready to be released, all the changes should be merged back into master somehow and then tagged with a release number."

This means that any commit on master is a production-ready release, be it a minor or a major version.

Any commit on master triggers a GitHub Action build generating and pushing documentation and docker images for the corresponding release version. As a version released from master is also by design the latest version, it will also update the latest docker images and the current documentation folder on the website.

3.1.1.3. Hotfix branches

While minor and major versions are tagged in increasing and linear order on the master branch, it might be necessary to create patches on previous releases.

To do so, we create hotfix branches branching off version commits on the master branch.

For example, the 1.8.hotfixes branch branches off the commit tagged 1.8.0.RELEASE on the master branch, and will contain tags for 1.8.1.RELEASE, 1.8.2.RELEASE and so on.

Naming convention: Hotfix branches names should always start with the two digits representing the minor version they’re patching, followed by ".hotfixes".

Examples of valid hotfix branch names:
  • 1.8.hotfixes

  • 2.0.hotfixes

3.1.1.4. Feature branches

Feature branches are used to develop new features or fix bugs described in GitHub issues. They have two distinct use cases with similar workflows.

Feature branches for the next release

These feature branches are used to develop new features or fix bugs for the next release.

Their lifecycle is as follows:

  1. A new feature branch is branched off develop before starting work on a feature or bug.

  2. Once the developments are deemed ready by the developer(s) working on the feature, a pull request should be created for this branch.

  3. New pull requests are discussed during daily meetings to assign someone from the Reviewers group to the issue.

  4. The pull request author and reviewer(s) then make use of the Git Hub pull requests features (comments, proposed changes, etc.) to make changes to the PR until it meets the project requirements.

  5. Once it is ready to be included in the next version, the pull request is then merged back into develop.

Feature branches for hotfixes

These feature branches fix bugs in existing releases and give rise to new patches.

Their lifecycle is similar to regular feature branches, except they should be branched off (and merged back to) the X.X.hotfixes branch corresponding to the release they are fixing.

Example: A feature branch working on bug 1234 affecting version 1.8.0.RELEASE should be branched off branch 1.8.hotfixes.

Common conventions

Naming convention: Feature branches names should always start with "FE-" followed by the reference of the GitHub issue they’re addressing, followed by additional information to give context.

Examples of valid feature branch names:
  • FE-123-AddMailNotification

  • FE-123-FixIssueWithMailNotification

  • FE-123-RefactorBundleCompression

Examples of invalid feature branch names:
  • 123

  • FE-123

  • SomeTextDescribingTheBranch

Commit messages should also contain the GitHub issue reference: ` My commit message (#123)`

This allows the branch, PR and commits to be directly accessible from the GitHub issue.

3.1.1.5. Release branches
Release candidate

Once developments are in a release-ready state and have been tested on the develop branch, a release candidate branch should be created off develop .

"All features that are targeted for the release-to-be-built must be merged in to develop at this point in time. All features targeted at future releases may not—they must wait until after the release branch is branched off."
By contrast to what is described in the original blog post, for now we have chosen to only create the release branch once the developments are completely ready and tested on the develop branch, so that no fixes should be made on the release branch. This simplifies things because it means that release branches don’t have to be merged back into develop.

Once the X.X.X.release branch has been created, a new commit should be made on this branch to change the repository version from SNAPSHOT to X.X.X-RC.RELEASE.

Release

When release candidate is ready to be released, a new commit should be made on the X.X.X.release branch to change the repository version from X.X.X-RC.RELEASE to X.X.X.RELEASE.

Then, pushing the branch will trigger a build and a "dry-run" generation of docker images. The aim is to detect any issue with this generation before moving to master.

Finally, the X.X.X.release can be merged into master, triggering The resulting merge commit on master should then be tagged with X.X.X.RELEASE.

All commits on master should be merged commits from release branches, direct pushes on master are disabled .

Naming convention: The name of a release branch should match the repository version it is meant to merge into master but in lower case to avoid confusion with release tags on master.

Example: The valid branch name for the branch bringing 1.3.0.RELEASE into master is 1.3.0.release

3.1.2. Examples and commands

The aim of this section is to illustrate how our workflow works on a concrete example, complete with the required git commands.

3.1.2.1. Initial state

In the initial state of our example, only develop and master exist.

The repository version in master is 1.3.0.RELEASE, and the develop branch has just been branched off it. Commits have been added to develop to change the repository version to SNAPSHOT and implement the changes necessary for Git flow.

3.1.2.2. Starting work on a new feature for the next version

Let’s say we want to start working on a feature described in GitHub issue #123.

git checkout develop (1)
git pull (2)
git checkout -b FE-123 (3)
1 Check out the develop branch
2 Make sure it is up to date with the remote (=GitHub repository)
3 Create a FE-123 off the develop branch

Then, you can start working on the feature and commit your work to the branch. Referencing the issue you’re working on at the end of the commit message allows the commit to be listed on the issue’s page for future reference.

git commit -s -m "Short message describing content of commit (#123)"
The -s flag is to automatically add a sign-off to your commit message, which is our way to implement the Developer Certificate of Origin .

At any point during your work you can push your feature branch to the GitHub repository, to back your work up, let others look at your work or contribute to the feature.

To do this, just run:

git push

If it’s your first push to this branch, Git will prompt you to define the remote branch to be associated with your local branch with the following command:

git push --set-upstream origin FE-123

You can re-work, squash your commits and push as many times as you want on a feature branch. Force pushes are allowed on feature branches.

To see your branch:

  1. Go to the operatorfabric-core repository on GitHub

  2. Click the branches tab

Feel free to add or update a copyright header (on top of the existing ones) to files you create or amend. See src/main/headers for examples.

3.1.2.3. Submitting a pull request to develop

Once you are satisfied with the state of your developments, you can submit it as a pull request.

Before submitting your branch as a pull request, please squash/fix your commits to reduce the number of commits and comment them accordingly. In the end, the division of changes into commits should make the PR easier to understand and review.

You should also take a look at the review checklist below to make sure your branch meets its criteria.

Once you feel your branch is ready, submit a pull request. Open pull requests are then reviewed by the core maintainers to assign a reviewer to each of them.

To do so, go to the branches tab of the repository as described above. Click the "New Pull Request" button for your branch.

Add a comment containing a short summary of the PR goal and any information that should go into the release notes. It’s especially important for PRs that have a direct impact on existing OperatorFabric deployments, to alert administrators of the impacts of deploying a new version and help them with the migration. Whenever possible/relevant, a link to the corresponding documentation is appreciated.

You need to link your PR to the issue it is fixing so merging the PR will automatically close the corresponding issue. You can do so either manually or by adding "Fix #XXX" to the PR’s description.

Make sure that the base branch for the PR is develop, because feature branches are meant to be merged back into develop. This should be the default value since develop is the default branch on this repository, but if not, select it in the base branch dropdown list.

At this point, GitHub will tell you whether your branch could be automatically merged into develop or whether there are conflicts to be fixed.

Case 1: GitHub is able to automatically merge your branch

This means that either your branch was up to date with develop or there were no conflicts. In this case, just go ahead and fill in the PR title and message, then click "Create pull request".

Case 2: GitHub can’t merge your branch automatically

This means that there are conflicts with the current state of the develop branch on GitHub. To fix these conflicts, you need to update your local copy of the develop branch and merge it into your feature branch.

git checkout develop (1)
git pull (2)
git checkout FE-123 (3)
git merge develop (4)
1 Check out the develop branch
2 Make sure it is up to date with the remote (=GitHub repository)
3 Check out the FR-123 branch
4 Merge the new commits from develop into the feature branch

Then, handle any conflicts from the merge. For example, let’s say there is a conflict on file dummy1.txt:

Auto-merging dummy1.txt
CONFLICT (add/add): Merge conflict in dummy1.txt
Automatic merge failed; fix conflicts and then commit the result.

Open file dummy1.txt:

dummy1.txt
 <<<<<<< HEAD
 Some content from FE-123.
 =======
 Some content that has been changed on develop since FE-123 branched off.
 >>>>>>> develop

Update the content to reflect the changes that you want to keep:

dummy1.txt
Some content from FE-123 and some content that has been changed on develop since FE-123 branched off.
git add dummy1.txt (1)
git commit (2)
git push (3)
1 Add the manually merged file to the changes to be committed
2 Commit the changes to finish the merge
3 Push the changes to GitHub

Now, if you go back to GitHub and try to create a pull request again, GitHub should indicate that it is able to merge automatically.

3.1.2.4. Working on a fix for a previous version

To work on a fix for an existing version, the steps are similar to those described above, substituting X.X.hotfix for develop.

3.1.2.5. Reviewing a Pull Request

Only developers from the reviewers group can merge pull requests into develop, but this shouldn’t stop anyone interested in the topic of a PR to comment and review it.

Review checklist
  • The PR comment contains the text to insert in release note. Otherwise, it should say why this development doesn’t need to be on the release notes.

  • If necessary, the PR should create or add content to a migration guide for the next version, under src/docs/asciidoc/resources

  • Check that GitHub Action build is passing for the PR

  • The SonarCloud analysis should report no new bug or code smells, and should pass the quality gate

  • Check that the base branch (i.e. the branch into which we want to merge changes) is correct: for feature branches pull requests, this branch should be develop.

  • Look through changed files to make sure everything is relevant to the PR (no mistakenly added changes, no secret information, no malicious changes) and to see if you have remarks on the way things are implemented

  • Check that the commit(s) message(s) is(are) relevant and follow conventions

  • If there is more than one commit, is it meaningful or do we need to squash ?

  • Meaningful and sufficient unit tests for the backend (we aim for 80% coverage)

  • Meaningful unit tests for the frontend (Angular tests can be complex to implement, we should focus on testing complex logic and not the framework itself)

  • API testing via Karate has been updated

  • Documentation has been updated (especially if configuration is needed)

  • Configuration examples have been updated

  • Build and run OpFab locally to see the new feature or bug fix at work. In the case of a new feature, it’s also a way of making sure that the configuration documentation is correct and easily understandable.

  • Check for error messages in the browser console.

  • Check the UI in resolution 1680x1050 (minimum supported resolution for all features)

  • Check the UI in smartphone resolution (only for feed, settings and notification filter features)

  • Depending on the scope of the PR , build docker images and test in docker mode

  • Check that the copyright header has been updated on the changed files if need be, and in the case of a first-time contributor, make sure they’re added to the AUTHORS.txt file.

  • Check new dependencies added to the project to see if they are compatible with the OperatorFabric license , see the following table

License usage restrictions

License Name

SPX Identifier

Type

Usage, Restrictions

Academic Free License v1.1, v1.2, v2.0, v2.1, v3.0

AFL-1.1, AFL-1.2, AFL-2.0, AFL-2.1, AFL-3.0

Permissive

None , Be careful of incompatibility with GPL license.

Apache License 2.0

Apache-2.0

Permissive

None

BSD 2-Clause "Simplified" License

BSD-2-Clause

Permissive

None

BSD 3-Clause "New" or "Revised" License

BSD-3-Clause

Permissive

None

BSD 4-Clause "Original" or "Old" License

BSD-4-Clause

Permissive

Usage prohibited due to advertising clause.

Common Development and Distribution License 1.0

CDDL-1.0 Moderate

copyleft

Only as a distinct library. Be careful of incompatibility with GPL license.

Common Development and Distribution License 1.1

CDDL-1.1

Moderate copyleft

Only as a distinct library.Be careful of incompatibility with GPL license.

Creative Commons Attribution 3.0

CC-BY-3.0

Permissive

None. Suitable for documentation material.

Creative Commons Attribution 4.0

CC-BY-4.0

Permissive

None. Suitable for documentation material.

Creative Commons Attribution Non Commercial (any version)

CC-BY-NC-…​

Non commercial

Usage prohibited due to non commercial restriction.

Creative Commons Zero v1.0 Universal

CC0-1.0

Free usage (public domain)

None. Suitable for documentation material.

Eclipse Public License 1.0

EPL-1.0

Moderate copyleft

Only as a distinct library.Be careful of incompatibility with GPL license.

Eclipse Public License 2.0

EPL-2.0 Moderate

copyleft

Only as a distinct library GNU General Public License v2.0 only GPL-2.0-only Strong copyleft Usage prohibited. Exemptions on a case by case basis.

GNU General Public License v2.0 or later

GPL-2.0-or-later

Strong copyleft

Usage prohibited. Exemptions on a case by case basis.

GNU General Public License v3.0 only

GPL-3.0-only

Strong copyleft

Usage prohibited. Exemptions on a case by case basis.

GNU General Public License v3.0 or later

GPL-3.0-or-later

Strong copyleft

Usage prohibited. Exemptions on a case by case basis.

GNU Lesser General Public License v2.1 only

LGPL-2.1-only

Moderate copyleft

Only as a distinct library

GNU Lesser General Public License v2.1 or later

LGPL-2.1-or-later

Moderate copyleft

Only as a distinct library

GNU Lesser General Public License v3.0 only

LGPL-3.0-only

Moderate copyleft

Only as a distinct library

GNU Lesser General Public License v3.0 or later

LGPL-3.0-or-later

Moderate copyleft

Only as a distinct library

ISC License

ISC

Permissive

None

MIT License

MIT

Permissive

None

Mozilla Public License 2.0

MPL-2.0 Moderate (weak)

copyleft

Only as a distinct library

Public domain

-

Free usage

None

SIL Open Font License 1.1

OFL-1.1

Permissive in relation to combination with non-font code (strong copyleft for font code)

Only for font components

zlib License

Zlib

Permissive

None

Testing environment for reviewer

Compile and run OperatorFabric docker images is the most effective way to check any regression.

  1. Pull the submitted branch on a testing machine;

  2. Run a docker-compose with the ${OF_HOME}/src/main/docker/test-environment/docker-compose.yml file;

  3. Create SNAPSHOT docker images, from the ${OF_HOME} directory with the following command: ./gradlew clean dockerTagSNAPSHOT;

  4. Stop the test-environment docker-compose;

  5. Go to ${OF_HOME}/config/docker;

  6. Run the ./docker-compose.sh script (or use the docker-compose.yml with a docker-compose command);

  7. Go to ${OF_HOME}/src/test/resources/;

  8. Run the following scripts: ./loadTestConf.sh && ./send6TestCards.sh;

  9. Open the front-end in a browser and look for any regression.

To automate build and API testing, you can use ${OF_HOME}/src/test/api/karate/buildAndLaunchAll.sh.

3.1.2.6. Merging a Pull Request

Once the pull request meets all the criteria from the above check list, you can merge it into the develop branch.

  1. Go to the pull request page on GitHub

  2. Check that the base branch for the pull request is develop (or X.X.hotfixes). This information is visible at the top of the page.

    existing PR check base
  3. If that is not the case, you can edit the base branch by clicking the Edit button in the top right corner.

  4. Click the merge pull request button at the bottom of the PR page

  5. Make sure that the corresponding GitHub issue was associated to the project for the current release. It should now be visible under the "Done" column. If not, add it to the project and put it there manually.

  6. Go to the release-notes repository and add the issue to the list with the information provided in the PR comments.

3.1.2.7. Creating a release or hotfix

See the release process described in our CICD documentation for details.

3.2. Code Guidelines

  • We don’t mention specific authors by name in each file so as not to have to maintain these mentions (since this information is tracked by git anyway).

  • For ui code, you must use prettier (prettier.io/) to format the code (config provided in .prettierrc.json in the git root repository). The file types to format via prettier are the following : js, ts, css and scss.

  • When adding a dependency, define a precise version of the dependency

  • When fixing a bug, the commit message shall be "Fix : Issue text (#XXXX) "

3.2.1. Angular/TypeScript development caution and guidelines

  • Use foreach to iterate over an array (instead of for(let i = ..).

  • Do not use ngFor / ngIf with methods with computing as angular will call these methods very regularly (around ten times per seconds), use instead variables and compute them only when necessary.

  • ngOnInit() : ngOnInit is called when component is created, the creation is made by the parent component : be careful to check when initialization is done when calling method inside ngOnInit. When the context of the parent component change, it can lead to a new initialization or not.

  • Prefer using *ngIf over hidden property to hide elements : stackoverflow.com/questions/51317666/when-should-i-use-ngif-over-hidden-property-and-vice-versa/51317774

  • Do not use console.log or console.error, use specific opfab service : OpfabLoggerService

  • To give id to an HTML element, please use dashes between words and only lowercase letters. Example id="opfab-feed-filter-publish-date-to"

  • Always precise the return type of a function except when it is void (Example : getUserName():string)

  • Always precise the type of the function parameters (Example : setUserName(name : string))

  • Function shall start with a verb (Example : showAlertPopup())

  • When the return type is a boolean, the method name shall be a yes/no question (Example : isUserDeleted() : boolean)

  • Whenever possible use changeDetection: ChangeDetectionStrategy.OnPush in the component decorator to improve performance

3.2.2. Back development

  • When developing a Spring Controller, you do not need to develop unit test, use karate api test (file pattern **/controllers/** is excluded from test coverage indicator in sonarCloud).

  • Do not use spring annotation (@Autowired, @PostConstruct.. ) in business code to avoid coupling business code with spring framework. This rules is recent so a lot of the business code depends on spring.

3.2.3. Unit test

  • Unit test shall not use random values which is considered as a bad practice

  • Unit test shall not use external resources (database, file system, network, …​)

3.3. Documentation Guidelines

The aim of this section is to explain how the documentation is currently organized and to give a few guidelines on how it should be written.

3.3.1. Structure

All the sources for the AsciiDoc documentation published on our website are found under the src/docs/asciidoc folder in the operatorfabric-core repository.

It is organized into several folders (architecture documentation, deployment documentation, etc.). Each of these folders represent a document and contain an index.adoc file, optionally referencing other adoc files (to break it down into sections).

In addition, an images folder contains images for all documents and a resources folder contains various appendices that might be of use to some people but that we felt weren’t part of the main documentation.

The table below gives a short summary of the content of each document as well as advice on which ones you should focus on depending on your profile.

Contributor

A developer who contributes (or wishes to) to the OperatorFabric project

Developer

A developer working on an application using OperatorFabric or a businessconfig-party application posting content to an OperatorFabric instance

Admin

Someone who is in charge of deploying and maintaining OperatorFabric in production as part of an integrated solution

Product Owner

Project managers, anyone interested in using OperatorFabric for their business requirements.

Documentation Structure and Intended Readers
Folder Content Contributor Developer Admin Product Owner

architecture

Architecture documentation

Describes the business objects and concepts handled by OperatorFabric as well as the microservices architecture behind it.

Yes

Yes

Yes

CICD

CICD Pipeline documentation

Describes our CICD pipeline and release process

Yes

community

OF Community documentation

Everything about the OperatorFabric Community: Code of conduct, governance, contribution guidelines, communication channels.

Yes

deployment

Deployment documentation

Explains how to deploy and configure an OperatorFabric instance

Yes

Yes

Yes

dev_env

Development Environment documentation

Explains how to set up a working development environment for OperatorFabric with all the appropriate tooling and how to run OperatorFabric in development mode.

Yes

docs

This folder contains the documentation that should be archived for previous releases (as of today, the release notes and single page documentation - see below).

Yes

Yes

Yes

Yes

getting_started

Getting Started Guide guides you through setting up OperatorFabric and experimenting with its main features

Yes

Yes

Maybe

reference_doc

Reference Documentation contains the reference documentation for each microservice. It starts off with a high-level functional documentation and then goes into more technical details when needed.

Yes

Yes

Yes

In addition to this asciidoctor documentation, API documentation is available in the form of SwaggerUI-generated html pages. It is generated by the generateSwaggerUI Gradle task, using the swagger.yaml files from each service (for example for the BusinessConfig API ). It can be found under the build/docs/api folder for each client or service project.

3.3.2. Conventions

  • In addition to the "visible" structure described above, documents are broken down into coherent parts using the "include" feature of AsciiDoc. This is done mostly to avoid long files that are harder to edit, but it also allows us to reuse some content in different places.

  • Given the number of files this creates, we try to keep header attributes in files to a minimum. Instead, they’re set in the configuration of the asciidoctor gradle task:

    build.gradle
    asciidoctor {
    
        baseDirFollowsSourceFile()
    
        sources {
            include '*/index.adoc','docs/*'
        }
        resources {
            from('src/docs/asciidoc') {
                include 'images/*','pdf/*'
            }
        }
        attributes  nofooter            : '',
                revnumber           : operatorfabric.version,
                revdate             : operatorfabric.revisionDate,
                sectnums            : '',
                sectnumlevels       : '4',
                sectanchors         : '',
                toc                 : 'left',
                toclevels           : '4',
                icons               : 'font',
                imagesdir           : '../images',
                "hide-uri-scheme"   : '',
                "source-highlighter": 'coderay'
    }

    In particular, the version and revision date are set automatically from the version defined in the VERSION file at the root of the project and the current date.

  • All files are created starting with level 0 titles so:

    • They can be generated on their own if need be.

    • They can be included at different levels in different documents using leveloffset.

  • In addition to being available as separate documents (architecture, reference, etc.) for the current release, the documentation is also generated as a single page document available for all releases from the releases page. This is also a way to make searching the documentation for specific terms easier, and could be used to generate a single page pdf documentation.

  • Unfortunately, this entails a little complexity for cross-references and relative links, because the path to the content is a little different depending on whether the content is generated as different pages or as a single page document.

    For example, to link to the "Card Structure" section of the reference document from the architecture document, one needs to use the following external cross-reference:

    <</documentation/current/reference_doc/index.adoc#card_structure, Card Structure>>

    In the case of the single-page documentation however, both the architecture content and the reference content are part of the same document, so the cross-reference becomes a simple internal cross-reference:

    <<card_structure, Card Structure>>

    This is managed by using the ifdef and indef directives to define which link syntax should be used:

    ifdef::single-page-doc[<<card_structure, Card Structure>>]
    ifndef::single-page-doc[<</documentation/current/reference_doc/index.adoc#card_structure, Card Structure>>]
    The label ("Card Structure" in this example) is defined with each link because it seems that defining it in the target file along with the ID ([[my_section_id, text to display]]) doesn’t work with relative links.

    In the same way, for relative links to external files (mostly the API documentation):

    ifdef::single-page-doc[link:../api/cards/index.html#/archives[here]]
    ifndef::single-page-doc[link:/documentation/current/api/cards/index.html#/archives[here]]
    For this to work, the single_page_doc.adoc file needs to have :single-page-doc: as a header attribute.
  • As you can see in the examples above, we are using custom-defined section ids as anchors rather than taking advantage of generated ones (see documentation). This is cumbersome but:

    • Generation will give a warning if duplicate ids are defined, whereas with generated ids it will silently link to the wrong section.

    • Restructuring the document might change the generated section ID, creating broken links.

    • Its easier to find referenced text (ctrl-f on id)

    • The presence of a custom-defined ID is a sign that the content is referenced somewhere else, which you should take into account if you’re thinking of deleting or moving this content.

  • The :imagesdir: attribute is set globally as ../images, because all images are stored under src/docs/asciidoc/images.

  • In addition to links, it is sometimes necessary to display the actual content of files (or part of it) in the documentation (in the case of configuration examples, for instance). Whenever possible, this should be done by using the include directive rather than copying the content into the adoc file. This way the documentation will always be up to date with the file content at the time of generation.

    See the build.gradle include above for an example using tags to include only part of a file.

  • Source-highlighting is done using Coderay. See their documentation for supported languages, and the AsciiDoctor documentation on how to apply source-highlighting.

  • Avoid long lines whenever possible (for example, try not to go beyond 120 characters). This makes editing the documentation easier and diffs more readable.

  • Most links to other OperatorFabric documents should be relative (see above) so they automatically point to the document in the same version rather than the latest version. Links starting with opfab.github.io/documentation/current/ should only be used when we want to always refer to the latest (release) version of the documentation.

  • If necessary, add the relevant copyright at the top of the file.

All source files and documentation files for the project should bear copyright headers.

3.4.1. Header templates

In the case of source files (*.java, *.css or *.scss, *.html, *.ts, etc.), we are working with the Mozilla Public License, v. 2.0, so the header should be something like this:

Copyright (c) YYYY-YYYY, Entity Name (website or contact info)
See AUTHORS.txt
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
SPDX-License-Identifier: MPL-2.0
This file is part of the OperatorFabric project.

In the case of documentation files (*.adoc), we use the Creative Commons Attribution 4.0 International license, so the header should be:

Copyright (c) YYYY-YYYY, Entity Name (website or contact info)
See AUTHORS.txt
This document is subject to the terms of the Creative Commons Attribution 4.0 International license.
If a copy of the license was not distributed with this
file, You can obtain one at https://creativecommons.org/licenses/by/4.0/.
SPDX-License-Identifier: CC-BY-4.0

These templates should of course be converted to comments depending on the file type. See src/main/headers for examples.

Please make sure to include the appropriate header when creating new files and to update the existing one when making changes to a file.

In the case of a first time contribution, the GitHub username of the person making the contribution should also be added to the AUTHORS file.

3.4.2. Examples

3.4.2.1. Creating a new file

Let’s say a developer from entity Entity X creates a new java file in 2020. The header should read:

Copyright (c) 2020, Entity X (http://www.entityX.org)
See AUTHORS.txt
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
SPDX-License-Identifier: MPL-2.0
This file is part of the OperatorFabric project.
3.4.2.2. Updating a file

Given an existing java file with the following header:

Copyright (c) 2020, Entity X (http://www.entityX.org)
See AUTHORS.txt
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
SPDX-License-Identifier: MPL-2.0
This file is part of the OperatorFabric project.

If a developer from entity Entity X edits it in 2021, the header should now read:

Copyright (c) 2020-2021, Entity X (http://www.entityX.org)
See AUTHORS.txt
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
SPDX-License-Identifier: MPL-2.0
This file is part of the OperatorFabric project.

However, if a developer from entity Entity X edits it in 2022, but no one from Entity X had touched it in 2021, the header should now read:

Copyright (c) 2020, 2022 Entity X (http://www.entityX.org)
See AUTHORS.txt
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
SPDX-License-Identifier: MPL-2.0
This file is part of the OperatorFabric project.
3.4.2.3. Multiple contributors

Given an existing java file with the following header:

Copyright (c) 2020-2021, Entity X (http://www.entityX.org)
See AUTHORS.txt
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
SPDX-License-Identifier: MPL-2.0
This file is part of the OperatorFabric project.

If a developer from entity Entity Y edits it in 2021, the header should now read:

Copyright (c) 2020-2021, Entity X (http://www.entityX.org)
Copyright (c) 2021, Entity Y (http://www.entityY.org)
See AUTHORS.txt
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
SPDX-License-Identifier: MPL-2.0
This file is part of the OperatorFabric project.

4. Project Governance

4.1. Project Owner

OperatorFabric is part of the LF Energy Foundation, a project of the Linux Foundation that supports open source innovation projects within the energy and electricity sectors.

4.2. Committers

Committers are contributors who have made several valuable contributions to the project and are now relied upon to both write code directly to the repository and screen the contributions of others. In many cases they are programmers but it is also possible that they contribute in a different role. Typically, a committer will focus on a specific aspect of the project, and will bring a level of expertise and understanding that earns them the respect of the community and the project owner.

4.3. Technical Steering Committee

See the dedicated page for more details on the Technical Steering Committee (scheduled meetings, minutes of past meetings, etc.).

4.4. Contributors

Contributors include anyone in the technical community that contributes code, documentation, or other technical artifacts to the project.

Anyone can become a contributor. There is no expectation of commitment to the project, no specific skill requirements and no selection process. To become a contributor, a community member simply has to perform one or more actions that are beneficial to the project.

5. Communication channels

In addition to issues and discussions on GitHub, we use the following communication channels:

5.1. Slack channel

We use the operator-fabric channel on the LFEnergy Slack for daily discussions, to warn of breaking changes being merged into develop for example.

Everyone is welcome to join.

5.2. LF Energy Mailing Lists

Several mailing lists have been created by LF Energy for the project, please feel free to subscribe to the ones you could be interested in:

And if you’re interested in LF Energy in general: LF Energy General Discussion

6. Code of Conduct

The Code of Conduct for the OperatorFabric community is version 2.0 of the Contributor Covenant.

6.1. Our Pledge

We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.

6.2. Our Standards

Examples of behavior that contributes to a positive environment for our community include:

  • Demonstrating empathy and kindness toward other people

  • Being respectful of differing opinions, viewpoints, and experiences

  • Giving and gracefully accepting constructive feedback

  • Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience

  • Focusing on what is best not just for us as individuals, but for the overall community

Examples of unacceptable behavior include:

  • The use of sexualized language or imagery, and sexual attention or advances of any kind

  • Trolling, insulting or derogatory comments, and personal or political attacks

  • Public or private harassment

  • Publishing others’ private information, such as a physical or email address, without their explicit permission

  • Other conduct which could reasonably be considered inappropriate in a professional setting

6.3. Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.

6.4. Scope

This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.

6.5. Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at opfab-tsc_AT_lists.lfenergy.org. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:

  1. Correction

    Community Impact

    Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.

    Consequence

    A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.

  2. Warning

    Community Impact

    A violation through a single incident or series of actions.

    Consequence

    A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.

  3. Temporary Ban

    Community Impact

    A serious violation of community standards, including sustained inappropriate behavior.

    Consequence

    A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.

  4. Permanent Ban

    Community Impact

    Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.

    Consequence

    A permanent ban from any sort of public interaction within the community.

6.6. Attribution

This Code of Conduct is adapted from the Contributor Covenant, version 2.0, available at www.contributor-covenant.org/version/2/0/code_of_conduct.html. Community Impact Guidelines were inspired by Mozilla’s code of conduct enforcement ladder. For answers to common questions about this code of conduct, see the FAQ at www.contributor-covenant.org/faq. Translations are available at www.contributor-covenant.org/translations. www.contributor-covenant.org/version/2/0/code_of_conduct/code_of_conduct.txt