Refactor Jenkins pipeline to remove global environment variable for Sonar Scanner and streamline installation process within the analysis stage
This commit is contained in:
parent
22dac4413c
commit
6ef1543dcd
|
|
@ -3,10 +3,7 @@ pipeline {
|
|||
// Defines the execution environment. Using 'agent any' to ensure an agent is available.
|
||||
agent any
|
||||
|
||||
// Global environment variable to store the path to the manually installed scanner.
|
||||
environment {
|
||||
SONAR_SCANNER_PATH = ''
|
||||
}
|
||||
// Global environment block removed to prevent Groovy scoping issues with manual path calculation.
|
||||
|
||||
stages {
|
||||
// Stage 1: Checkout the code (Relies on the initial SCM checkout done by Jenkins)
|
||||
|
|
@ -16,7 +13,7 @@ pipeline {
|
|||
}
|
||||
}
|
||||
|
||||
// Stage 2: Setup Node.js v20, install pnpm, and MANUALLY install Sonar Scanner
|
||||
// Stage 2: Setup Node.js v20 and install pnpm
|
||||
stage('Setup Environment and Tools') {
|
||||
steps {
|
||||
sh '''
|
||||
|
|
@ -33,34 +30,6 @@ pipeline {
|
|||
npm install -g pnpm@8
|
||||
echo "pnpm version: \$(pnpm -v)"
|
||||
'''
|
||||
|
||||
// --- MANUALLY INSTALL THE SONAR SCANNER CLI (FIXED GROOVY SCOPE) ---
|
||||
script {
|
||||
sh """
|
||||
echo "Manually downloading and installing Sonar Scanner CLI..."
|
||||
|
||||
# Download the stable scanner CLI package
|
||||
curl -sS -o sonar-scanner.zip \
|
||||
"https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip"
|
||||
|
||||
unzip -q sonar-scanner.zip -d .
|
||||
|
||||
# Find the extracted directory name
|
||||
def scannerDir = \$(find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1)
|
||||
|
||||
echo "Scanner extracted to: \${scannerDir}"
|
||||
|
||||
# Set the global environment variable (SONAR_SCANNER_PATH)
|
||||
// This allows us to run the scanner by full path in the next stage
|
||||
echo "SONAR_SCANNER_PATH=\${scannerDir}/bin" > .scanner_path.env
|
||||
"""
|
||||
// Load the environment variable set by the shell script
|
||||
// This is the correct way to pass shell variables back to Groovy/Jenkins environment
|
||||
def scannerPath = readProperties file: '.scanner_path.env'
|
||||
env.SONAR_SCANNER_PATH = "${env.WORKSPACE}/${scannerPath.SONAR_SCANNER_PATH}"
|
||||
|
||||
echo "Global Sonar Path set to: ${env.SONAR_SCANNER_PATH}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +41,7 @@ pipeline {
|
|||
}
|
||||
}
|
||||
|
||||
// Stage 4: Run SonarQube analysis using the plugin's variables and the manual path.
|
||||
// Stage 4: Run SonarQube analysis: Install scanner, get version, and execute.
|
||||
stage('SonarQube Analysis') {
|
||||
steps {
|
||||
script {
|
||||
|
|
@ -80,15 +49,39 @@ pipeline {
|
|||
def commitShaShort = sh(returnStdout: true, script: 'git rev-parse --short=8 HEAD').trim()
|
||||
echo "Commit SHA (short) is: ${commitShaShort}"
|
||||
|
||||
// 2. Use withSonarQubeEnv to set up the secure variables (HOST and TOKEN)
|
||||
// The 'SonarQube-Server' name is used as per your previous log.
|
||||
// --- 2. MANUALLY INSTALL THE SONAR SCANNER CLI LOCALLY IN THIS STAGE ---
|
||||
sh """
|
||||
echo "Manually downloading and installing Sonar Scanner CLI..."
|
||||
|
||||
# Download the stable scanner CLI package
|
||||
curl -sS -o sonar-scanner.zip \
|
||||
"https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip"
|
||||
|
||||
# Added -o flag to force overwrite and prevent interactive prompt failure
|
||||
unzip -o -q sonar-scanner.zip -d .
|
||||
"""
|
||||
|
||||
// 3. Find the extracted directory name and capture the full absolute bin path in Groovy
|
||||
// This is defined locally and used directly, avoiding environment variable issues.
|
||||
def scannerBinPath = sh(
|
||||
returnStdout: true,
|
||||
script: '''
|
||||
SCANNER_DIR=$(find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1)
|
||||
# Get the full absolute path to the executable file
|
||||
echo \$(pwd)/\${SCANNER_DIR}/bin/sonar-scanner
|
||||
'''
|
||||
).trim()
|
||||
|
||||
echo "Scanner executable path captured: ${scannerBinPath}"
|
||||
|
||||
// 4. Use withSonarQubeEnv to set up the secure variables (HOST and TOKEN)
|
||||
withSonarQubeEnv(installationName: 'SonarQube-Server') {
|
||||
// 3. Execute the scanner using the manually determined full path.
|
||||
// We rely on the sonar-project.properties file for the project key.
|
||||
// 5. Execute the scanner using the Groovy variable directly.
|
||||
sh """
|
||||
echo "Starting SonarQube Analysis for project version: ${commitShaShort}"
|
||||
|
||||
\${SONAR_SCANNER_PATH}/sonar-scanner \\
|
||||
# Execute the full, absolute path captured in the Groovy variable.
|
||||
'${scannerBinPath}' \\
|
||||
-Dsonar.projectVersion=${commitShaShort} \\
|
||||
-Dsonar.sources=.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,54 +1,38 @@
|
|||
// Declarative Pipeline for building Node.js application and running SonarQube analysis for a Pull Request.
|
||||
pipeline {
|
||||
// Defines the execution environment. Replace 'linux-agent' with your specific agent label.
|
||||
// Defines the execution environment. Using 'agent any' to ensure an agent is available.
|
||||
agent any
|
||||
|
||||
// Environment variables that hold PR details (set automatically by Jenkins SCM plugins like Git/GitHub Branch Source)
|
||||
|
||||
// Environment variables that hold PR details, provided by Jenkins Multibranch setup.
|
||||
environment {
|
||||
// These variables are provided by Jenkins (e.g., in a Multibranch Pipeline setup)
|
||||
// CHANGE_ID corresponds to ${{ github.event.pull_request.number }}
|
||||
// CHANGE_BRANCH corresponds to ${{ github.event.pull_request.head.ref }}
|
||||
// CHANGE_TARGET corresponds to ${{ github.event.pull_request.base.ref }}
|
||||
// These variables are typically provided by Jenkins (e.g., in a Multibranch Pipeline setup)
|
||||
PR_KEY = env.CHANGE_ID
|
||||
PR_BRANCH = env.CHANGE_BRANCH
|
||||
PR_BASE = env.CHANGE_TARGET
|
||||
}
|
||||
|
||||
stages {
|
||||
// Stage 1: Checkout the code with full history (fetch-depth: 0)
|
||||
// Stage 1: Checkout the code (Relies on the initial SCM checkout done by Jenkins)
|
||||
stage('Source Checkout') {
|
||||
steps {
|
||||
script {
|
||||
// This performs a deep clone (fetch-depth: 0)
|
||||
// NOTE: You must replace 'YOUR_GIT_CREDENTIALS_ID' with the actual Jenkins credential ID
|
||||
// that has access to your repository.
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: [[name: 'HEAD']],
|
||||
extensions: [
|
||||
[$class: 'WipeWorkspace'],
|
||||
[$class: 'CleanBeforeCheckout'],
|
||||
[$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false]
|
||||
],
|
||||
userRemoteConfigs: [
|
||||
[url: env.GIT_URL ?: '']
|
||||
]
|
||||
])
|
||||
}
|
||||
echo "Workspace already populated by the initial SCM checkout. Proceeding."
|
||||
}
|
||||
}
|
||||
|
||||
// Stage 2: Setup Node.js v20 and install pnpm
|
||||
stage('Setup Environment') {
|
||||
// Stage 2: Setup Node.js v20, install pnpm, and install required tools (curl, unzip)
|
||||
stage('Setup Environment and Tools') {
|
||||
steps {
|
||||
sh '''
|
||||
# Install Node.js v20 (closest matching the specified version '20.17.0')
|
||||
echo "Ensuring required utilities and Node.js are installed..."
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y curl unzip nodejs
|
||||
|
||||
# 1. Install Node.js v20 (closest matching the specified version '20.17.0')
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
|
||||
echo "Node.js version: \$(node -v)"
|
||||
|
||||
# Install pnpm globally (version 8)
|
||||
# 2. Install pnpm globally (version 8)
|
||||
npm install -g pnpm@8
|
||||
echo "pnpm version: \$(pnpm -v)"
|
||||
'''
|
||||
|
|
@ -63,7 +47,7 @@ pipeline {
|
|||
}
|
||||
}
|
||||
|
||||
// Stage 4: Retrieve secrets from Vault and run SonarQube PR analysis
|
||||
// Stage 4: Run SonarQube PR analysis: Install scanner locally, get version, and execute.
|
||||
stage('SonarQube Pull Request Analysis') {
|
||||
steps {
|
||||
script {
|
||||
|
|
@ -71,26 +55,41 @@ pipeline {
|
|||
def commitShaShort = sh(returnStdout: true, script: 'git rev-parse --short=8 HEAD').trim()
|
||||
echo "Commit SHA (short) is: ${commitShaShort}"
|
||||
|
||||
// 2. Retrieve secrets from HashiCorp Vault using the dedicated plugin binding.
|
||||
withCredentials([
|
||||
// Requires the Jenkins HashiCorp Vault Plugin
|
||||
[$class: 'VaultSecretCredentialsBinding',
|
||||
vaultSecrets: [
|
||||
[$class: 'VaultSecret', secretPath: 'postiz/data/ci/sonar', secretKey: 'SONAR_TOKEN', envVar: 'SONAR_TOKEN'],
|
||||
[$class: 'VaultSecret', secretPath: 'postiz/data/ci/sonar', secretKey: 'SONAR_HOST_URL', envVar: 'SONAR_HOST_URL']
|
||||
]]
|
||||
]) {
|
||||
// 3. Execute sonar-scanner CLI with Pull Request parameters
|
||||
// --- 2. MANUALLY INSTALL THE SONAR SCANNER CLI LOCALLY ---
|
||||
sh """
|
||||
echo "Manually downloading and installing Sonar Scanner CLI..."
|
||||
curl -sS -o sonar-scanner.zip \
|
||||
"https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip"
|
||||
unzip -o -q sonar-scanner.zip -d .
|
||||
"""
|
||||
|
||||
// 3. Find the extracted directory name and capture the full absolute executable path.
|
||||
def scannerBinPath = sh(
|
||||
returnStdout: true,
|
||||
script: '''
|
||||
SCANNER_DIR=$(find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1)
|
||||
# Get the full absolute path to the executable file
|
||||
echo \$(pwd)/\${SCANNER_DIR}/bin/sonar-scanner
|
||||
'''
|
||||
).trim()
|
||||
|
||||
echo "Scanner executable path captured: ${scannerBinPath}"
|
||||
|
||||
// 4. Use withSonarQubeEnv to set up the secure variables (HOST and TOKEN)
|
||||
withSonarQubeEnv(installationName: 'SonarQube-Server') {
|
||||
// 5. Execute the scanner using the Groovy variable directly with PR parameters.
|
||||
sh """
|
||||
echo "Starting SonarQube Pull Request Analysis for PR #${PR_KEY}"
|
||||
sonar-scanner \\
|
||||
|
||||
'${scannerBinPath}' \\
|
||||
-Dsonar.projectVersion=${commitShaShort} \\
|
||||
-Dsonar.token=\${SONAR_TOKEN} \\
|
||||
-Dsonar.host.url=\${SONAR_HOST_URL} \\
|
||||
-Dsonar.sources=. \\
|
||||
-Dsonar.pullrequest.key=${PR_KEY} \\
|
||||
-Dsonar.pullrequest.branch=${PR_BRANCH} \\
|
||||
-Dsonar.pullrequest.base=${PR_BASE}
|
||||
# Add other analysis properties here if needed (e.g., -Dsonar.projectKey=...)
|
||||
|
||||
# SONAR_HOST_URL and SONAR_TOKEN are automatically passed as environment variables
|
||||
# by the withSonarQubeEnv block.
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue