Skip to content

Commit

Permalink
docs: transfer decision records and templates from old website repo (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
ndr-brt committed Sep 19, 2024
1 parent 2fd65ed commit e06f763
Show file tree
Hide file tree
Showing 57 changed files with 2,233 additions and 0 deletions.
31 changes: 31 additions & 0 deletions developer/decision-records/2022-02-10-code-coverage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Code coverage

## Decision

JaCoCo is used for measuring test code coverage in the build, in order to obtain metrics on the current state of EDC testing as well as its evolution over time.

The Codecov platform is used for visualizing code coverage statistics on PRs. This will raise developer awareness on an increase/decrease of coverage introduced by PRs. Codecov provides a detailed report including a dashboard with additional metrics like code complexity.

## Rationale

Test code coverage is a measure of the source code that executed when a test suite is run. A program with high test coverage has a lower chance of containing bugs.

At the time of writing, code coverage in the solution is under 50%. Increasing code coverage can best be achieved over time by providing feedback on coverage impact on each PR. This requires a more advanced tool than JaCoCo on its own can provide, and is well achieved by Codecov.

## Spikes

We evaluated the following options:

- [JaCoCo without or with aggregation](jacoco.md)
- [JaCoCo with Codecov](codecov.md)
- [JaCoCo with Codacy](codacy.md)
- [JaCoCo with SonarQube](sonarqube.md)
- [JaCoCo with GitHub Action](jacoco_github_action.md)

## Comparison of selected options

| Tool | Project coverage report | Coverage on PR in GitHub | Additional comments |
| -------------------------- | -------------------------------------- | ------------------------------------------------------------ |-------------------------------------------------------------------------------------------------------------------|
| JaCoCo with Codecov | ✅ Detailed report on Codecov dashboard | ✅ GitHub bot messages on every PR (coverage after the PR is merged, total project coverage, code complexity) | ✅ Reports on code complexity<br/> ✅ Easy configuration |
| JaCoCo with GitHub Actions | ✅ Basic report (percentage) | ✅ GitHub bot messages on every PR (coverage on changed files and total project coverage) | ⚠️ [Minor issue] Manual configuration (JaCoCo Report GitHub Action requires a property to path to JaCoCo reports) |
| JaCoCo with Codacy | ✅ Report available on Codacy dashboard | ⚠️ Not supported | ⚠️ Delays in reports showing up in the dashboard |
31 changes: 31 additions & 0 deletions developer/decision-records/2022-02-10-code-coverage/codacy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# JaCoCo with Codacy

[Codacy](https://www.codacy.com/) is an online service for both static code analysis and test code coverage analysis. It is free for Open Source projects.

We [enrolled our repository fork](https://docs.codacy.com/getting-started/codacy-quickstart/) into Codacy using its Web UI, and obtained a [Project API token](https://docs.codacy.com/codacy-api/api-tokens/) which we set up as a GitHub secret.

We used the modified `build.gradle.kts` file as above to create JaCoCo XML reports. We then used the [Codacy GitHub action](https://github.com/codacy/codacy-coverage-reporter-action) to upload our reports. The `find ` command is set up to exclude one XML report with empty content that is 240 bytes long, and causes the following action to fail.

```yaml
- name: Set Coverage Report Paths
id: coverage-paths
run: |
echo -n "::set-output name=COVERAGE_REPORT_PATHS::"
find . -name jacocoTestReport.xml -size +300c -printf '%p,'
- name: Publish Code Coverage Results
uses: codacy/codacy-coverage-reporter-action@v1
with:
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
coverage-reports: ${{ steps.coverage-paths.outputs.COVERAGE_REPORT_PATHS }}
```
At first the reports weren't visible in the [Codacy UI](https://app.codacy.com/gh/Agera-CatenaX/EclipseDataSpaceConnector/settings/coverage), but they
started to appear after ~16 hours.
In the meantime we also reached out to Codacy support to investigate the issue.
Below screenshot shows code coverage diagram of the main branch analysis.
![Code Coverage with Codacy](code-coverage-codacy.png)
We didn't manage to set up Codacy to see the code coverage reports for the PRs neither in the Codacy dashboard nor in GitHub Actions.
Codacy seems to offer more features for code quality analysis than for code coverage scans.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
92 changes: 92 additions & 0 deletions developer/decision-records/2022-02-10-code-coverage/codecov.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# JaCoCo with Codecov

## Evaluation

Codecov is an online service for code coverage analysis that promises to "always be free for open source projects". We have been widely using it in various (open-source and proprietary) projects for years with good results.

We modified the root `build.gradle.kts` file to apply the JaCoCo plugin to all projects, and produce an XML format report that can be used by Codecov:

```kotlin
// build.gradle.kts

allprojects {
//...
apply(plugin = "jacoco")

//...
tasks.jacocoTestReport {
reports {
xml.required.set(true)
}
}
}

```

We modified the `.github/workflows/verify.yaml` workflow as follows:

```yaml
- name: Gradle Test Core
run: ./gradlew clean check jacocoTestReport

- name: CodeCov
uses: codecov/codecov-action@v2
with:
token: ${{ secrets.CODECOV_TOKEN }}
```
The token is supposedly not required for open-source projects, but we got an error running the action without providing a token.
By logging in at https://about.codecov.io with our GitHub Account, we were able to browse straight away to our EDC (fork) repository and obtain a token for the repository. We added the token as a GitHub secret.
We merged a PR with the action configuration above into the `main` (default) branch of our fork repository, for Codecov to report code coverage differences in PRs.

Finally, we installed the Codecov GitHub app into the repository, to enable the Codecov bot to post comments directly into PRs.

The Codecov online site provides detailed coverage reports. These reports also measure cyclomatic complexity.

![Code Coverage with Codecov](code-coverage-codecov-summary.png)

In PRs, the Codecov bot automatically posts a report indicating coverage changes.

![Code Coverage with Codecov](code-coverage-codecov-pr-github.png)

These reports can also be accessed from the Codecov online service.

![Code Coverage with Codecov](code-coverage-codecov-pr.png)

The report can be drilled to highlight the code subjected to coverage changes.

![Code Coverage with Codecov](code-coverage-codecov-pr-detail.png)

The configuration of Codecov can be adjusted in a [`codecov.yaml` configuration file](https://docs.codecov.com/docs/codecov-yaml). That allows for example configuration to ensure each new PR [does not decrease coverage](https://docs.codecov.com/docs/common-recipe-list#increase-overall-coverage-on-each-pull-request).

## Using Codecov with forks

Further tests showed that if Codecov is installed in the base repository then providing the Codecov token is indeed not required for open source projects:

```yaml
- name: CodeCov
uses: codecov/codecov-action@v2
```

The Codecov PR reports are available with no additional changes also for PRs between forks and the base repository.

If the owners of a fork repository want to use Codecov also for internal PRs (before merging to upstream) then Codecov App needs to be installed also in the
fork, but in this case we also got the reports without providing the token.

## Codecov reports

We can download a report containing the data from (max) last 6 months about Line and Complexity Coverage from the Codecov dashboard.
The coverage on the chart can be aggregated per day, hour, month and commit.

![Code Coverage with Codecov](code-coverage-codecov-dashboard.png)

Codecov only shows commits that have uploaded coverage reports and are six months or less old ([Codecov doc](https://docs.codecov.com/docs/frequently-asked-questions#where-are-my-older-commits-my-project-dashboard-doesnt-show-any-commit-data-in-the-line-graph)).

## Useful links

- [How to interpret Codecov graphs](https://docs.codecov.com/docs/graphs)
- [How to interpret delta in Codecov reports](https://docs.codecov.com/docs/codecov-delta)
- [More information about Codecov Pull Request comments](https://docs.codecov.com/docs/pull-request-comments)

32 changes: 32 additions & 0 deletions developer/decision-records/2022-02-10-code-coverage/jacoco.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Option 1: JaCoCo

JaCoCo (Java Code Coverage) is a popular and mature open-source tool. It runs as a Java agent during test execution, to capture which lines are exercised during which test.

Capturing coverage for a particular project in JaCoCo is straightforward, using the [Gradle JaCoCo Plugin](https://docs.gradle.org/current/userguide/jacoco_plugin.html).

```kotlin
// build.gradle.kts
plugins {
jacoco
}
```

This yields an HTML report.

![Code Coverage with JaCoCo](code-coverage-jacoco-summary.png)

The report can be drilled to highlight covered lines (green), not covered lines (red), and lines where some execution branches are not covered (orange).

![Code Coverage with JaCoCo](code-coverage-jacoco-code.png)

This configuration has limited value since each project produces its own report. Furthermore, there is no indication of whether a given commit is increasing or decreasing coverage, and in which areas of the code.

# Option 2: JaCoCo with aggregation

The Gradle documentation includes a sample for [Reporting code coverage across multiple sub-projects with JaCoCo](https://docs.gradle.org/current/samples/sample_jvm_multi_project_with_code_coverage.html). The sample explains how to generate a single aggregated report.

We were not able to get the sample working in the EDC repository.

In any case, extensive complex Kotlin code needs to be added to the build. This is concerning for maintainability.

As it would anyway not solve the problem that code coverage is best analyzed relatively to a previous commit, we did not attempt further to get the sample working.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# JaCoCo with GitHub Action

Code coverage coming from JaCoCo reports can be added to a PR using [GitHub Action JaCoCo Report](https://github.com/marketplace/actions/jacoco-report).

```yaml
- name: Set Coverage Report Paths
id: coverage-paths
run: |
echo -n "::set-output name=COVERAGE_REPORT_PATHS::$(find ~+ -name jacocoTestReport.xml -size +300c -printf '%p,' | sed 's/.$//')"
- name: Add coverage to PR
id: jacoco
uses: madrapps/jacoco-report@v1.2
with:
paths: ${{ steps.coverage-paths.outputs.COVERAGE_REPORT_PATHS }} # Comma separated absolute paths of the generated jacoco xml files
token: ${{ secrets.GITHUB_TOKEN }} # GitHub personal token to add commits to Pull Request
min-coverage-overall: 40 # The minimum code coverage that is required to pass for overall project
min-coverage-changed-files: 60 #The minimum code coverage that is required to pass for changed files
```
The above workflow will send a comment to the PR showing the code coverage of the files modified in the PR and the overall project code coverage.
![Code Coverage with JaCoCo and GitHub Action](code-coverage-jacoco-gitbhub-actions.png)
57 changes: 57 additions & 0 deletions developer/decision-records/2022-02-10-code-coverage/sonarqube.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# JaCoCo with SonarQube

[SonarQube](https://docs.sonarqube.org/latest/setup/get-started-2-minutes/) is a platform for both static code analysis and test code coverage analysis. It offers an open source Community
Edition version, which is free but has some limitations.

SonarQube can be run locally by adding a SonarQube plugin to gradle and e.g. running SonarQube instance from docker.

Add Gradle plugin:

```gradle
plugin {
id("org.sonarqube") version "3.3"
}
```

To enable code coverage reports test coverage reports should be generated (explained in sections: Option 1 and Option 2).

Docker-compose file with minimal configuration:

```yml
version: "3"
services:
sonarqube:
image: sonarqube:lts
ports:
- 9000:9000
environment:
- SONAR_FORCEAUTHENTICATION=false
```
Then when sonar is up current project can be added to the analysis by running a command:
```bash
./gradlew sonarqube
```

Above-mentioned configuration works when SonarQube is running on default url: http://localhost:9000 and jacoco reports are placed in default location.
Otherwise, these properties should be set: _sonar.host.url_, _sonar.jacoco.reportPaths_. Here can be found more information about [sonarqube Gradle plugin](https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-gradle/).

Code coverage analysis with SonarQube:

![Code Coverage with Sonar](code-coverage-sonar.png)

## Integration with GitHub Actions

Integration with GitHub Actions wasn't a part of this spike, because it requires having a SonarQube instance deployed for the whole project, instead of using
localhost version.

More information about [GitHub Integration](https://docs.sonarqube.org/latest/analysis/github-integration/).

[GitHub Action that helps to run the code analysis.](https://github.com/marketplace/actions/official-sonarqube-scan)

## Limitations of the Community Edition version

- Analysis of multiple branches is not supported
- Reporting measures to branches and pull requests in GitHub not supported
- Automatic detection of branches/pull requests in GitHub Actions not supported
69 changes: 69 additions & 0 deletions developer/decision-records/2022-02-11-codeql/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# CodeQL
CodeQL is a semantic code analysis engine developed by GitHub to automate security checks. A database is extracted from source code that can be analysed with a powerful query language. Each single query can be thought of as a “check” or “rule” representing a distinct security vulnerability that is being searched for. There is an available set of standard CodeQL queries, written by GitHub researchers and community contributors, and custom ones can be written too. See [Writing queries](https://codeql.github.com/docs/writing-codeql-queries/codeql-queries/) in the CodeQL docs for more information.

## Extending the scope of CodeQL queries scan
CodeQL is integrated in the EDC CI build in a dedicated [GitHub workflow](../../../docs/submodule/GitHub/.github/workflows/codeql-analysis.yml).
Currently, the workflow runs on PRs and commits to the main branch and runs the default set of queries as provided by CodeQL.

To have more detailed scan we decided to extend the CodeQL queries, by using the built-in CodeQL query suite: [security-and-quality](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs).

```yaml
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
```
To reduce amount on false positive alerts we excluded the test code from the scan by replacing CodeQL Autobuild with a task that compiles only Java
production sources:
```yaml
# Compiles production Java source (without tests)
- name: Build
run: ./gradlew compileJava
```
The results can be visible in the GitHub Workflow check view under the PR and in Security Tab.
![CodeQL](codeql_github_alerts.png)
After clicking on the alert we can see a view with more detailed explanations about it, references and examples.
## Suppressing the alerts
The alerts can be suppressed or removed by users with Security permissions which are assigned by default to user roles Write, Maintain and Admin.
![CodeQL](security_permissions.png)
Users with Read permissions (repository Members by default) can see the alerts in the PRs, but they don't have access to suppress the alerts or to see
the details.
Users with the proper permissions can analyse the alerts and dismiss/remove them if they are not applicable from both views - under the PR and in the Security Tab.
![CodeQL](codeql_dismiss_alerts.png)
Dismissing the alerts will dismiss them on all branches. Dismissed alerts can be later reopened. Deleting the alerts doesn't prevent them from appearing on
the next scans.
[Here](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/managing-code-scanning-alerts-for-your-repository#dismissing-or-deleting-alerts) you can find more information about dismissing/deleting CodeQL alerts.
In Settings tab we can also define the alert severities causing [pull request check failure](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#defining-the-severities-causing-pull-request-check-failure) (available also only for users with at least Write role).
![CodeQL](codeql_severity_settings.png)
[GitHub code scanning](https://github.com/github/codeql/issues/7294#issuecomment-985496463) does not support alert suppression comments and annotations at
the moment.
### LGTM
[LGTM](https://lgtm.com/) is an online analysis platform that automatically checks your code for real CVEs and vulnerabilities using CodeQL.
In contrast to running CodeQL as a GitHub Action, LGTM supports [alert suppression](https://help.semmle.com/lgtm-enterprise/user/help/alert-suppression.html)
through comments and annotations in the code.
It could be considered a useful addition to the project in the future as it seems more comfortable to use and mature alternative.
## Customization of Queries
After reviewing the current capabilities of CodeQL for the customization of queries with the intention of providing additional insight for the repo the following findings are presented:
- The documentation for CodeQL is lacking in detail and provides little insight into the capabilities of the query language
- Customization of CodeQL at this time brings little benefit and would require addition review of the source code in order to fully expose a robust features to enable customizations
- CodeQL has valuable functionality in existing `packs` which can and should be used when it benefits the needs for the project
- Development efforts for CodeQL remain strong and progress is expected to bring clarity and new features that will enable one to develop customizations in the future
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit e06f763

Please sign in to comment.