1 SonarQube和SonarScan的安裝配置
1.1 Windows環(huán)境下的安裝和使用
1.1.1 啟動sonarqube服務
1.1.2 在mysql里面創(chuàng)建一個存儲掃描結果的庫(比如sonarDB)
1.1.3 配置sonar qube的sonar.properties
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonarDB?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
sonar.jdbc.username=root
sonar.jdbc.password=root
sonar.sorceEncoding=UTF-8
1.1.4 重啟sonar qube(使用ctrl + c)
停止sonar qube(使用ctrl + c)
然后重新啟動sonar qube...
1.1.5 Sonar Scanner插件配置
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonarDB?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance
sonar.jdbc.username=root
sonar.jdbc.password=root
# 如果測試項目與服務器不在同一臺機子析孽,則需要添加SonarQube服務器的IP:
sonar.host.url=http://localhost:9000
1.1.6 運行Sonar scanner
注意:需要提前把sonar qube運行起來
1.1.6.1 下載代碼到本地
1.1.6.2 創(chuàng)建一個sonar-project.properties
sonar.projectKey=yay:project
# this is the name displayed in the SonarQube UI
sonar.projectName=whatproject.0project
sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# Since SonarQube 4.2, this property is optional if sonar.modules is set.
# If not set, SonarQube starts looking for source code from the directory containing
# the sonar-project.properties file.
sonar.sources=personrecord
sonar.java.binaries=newtarget
sonar.language=java
# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8
1.1.6.3 運行sonar-scanner執(zhí)行代碼掃描
D:\svncode>D:\softwareback\devops\sonar\sonar-scanner-3.0.3.778-windows\bin\sonar-scanner
注意,在執(zhí)行過程中很可能會遇到這種錯誤:這主要是由于生產(chǎn)的報告大于mysql允許的最大包大小(比如默認值只允許4M)。
解決方法為修改mysql根目錄里面的my.ini文件,增加一行:max_allowed_packet= 100M
我們可以查看mysql現(xiàn)有的包大小配置:
SHOW VARIABLES LIKE 'max_allowed_packet';
[mysqld]
#設置3306端口
port = 3306
# 設置mysql的安裝目錄
basedir=D:/softwareback/db/mysql-5.7.26
# 設置mysql數(shù)據(jù)庫的數(shù)據(jù)的存放目錄
datadir=D:/softwareback/db/mysql-5.7.26/data
# 服務端使用的字符集默認為8比特編碼的latin1字符集
character-set-server=utf8
default-storage-engine=INNODB
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
# 解決sonarscanner插件允許時候出錯:ERROR: Failed to upload report - 500: An error has occurred. Please contact your administrator
max_allowed_packet= 100M
[mysql]
# 設置mysql客戶端默認字符集
default-character-set=utf8
1.1.7 查看掃描結果
1.2 Centeros環(huán)境下的安裝和使用
1.2.1 大多數(shù)安裝環(huán)境和windows差不多
。。吱殉。
2. 和Jenkins集成
2.1 Mysql和Sonarqube加入到PATH中
2.2 SonarScanner Jenkins插件的安裝
注意SonarScanner仍然需要在本地環(huán)境現(xiàn)安裝好
2.3 在Jenkins上某個task上增加這個步驟
2.3.1 直接在Jenkins上配置
接下來是這個步驟的配置:
sonar.projectKey=HGARCH1.0.01:project
sonar.projectName=HGARCH1.0.01.0project
sonar.projectVersion=1.0.01
sonar.sources=.
sonar.java.binaries=output
sonar.language=java
sonar.sourceEncoding=UTF-8
然后到sonar系統(tǒng)修改一個地方,否則在運行Jenkins的job時候會出錯
然后運行厘托,注意上一步配置如果不做可能會出錯:
運行成功后可以在Jenkins看到sonar上相關工程執(zhí)行結果鏈接:
2.3.2 在pipeline腳本里面配置
pipeline{
agent any
tools {
//工具名稱必須在Jenkins 管理Jenkins → 全局工具配置中預配置友雳。
maven 'maven3'
}
environment{
def SRCCODE_DIR = "/var/jenkins_home/workspace/${env.JOB_NAME}"
def DAILYCI_DIR = "/var/ciOutput/dailyCiOutput"
def SVN_FOLD = "personrecord"
}
options {
//pipeline保持構建的最大個數(shù)
buildDiscarder(logRotator(numToKeepStr: '28'))
}
triggers { cron('H 0,12 * * *') }
stages{
stage('Checkout'){
steps{
checkout([
$class: 'SubversionSCM',
additionalCredentials: [],
excludedCommitMessages: '',
excludedRegions: '',
excludedRevprop: '',
excludedUsers: '',
filterChangelog: false,
ignoreDirPropChanges: false,
includedRegions: '',
locations: [[credentialsId: '6aab1014-b1c9-4a8a-adba-f1cd0d27a483',
depthOption: 'infinity',
ignoreExternalsOption: true,
remote: "https://10.xxx.xxx.xxx/svn/ZYN/xxx/branch/V1.0/code/personrecord"]],
workspaceUpdater: [$class: 'UpdateUpdater']])
}
}
stage('Build'){
steps{
compileAllFiles()
}
}
stage('Backend Unit Test') {
steps {
sh 'mvn -f $SVN_FOLD/algorithm/pom.xml test'
sh 'mvn -f $SVN_FOLD/pom.xml test'
//junit '**/target/surefire-reports/TEST-*.xml'
//archive 'target/*.jar'
}
}
stage('SonarQube Analysis') {
steps {
withSonarQubeEnv('snoar-6.7.7') {
script {
def sonarScanner = tool name: 'sonarscanner', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
sh "${sonarScanner}/bin/sonar-scanner " +
"-Dsonar.projectKey=HGARCHMain:project " +
"-Dsonar.projectName=HGARCHMainProject " +
"-Dsonar.projectVersion=1 " +
"-Dsonar.sources=$SVN_FOLD " +
"-Dsonar.java.binaries=$SVN_FOLD/output " +
"-Dsonar.sourceEncoding=UTF-8"
}
}
//timeout(time: 15, unit: 'MINUTES') {
// script {
// def qg = waitForQualityGate()
// if (qg.status != 'OK') {
error "代碼不滿足Pipelin中Sonar設定的質量門限: ${qg.status}"
// }
// }
// }
}
}
stage('UploadToRepository'){
steps{
rmDailyCIOutputFiles()
copyJarsToDailyCIOutoutDir()
}
}
stage('copy to 118'){
steps{
sshPublisher(publishers: [sshPublisherDesc(configName: 'fornanjing118', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'dailyOutput', remoteDirectorySDF: false, removePrefix: 'personrecord/output', sourceFiles: 'personrecord/output/**/*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('Deploy to 117'){
steps{
//調用Publish Over SSH插件,上傳docker-compose.yaml文件并且執(zhí)行deploy腳本
sshPublisher(publishers: [sshPublisherDesc(configName: 'forchongqing117', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'sh /root/hgarchDevops/redeploy.sh', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'dailyOutput', remoteDirectorySDF: false, removePrefix: 'personrecord/output', sourceFiles: 'personrecord/output/**/*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
//sh /root/hgarchDevops/redeploy.sh
//remoteDirectory: '/root/hgarchDevops/dailyOutput'
//flatten: true會避免copy過來的jar包在personrecord/output中
//personrecord/output/*.jar
//. ./hgarchDevops/dailyOutput/redeploy.sh
}
}
}
post {
failure
{
sh '$mail'
}
}
}
def compileAllFiles()
{
//執(zhí)行shell命令
sh 'mvn -f $SVN_FOLD/algorithm/pom.xml clean scala:compile compile package -DskipTests=true'
sh 'mvn -f $SVN_FOLD/pom.xml clean package'
}
def rmDailyCIOutputFiles()
{
sh 'rm -rf $DAILYCI_DIR.'
}
def copyJarsToDailyCIOutoutDir()
{
if (isUnix())
{
sh 'cp -r $SVN_FOLD/output/* $DAILYCI_DIR'
}
else
{
bat 'cp -r $SVN_FOLD/output/* $DAILYCI_DIR'
}
}
def mail=
{
emailext body: emailBody(),//"${env.DEFAULT_CONTENT}",
recipientProviders: [ //[$class: 'CulpritsRecipientProvider'],
//[$class: 'DevelopersRecipientProvider'],
//[$class: 'RequesterRecipientProvider'],
//[$class: 'FailingTestSuspectsRecipientProvider'],
[$class: 'FirstFailingBuildSuspectsRecipientProvider'],
[$class: 'UpstreamComitterRecipientProvider']
],
subject: '構建失敗',
mimeType: "text/html"
}
def emailBody()
{
return '''<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次構建日志</title>
</head>
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"
offset="0">
<table width="95%" cellpadding="0" cellspacing="0" style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
<tr>
本郵件由系統(tǒng)自動發(fā)出铅匹,無需回復押赊!<br/>
各位同事,大家好包斑,以下為${PROJECT_NAME }項目構建信息</br>
<td><font color="#CC0000">構建結果 - ${BUILD_STATUS}</font></td>
</tr>
<tr>
<td><br />
<b><font color="#0B610B">構建信息</font></b>
<hr size="2" width="100%" align="center" /></td>
</tr>
<tr>
<td>
<ul>
<li>項目名稱 : ${PROJECT_NAME}</li>
<li>構建編號 : 第${BUILD_NUMBER}次構建</li>
<li>觸發(fā)原因: ${CAUSE}</li>
<li>構建狀態(tài): ${BUILD_STATUS}</li>
<li>構建日志: <a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
<li>構建 Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li>
<li>工作目錄 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
<li>項目 Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
</ul>
<h4><font color="#0B610B">失敗用例</font></h4>
<hr size="2" width="100%" />
$FAILED_TESTS<br/>
<h4><font color="#0B610B">最近提交(#$SVN_REVISION)</font></h4>
<hr size="2" width="100%" />
<ul>
${CHANGES_SINCE_LAST_SUCCESS, reverse=true, format="%c", changesFormat="<li>%d [%a] %m</li>"}
</ul>
詳細提交: <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a><br/>
</td>
</tr>
</table>
</body>
</html>'''
}