SonarQube - GitHub Action - Xcode

Hi all

I have a problem with the SonarQube GitHub Action

I have a dashboard → Enterprise Edition v10.6 (92116)

This is my Action

After checkout, install Pod, and install certificates

- name: Build project with build-wrapper
        run: |
          echo 'Building project with build-wrapper...'
          ${{ github.workspace }}/sonarqube/build-wrapper/build-wrapper-macosx-x86 --out-dir $BUILD_WRAPPER_OUT_DIR \
          xcodebuild \
            -workspace MyApp.xcworkspace \
            -scheme MyApp \
            -derivedDataPath DerivedData/ \
            -enableCodeCoverage YES \
            -configuration Debug \
            -destination 'platform=iOS Simulator,name=${{ vars.DEVICENAME }}' \
            clean build test

**********

- name: SwiftLint JSON for SonarQube
        continue-on-error: true
        run: |
          echo ">>> installing swiftlint <<<"
          brew install swiftlint
          echo ">>> entering source directory <<<"
          cd $GITHUB_WORKSPACE
          echo ">>> creating swiftlint json file <<<"
          touch DerivedData/swiftlint.json
          echo ">>> running swiftlint with config file <<<"
          swiftlint --config $GITHUB_WORKSPACE/.swiftlint.yml --reporter json > DerivedData/swiftlint.json || true
          echo ">>> listing folder <<<"
          ls

      - name: Download and set up sonar-scanner
        env:
          SONAR_SCANNER_DOWNLOAD_URL: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-macosx.zip
        run: |
          mkdir -p $HOME/.sonar
          curl -sSLo $HOME/.sonar/sonar-scanner.zip ${{ env.SONAR_SCANNER_DOWNLOAD_URL }}
          unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
          echo "$HOME/.sonar/sonar-scanner-5.0.1.3006-macosx/bin" >> $GITHUB_PATH
    
      - name: Analyze with SonarQube
        env:
          SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        run: |
           $HOME/.sonar/sonar-scanner-5.0.1.3006-macosx/bin/sonar-scanner \
            -Dsonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" \
            -X \
            -Dsonar.projectKey=myKey \
            -Dsonar.projectName=myKey \
            -Dsonar.test.inclusions=**/*Tests/*.swift \
            -Dsonar.coverage.exclusions=**/*.xml,Pods/**/*,Reports/**/*,DerivedData/**/*,**/*.html,**/,DerivedData/SourcePackages/** \
            -Dsonar.swift.project=MyApp.xcodeproj \
            -Dsonar.swift.appName=MyApp \
            -Dsonar.swift.appScheme=MyApp \
            -Dsonar.swift.appConfiguration=Debug \
            -Dsonar.sourceEncoding=UTF-8 \
            -Dsonar.swift.excludePathsFromCoverage=build,DerivedData,fastlane,Pods,reports,xcov_output \
            -Dsonar.swift.excludedPathsFromCoverage=.*Tests.*,MyAppTest \
            -Dsonar.c.file.suffixes=- \
            -Dsonar.objc.file.suffixes=.h,.m \
            -Dsonar.cfamily.compile-commands=compile_commands.json \
            -Dsonar.swift.swiftlint.reportPaths=DerivedData/swiftlint.json \
            -Dsonar.coverageReportPaths=DerivedData/sonarqube-converted.xml \
            -Dsonar.cfamily.threads=4 \
            -Dsonar.branch.name=development \
            -Dsonar.projectVersion=${{env.CURRENT_VERSION_NUMBER}}

I got a lot of errors during Building wrapper

