SQSCANGHA-46 Replace the Docker action by a composite action

This commit is contained in:
Antonio Aversa 2024-11-12 14:16:39 +01:00
parent 13990a6956
commit 94d4f8ac4a
11 changed files with 155 additions and 154 deletions

View file

@ -1,4 +0,0 @@
load("github.com/SonarSource/cirrus-modules@v3", "load_features")
def main(ctx):
return load_features(ctx)

View file

@ -1,37 +0,0 @@
env:
CIRRUS_VAULT_URL: https://vault.sonar.build:8200
CIRRUS_VAULT_AUTH_PATH: jwt-cirrusci
CIRRUS_VAULT_ROLE: cirrusci-${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}
# Mend scan global configuration
MEND_API_KEY: VAULT[development/kv/data/mend data.apikey]
# Staging image configuration
STAGING_IMAGE_NAME: sonarsource/sonarqube-scan-action
CURRENT_TAG: master
vm_instance_template: &VM_TEMPLATE
experimental: true # see https://github.com/cirruslabs/cirrus-ci-docs/issues/1051
image: docker-builder-v*
type: t2.small
region: eu-central-1
disk: 10
cpu: 4
memory: 16G
mend_task:
ec2_instance:
<<: *VM_TEMPLATE
# run only on master and long-term branches
only_if: $CIRRUS_USER_COLLABORATOR == 'true' && ($CIRRUS_BRANCH == "master" || $CIRRUS_BRANCH =~ "branch-.*")
setup_script:
- docker build --tag "${STAGING_IMAGE_NAME}:${CURRENT_TAG}" .
- apt-get remove -y unattended-upgrades
- apt-get update && apt-get install -y --no-install-recommends openjdk-17-jre
- curl -sSL https://unified-agent.s3.amazonaws.com/wss-unified-agent.jar -o wss-unified-agent.jar
- echo "docker.includes=${CURRENT_TAG}" >> .cirrus/wss-unified-agent.config
scan_script:
- echo "Scan the ${STAGING_IMAGE_NAME}:${CURRENT_TAG} image"
- java -jar wss-unified-agent.jar -c .cirrus/wss-unified-agent.config -apiKey $MEND_API_KEY

View file

@ -27,7 +27,10 @@ jobs:
argsInputTest:
name: >
'args' input
runs-on: ubuntu-latest
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
@ -35,7 +38,7 @@ jobs:
- name: Run action with args
uses: ./
with:
args: -Dsonar.someArg=aValue
args: -Dsonar.someArg=aValue -Dsonar.scanner.internal.dumpToFile=./output.properties
env:
SONAR_HOST_URL: http://not_actually_used
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
@ -45,7 +48,10 @@ jobs:
projectBaseDirInputTest:
name: >
'projectBaseDir' input
runs-on: ubuntu-latest
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
@ -54,6 +60,7 @@ jobs:
- name: Run action with projectBaseDir
uses: ./
with:
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
projectBaseDir: ./baseDir
env:
SONAR_HOST_URL: http://not_actually_used
@ -78,6 +85,7 @@ jobs:
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
with:
projectBaseDir: ./test/gradle-project
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
- name: Assert
run: |
./test/assertFileExists ./output.properties
@ -98,6 +106,7 @@ jobs:
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
with:
projectBaseDir: ./test/gradle-project
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
- name: Assert
run: |
./test/assertFileExists ./output.properties
@ -118,6 +127,7 @@ jobs:
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
with:
projectBaseDir: ./test/maven-project
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
- name: Assert
run: |
./test/assertFileExists ./output.properties
@ -145,7 +155,7 @@ jobs:
id: runTest
uses: ./
env:
SONAR_HOST_URL: http://sonarqube:9000
SONAR_HOST_URL: http://localhost:9000
with:
args: -Dsonar.login=admin -Dsonar.password=admin
projectBaseDir: ./test/example-project
@ -155,13 +165,18 @@ jobs:
runnerDebugUsedTest:
name: >
'RUNNER_DEBUG' is used
runs-on: ubuntu-latest
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Run action with debug mode
uses: ./
with:
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
env:
RUNNER_DEBUG: 1
SONAR_HOST_URL: http://not_actually_used
@ -193,29 +208,34 @@ jobs:
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/.sonar/cache
key: ${{ runner.os }}-sonar
key: ${{ runner.os }}-${{ runner.arch }}-sonar
- name: Run action on sample project
id: runTest
uses: ./
env:
SONAR_HOST_URL: http://sonarqube:9000
SONAR_HOST_URL: http://localhost:9000
SONAR_USER_HOME: ${{ github.workspace }}/.sonar
with:
args: -Dsonar.login=admin -Dsonar.password=admin
projectBaseDir: ./test/example-project
- name: Assert
run: |
./test/assertFileExists ./test/example-project/.scannerwork/report-task.txt
./test/assertFileExists ./test/example-project/.scannerwork/report-task.txt
useSslCertificate:
name: >
'SONAR_ROOT_CERT' is converted to truststore
runs-on: ubuntu-latest
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Run action with SSL certificate
uses: ./
with:
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
env:
SONAR_ROOT_CERT: |
-----BEGIN CERTIFICATE-----
@ -252,7 +272,6 @@ jobs:
Fct6d1S08JAosVnZcP2P7Yz+TbmDRtsqCgk=
-----END CERTIFICATE-----
SONAR_HOST_URL: http://not_actually_used
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
- name: Assert
run: |
./test/assertFileContains ./output.properties "sonar.scanner.truststorePassword=changeit"
./test/assertFileExists ~/.sonar/ssl/truststore.p12

