I've got a Github Action that runs SonarQube scanner:
- name: SonarQube analysis
continue-on-error: true
shell: bash
run: |
sonar-scanner \
-Dsonar.cfamily.build-wrapper-output=bw-output
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
Mostly this works fine, but sometimes it throws an exception because of a hash/checksum error on a downloaded file. I can rerun the action and it'll usually work but because the build takes a while I'd rather rerun just this step.
I tried using Retrying a bash command - Meziantou's blog and removing the continue-on-error: true
command:
- name: SonarQube analysis
shell: bash
run: |
# Set the maximum number of attempts
max_attempts=5
# Set a counter for the number of attempts
attempt_num=1
# Set a flag to indicate whether the command was successful
success=false
# Loop until the command is successful or the maximum number of attempts is reached
while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do
# Execute the command
sonar-scanner \
-Dsonar.cfamily.build-wrapper-output=bw-output
# Check the exit code of the command
if [ $? -eq 0 ]; then
# The command was successful
success=true
else
# The command was not successful
echo "Attempt $attempt_num failed. Trying again..."
# Increment the attempt counter
attempt_num=$(( attempt_num + 1 ))
fi
done
# Check if the command was successful
if [ $success = true ]; then
# The command was successful
echo "sonar-scanner was successful after $attempt_num attempts."
else
# The command was not successful
echo "sonar-scanner failed after $max_attempts attempts."
fi
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
but it doesn't work - when an exception is thrown it exits the loop:
03:33:30.088 INFO Scanner configuration file: /home/runner/.sonar/sonar-scanner-6.2.1.4610-linux-x64/conf/sonar-scanner.properties
03:33:30.102 INFO SonarScanner CLI 6.2.1.4610
03:33:30.104 INFO Java 17.0.12 Eclipse Adoptium (64-bit)
03:33:30.104 INFO Linux 6.5.0-1025-azure amd64
03:33:30.125 INFO User cache: /home/runner/.sonar/cache
03:33:53.701 INFO Communicating with SonarQube Server 9.9.7.96285
03:33:53.964 INFO Load global settings
03:33:54.399 INFO Load global settings (done) | time=435ms
03:33:54.401 INFO Server id: 8F6C7167-AW8zf1mS7d4EVV8efcCG
03:33:54.404 INFO User cache: /home/runner/.sonar/cache
03:33:54.406 INFO Load/download plugins
03:33:54.407 INFO Load plugins index
03:33:54.794 INFO Load plugins index (done) | time=387ms
03:34:20.190 INFO Load/download plugins (done) | time=25784ms
03:34:20.198 INFO EXECUTION FAILURE
03:34:20.199 INFO Total time: 50.113s
03:34:20.199 ERROR Error during SonarScanner CLI execution
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.sonarsource.scanner.lib.internal.IsolatedClassloader@740d2e78-org.sonar.scanner.bootstrap.ScannerPluginRepository': Initialization of bean failed; nested exception is java.lang.IllegalStateException: Fail to download plugin [cpp]. File /home/runner/.sonar/_tmp/fileCache2060103996137565963.tmp was expected to have checksum 648b7fda1ced5cc3a204981786143349 but had 5c56ae7029503f40ef4e337edf513626
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:628)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:920)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:187)
at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:72)
at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:66)
at org.sonarsource.scanner.lib.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:41)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.sonarsource.scanner.lib.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:62)
at jdk.proxy3/jdk.proxy3.$Proxy2.execute(Unknown Source)
at org.sonarsource.scanner.lib.InProcessScannerEngineFacade.doAnalyze(InProcessScannerEngineFacade.java:39)
at org.sonarsource.scanner.lib.ScannerEngineFacade.analyze(ScannerEngineFacade.java:61)
at org.sonarsource.scanner.cli.Main.analyze(Main.java:77)
at org.sonarsource.scanner.cli.Main.main(Main.java:63)
Caused by: java.lang.IllegalStateException: Fail to download plugin [cpp]. File /home/runner/.sonar/_tmp/fileCache2060103996137565963.tmp was expected to have checksum 648b7fda1ced5cc3a204981786143349 but had 5c56ae7029503f40ef4e337edf513626
at org.sonar.scanner.bootstrap.PluginFiles.download(PluginFiles.java:105)
at org.sonar.scanner.bootstrap.PluginFiles.get(PluginFiles.java:82)
at org.sonar.scanner.bootstrap.ScannerPluginInstaller.loadPlugins(ScannerPluginInstaller.java:78)
at org.sonar.scanner.bootstrap.ScannerPluginInstaller.installRemotes(ScannerPluginInstaller.java:61)
at org.sonar.scanner.bootstrap.ScannerPluginRepository.start(ScannerPluginRepository.java:63)
at org.sonar.core.platform.StartableBeanPostProcessor.postProcessBeforeInitialization(StartableBeanPostProcessor.java:33)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:440)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
... 23 common frames omitted
03:34:20.200 ERROR
03:34:20.200 ERROR Re-run SonarScanner CLI using the -X switch to enable full debug logging.
Error: Process completed with exit code 1.
How can I get this step to repeat if it fails? Note I'd prefer to do this without a thirdparty solution because that would require approval from our security team.
Setting shell: bash
results in this command being run internally:
bash --noprofile --norc -eo pipefail {0}
(see documentation).
It includes -e
, "error on exit", so when your scanner hits an error, the entire step is aborted.
You can prevent that from happening by executing the command in an if-clause, which exempts it from the set -e
effects:
# Execute the command
if sonar-scanner -Dsonar.cfamily.build-wrapper-output=bw-output; then
success=true
else
# The command was not successful
As a side note, there is a dedicated SonarQube action provided by SonarSource; using it might simplify your setup.