mirror of
https://github.com/SonarSource/sonarqube-scan-action.git
synced 2026-06-05 17:10:31 +03:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c9d327c024 |
@@ -245,9 +245,9 @@ jobs:
|
|||||||
- name: Assert Sonar Scanner CLI was not executed
|
- name: Assert Sonar Scanner CLI was not executed
|
||||||
run: |
|
run: |
|
||||||
./test/assertFileDoesntExist ./output.properties
|
./test/assertFileDoesntExist ./output.properties
|
||||||
scannerBinariesUrlIsEscapedWithWget:
|
scannerBinariesUrlCommandInjectionTest:
|
||||||
name: >
|
name: >
|
||||||
'scannerBinariesUrl' is escaped with wget so special chars are not injected in the download command
|
'scannerBinariesUrl' does not allow command injection via semicolons
|
||||||
runs-on: github-ubuntu-latest-s
|
runs-on: github-ubuntu-latest-s
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
@@ -266,22 +266,14 @@ jobs:
|
|||||||
- name: Assert file.txt does not exist
|
- name: Assert file.txt does not exist
|
||||||
run: |
|
run: |
|
||||||
./test/assertFileDoesntExist "$RUNNER_TEMP/sonarscanner/file.txt"
|
./test/assertFileDoesntExist "$RUNNER_TEMP/sonarscanner/file.txt"
|
||||||
scannerBinariesUrlIsEscapedWithCurl:
|
scannerBinariesUrlCommandInjectionWithSpacesTest:
|
||||||
name: >
|
name: >
|
||||||
'scannerBinariesUrl' is escaped with curl so special chars are not injected in the download command
|
'scannerBinariesUrl' does not allow command injection via spaces and quotes
|
||||||
runs-on: github-ubuntu-latest-s
|
runs-on: github-ubuntu-latest-s
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Remove wget
|
|
||||||
run: sudo apt-get remove -y wget
|
|
||||||
- name: Assert wget is not available
|
|
||||||
run: |
|
|
||||||
if command -v wget 2>&1 >/dev/null
|
|
||||||
then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
- name: Run action with scannerBinariesUrl
|
- name: Run action with scannerBinariesUrl
|
||||||
id: runTest
|
id: runTest
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -472,22 +464,14 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
./test/assertFileContains ./output.properties "sonar.host.url=mirror.sonarcloud.io"
|
./test/assertFileContains ./output.properties "sonar.host.url=mirror.sonarcloud.io"
|
||||||
./test/assertFileContains ./output.properties "sonar.scanner.sonarcloudUrl=mirror.sonarcloud.io"
|
./test/assertFileContains ./output.properties "sonar.scanner.sonarcloudUrl=mirror.sonarcloud.io"
|
||||||
curlPerformsRedirect:
|
scannerBinariesUrlRedirectFollowed:
|
||||||
name: >
|
name: >
|
||||||
curl performs redirect when scannerBinariesUrl returns 3xx
|
scannerBinariesUrl redirect (3xx) is followed
|
||||||
runs-on: github-ubuntu-latest-s
|
runs-on: github-ubuntu-latest-s
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Remove wget
|
|
||||||
run: sudo apt-get remove -y wget
|
|
||||||
- name: Assert wget is not available
|
|
||||||
run: |
|
|
||||||
if command -v wget 2>&1 >/dev/null
|
|
||||||
then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
- name: Generate SSL certificates for nginx
|
- name: Generate SSL certificates for nginx
|
||||||
run: ./generate-ssl.sh
|
run: ./generate-ssl.sh
|
||||||
working-directory: .github/qa-nginx-redirecting
|
working-directory: .github/qa-nginx-redirecting
|
||||||
@@ -841,8 +825,8 @@ jobs:
|
|||||||
- projectBaseDirInputTest
|
- projectBaseDirInputTest
|
||||||
- scannerVersionTest
|
- scannerVersionTest
|
||||||
- scannerBinariesUrlTest
|
- scannerBinariesUrlTest
|
||||||
- scannerBinariesUrlIsEscapedWithWget
|
- scannerBinariesUrlCommandInjectionTest
|
||||||
- scannerBinariesUrlIsEscapedWithCurl
|
- scannerBinariesUrlCommandInjectionWithSpacesTest
|
||||||
- dontFailGradleTest
|
- dontFailGradleTest
|
||||||
- dontFailGradleKotlinTest
|
- dontFailGradleKotlinTest
|
||||||
- dontFailMavenTest
|
- dontFailMavenTest
|
||||||
@@ -850,7 +834,7 @@ jobs:
|
|||||||
- runnerDebugUsedTest
|
- runnerDebugUsedTest
|
||||||
- runAnalysisWithCacheTest
|
- runAnalysisWithCacheTest
|
||||||
- overrideSonarcloudUrlTest
|
- overrideSonarcloudUrlTest
|
||||||
- curlPerformsRedirect
|
- scannerBinariesUrlRedirectFollowed
|
||||||
- useSslCertificate
|
- useSslCertificate
|
||||||
- analysisWithSslCertificate
|
- analysisWithSslCertificate
|
||||||
- updateTruststoreWhenPresent
|
- updateTruststoreWhenPresent
|
||||||
|
|||||||
@@ -483,11 +483,11 @@ See also [example configurations of C++ projects for SonarQube Server](https://g
|
|||||||
|
|
||||||
When running the action in a self-hosted runner or container, please ensure that the following programs are installed:
|
When running the action in a self-hosted runner or container, please ensure that the following programs are installed:
|
||||||
|
|
||||||
* **curl** or **wget**
|
|
||||||
* **unzip**
|
|
||||||
* **gpg**
|
* **gpg**
|
||||||
* **dirmngr**
|
* **dirmngr**
|
||||||
|
|
||||||
|
Note: `gpg` and `dirmngr` are only required for GPG signature verification (enabled by default). They can be omitted when setting `skipSignatureVerification: true`.
|
||||||
|
|
||||||
### Additional information
|
### Additional information
|
||||||
|
|
||||||
The `sonarqube-scan-action/install-build-wrapper` action installs `coreutils` if run on macOS.
|
The `sonarqube-scan-action/install-build-wrapper` action installs `coreutils` if run on macOS.
|
||||||
|
|||||||
Vendored
+2
-16
@@ -3862,19 +3862,6 @@ function getScannerDownloadURL({
|
|||||||
const scannerDirName = (version, flavor) =>
|
const scannerDirName = (version, flavor) =>
|
||||||
`sonar-scanner-${version}-${flavor}`;
|
`sonar-scanner-${version}-${flavor}`;
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a 4-part version string (e.g. "8.0.1.6346") to a SemVer 2.0 compatible
|
|
||||||
* string (e.g. "8.0.1-build.6346") for use with GitHub's tool-cache library,
|
|
||||||
* which requires SemVer-compliant version strings.
|
|
||||||
*/
|
|
||||||
function toSemVer(version) {
|
|
||||||
const parts = version.split(".");
|
|
||||||
if (parts.length === 4) {
|
|
||||||
return `${parts[0]}.${parts[1]}.${parts[2]}-build.${parts[3]}`;
|
|
||||||
}
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sonarqube-scan-action
|
* sonarqube-scan-action
|
||||||
* Copyright (C) 2025 SonarSource SA
|
* Copyright (C) 2025 SonarSource SA
|
||||||
@@ -4164,10 +4151,9 @@ async function installSonarScanner({
|
|||||||
skipSignatureVerification = false,
|
skipSignatureVerification = false,
|
||||||
}) {
|
}) {
|
||||||
const flavor = getPlatformFlavor(os$1.platform(), os$1.arch());
|
const flavor = getPlatformFlavor(os$1.platform(), os$1.arch());
|
||||||
const semVerVersion = toSemVer(scannerVersion);
|
|
||||||
|
|
||||||
// Check if tool is already cached
|
// Check if tool is already cached
|
||||||
let toolDir = find(TOOLNAME, semVerVersion, flavor);
|
let toolDir = find(TOOLNAME, scannerVersion, flavor);
|
||||||
|
|
||||||
if (!toolDir) {
|
if (!toolDir) {
|
||||||
info(
|
info(
|
||||||
@@ -4210,7 +4196,7 @@ async function installSonarScanner({
|
|||||||
scannerDirName(scannerVersion, flavor)
|
scannerDirName(scannerVersion, flavor)
|
||||||
);
|
);
|
||||||
|
|
||||||
toolDir = await cacheDir(scannerPath, TOOLNAME, semVerVersion, flavor);
|
toolDir = await cacheDir(scannerPath, TOOLNAME, scannerVersion, flavor);
|
||||||
|
|
||||||
info(`Sonar Scanner CLI cached to: ${toolDir}`);
|
info(`Sonar Scanner CLI cached to: ${toolDir}`);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -22,7 +22,6 @@ import assert from "node:assert/strict";
|
|||||||
import { describe, it, mock } from "node:test";
|
import { describe, it, mock } from "node:test";
|
||||||
|
|
||||||
const SCANNER_VERSION = "6.2.0.4584";
|
const SCANNER_VERSION = "6.2.0.4584";
|
||||||
const SCANNER_SEMVER_VERSION = "6.2.0-build.4584";
|
|
||||||
const BINARIES_URL = "https://my.artifactory.example.com/sonar-scanner-cli";
|
const BINARIES_URL = "https://my.artifactory.example.com/sonar-scanner-cli";
|
||||||
const BINARY_DOWNLOAD_URL = `${BINARIES_URL}/sonar-scanner-cli-${SCANNER_VERSION}-linux-x64.zip`;
|
const BINARY_DOWNLOAD_URL = `${BINARIES_URL}/sonar-scanner-cli-${SCANNER_VERSION}-linux-x64.zip`;
|
||||||
|
|
||||||
@@ -32,7 +31,6 @@ function mockUtils(t) {
|
|||||||
getPlatformFlavor: mock.fn(() => "linux-x64"),
|
getPlatformFlavor: mock.fn(() => "linux-x64"),
|
||||||
getScannerDownloadURL: mock.fn(() => BINARY_DOWNLOAD_URL),
|
getScannerDownloadURL: mock.fn(() => BINARY_DOWNLOAD_URL),
|
||||||
scannerDirName: mock.fn(() => `sonar-scanner-${SCANNER_VERSION}-linux-x64`),
|
scannerDirName: mock.fn(() => `sonar-scanner-${SCANNER_VERSION}-linux-x64`),
|
||||||
toSemVer: mock.fn(() => SCANNER_SEMVER_VERSION),
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -173,50 +171,6 @@ describe("installSonarScanner", () => {
|
|||||||
assert.equal(downloadCalls[0].auth, "Bearer mytoken");
|
assert.equal(downloadCalls[0].auth, "Bearer mytoken");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should use semver-compatible version for tool-cache find and cacheDir", async (t) => {
|
|
||||||
const findFn = mock.fn(() => null);
|
|
||||||
const cacheDirFn = mock.fn(async () => "/tmp/cached");
|
|
||||||
|
|
||||||
mockUtils(t);
|
|
||||||
|
|
||||||
t.mock.module("@actions/tool-cache", {
|
|
||||||
namedExports: {
|
|
||||||
find: findFn,
|
|
||||||
downloadTool: mock.fn(async () => "/tmp/downloaded"),
|
|
||||||
extractZip: mock.fn(async () => "/tmp/extracted"),
|
|
||||||
cacheDir: cacheDirFn,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
t.mock.module("@actions/core", {
|
|
||||||
namedExports: {
|
|
||||||
info: mock.fn(),
|
|
||||||
warning: mock.fn(),
|
|
||||||
addPath: mock.fn(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
t.mock.module("../gpg-verification.js", {
|
|
||||||
namedExports: {
|
|
||||||
verifySignature: mock.fn(async () => {}),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const { installSonarScanner } = await import(
|
|
||||||
`../install-sonar-scanner.js?test=semver-version`
|
|
||||||
);
|
|
||||||
|
|
||||||
await installSonarScanner({
|
|
||||||
scannerVersion: SCANNER_VERSION,
|
|
||||||
scannerBinariesUrl: BINARIES_URL,
|
|
||||||
});
|
|
||||||
|
|
||||||
assert.equal(findFn.mock.calls[0].arguments[1], SCANNER_SEMVER_VERSION,
|
|
||||||
"tc.find should be called with semver-compatible version");
|
|
||||||
assert.equal(cacheDirFn.mock.calls[0].arguments[2], SCANNER_SEMVER_VERSION,
|
|
||||||
"tc.cacheDir should be called with semver-compatible version");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should use cached tool when available and skip download", async (t) => {
|
it("should use cached tool when available and skip download", async (t) => {
|
||||||
const downloadToolFn = mock.fn();
|
const downloadToolFn = mock.fn();
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import {
|
|||||||
getPlatformFlavor,
|
getPlatformFlavor,
|
||||||
getScannerDownloadURL,
|
getScannerDownloadURL,
|
||||||
scannerDirName,
|
scannerDirName,
|
||||||
toSemVer,
|
|
||||||
} from "../utils.js";
|
} from "../utils.js";
|
||||||
|
|
||||||
describe("getPlatformFlavor", () => {
|
describe("getPlatformFlavor", () => {
|
||||||
@@ -98,22 +97,3 @@ describe("scannerDirName", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("toSemVer", () => {
|
|
||||||
it("converts 4-part version to semver pre-release format", () => {
|
|
||||||
assert.equal(toSemVer("8.0.1.6346"), "8.0.1-build.6346");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("leaves 3-part semver version unchanged", () => {
|
|
||||||
assert.equal(toSemVer("8.0.1"), "8.0.1");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("leaves version with pre-release identifier unchanged", () => {
|
|
||||||
assert.equal(toSemVer("7.2.0-SNAPSHOT"), "7.2.0-SNAPSHOT");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("converts different 4-part versions correctly", () => {
|
|
||||||
assert.equal(toSemVer("6.2.0.4584"), "6.2.0-build.4584");
|
|
||||||
assert.equal(toSemVer("8.1.0.6389"), "8.1.0-build.6389");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import {
|
|||||||
getPlatformFlavor,
|
getPlatformFlavor,
|
||||||
getScannerDownloadURL,
|
getScannerDownloadURL,
|
||||||
scannerDirName,
|
scannerDirName,
|
||||||
toSemVer,
|
|
||||||
} from "./utils.js";
|
} from "./utils.js";
|
||||||
import { verifySignature } from "./gpg-verification.js";
|
import { verifySignature } from "./gpg-verification.js";
|
||||||
|
|
||||||
@@ -40,10 +39,9 @@ export async function installSonarScanner({
|
|||||||
skipSignatureVerification = false,
|
skipSignatureVerification = false,
|
||||||
}) {
|
}) {
|
||||||
const flavor = getPlatformFlavor(os.platform(), os.arch());
|
const flavor = getPlatformFlavor(os.platform(), os.arch());
|
||||||
const semVerVersion = toSemVer(scannerVersion);
|
|
||||||
|
|
||||||
// Check if tool is already cached
|
// Check if tool is already cached
|
||||||
let toolDir = tc.find(TOOLNAME, semVerVersion, flavor);
|
let toolDir = tc.find(TOOLNAME, scannerVersion, flavor);
|
||||||
|
|
||||||
if (!toolDir) {
|
if (!toolDir) {
|
||||||
core.info(
|
core.info(
|
||||||
@@ -86,7 +84,7 @@ export async function installSonarScanner({
|
|||||||
scannerDirName(scannerVersion, flavor)
|
scannerDirName(scannerVersion, flavor)
|
||||||
);
|
);
|
||||||
|
|
||||||
toolDir = await tc.cacheDir(scannerPath, TOOLNAME, semVerVersion, flavor);
|
toolDir = await tc.cacheDir(scannerPath, TOOLNAME, scannerVersion, flavor);
|
||||||
|
|
||||||
core.info(`Sonar Scanner CLI cached to: ${toolDir}`);
|
core.info(`Sonar Scanner CLI cached to: ${toolDir}`);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -51,16 +51,3 @@ export function getScannerDownloadURL({
|
|||||||
|
|
||||||
export const scannerDirName = (version, flavor) =>
|
export const scannerDirName = (version, flavor) =>
|
||||||
`sonar-scanner-${version}-${flavor}`;
|
`sonar-scanner-${version}-${flavor}`;
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a 4-part version string (e.g. "8.0.1.6346") to a SemVer 2.0 compatible
|
|
||||||
* string (e.g. "8.0.1-build.6346") for use with GitHub's tool-cache library,
|
|
||||||
* which requires SemVer-compliant version strings.
|
|
||||||
*/
|
|
||||||
export function toSemVer(version) {
|
|
||||||
const parts = version.split(".");
|
|
||||||
if (parts.length === 4) {
|
|
||||||
return `${parts[0]}.${parts[1]}.${parts[2]}-build.${parts[3]}`;
|
|
||||||
}
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user