0

I was able to get code coverage and sonar-scanner working with Xcode Cloud for our iOS project.

  1. First, in post-clone script I install sonar-scanner tool like this

brew install sonar-scanner

  1. Then, in post-xcodebuild script, I do five things: (a) get current app version, (b) get app version, (c) run xcodebuild again with forced code coverage reporting, (d) find coverage data and convert it to the format that Sonarqube understands, and finally (e) run sonar-scanner, which uploads results to Sonarqube dashboard.
  cd $CI_WORKSPACE
  
  # declare variables
  SCHEME=[REMOVED]
  PRODUCT_NAME=[REMOVED]
  WORKSPACE_NAME=${PRODUCT_NAME}.xcworkspace
  APP_VERSION=$(sed -n '/MARKETING_VERSION/{s/MARKETING_VERSION = //;s/;//;s/^[[:space:]]*//;p;q;}' ./${PRODUCT_NAME}.xcodeproj/project.pbxproj)

  # clean, build and test project
  xcodebuild \
    -workspace ${WORKSPACE_NAME} \
    -destination 'platform=iOS Simulator,name=iPad (10th generation),OS=latest' \
    -scheme ${SCHEME} \
    -derivedDataPath DerivedData/ \
    -enableCodeCoverage YES \
    -resultBundlePath DerivedData/Logs/Test/ResultBundle.xcresult \
    clean build test

  # find profdata and binary
  PROFDATA=$(find . -name "Coverage.profdata")
  BINARY=$(find . -path "*${PRODUCT_NAME}.app/${PRODUCT_NAME}")

  # check if we have profdata file
  if [[ -z $PROFDATA ]]; then
    echo "ERROR: Unable to find Coverage.profdata. Be sure to execute tests before running this script."
    exit 1
  fi
  
  # extract coverage data from project using xcode native tool
  xcrun --run llvm-cov show -instr-profile=${PROFDATA} ${BINARY} > sonarqube-coverage.report

  # run sonar scanner and upload coverage data with the current app version
  sonar-scanner \
    -Dsonar.projectVersion=${APP_VERSION}

It all works fine but my team and I think that this is a workaround that shouldn't work like this, because technically xcodebuild command is executed two times, first by Xcode Cloud, then by my script, which takes a lot of time and feels hacky.

Ideally, Xcode Cloud's Build and Test actions should generate code coverage (the option is already enabled in our project) and give us access to profile data in DerivedData folder which I can access with environment variable CI_DERIVED_DATA_PATH. However, there is none.

My question is, do I do everything correctly? Is there a way to improve this flow? Do I miss on how to correctly get code coverage data from Xcode Cloud?

kovallux
  • 11
  • 6
  • [What topics can I ask about here?](https://stackoverflow.com/help/on-topic) and [ask] – Rob Jul 11 '23 at 17:57
  • I have reported this redundant way of coverage data gathering to Apple since the beginning of year, still no result. The only way to gather the coverage data to rerun the xcodebuild one more as you mentioned. – Karim Karimov Aug 29 '23 at 05:13

0 Answers0