View file

@ -1,21 +0,0 @@
FROM sonarsource/sonar-scanner-cli:11.1
LABEL version="3.1.0" \
repository="https://github.com/sonarsource/sonarqube-scan-action" \
homepage="https://github.com/sonarsource/sonarqube-scan-action" \
maintainer="SonarSource" \
com.github.actions.name="SonarQube Scan" \
com.github.actions.description="Scan your code with SonarQube to detect Bugs, Vulnerabilities and Code Smells in up to 27 programming languages!" \
com.github.actions.icon="check" \
com.github.actions.color="green"
# GitHub actions should be run under ROOT
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#docker-container-filesystem
USER 0
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
COPY cleanup.sh /cleanup.sh
RUN chmod +x /cleanup.sh
ENTRYPOINT ["/entrypoint.sh"]

View file

@ -118,25 +118,10 @@ This GitHub Action will not work for all technologies. If you are in one of the
* You want to analyze a .NET solution. Read the documentation about our [Scanner for .NET](https://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html).
* You want to analyze C or C++ code. Starting from SonarQube 10.6, this GitHub Action will scan C and C++ out of the box. If you want to have better control over the scan configuration/setup, you can switch to the [SonarQube C and C++](https://github.com/SonarSource/sonarqube-github-c-cpp) GitHub Action.
## Error cleaning up workspace
In some cases, the checkout action may fail to clean up the workspace. This is a known problem for GitHub actions implemented as a docker container (such as `sonarqube-scan-action`) when self-hosted runners are used.
Example of the error message: `File was unable to be removed Error: EACCES: permission denied, unlink '/actions-runner/_work//project/.scannerwork/.sonar_lock'`
To work around the problem, `sonarqube-scan-action` attempts to fix the permission of the temporary files that it creates. If that doesn't work, you can manually clean up the workspace by running the following action:
```
- name: Clean the workspace
uses: docker://alpine
with:
args: /bin/sh -c "find \"${GITHUB_WORKSPACE}\" -mindepth 1 ! -name . -prune -exec rm -rf {} +"
```
You can find more info [here](https://github.com/actions/runner/issues/434).
## Have questions or feedback?
To provide feedback (requesting a feature or reporting a bug) please post on the [SonarSource Community Forum](https://community.sonarsource.com/tags/c/help/sq/github-actions).
## License
The Dockerfile and associated scripts and documentation in this project are released under the LGPLv3 License.
Container images built with this project include third-party materials.

View file

@ -4,11 +4,6 @@ description: >
branding:
icon: check
color: green
runs:
using: docker
image: Dockerfile
entrypoint: "/entrypoint.sh"
post-entrypoint: "/cleanup.sh"
inputs:
args:
description: Additional arguments to the sonar-scanner
@ -16,4 +11,35 @@ inputs:
projectBaseDir:
description: Set the sonar.projectBaseDir analysis property
required: false
default: .
scannerVersion:
description: Version of the Sonar Scanner CLI to use
required: false
default: 6.2.1.4610
runs:
using: "composite"
steps:
- name: Sanity checks
run: ${GITHUB_ACTION_PATH}/sanity-checks.sh
shell: bash
env:
INPUT_PROJECTBASEDIR: ${{ inputs.projectBaseDir }}
- name: Load Sonar Scanner CLI from cache
id: sonar-scanner-cli
uses: actions/cache@v4.0.2
with:
path: ${{ runner.temp }}/sonar-scanner-cli-${{ inputs.scannerVersion }}-${{ runner.os }}-${{ runner.arch }}
key: sonar-scanner-cli-${{ inputs.scannerVersion }}-${{ runner.os }}-${{ runner.arch }}
- name: Install Sonar Scanner CLI
if: steps.sonar-scanner-cli.outputs.cache-hit != 'true'
run: ${GITHUB_ACTION_PATH}/install-sonar-scanner-cli.sh
shell: bash
env:
INPUT_SCANNERVERSION: ${{ inputs.scannerVersion }}
- name: Add SonarScanner CLI to the PATH
run: echo "${RUNNER_TEMP}/sonar-scanner-cli-${{ inputs.scannerVersion }}-${{ runner.os }}-${{ runner.arch }}/bin" >> $GITHUB_PATH
shell: bash
- name: Run SonarScanner
run: ${GITHUB_ACTION_PATH}/run-sonar-scanner.sh ${{ inputs.args }}
shell: bash
env:
INPUT_PROJECTBASEDIR: ${{ inputs.projectBaseDir }}

View file

@ -1,13 +0,0 @@
#!/bin/bash
set -e
# Reset all files permissions to the default Runner user and group to allow the follow up steps (mainly cache) to access all files.
# Assume that the first (non-hidden) file in the project directory is one from the project, and not one written by the scanner
_tmp_file=$(ls "${INPUT_PROJECTBASEDIR%/}/" | head -1)
echo "Reading permissions from $_tmp_file"
PERM=$(stat -c "%u:%g" "${INPUT_PROJECTBASEDIR%/}/$_tmp_file")
echo "Applying permissions $PERM to all files in the project base directory"
chown -R "$PERM" "${INPUT_PROJECTBASEDIR%/}/"

View file

@ -1,47 +0,0 @@
#!/bin/bash
set -eo pipefail
echo "::warning title=Docker removed in the next major version::Users on the master branch of this GitHub action will be upgraded automatically on December 9th to its next major version, which replaces Docker with a composite action, executing in the runner environment. Self-hosted runners analyzing JS/TS code against SonarQube 10.2 and below will need to have Node JS installed."
declare -a args=()
if [[ -z "${SONAR_TOKEN}" ]]; then
echo "============================ WARNING ============================"
echo "Running this GitHub Action without SONAR_TOKEN is not recommended"
echo "============================ WARNING ============================"
fi
if [[ -n "${SONAR_ROOT_CERT}" ]]; then
echo "Adding custom root certificate to the scanner truststore"
rm -f /tmp/tmpcert.pem
echo "${SONAR_ROOT_CERT}" > /tmp/tmpcert.pem
# we can't use the default "sonar" password as keytool requires a password with at least 6 characters
args+=("-Dsonar.scanner.truststorePassword=changeit")
mkdir -p $SONAR_USER_HOME/ssl
keytool -storetype PKCS12 -keystore $SONAR_USER_HOME/ssl/truststore.p12 -storepass changeit -noprompt -trustcacerts -importcert -alias sonarqube -file /tmp/tmpcert.pem
# for older SQ versions < 10.6
export SONAR_SCANNER_OPTS="${SONAR_SCANNER_OPTS:-} -Djavax.net.ssl.trustStore=$SONAR_USER_HOME/ssl/truststore.p12 -Djavax.net.ssl.trustStorePassword=changeit"
fi
if [[ -f "${INPUT_PROJECTBASEDIR%/}/pom.xml" ]]; then
echo "WARNING! Maven project detected. Sonar recommends running the 'org.sonarsource.scanner.maven:sonar-maven-plugin:sonar' goal during the build process instead of using this GitHub Action
to get more accurate results."
fi
if [[ -f "${INPUT_PROJECTBASEDIR%/}/build.gradle" || -f "${INPUT_PROJECTBASEDIR%/}/build.gradle.kts" ]]; then
echo "WARNING! Gradle project detected. Sonar recommends using the SonarQube plugin for Gradle during the build process instead of using this GitHub Action
to get more accurate results."
fi
if [[ "$RUNNER_DEBUG" == '1' ]]; then
args+=("--debug")
fi
unset JAVA_HOME
args+=("-Dsonar.projectBaseDir=${INPUT_PROJECTBASEDIR}")
sonar-scanner "${args[@]}" ${INPUT_ARGS}

34
install-sonar-scanner-cli.sh Executable file
View file

@ -0,0 +1,34 @@
#!/bin/bash
set -eou pipefail
#See https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables
WGET=wget
if [[ "$RUNNER_OS" == "Linux" && "$RUNNER_ARCH" == "X64" ]]; then
FLAVOR="linux-x64"
elif [[ "$RUNNER_OS" == "Linux" && "$RUNNER_ARCH" == "ARM64" ]]; then
FLAVOR="linux-aarch64"
elif [[ "$RUNNER_OS" == "Windows" && "$RUNNER_ARCH" == "X64" ]]; then
FLAVOR="windows-x64"
WGET="C:\\msys64\\usr\\bin\\wget.exe"
elif [[ "$RUNNER_OS" == "macOS" && "$RUNNER_ARCH" == "X64" ]]; then
FLAVOR="macosx-x64"
elif [[ "$RUNNER_OS" == "macOS" && "$RUNNER_ARCH" == "ARM64" ]]; then
FLAVOR="macosx-aarch64"
else
echo "$RUNNER_OS $RUNNER_ARCH not supported"
exit 1
fi
set -x
mkdir -p $RUNNER_TEMP/sonarscanner
cd $RUNNER_TEMP/sonarscanner
$WGET --no-verbose --user-agent="sonarqube-scan-action" https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$INPUT_SCANNERVERSION-$FLAVOR.zip
unzip -q sonar-scanner-cli-$INPUT_SCANNERVERSION-$FLAVOR.zip
# Folder name should correspond to the directory cached by the actions/cache
mv sonar-scanner-$INPUT_SCANNERVERSION-$FLAVOR $RUNNER_TEMP/sonar-scanner-cli-$INPUT_SCANNERVERSION-$RUNNER_OS-$RUNNER_ARCH

41
run-sonar-scanner.sh Executable file
View file

@ -0,0 +1,41 @@
#!/bin/bash
set -eo pipefail
if [[ "$RUNNER_OS" == "Windows" ]]; then
SCANNER_BIN="sonar-scanner.bat"
else
SCANNER_BIN="sonar-scanner"
fi
scanner_args=()
if [[ ${SONARCLOUD_URL} ]]; then
scanner_args+=("-Dsonar.scanner.sonarcloudUrl=${SONARCLOUD_URL}")
fi
if [[ "$RUNNER_DEBUG" == '1' ]]; then
scanner_args+=('--debug')
fi
if [[ -n "${INPUT_PROJECTBASEDIR}" ]]; then
scanner_args+=("-Dsonar.projectBaseDir=${INPUT_PROJECTBASEDIR}")
fi
if [[ -n "${SONAR_ROOT_CERT}" ]]; then
echo "Adding SSL certificate to the Scanner truststore"
rm -f $RUNNER_TEMP/tmpcert.pem
echo "${SONAR_ROOT_CERT}" > $RUNNER_TEMP/tmpcert.pem
# Use keytool for now, as SonarQube 11.6 won't support openssl generated keystores
# keytool require a password > 6 characters, so we wan't use the default password 'sonar'
store_pass=changeit
mkdir -p ~/.sonar/ssl
keytool -storetype PKCS12 -keystore ~/.sonar/ssl/truststore.p12 -storepass $store_pass -noprompt -trustcacerts -importcert -alias sonar -file $RUNNER_TEMP/tmpcert.pem
scanner_args+=("-Dsonar.scanner.truststorePassword=$store_pass")
fi
scanner_args+=("$@")
set -ux
$SCANNER_BIN "${scanner_args[@]}"

18
sanity-checks.sh Executable file
View file

@ -0,0 +1,18 @@
#!/bin/bash
set -eo pipefail
if [[ -z "${SONAR_TOKEN}" ]]; then
echo "::warning title=SonarScanner::Running this GitHub Action without SONAR_TOKEN is not recommended"
fi
if [[ -f "${INPUT_PROJECTBASEDIR%/}/pom.xml" ]]; then
echo "::warning title=SonarScanner::Maven project detected. Sonar recommends running the 'org.sonarsource.scanner.maven:sonar-maven-plugin:sonar' goal during the build process instead of using this GitHub Action
to get more accurate results."
fi
if [[ -f "${INPUT_PROJECTBASEDIR%/}/build.gradle" || -f "${INPUT_PROJECTBASEDIR%/}/build.gradle.kts" ]]; then
echo "::warning title=SonarScanner::Gradle project detected. Sonar recommends using the SonarQube plugin for Gradle during the build process instead of using this GitHub Action
to get more accurate results."
fi