Skip to content

6. Continuous integration ​

A CI job runs the same commands as you do, and reads their results. With --json a command writes one JSON document on its standard output, and its messages on the standard error: a script reads facts, not log lines.

Checking the sources ​

fobis check resolves the dependencies of every file without compiling anything: a quick first step for a job.

console
$ fobis check --json
{
  "status": "ok",
  "files": 241,
  "unresolved": [],
  "cycles": [],
  "warnings": []
}

Building ​

console
$ fobis build --mode release --json
{
  "status": "ok",
  "target": "src/integrate.F90",
  "objects_compiled": 0,
  "errors": []
}

When a build fails, the document carries the compiler's messages parsed (diagnostics) and what FoBiS concludes from the project's facts (diagnoses). A file that uses a module nobody defines:

console
$ fobis build --mode release --json
{
  "status": "error",
  "target": "src/integrate.F90",
  "objects_compiled": 0,
  "errors": [
    "warning: the file 'src/residual.F90' depends on 'quad_errors' that is unreachable",
    "src/residual.F90:4:5:\n\n    4 | use quad_errors, only : R8P\n      |     1\nFatal Error: Cannot open module file 'quad_errors.mod' for reading at (1): No such file or directory\ncompilation terminated.\n"
  ],
  "diagnostics": [
    {
      "tool": "gnu",
      "severity": "fatal",
      "message": "Cannot open module file 'quad_errors.mod' for reading at (1): No such file or directory",
      "file": "src/residual.F90",
      "line": 4,
      "column": 5
    }
  ],
  "diagnoses": [
    {
      "kind": "missing-module",
      "summary": "module quad_errors is not available when src/residual.F90 is compiled",
      "diagnostic": {
        "tool": "gnu",
        "severity": "fatal",
        "message": "Cannot open module file 'quad_errors.mod' for reading at (1): No such file or directory",
        "file": "src/residual.F90",
        "line": 4,
        "column": 5
      },
      "facts": [
        "no project source defines module quad_errors, and it is not a known library module."
      ],
      "advice": [
        "declare the project that provides it in fobos `[dependencies]` and run `fobis fetch`, or add the directory of its .mod files to `cflags` (`-I...`)"
      ],
      "consequences": 0
    }
  ]
}
[exit status 1]

Testing ​

console
$ fobis test --json 2> /dev/null
{
  "status": "ok",
  "test_dir": "test",
  "passed": 2,
  "failed": 0,
  "results": [
    {
      "name": "test_exactness",
      "suite": "",
      "exit_code": 0,
      "duration": 0.001,
      "stdout": "exact on polynomials of its degree",
      "stderr": "",
      "status": "passed"
    },
    {
      "name": "test_order",
      "suite": "",
      "exit_code": 0,
      "duration": 0.001,
      "stdout": "observed orders: trapezoid  2.001, simpson  4.005",
      "stderr": "",
      "status": "passed"
    }
  ]
}

Every result carries its status, exit code and output; a failed one also the crash (here an error stop), located in the sources.

A workflow ​

yaml
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - name: Tools
        run: |
          sudo apt-get install -y gfortran
          pip install FoBiS.py gcovr
      - name: Dependencies, at the tags the fobos pins
        run: fobis fetch
      - name: Build
        run: fobis build --mode release
      - name: Tests
        run: fobis test --json > tests.json
      - name: Coverage
        run: |
          fobis test --mode coverage
          fobis coverage --mode coverage --format xml --fail-under 90
  • fobis fetch clones the dependencies at the tags the fobos pins. The lock file stays in .fobis_deps/, which is not committed: a fresh checkout has none, so --frozen belongs on machines that keep their fetched dependencies.
  • The coverage step fails the job below 90% of the lines.
  • tests.json can be uploaded as an artifact, or read by a later step.

What you learned

fobis check, --json on build, check, test (also on clean, fetch, tree and the verification commands), and a CI workflow. Reference: JSON output.

Next: 7. Other build systems.