Skip to content

Git Strategy

southeo edited this page Apr 10, 2025 · 7 revisions

Git Approach

To keep our work structured and neatly organized, we use Git as the main software for storing our projects’ code and other types of files. Git is a software that offers a variety of functionalities built upon the base of file storage. With these functionalities we can retain an insight in every developer’s contributions to projects and review these with ease. Reviewing is important because of checking for the code validity, but also for learning from each other’s work.

Trunk-Based Development

A ‘trunk’ can be related to that of a tree, it is the basis whereupon a tree grows. The same goes for Git branches. The main branch, sometimes called master, is the trunk of a Git repository. The trunk can grow over time with the introduction of new features that are merged from different branches. The difference between trunk based development over other branching models is the way branches are being handled. A branch from the trunk is short lived and specially created for building a feature out of a user story. This means branches will exist for specific items that can be developed over a short period of time.

A summary:

"A source-control branching model, where developers collaborate on code in a single branch called ‘trunk’ *, resist any pressure to create other long-lived development branches by employing documented techniques. They therefore avoid merge hell, do not break the build, and live happily ever after." (Hammant, 2020)

During development we will make use of trunk based development to control our way of handling branches and workflows. The method states we use:

  • A trunk branch called ‘main’ as the basis of a repository (not “master”)
  • Short lived branches based upon handable user stories
  • A release branch that contains stable releases of the repository’s software

Following these guidelines we have created a manifest on how to work with Git according to trunk based development.

GitHub

GitHub is a website for using Git. It is basically a front-end for skipping through the different repositories inside a project. It also provides useful functions for interacting with repositories. Especially creating and collaborating on pull requests is very useful. Different developers can commit and comment on each other’s code that allows for quick reviewing. Merging is another functionality that can easily be executed via GitHub.

All projects should be publicly available on the GitHub DiSSCo Organisation page. Make sure you are added to this organisation as soon as possible.

Creating a New Repository

We can create a new repository with GitHub. When creating a new repository in Git, the name of the repository can be determined by the name of the application as stated by the product owner. A newly created repository always contains one basic branch we call ‘main’. This branch is the trunk of the repository and will be the parent for all newly created branches.

Important: When creating a new repository, you must make sure your main branch is protected. This means after the initial commit, the main branch can not be modified without a pull request. More information about pull requests can be found later in this page.

A new repository should always contain a certain set of files that can automatically (or manually) be added to the main branch. These files include:

  • A .gitignore file
  • A README.md file
  • A LICENCE file
  • A .github/workflows/build.yaml file and a .github/workflows/cache-trivy.yaml file for the CI/CD pipeline.

The gitignore file is mandatory. Even if the project does not make use of it, it will still indicate to other developers the repository does not negate anything specific.

The purpose of the README file is to give a general description of the application that is being built using the repository. A standard README file could include:

  • The purpose of the application
  • Requirements
  • A basic explanation on how to use the application
  • Usable parameters
  • How to install

Branch Protection

We protect the main branch so no non-authorised merges can take place. We force each merge to go through the Peer Review process described in this document. Be aware that only user with Admin role can add/change branch protection. The following branch policies are active.

  • At least 1 approval is necessary
  • We dismiss stale pull requests approvals when new commits are pushed. Change in the code will require a new review
  • We require the following status checks before merging:
    • SonarCloud Code Analysis
    • No high/critical security vulnerabilities
  • Conversation needs to be resolved before pull request can be merged

Working on User Stories

Typically, each user story should result in at most one branch. Remember, according to trunk based development, new branches will be short lived and specifically made for one user story. Important to recognize is that branches will always and only sprout from the main branch. This will make sure the structure will remain simple and clean.

Branch Naming Conventions

When creating a new branch to work on a user story, we make use of standard naming conventions. The naming conventions indicate the purpose of a branch and the origin in the shape of the user story. When using the naming conventions we will make sure to work inline with the TeamWork application that provides the user stories and contextual information.

feature: The feature naming convention indicates a branch whereupon a new feature is being developed. Example: feature/{brief description}

bug: The bug naming convention indicates a branch that is being used to resolve a bug inside developed code. A file name can be used when a bug is not relevant to an user story anymore. Example: bug/{brief description} or bug/{file_name}

hotfix: We use “hotfix” to designate a short-lived branch for small PRs. (The difference between a feature and hotfix is somewhat subjective.) Example: hotfix/{version 0.1}

Creating a Pull Request

When your commits ‘fully’ implement the requested features of a user story, it is time to create a pull request. First off, make sure you have committed all necessary changes to your branch. Secondly, push your branch’s changes to the main branch, the trunk of the repository. Git will now allow you to create a pull request. When creating a new pull request, check if you select the correct branch and if all commits are present.

The description of a PR should summarize the contents of a PR. It can contain several lines of information but should remain brief. Try to list the important items you added, changed or removed for this commit and think of a suitable statement to accompany the list. Furthermore, try to write in a present tense, the commit has yet to be merged and could be backed up by another commit. The example below makes use of the calculator example:

