Skip to main content

GitLab

Goal

Integrate codee with GitLab to automatically run static analysis over your source code.

Prerequisites

Ensure you have:

  • codee installed and accessible in your GitLab runners.

GitLab CI/CD pipelines

1. Generate status report

GitLab CI/CD can be used to produce Codee HTML reports to summarize the detected quality and security issues found throughout the entire codebase.

This example uses the MATMUL Fortran code of the codee-demos repository.

Add the following content to your .gitlab-ci.yml file:

stages:
- codee-report
- pages

codee_html_report:
stage: codee-report
tags:
- self-hosted
only:
- main
script:
- |
cd Fortran/MATMUL
cmake . -DCMAKE_Fortran_COMPILER=gfortran -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -G "Ninja" -B build
echo "Running Codee screening and generating HTML report..."
codee screening -p build/compile_commands.json --html htmlOUT
artifacts:
paths:
- Fortran/MATMUL/htmlOUT
expire_in: 1 hour # Adjust as needed

pages:
stage: pages
dependencies:
- codee_html_report
script:
- mkdir public
- cp Fortran/MATMUL/htmlOUT/* public
artifacts:
paths:
- public
only:
- main

How it works

  • The workflow runs whenever changes are updated to the main branch.
  • It runs codee to generate the screening and checks reports on HTML format.
  • In the GitLab artifacts section of the job you can find the resulting index.html Codee report.

2. Verify critical checkers

Warning

A Fatal/Error checker is a user-defined analysis rule that flags high-severity issues in the code. These checkers are explicitly defined by the user using the --check-id flag when running Codee.

GitLab CI/CD can be used to run codee checks automatically on merge requests and ensure that all contributions do not include bugs in their Fortran code.

This example uses the MATMUL Fortran code of the codee-demos repository. In this case, the pipeline will be stopped if Codee triggers PWR072 or PWR079.

Add the following content to your .gitlab-ci.yml file:

stages:
- codee-checks

codee_static_analysis:
stage: codee-checks
tags:
- self-hosted
only:
- merge_requests
before_script:
- apt update && apt install -y git jq cmake ninja-build gfortran
- git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME --depth=1
- git fetch origin
- git checkout "$CI_COMMIT_REF_NAME"
script:
- |
echo "Detecting modified Fortran files..."
MODIFIED_FILES=$(git diff --name-only --diff-filter=d origin/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}...HEAD -- '*.f90' '*.F90' '*.f' '*.F')
echo "Modified files: $MODIFIED_FILES"
if [ -n "$MODIFIED_FILES" ]; then
echo "Generate compile_commands.json"
cd Fortran/MATMUL
cmake . -DCMAKE_Fortran_COMPILER=gfortran -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -G "Ninja" -B build
echo "Running Codee checks..."
codee checks \
--check-id PWR072,PWR079 \
--verbose \
-p build/compile_commands.json \
$MODIFIED_FILES --json > codee_output.json
ISSUE_COUNT=$(jq '.Checks | length' codee_output.json)
if [ "$ISSUE_COUNT" -gt 0 ]; then
echo "Codee detected $ISSUE_COUNT critical issues."
exit 1
else
echo "No critical issues found by Codee."
fi
else
echo "No modified Fortran files. Skipping Codee checks."
fi
allow_failure: false

How it works

  • The workflow runs whenever a merge request is opened or updated.
  • It runs codee checks if there are modified Fortran source files in the current branch.
  • If codee triggers a PWR072 or a PWR079 checker, the GitLab Ci pipeline will fail.

3. Warning on nice-to-have checkers

Similar to the previous example we can use GitLab CI/CD to execute codee checks and notify the user about the presence of non-critical checkers. To do this we can use the --no-check-id Codee flag to filter-out the critical checkers. In this case the pipeline, it will only raise a warning and an artifact with the Codee output in JSON format (note the --json Codee flag) will be generated so it can be reviewed.

This example uses the MATMUL Fortran code of the codee-demos repository.

Add the following content to your .gitlab-ci.yml file:

stages:
- codee-checks

codee_static_analysis:
stage: codee-checks
tags:
- self-hosted
only:
- merge_requests
before_script:
- apt update && apt install -y git jq cmake ninja-build gfortran
- git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME --depth=1
- git fetch origin
- git checkout "$CI_COMMIT_REF_NAME"
script:
- |
echo "Detecting modified Fortran files..."
MODIFIED_FILES=$(git diff --name-only --diff-filter=d origin/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}...HEAD -- '*.f90' '*.F90' '*.f' '*.F')
echo "Modified files: $MODIFIED_FILES"
if [ -n "$MODIFIED_FILES" ]; then
echo "Generating the compile_commands.json file..."
cd Fortran/MATMUL
cmake . -DCMAKE_Fortran_COMPILER=gfortran -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -G "Ninja" -B build
echo "Running Codee checks report..."
codee checks \
--no-check-id PWR072,PWR079 \
--verbose \
-p build/compile_commands.json \
--json > codee_output.json
WARN_COUNT=$(jq '.Checks | length' codee_output.json)
if [ "$WARN_COUNT" -gt 0 ]; then
echo "Codee detected $WARN_COUNT non critical issues."
cat codee_output.json
else
echo "No non-critical issues found by Codee."
fi
else
echo "No modified Fortran files. Skipping Codee checks."
fi
allow_failure: false
artifacts:
paths:
- Fortran/MATMUL/codee_output.json

How it works

  • The workflow runs whenever a merge request is opened or updated.
  • It runs codee checks if there are modified Fortran source files in the current branch.
  • If codee finds non-critical checkers, it will warn the users and create an artifact with the codee output for review.

4. Apply Autofixes

Warning

Be cautious when using Codee Autofixes to apply automatic changes to your codebase. Always review the proposed modifications before merging, as they might introduce unintended side effects.

GitLab CI/CD can also be used to automatically apply codee rewrite to fix Fortran code if there are Autofixes available for certain checkers. To follow this approach it is necessary to create a personal token on your GitLab instance.

Add the following content to your .gitlab-ci.yml file:

stages:
- autofix

codee_autofix:
stage: autofix
tags:
- self-hosted
only:
- merge_requests
before_script:
- apt update && apt install -y git jq cmake ninja-build gfortran
- git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME --depth=1
- git fetch origin
- git checkout "$CI_COMMIT_REF_NAME"
script:
- echo "Detecting modified Fortran files..."
- |
MODIFIED_FILES=$(git diff --name-only --diff-filter=d origin/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}...HEAD -- '*.f90' '*.F90' '*.f' '*.F')
echo "Modified files: $MODIFIED_FILES"
if [ -n "$MODIFIED_FILES" ]; then
echo "Generating compile_commands.json"
cd Fortran/MATMUL
cmake . -DCMAKE_Fortran_COMPILER=gfortran -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -G "Ninja" -B build
echo "Running Codee checks..."
codee checks \
--check-id PWR007,PWR008,PWR068,PWR003 \
--verbose \
-p build/compile_commands.json \
$MODIFIED_FILES --json > codee_output.json
echo "Checking for autofixes..."
jq -r '.Checks[] | select(."Auto-fix" != null) | ."Auto-fix"[]' codee_output.json > autofix_commands.txt
if [ ! -s autofix_commands.txt ]; then
echo "No autofixes found."
exit 0
fi
applied=0
while IFS= read -r fix_cmd; do
echo "Applying: $fix_cmd"
eval "$fix_cmd"
applied=$((applied + 1))
done < autofix_commands.txt
echo "Total autofixes applied: $applied"
if ! git diff --quiet; then
git commit -c user.name="gitlab-ci" -c user.email="ci@example.com" -am "Apply Codee autofixes"
git push https://gitlab-ci-token:${GITLAB_TOKEN}@gitlab.com/${CI_PROJECT_PATH}.git $CI_COMMIT_REF_NAME;
else
echo "No changes from autofixes."
fi
else
echo "No modified Fortran files. Skipping Codee autofix."
fi
allow_failure: true

How it works

  • The workflow runs whenever a pull request is opened or updated.
  • It runs codee checks to check if the checkers appear in the code; in this case it is configure to trigger PWR007, PWR008, PWR068 and PWR003.
  • If there is an Autofix available it will automatically apply it and commit the changes.
  • It won't block the merging of the branch.

Troubleshooting

  • If the job does is not triggered, verify the rules: section.
  • If changes are not performed, check if your file names match the specified glob patterns (*.f90, *.F90, etc.).