mirror of
https://github.com/SonarSource/sonarqube-scan-action.git
synced 2026-09-23 21:28:42 +00:00
Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f85f58d535 | ||
|
|
bbc1dc389a | ||
|
|
e0c4e7abeb | ||
|
|
280d6fc5b8 | ||
|
|
154f7918a7 | ||
|
|
2448e3394c | ||
|
|
62d06e46aa | ||
|
|
f8132da3be | ||
|
|
f9b74a459a | ||
|
|
bf5bc7ceac | ||
|
|
8b19b74547 | ||
|
|
78aa5797b9 | ||
|
|
ad8210318a | ||
|
|
7451daf950 |
@@ -0,0 +1,90 @@
|
||||
# Reproducer for: "sonarqube-scan-action GPG check not working on Windows runner"
|
||||
# https://community.sonarsource.com/t/sonarqube-scan-action-gpg-check-not-working-on-windows-runner/186785
|
||||
#
|
||||
# Root cause (see investigation.md): on Windows, convertToUnixPath() rewrites drive
|
||||
# letters into MSYS/Git-Bash form (R:\... -> /r/...). The native GnuPG (Gpg4win) that
|
||||
# the reporter has on PATH (C:\Program Files (x86)\GnuPG\bin\gpg.exe) cannot resolve
|
||||
# that form, so GPG signature verification fails.
|
||||
#
|
||||
# This workflow reproduces the failure by installing native GnuPG and putting it first
|
||||
# on PATH, matching the reporter's environment. It runs the local action (which executes
|
||||
# the committed dist/index.js) and expects it to FAIL during signature verification.
|
||||
|
||||
name: Reproduce GPG check failure on Windows
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
reproduce-windows-gpg-bug:
|
||||
runs-on: github-windows-latest-s
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install native GnuPG (winget GnuPG.GnuPG) and put it first on PATH
|
||||
shell: powershell
|
||||
run: |
|
||||
# Install native GnuPG via winget. The choco 'gnupg' package hangs at
|
||||
# "Installing gnupg..." (its installer blocks in the non-interactive runner
|
||||
# session), so we use winget's GnuPG.GnuPG package instead.
|
||||
winget install --id GnuPG.GnuPG --exact --silent --accept-source-agreements --accept-package-agreements --disable-interactivity
|
||||
# winget exits non-zero for benign cases (e.g. already installed); don't fail
|
||||
# here on that. The gpg.exe presence check below is the real gate.
|
||||
Write-Host "winget exit code: $LASTEXITCODE"
|
||||
# The reporter's gpg lives at C:\Program Files (x86)\GnuPG\bin\gpg.exe.
|
||||
# Prepend the native GnuPG dir to PATH so `gpg` resolves to it (and NOT to
|
||||
# the Git-for-Windows build, which would mask the bug by accepting /r/... paths).
|
||||
$candidates = @(
|
||||
"C:\Program Files (x86)\GnuPG\bin",
|
||||
"C:\Program Files\GnuPG\bin"
|
||||
)
|
||||
$gpgDir = $candidates | Where-Object { Test-Path (Join-Path $_ "gpg.exe") } | Select-Object -First 1
|
||||
if (-not $gpgDir) { Write-Error "Native GnuPG not found after install"; exit 1 }
|
||||
Write-Host "Using native GnuPG from: $gpgDir"
|
||||
Add-Content -Path $env:GITHUB_PATH -Value $gpgDir
|
||||
|
||||
- name: Confirm `gpg` resolves to native GnuPG
|
||||
shell: powershell
|
||||
run: |
|
||||
$g = Get-Command gpg
|
||||
Write-Host "gpg resolves to: $($g.Source)"
|
||||
gpg --version
|
||||
if ($g.Source -notmatch "GnuPG") {
|
||||
Write-Error "Expected native GnuPG on PATH but got: $($g.Source)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Root-cause demo — native gpg rejects an MSYS-style --homedir
|
||||
shell: powershell
|
||||
continue-on-error: true
|
||||
run: |
|
||||
# convertToUnixPath() would turn e.g. C:\...\gpg-home into /c/.../gpg-home.
|
||||
# Show that native GnuPG cannot use such a --homedir.
|
||||
$msysHome = "/c/Users/runneradmin/gpg-home-demo"
|
||||
Write-Host "Running: gpg --homedir '$msysHome' --batch --list-keys"
|
||||
gpg --homedir "$msysHome" --batch --list-keys
|
||||
Write-Host "native-gpg exit code with MSYS-style homedir: $LASTEXITCODE"
|
||||
|
||||
- name: Run the action (expected to FAIL at GPG signature verification)
|
||||
id: action
|
||||
continue-on-error: true
|
||||
# No SONAR_TOKEN / server needed: the failure happens during signature
|
||||
# verification in installSonarScanner, before the scanner is ever invoked.
|
||||
uses: ./
|
||||
with:
|
||||
skipSignatureVerification: false
|
||||
|
||||
- name: Assert the bug reproduced
|
||||
shell: powershell
|
||||
run: |
|
||||
Write-Host "Action step outcome: ${{ steps.action.outcome }}"
|
||||
if ("${{ steps.action.outcome }}" -eq "failure") {
|
||||
Write-Host "OK - Bug reproduced: the action failed on Windows with native GnuPG."
|
||||
} else {
|
||||
Write-Error "Bug did NOT reproduce (outcome: ${{ steps.action.outcome }}). The GPG path handling may have been fixed."
|
||||
exit 1
|
||||
}
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
os: [github-ubuntu-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action without args
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with args
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with args
|
||||
@@ -93,7 +93,7 @@ jobs:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with args
|
||||
@@ -121,7 +121,7 @@ jobs:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with args
|
||||
@@ -148,7 +148,7 @@ jobs:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with args
|
||||
@@ -178,7 +178,7 @@ jobs:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: mkdir -p ./baseDir
|
||||
@@ -198,7 +198,7 @@ jobs:
|
||||
'scannerVersion' input
|
||||
runs-on: github-ubuntu-latest-s # assumes default RUNNER_ARCH for linux is X64
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with scannerVersion
|
||||
@@ -222,7 +222,7 @@ jobs:
|
||||
'scannerBinariesUrl' input with invalid URL
|
||||
runs-on: github-ubuntu-latest-s # assumes default RUNNER_ARCH for linux is X64
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with scannerBinariesUrl
|
||||
@@ -250,7 +250,7 @@ jobs:
|
||||
'scannerBinariesUrl' does not allow command injection via semicolons
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with scannerBinariesUrl
|
||||
@@ -271,7 +271,7 @@ jobs:
|
||||
'scannerBinariesUrl' does not allow command injection via spaces and quotes
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with scannerBinariesUrl
|
||||
@@ -292,7 +292,7 @@ jobs:
|
||||
Don't fail on Gradle project
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action on Gradle project
|
||||
@@ -313,7 +313,7 @@ jobs:
|
||||
Don't fail on Kotlin Gradle project
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action on Kotlin Gradle project
|
||||
@@ -334,7 +334,7 @@ jobs:
|
||||
Don't fail on Maven project
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action on Maven project
|
||||
@@ -367,7 +367,7 @@ jobs:
|
||||
--health-timeout 5s
|
||||
--health-retries 10
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action on sample project
|
||||
@@ -390,7 +390,7 @@ jobs:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with debug mode
|
||||
@@ -421,7 +421,7 @@ jobs:
|
||||
--health-timeout 5s
|
||||
--health-retries 10
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: SonarQube Cache
|
||||
@@ -450,7 +450,7 @@ jobs:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with deprecated SONARCLOUD_URL
|
||||
@@ -469,7 +469,7 @@ jobs:
|
||||
scannerBinariesUrl redirect (3xx) is followed
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Generate SSL certificates for nginx
|
||||
@@ -505,7 +505,7 @@ jobs:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with SSL certificate
|
||||
@@ -556,7 +556,7 @@ jobs:
|
||||
Analysis takes into account 'SONAR_ROOT_CERT'
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Generate server certificate
|
||||
@@ -664,7 +664,7 @@ jobs:
|
||||
truststore.p12 is updated when present
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Create SONAR_SSL_FOLDER with a file in it (not-truststore.p12)
|
||||
@@ -793,7 +793,7 @@ jobs:
|
||||
'scannerVersion' input validation
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with invalid scannerVersion
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
name: create_install_path.sh
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
@@ -123,7 +123,7 @@ jobs:
|
||||
SONAR_SCANNER_URL_MACOSX_AARCH64: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-macosx-aarch64.zip'
|
||||
SONAR_SCANNER_SHA_MACOSX_AARCH64: 'DOWNLOAD-SHA-MACOSX-AARCH64'
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
@@ -252,7 +252,7 @@ jobs:
|
||||
name: download.sh
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
@@ -321,7 +321,7 @@ jobs:
|
||||
name: fetch_latest_version.sh
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
- name: Test script
|
||||
|
||||
@@ -13,10 +13,10 @@ jobs:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e #v6.4.0
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 #v7.0.0
|
||||
with:
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Parse semver
|
||||
uses: madhead/semver-utils@4cf918affe9106ea59f86c6250e5ec4570ac4389 # v5.0.0
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
new-version: ${{ steps.latest-version.outputs.sonar-scanner-version }}
|
||||
steps:
|
||||
- run: sudo apt install -y jq
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: master
|
||||
fetch-depth: 0
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
pull-requests: write
|
||||
if: needs.check-version.outputs.should_update == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: master
|
||||
persist-credentials: true
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
# Investigation: GPG check not working on Windows runner
|
||||
|
||||
- **Reported:** https://community.sonarsource.com/t/sonarqube-scan-action-gpg-check-not-working-on-windows-runner/186785
|
||||
- **Affected version:** `SonarSource/sonarqube-scan-action@v8.2.1`
|
||||
- **Environment:** Windows runner with native GnuPG (Gpg4win) at `C:\Program Files (x86)\GnuPG\bin\gpg.exe`
|
||||
- **Verdict:** ✅ **Confirmed bug** in `src/main/gpg-verification.js`
|
||||
|
||||
## Summary
|
||||
|
||||
On Windows, the action converts every path it hands to `gpg` (the `--homedir`, the
|
||||
signature file, and the ZIP file) into an **MSYS/Git-Bash-style path** such as
|
||||
`/r/GHEC/Build_B1/_temp/gpg-957091c8`. That format is only understood by the
|
||||
**Git-for-Windows** build of GPG. When the `gpg` on `PATH` is the **native GnuPG
|
||||
(Gpg4win)** — as in the reporter's environment — those paths are meaningless, so GPG
|
||||
cannot create/read its home directory, keyring, sockets, or lock files, and signature
|
||||
verification fails.
|
||||
|
||||
## Root cause
|
||||
|
||||
`convertToUnixPath()` in `src/main/gpg-verification.js:106-118`:
|
||||
|
||||
```js
|
||||
export function convertToUnixPath(windowsPath) {
|
||||
if (process.platform !== "win32") {
|
||||
return windowsPath;
|
||||
}
|
||||
let unixPath = windowsPath.replaceAll('\\', "/");
|
||||
unixPath = unixPath.replace(/^([A-Za-z]):/, (match, drive) => {
|
||||
return `/${drive.toLowerCase()}`; // R:\... -> /r/...
|
||||
});
|
||||
return unixPath;
|
||||
}
|
||||
```
|
||||
|
||||
For the reporter's temp dir `R:\GHEC\Build_B1\_temp\gpg-957091c8` this produces:
|
||||
|
||||
```
|
||||
R:\GHEC\Build_B1\_temp\gpg-957091c8 → /r/GHEC/Build_B1/_temp/gpg-957091c8
|
||||
```
|
||||
|
||||
which is exactly the path seen in the failure logs.
|
||||
|
||||
The function's own comment states the assumption:
|
||||
|
||||
> `GPG on Windows (from Git for Windows) expects Unix-style paths` — `src/main/gpg-verification.js:102`
|
||||
|
||||
That assumption is wrong for the common case. There are two GPG builds on Windows:
|
||||
|
||||
| GPG build | Understands `/r/GHEC/...` (MSYS) | Understands `R:/GHEC/...` (native) |
|
||||
|---|---|---|
|
||||
| Git for Windows / MSYS2 `gpg` | ✅ | ✅ |
|
||||
| **Native GnuPG / Gpg4win** (`C:\Program Files (x86)\GnuPG\bin\gpg.exe`) | ❌ | ✅ |
|
||||
|
||||
The MSYS drive-letter form (`/r/...`) is understood by *only one* of the two builds,
|
||||
whereas the plain Windows form with forward slashes (`R:/...`) is understood by **both**.
|
||||
By rewriting `R:` → `/r`, the action picks the form that breaks native GnuPG.
|
||||
|
||||
## How the converted path is used
|
||||
|
||||
All three call sites feed native GnuPG a path it cannot resolve:
|
||||
|
||||
- `src/main/gpg-verification.js:165` — `--homedir` for `--recv-keys` (key import)
|
||||
- `src/main/gpg-verification.js:247` — `--homedir` for `--verify`
|
||||
- `src/main/gpg-verification.js:250-251` — the `.asc` signature path and the ZIP path
|
||||
|
||||
## Mapping to the reported errors
|
||||
|
||||
With `--homedir /r/GHEC/Build_B1/_temp/gpg-957091c8`, native GnuPG treats the argument
|
||||
as a bogus location and cannot create/open its home dir. That directly explains every
|
||||
symptom in the report:
|
||||
|
||||
| Reported symptom | Explanation |
|
||||
|---|---|
|
||||
| `pubring.kbx` → *No such file or directory* | Keyring cannot be created/read under the bogus homedir |
|
||||
| `can't create '…/gnupg_spawn_dirmngr_sentinel.lock'` → *The system cannot find the path specified* | Native Windows API cannot resolve `/r/...`; parent path does not exist |
|
||||
| `can't connect to the dirmngr: No such file or directory` | `dirmngr` socket cannot be created under the bogus homedir |
|
||||
| `Kein Dirmngr` (keyserver retrieval failed) | Consequence of dirmngr never starting → `--recv-keys` fails |
|
||||
|
||||
The reporter's own suggested fix — use `R:/GHEC/Build_B1/_temp/gpg-957091c8` — matches
|
||||
the analysis above.
|
||||
|
||||
## Why it isn't caught by CI / existing tests
|
||||
|
||||
- The unit tests in `src/main/__tests__/gpg-verification.test.js:132-163` only assert the
|
||||
transformation itself (`C:\a\_temp\gpg-home` → `/c/a/_temp/gpg-home`). They **encode the
|
||||
buggy behaviour as the expected behaviour**, so they pass while the real bug persists.
|
||||
- GitHub-hosted `windows-latest` runners resolve `gpg` to the **Git-for-Windows** build,
|
||||
which happens to accept `/r/...`. The bug only surfaces when the native GnuPG (Gpg4win)
|
||||
is first on `PATH` — the reporter's self-hosted setup. This is why it escaped testing.
|
||||
|
||||
## Suggested fix (not applied — investigation only)
|
||||
|
||||
On Windows, do **not** rewrite the drive letter. Normalise separators only, keeping a
|
||||
native Windows path with forward slashes, which both GPG builds accept:
|
||||
|
||||
```js
|
||||
export function convertToUnixPath(windowsPath) {
|
||||
if (process.platform !== "win32") {
|
||||
return windowsPath;
|
||||
}
|
||||
// Keep the drive letter (R:/...). Native GnuPG (Gpg4win) cannot resolve the
|
||||
// MSYS "/r/..." form, and Git-for-Windows GPG understands "R:/..." too.
|
||||
return windowsPath.replaceAll("\\", "/");
|
||||
}
|
||||
```
|
||||
|
||||
The corresponding tests at `src/main/__tests__/gpg-verification.test.js:132-153` should be
|
||||
updated to expect `C:/a/_temp/gpg-home` (and the function likely renamed, since it no
|
||||
longer produces a Unix path).
|
||||
|
||||
## Secondary observation (not the reported bug)
|
||||
|
||||
`src/main/run-sonar-scanner.js:147` invokes `${scannerDir}/jre/bin/java` without a `.exe`
|
||||
suffix and with forward slashes. This only runs when `SONAR_ROOT_CERT` is set (truststore
|
||||
handling) and is unrelated to the GPG failure, but is worth a separate look for Windows
|
||||
robustness.
|
||||
|
||||
## Reproducer
|
||||
|
||||
A CI reproducer is provided in `.github/workflows/issue-reproduced.yml`. It runs on
|
||||
`windows-latest`, installs the **native GnuPG (Gpg4win)** and puts it first on `PATH` to
|
||||
match the reporter's environment, then runs the action (`uses: ./`, which executes the
|
||||
committed `dist/index.js`). It expects the action to **fail at GPG signature
|
||||
verification**. It also includes a direct step showing native `gpg` rejecting an
|
||||
MSYS-style `--homedir`, isolating the root cause. The workflow triggers `on: push`.
|
||||
Reference in New Issue
Block a user