Steps to contribute

This guide covers the steps for internal and external contributors. Differences will be outlined.

Depending on the project, not all steps make sense. For instance, if the documentation was changed then the integration tests need not to be adapted. Please skip the steps which are not applicable.

Preparation

  1. As an external contributor, please fork the according repository on GitHub.

  2. Clone the repository to the local machine or if it is already cloned then make sure to pull the latest changes. Backports to previous releases are not covered in this guide.

  3. Create a feature branch. As for now, there is no naming convention.

Changes in Rust projects

  1. Make your desired changes in the according repository and test them manually. Ensure that the code compiles without warnings (cargo clippy --all-targets) and that the code is formatted with cargo fmt. Also make sure that all changes are made in accordance to the source code style guide.

  2. If code was added or adapted then please create or adapt the unit tests in the same file as well as the integration tests in the tests directory. Ensure that all unit tests run successfully cargo test) and all integration tests run successfully (./scripts/run_tests.sh). See also Changes in the integration tests.

  3. Comment your code and check with cargo doc --document-private-items that there are no syntax errors.

  4. The YAML schemas of the custom resource definitions (CRDs) are rebuilt when the project is compiled (see rust/operator-binary/build.rs if changing an operator). These CRDs as well as the product configuration are also required in the Helm chart and the Kubernetes manifest. To ensure that everything is in a consistent state, please execute make regenerate-charts.

  5. If it is useful for the users of the project to know about the change then it must be added to the changelog. For instance, if only the dependencies in an operator are upgraded but nothing changes for the user then the upgrade should not be added to the changelog. Conversely, if the dependencies in the operator framework are upgraded then changes are probably required in the operators (which are the clients of the framework) and therefore the upgrade must be mentioned in the changelog. The changelog must be formatted according to keep a changelog.

Changes in the product images

  1. The code for building the product images can be found in the docker-images repository. Please follow the steps in Preparation.

  2. Make the desired changes.

  3. Add an entry to the product image changelog and use the pattern <product>-stackable<stackable-image-version> to reference the next image version. The <stackable-image-version> follows semantic versioning and is independent of the upstream version.

  4. If a new version of a product was added then the following tasks must be performed:

    • Add the new version to the supported ones in the documentation of the operators (see docs/modules/\{product name\}/partials/supported-versions.adoc in the operator repositories).

    • Update the operator to support the new version if necessary.

    • Update the examples in the operator to use the new version.

    • Update the integration tests. The tests should cover the latest patch version of each supported versions.

  5. Run the integration tests with the new product image. The image can be built and uploaded to the kind cluster with the following commands:

    ./build_product_images.py --product <product> --image_version <stackable-image-version>
    kind load docker-image <image-tagged-with-the-major-version> --name=integration-tests

    See the output of build_product_images.py to retrieve the image tag for <image-tagged-with-the-major-version>.

Changes in the integration tests

  1. Most code changes should also be tested with integration tests. The tests for every operator can be found in the operator repository in the tests directory. Follow the steps in Preparation for the integration tests as well.

  2. Create or adapt the tests. Try to mimic the style of the other tests. They are written with KUTTL and using a jinja2 templating mechanism to test multiple product versions at once.

  3. Start a test cluster using kind. You can also use stackablectl to install a kind cluster.

  4. If changes in an operator are tested then the according version of the operator must be started. The operator can be started outside the cluster with cargo run — crd | kubectl apply -f - && cargo run — run. This approach allows a fast test develop cycle but has the downside that the RBAC rules are not tested. So a proper Helm installation should be tested before creating a pull request. First a Docker image of the operator must be built locally and uploaded to the kind cluster and then the Helm chart must be installed. This can be achieved in the operator directory with the following commands:

    docker build --file docker/Dockerfile --tag docker.stackable.tech/stackable/<operator>:<version>-dev .
    kind load docker-image docker.stackable.tech/stackable/<operator>:<version>-dev --name=integration-tests
    helm install <operator> deploy/helm/<operator>/
  5. Run the tests from the repository root with ./scripts/run_tests.sh.

Changes in the documentation

  1. The Stackable Platform documentation can be found at https://docs.stackable.tech/. The documentation is built with Antora from the sources in the documentation repository and the docs directories in the operator repositories. Follow the steps in Preparation to be able to change the documentation.

  2. Make your changes.

  3. Build the documentation locally to ensure that the formatting is fine and all links are specified correctly. See the README.adoc file for further details and the Documentation style guide for style and formatting guidelines.

Changes in the operator-templating

  1. Files which are common in all operators are handled and rolled out by the operator-templating. Follow the steps in Preparation to check out the repository.

  2. Make your changes.

  3. Test the changes locally. Create the directory work, clone all operators into this directory, and run the test.sh script. The changes can be examined with git status. When the pull request is later merged into the main branch then pull requests with these changes will be created automatically. Depending on the change, it makes sense to run the integration tests for all changed operators. If the tests are not run in this stage and if there is even just one integration test failing in the subsequential generated pull requests then the operator-templating must be adapted which creates again pull requests for all operators. Changes in the GitHub workflow actions cannot be tested until finally merged.

Create pull requests

  1. Finally, pull requests must be created for all adapted repositories.

    • Have a look at the review checklist and ensure that all applicable points are fulfilled.

    • Create a comprehensive description of the changes.

    • Link the according issue to the pull request by using a keyword like "Closes".

    • Add references to other pull requests, like the pull request in the integration-tests repository which contains test cases for the change in the operator pull request.

    • Select a reviewer. Usually "stackabletech/developers" is a good choice.

    • If you are an internal contributor then assign yourself to the issue.

  2. All pull requests must pass a quality gate before they can be merged. This gate consists of required and not strictly required checks which are performed by automated GitHub checks, as well as the mentioned checklist which is checked manually in the review. The number of checks seems to be overwhelming but in practice they can be quite easily fulfilled if following this guide. A properly set-up development environment (see Development Environment) makes it even easier because the most critical steps are performed automatically like showing Clippy warnings while developing and formatting the code. Have a look at the status of the checks after they are processed and fix them. The reviewdog checks are not mandatory and can be ignored if the according change was intentionally. For instance, if a Kubernetes secret was added to the examples of an operator then the detect-secrets steps could fail which is okay in this case.

  3. After the pull request is approved, it can be merged. Internal contributors merge them on their own. Pull request from external contributors are merged by the approver.