How to mark stage as unstable if Powershell condition results into true?

I have a .Net 5 solution and build the projects with code style analysis. Each violated rule results in a warning. But the build command exits with the code 0.

I created a .gitlab-ci.yml file that should mark the pipeline as unstable if any build warnings have been thrown.

image: mcr.microsoft.com/dotnet/sdk:5.0

stages:
  - build
  - unit-tests

build:
  stage: build
  script:
      - |-
        dotnet build --output build -consoleloggerparameters:"Summary;Verbosity=normal" -m -p:"WarnLevel=5;EnforceCodeStyleInBuild=true" -t:"clean,build" -fl1 "/flp1:warningsonly";

        if ((!$LASTEXITCODE) -and (Get-Content "msbuild1.log"))
        {
          # >>> mark stage as unstable here <<<
        }
  artifacts:
    paths:
      - build

unit-tests:
  stage: unit-tests
  script:
    - dotnet test --no-build --output build
  dependencies:
    - build

The stage itself passes but I was hoping that it passes with an unstable state (because of the warnings), unfortunately it’s green.

A bad solution would be adding the -warnaserror flag for the build command and use allow_failure: true for the stage. This would set the stage into an unstable state but next stages would fail because of the missing build.

So what would be the correct way to check if the build command finished with warnings to mark the stage as unstable?

There is no such state as an “unstable” job in Gitlab CI. It either fails or succeeds.
To get the build still marked as failed (not “unstable”) inside your if clause even though your compiler is asked to not “fail” on warnings (so its return code will be just fine and you will have build artifacts) you can break the script intentionally with a failing line of code after scanning the return of your build for warnings. If you then want the other stages to try to execute even though the build gives a failed state, that is the already mentioned allow_failure: true.

1 Like

Thanks for your reply, I found another solution. I added an additional stage

code-quality:
  stage: code-quality
  script:
    - |-
      dotnet tool install -g dotnet-format;
      dotnet format -wsa --check --verbosity diagnostic;

      if ($LASTEXITCODE) 
      {
        exit 1;
      }
  allow_failure: true
  dependencies:
    - build

The only thing I’m wondering is why I have to check for the exit code. If dotnet format fails it exits with the code 2. But Gitlab seems to check for the exit code 0 or 1 only? Because the error code 2 results into success. That’s why I have to check for it manually.

1 Like

Gitlab might be only checking $? which can differ from the exit code.

1 Like