2024-11-13 16:52:01.782 xcodebuild[5945:28878] Writing error result bundle to /var/folders/1y/56hdyx6x0_jb18k7b4ys9b6w0000gn/T/ResultBundle_2024-13-11_16-52-0001.xcresult
xcodebuild: error: Could not resolve package dependencies:
<unknown>:0: warning: legacy driver is now deprecated; consider avoiding specifying '-disallow-use-new-driver'build-wrapper: connect to /tmp/build-wrapper-socket.dX7UyI: Operation not permitted
  Invalid manifest (compiled with: ["/Applications/Xcode_15.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc", "-

How can I fix it?

The other steps are right (SwiftLint, sonar scanner download, sonar analyze etc)?

I checked also to sonarsource github but without success

Could you help me?

thanks a lot

Hey there.

Can you post a wider range of logs? Ideally, the full analysis logs.

Hi @Colin I changed my workflow using Build Wrapper as you can see in the first edited post

Can you post a wider range of logs? Ideally, the full analysis logs.

I’m not able to download the full log from GitHub the zip was always corrupted

Now I got another strange error (as you can see in the first post)

It’s very tricky to do this with GitHub sonarqube and Xcode, no way to do it easily?

thanks a lot, I really stuck on this

Without more detailed logs, I’m not sure how we can help you further. You’ve also removed your original error from your post, so I don’t know what issue we’re trying to troubleshoot now.

FYI, if you’re only trying to analyze Swift, you don’t need the build wrapper. You only need the build wrapper if you’re analyzing C/C++/Objective-C code.

And in fact, even if you are trying to analyze C/C++/Objective-C code, the build-wrapper isn’t strictly necessary due to AutoConfig Mode.

So I suggest reverting your changes (don’t use the build wrapper), and provide more details (more logs) around the original issue

Hi @Colin

I appreciate your support

I reverted the changes and modified some properties (-Dsonar), and also changed the version of sonar-scanner-cli with this one

Now, I have the new version loaded on the dashboard, and everything works. :slight_smile:

Also the coverage converted to XML with sonarqube xcove script

Thanks

Hi @Colin

Do you know how Swift Lint works?

Is it possible to import swift lint JSON to import some rules?

-Dsonar.swift.swiftlint.reportPaths=${{ github.workspace }}/myPath
-Dsonar.externalIssuesReportPaths=${{ github.workspace }}/myPath

How can I check if it works and is correctly imported?

I got this error:

java.lang.IllegalStateException: Failed to read external issues report DerivedData/swiftlint.json': invalid JSON syntax

Thanks

Well, you should certainly stop pointing at sonar.externalIssuesReportPaths Swiftlint-style report, as that will cause an error.

Setting sonar.swift.swiftLint.reportPaths alone should be enough, with a Swiftlint report generated with reporter: "json"

What happens when you do that?

Hi @Colin

Yes, all works fine and the build uploaded to Sonarqube dashboard :slight_smile:

Just one thing, how can I know if sonarqube using my swift lint rules?

Thanks for support

Do you see an issue in the swiftlint report that is reflected on the SonarQube dashboard (check the Issues tab of your project or navigate to a specific file in the Code tab)?

Hi @Colin

I moved the .swiftlint.yml with rules in the root of the project because inside a subfolder doesn’t work

custom rules added:

custom_rules:
  my_custom_rule:
    included: "**/*.swift"
    name: "My Custom Rule"
    regex: "// my_custom_rule:.*"
    message: "This is a custom rule for testing"
    severity: error

and I pushed this comment in one Swift file

// my_custom_rule: Test Custom

I tried to run it locally and the resulting JSON have this custom rules

{
    "character" : 1,
    "file" : "pathToMyFile/MyFile.swift",
    "line" : 9,
    "reason" : "This is a custom rule for testing",
    "rule_id" : "my_custom_rule",
    "severity" : "Error",
    "type" : "My Custom Rule"
  },

Listing folder before launch Sonar

....
.....
....
drwxr-xr-x    6 runner  staff   192B Nov 28 14:54 SourcePackages
drwxr-xr-x    4 runner  staff   128B Nov 28 15:14 TestResults
-rw-r--r--    1 runner  staff   353B Nov 28 15:09 info.plist
-rw-r--r--    1 runner  staff   819K Nov 28 15:15 swiftlint.json

I set Sonar in this way

Sonar Step

- name: Analyze with SonarQube
        ....
        ....
        ....
        ....
-Dsonar.test.inclusions=**/*Tests/*.swift \

-Dsonar.exclusions=**/*.py,**/*.xml,Pods/**,Reports/**,DerivedData/**,**/*.html,DerivedData/SourcePackages/**,**/*.doccarchive/**,**/*.js \

-Dsonar.coverage.exclusions=**/*.xml,Pods/**,Reports/**,DerivedData/**,**/*.html,DerivedData/SourcePackages/**,**/*.doccarchive/**,**/*.js \

-Dsonar.swift.excludedPathsFromCoverage=build,DerivedData,fastlane,Pods,reports,xcov_output,.*Tests.*,MyAppTests

Log Sonar (GitHub Action)

17:17:47.504 INFO  Scanner configuration file: /Users/runner/.sonar/sonar-scanner-6.2.1.4610-macosx-aarch64/conf/sonar-scanner.properties
15:15:24.800 INFO  Scanner configuration file: /Users/runner/.sonar/sonar-scanner-6.2.1.4610-macosx-aarch64/conf/sonar-scanner.properties
15:15:24.803 INFO  Project root configuration file: NONE

15:15:24.813 INFO  SonarScanner CLI 6.2.1.4610
15:15:24.813 INFO  Java 17.0.12 Eclipse Adoptium (64-bit)
15:15:24.814 INFO  Mac OS X 15.1.1 aarch64
15:16:00.157 INFO  Process project properties
15:16:00.157 INFO  Process project properties (done) | time=0ms
15:16:00.365 INFO  Load project branches
15:16:00.547 INFO  Load project branches (done) | time=181ms
15:16:00.548 INFO  Load branch configuration
15:16:00.550 INFO  Found manual configuration of branch/PR analysis. Skipping automatic configuration.
15:16:00.552 INFO  Load branch configuration (done) | time=5ms
15:16:00.572 INFO  Load quality profiles
15:16:00.791 INFO  Load quality profiles (done) | time=220ms
15:16:00.795 INFO  Auto-configuring with CI 'Github Actions'
15:16:00.808 INFO  Load active rules
15:16:10.061 INFO  Load active rules (done) | time=9253ms

15:16:58.681 INFO    Excluded sources: **/*.py, **/*.xml, Pods/**, Reports/**, DerivedData/**, **/*.html, **/*DerivedData/SourcePackages/**, **/*.doccarchive/**, **/*.js, **/*Tests/*.swift
15:16:58.681 INFO    Included tests: **/*Tests/*.swift
15:16:58.681 INFO    Excluded sources for coverage: **/*.xml, Pods/**, Reports/**, DerivedData/**, **/*.html, **/*DerivedData/SourcePackages/**, **/*.doccarchive/**, **/*.js
15:16:59.266 INFO  8823 files indexed
15:16:59.267 INFO  Quality profile for c: Sonar way
15:16:59.267 INFO  Quality profile for json: Sonar way
15:16:59.267 INFO  Quality profile for ruby: Sonar way
15:16:59.267 INFO  Quality profile for swift: Sonar way
15:16:59.267 INFO  Quality profile for yaml: Sonar way
locations: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml,build/reports/jacoco/test/jacocoTestReport.xml
15:16:59.854 INFO  No report imported, no coverage information will be imported by JaCoCo XML Report Importer
15:16:59.854 INFO  Sensor JaCoCo XML Report Importer [jacoco] (done) | time=2ms
15:16:59.854 INFO  Sensor IaC CloudFormation Sensor [iac]
15:17:01.211 INFO  0 source files to be analyzed
15:18:28.119 INFO  Sensor Generic Coverage Report (done) | time=661ms
15:18:28.119 INFO  Sensor Zero Coverage Sensor
15:18:28.253 INFO  Sensor Zero Coverage Sensor (done) | time=133ms
15:18:29.057 INFO  CPD Executor 891 files had no CPD blocks
15:18:29.057 INFO  CPD Executor Calculating CPD for 4963 files
15:18:29.710 INFO  CPD Executor CPD calculation finished (done) | time=653ms
15:18:29.713 INFO  SCM revision ID 'e7113e4b9ec7f6530b248efc231ce6e869523a81'
15:18:31.112 INFO  Load New Code definition
15:18:31.288 INFO  Load New Code definition (done) | time=176ms
15:18:31.533 INFO  Analysis report generated in 1578ms, dir size=39.0 MB
15:18:41.742 INFO  Analysis report compressed in 10203ms, zip size=19.1 MB
15:18:48.331 INFO  Analysis report uploaded in 6589ms
15:18:48.335 INFO  ANALYSIS SUCCESSFUL
15:18:48.335 INFO  Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
15:18:52.494 INFO  SonarScanner Engine completed successfully
15:18:54.462 INFO  EXECUTION SUCCESS
15:18:54.473 INFO  Total time: 3:29.664s

I don’t know, but something is missing maybe?

So why:

  • I’m not able to see in the dashboard my custom rules

Thanks for support

Do you see lines like this in your logs?

INFO: Sensor Import of SwiftLint issues [swift]
INFO: Importing report.json
INFO: Sensor Import of SwiftLint issues [swift] (done) | time=56ms

I don’t see that in the logs you shared.

Hi @Colin

It was above the full log, that part was a single quote.

For clarity I edited the previous post removing the second question, so we can understand why I don’t see the custom rules on the dashboard but locally the JSON contains the custom rules works

Is there something missing on the sonarqube dashboard side or in my configuration?

Thanks

So back to my question:

Hi @Colin

I misunderstood, here is my log relating to those logs

Sonar-scanner used:

sonar-scanner-6.2.1.4610-macosx-aarch64
12:30:27.094 INFO 5594/5594 source files have been analyzed
12:30:27.095 INFO Sensor Swift Code Quality and Security [swift] (done) | time=65949ms
12:30:27.095 INFO Sensor Import of SwiftLint issues [swift]
12:30:27.096 INFO Importing /myRepo/swiftlint.json
12:30:27.097 ERROR No issues information will be saved as the report file can't be read.
java.io.FileNotFoundException:myPathswiftlint.json (No such file or directory)

Swift Lint step

- name: SwiftLint 
        continue-on-error: true
        run: |
          brew install swiftlint
          cd myRoot
          pwd
          touch DerivedData/swiftlint.json
          swiftlint --config myRoot/.swiftlint.yml --reporter json > DerivedData/swiftlint.json || true

I also print the DerivedData file and size

drwxr-xr-x    5 runner  staff   160B Nov 29 12:26 Build
drwxr-xr-x    4 runner  staff   128B Nov 29 12:26 TestResults
-rw-r--r--    1 runner  staff   353B Nov 29 12:21 info.plist
-rw-r--r--    1 runner  staff   819K Nov 29 12:27 swiftlint.json

And finally, I set the Analyze step

 -Dsonar.swift.swiftlint.reportPaths=/Users/runner/work/myApp/DerivedData/swiftlint.json \

The file exists, I also uploaded the artifact that saves the JSON and it’s correct (I validate it on line)

Thanks

I suggest trying to use the --output option and see if you have better results than >.

If not, please share an example report with valid JSON that is being errored on by the scanner.

Please also note the version of Swiftlint you’re using!

My Custom rules in the yml file

custom_rules:
    my_custom_rule: 
      included:
      - ".*.swift"
      name: "My Custom Rule"
      regex: "// my_custom_rule:.*"
      message: "This is a custom rule for testing"
      severity: error

My comment in Swift File

//MyProject

// my_custom_rule: Test 28 Nov
import Foundation
import ...
....
....

Swiftlint version after brew install swiftlint

Pouring swiftlint--0.57.1.arm64_sequoia.bottle.tar.gz

Ran locally command with --output

swiftlint --config /Users/runner/work/myApp/.swiftlint.yml --reporter json --output DerivedData/swiftlint.json || true

Long JSON file output

[
  {
    "character" : null,
    "file" : "MyFile.swift",
    "line" : 64,
    "reason" : "Line should be 200 characters or less; currently it has 223 characters",
    "rule_id" : "line_length",
    "severity" : "Warning",
    "type" : "Line Length"
  },
....
....
},
  {
    "character" : 1,
    "file" : "MyFile.swift",
    "line" : 9,
    "reason" : "This is a custom rule for testing",
    "rule_id" : "my_custom_rule",
    "severity" : "Error",
    "type" : "My Custom Rule"
  },
  {
...
...
]

But I still got this in the log

16:42:35.171 INFO  Sensor Swift Code Quality and Security [swift] (done) | time=66525ms
16:42:35.171 INFO  Sensor Import of SwiftLint issues [swift]
16:42:35.172 INFO  Importing /Users/runner/work/myApp/swiftlint.json
16:42:35.175 ERROR No issues information will be saved as the report file can't be read.
java.io.FileNotFoundException: /Users/runner/work/myApp/swiftlint.json (No such file or directory)

at java.base/java.io.FileInputStream.open0(Native Method)
	at java.base/java.io.FileInputStream.open(Unknown Source)
	at java.base/java.io.FileInputStream.<init>(Unknown Source)
	at com.sonar.swift.plugin.external.SwiftLintSensor.importReport(Unknown Source)
	at com.sonar.swift.plugin.external.SwiftLintSensor.lambda$execute$1(Unknown Source)
	at java.base/java.util.ArrayList.forEach(Unknown Source)
	at com.sonar.swift.plugin.external.SwiftLintSensor.execute(Unknown Source)
	at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:64)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:88)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:61)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:79)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:61)
	at org.sonar.scanner.scan.SpringModuleScanContainer.doAfterStart(SpringModuleScanContainer.java:82)
	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:226)
	at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:205)
	at org.sonar.scanner.scan.SpringProjectScanContainer.scan(SpringProjectScanContainer.java:204)
	at org.sonar.scanner.scan.SpringProjectScanContainer.scanRecursively(SpringProjectScanContainer.java:200)
