Skip to main content

GitHub

Goal

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

Prerequisites

Ensure you have:

  • codee installed and accessible in your GitHub runners.

Create a GitHub Actions workflow

GitHub Actions can be used to run codee checks automatically on pull requests and ensure that all contributions do not include bugs in their Fortran code.

In your repository, create the following directory structure if it does not exist:

mkdir
mkdir -p .github/workflows/

Then, create a new workflow file:

touch
touch .github/workflows/codee-checks.yml

Define the GitHub actions workflow

GitHub action to stop the pipeline if Codee triggers 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.

GitHub Actions can be used to run codee checks automatically on pull requests and ensure that all contributions do not include bugs in their Fortran code.

This example is done using 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 .github/workflows/codee-checks.yml:

name: Codee Checks

on:
pull_request:

jobs:
static-analysis:
name: Run Codee checks
runs-on: self-hosted

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Get modified Fortran files
id: modified-files
run: |
MODIFIED_FILES=$(git diff --name-only --diff-filter=d origin/${{ github.base_ref }}...HEAD -- '*.f90' '*.F90' '*.f' '*.F')
echo "MODIFIED_FILES=$MODIFIED_FILES" >> $GITHUB_ENV

- name: Run Codee checks
if: env.MODIFIED_FILES != ''
run: |
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 on modified files: $MODIFIED_FILES"
codee checks \
--check-id PWR072,PWR079 \
--verbose \
-p build/compile_commands.json \
$MODIFIED_FILES --json > codee_output.json

- name: Fail if critical checkers were found
if: env.MODIFIED_FILES != ''
run: |
ISSUE_COUNT=$(jq '.Checks | length' Fortran/MATMUL/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

How it works

  • The workflow runs whenever a pull 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 GitHub action will fail.

GitHub action to apply Codee 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.

GitHub actions can also be used to automatically apply codee rewrite to fix Fortran code if there are Autofixes available for certain checkers.

Add the following content to .github/workflows/codee-rewrite.yml:

name: Codee autofixes

on:
pull_request:

permissions:
contents: write
pull-requests: write

jobs:
autofix:
name: Apply autofix if possible
runs-on: self-hosted

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.head_ref }}

- name: Get modified Fortran files
id: modified-files
run: |
MODIFIED_FILES=$(git diff --name-only --diff-filter=d origin/${{ github.base_ref }}...HEAD -- '*.f90' '*.F90' '*.f' '*.F')
echo "MODIFIED_FILES=$MODIFIED_FILES" >> $GITHUB_ENV

- name: Run `codee checks` and export JSON
if: env.MODIFIED_FILES != ''
run: |
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
codee checks \
--check-id PWR007,PWR008,PWR068,PWR003 \
--verbose \
-p build/compile_commands.json \
$MODIFIED_FILES --json > codee_output.json

- name: Apply autofixes if available
if: env.MODIFIED_FILES != ''
run: |
echo "Checking for autofixes..."
cd Fortran/MATMUL
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"

- name: Commit changes if autofixes were applied
if: env.MODIFIED_FILES != ''
run: |
if ! git diff --quiet; then
# Push with the github-actions user. More information at:
# https://github.com/actions/checkout?tab=readme-ov-file#push-a-commit-using-the-built-in-token
git commit -c user.name="github-actions[bot]" -c user.email="41898282+github-actions[bot]@users.noreply.github.com" -am "Apply Codee autofixes"
git push --set-upstream origin ${{ github.head_ref }}
else
echo "No changes from autofixes."
fi

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 branch merges.

Troubleshooting

  • If the action does not trigger, verify the on: section.
  • If formatting does not apply, check if your files match the specified glob patterns (*.f90, *.F90, etc.).