This commit adds a refined way the Calculator can remember numbers for future usage. It changes the interface to suit the new functionality. It removes the old, outdated memory function. Adds: A new memory function for the Calculator Changes: The interface to support the new memory function Removes: The old function for remembering numbers

Lastly add your co-developers as reviewers so they can review the code. Save the pull request.

What happens now? In the most favorable situation, the co-developers will review your code within a short period of time. This will allow for optimization of the code and give the opportunity to yourself and the others to learn from each other’s code. It is not necessary to review the code by all co-developers, but the aim is to let at least one developer review the code. Therefore it is not a good practice to merge your code into the main branch without any notice of other developers. When a developer has finished reviewing, you can optionally apply changes in a new commit. When satisfied and with permission of at least one other developer (preferably the senior developer), the pull request can be merged into the trunk.

In order to merge a pull request to the trunk, the following conditions must be met:

  • Review and approval by at least one other developer
  • No SonarCloud issues
  • No High/Critical security vulnerabilities
  • 80% unit test coverage

GitHub Actions

GitHub actions are driven by workflows. We use GitHub actions to assess code quality, identify vulnerabilities, and to push code to the Elastic Container Registry on AWS.

To set up GitHub actions, create a build.yaml file with the following path: .github/workflows. The build.yaml file in this repository is a good example of what needs to be implemented.

A push to main or an open pull request will trigger the actions. The first action is to build the pushed project and run all unit tests. Upon a successful build and run, our quality checker SonarCloud will run its quality analysis on the code and verify test coverage. Trivy will then check for security vulnerabilities.

Build and Analyze

In this step, the compiler builds the code and runs all tests. This is the first line of defense against major issues. If this step fails, the pipeline will not continue.

Code Quality Checking with SonarCloud

Within DiSSCo, we use the tool SonarCloud as a code quality checker. SonarCloud scans code for security vulnerabilities and maintainability issues, such as Within DiSSCo, we expect all SonarCloud issues to be resolved before merging . SonarCloud analysis is triggered by the GitHub actions described in the previous section. You can also run Sonar code checks as you code using the SonarLint IDE Extension.

In Java, in addition to adding an action in your build.yaml file, the following plugins and dependencies are required in your pom.xml to allow SonarCloud scanning:

<properties>    
    <sonar.organization>dissco</sonar.organization>
    <sonar.host.url>https://sonarcloud.io</sonar.host.url>
    <sonar.coverage.jacoco.xmlReportPaths>
        ../app-it/target/site/jacoco-aggregate/jacoco.xml 
    </sonar.coverage.jacoco.xmlReportPaths>
</properties>

<plugin>
  <artifactId>maven-failsafe-plugin</artifactId>
  <configuration>
    <useSystemClassLoader>false</useSystemClassLoader>
  </configuration>
</plugin>

<plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.7</version>
        <executions>
          <execution>
            <id>prepare-agent</id>
            <goals>
              <goal>prepare-agent</goal>
            </goals>
          </execution>
          <execution>
            <id>prepare-agent-integration</id>
            <goals>
              <goal>prepare-agent-integration</goal>
            </goals>
          </execution>
          <execution>
            <id>report</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>report</goal>
            </goals>
          </execution>
          <execution>
            <id>report-integration</id>
            <goals>
              <goal>report-integration</goal>
            </goals>
          </execution>
        </executions
</plugin>

In JavaScript, create a sonar-project.properties file in the root directory of your project.

<properties>    
    <sonar.organization>dissco</sonar.organization>
    <sonar.host.url>https://sonarcloud.io</sonar.host.url>
    <sonar.coverage.jacoco.xmlReportPaths>
        ../app-it/target/site/jacoco-aggregate/jacoco.xml 
    </sonar.coverage.jacoco.xmlReportPaths>
</properties>

Vulnerability Scanning With Trivy

Trivy is an open-source tool that scans a project for Common Vulnerabilities and Exposures (CVEs). It checks your Software Bill of Materials using an up to-date CVE database and rates any vulnerabilities from Low to Critical severity. If an issue has been fixed in a later version, Trivy tells you which version you need to update to.

You can scan an image locally as well as incorporate Trivy into your GitHub workflow. To add Trivy to your workflow, you only need to add it to your build.yaml file.

Trivy is a powerful tool for identifying vulnerabilities in a project. Sometimes, issues may be easily fixed by updating your dependencies. If an issue has not been fixed, however, you have a problem. Some CVEs may not be immediately addressed.

The DiSSCo pipeline involves two scans using Trivy. The first pass scans and identifies all CVEs at all severity levels. The second pass searches for High and Critical vulnerabilities and breaks the pipeline if any vulnerabilities are found. If there are issues that can not be fixed, you can add the CVE to a .trivyignore file. The first pass should not ignore any CVEs.

If you add a CVE to the .trivyignore, you must address the following issues (1-2 sentences max)

  • Date CVE was identified
  • Why it must be ignored
  • Is it actively being amended/Is there a user story to fix this issue?
Clone this wiki locally