17:58:51.779 INFO  Sensor Import of SwiftLint issues [swift] (done) | time=3ms
	at org.sonar.scanner.scan.SpringProjectScanContainer.doAfterStart(SpringProjectScanContainer.java:173)
	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:226)
	at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:205)
	at org.sonar.scanner.bootstrap.SpringScannerContainer.doAfterStart(SpringScannerContainer.java:351)
	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:226)
	at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:205)
	at org.sonar.scanner.bootstrap.SpringGlobalContainer.doAfterStart(SpringGlobalContainer.java:144)
	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:226)
	at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:205)
	at org.sonar.scanner.bootstrap.ScannerMain.runScannerEngine(ScannerMain.java:149)
	at org.sonar.scanner.bootstrap.ScannerMain.run(ScannerMain.java:66)
	at org.sonar.scanner.bootstrap.ScannerMain.main(ScannerMain.java:52)

17:58:51.779 INFO  Sensor IaC Docker Sensor [iac]
17:58:51.792 INFO  0 source files to be analyzed
17:58:51.807 INFO  0/0 source files have been analyzed
17:58:51.807 INFO  Sensor IaC Docker Sensor [iac] (done) | time=29ms
17:58:51.808 INFO  Sensor Serverless configuration file sensor [security]
17:58:51.811 INFO  0 Serverless function entries were found in the project
17:58:51.817 INFO  0 Serverless function handlers were kept as entrypoints
17:58:51.817 INFO  Sensor Serverless configuration file sensor [security] (done) | time=9ms
17:58:51.817 INFO  Sensor AWS SAM template file sensor [security]
17:58:51.867 INFO  Sensor AWS SAM template file sensor [security] (done) | time=50ms
17:58:51.867 INFO  Sensor AWS SAM Inline template file sensor [security]
17:58:51.916 INFO  Sensor AWS SAM Inline template file sensor [security] (done) | time=48ms
17:58:51.916 INFO  Sensor CFamily [cpp]
17:58:51.939 INFO  CFamily plugin version: 6.56.0.72172
17:58:51.939 INFO  CFamily analysis configuration mode: AutoConfig
17:58:51.944 INFO  AutoConfig mode for C and C++ is enabled
17:58:51.945 INFO  Objective-C is not supported in AutoConfig mode

Sonar Analyze step

.....
.....
run: |
     $HOME/.sonar/sonar-scanner-6.2.1.4610-macosx-aarch64/bin/sonar-scanner
.....
.....

I think I see the problem.

These paths don’t match:

Where did DerivedData go from the file path?

I see it here:

But that might have been a few test runs ago.

If DerivedData is no longer in your sonar.swift.swiftlint.reportPaths, you should specify it.

If it is, then something is preventing the parameter from being read.

We should figure that out, but as a test you might want to try removing DerivedData from the --output and see if the scanner finds the file then.

UPDATE

if I set --output to the root of the project all works fine

I suspect that sonar-scanner

https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-6.2.1.4610-macosx-aarch64.zip

does not support custom paths other than root even if specified in the properties of run -Dsonar

These files

  • swiftlint.json
  • swiftlint.yml
  • sonar-project.properties

must be in the root otherwise sonar-scanner generates those log errors

Now I have put this key

sonar.swift.swiftlint.reportPaths=DerivedData/swiftlint.json

in the sonar-project.properties file

To understand if reading the key from the sonar-project.properties file works or not.

EDIT: NOT WORK → Only changing the path with root works

There would be the possibility of updating (fixing this kind of issue) sonar-scanner or even making this sonarsource/sonarqube-scan-action functional and 100% compatible with Xcode (now not work)

Thanks