sonarqube 覆盖率为0_net持续集成篇之 sonarqube触发webhook

本文介绍如何利用SonarQube的WebHook功能实现持续发布和发布包归档。通过具体步骤演示如何设置Web服务器接收SonarQube构建成功的通知,并验证请求的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WebHook近些年来变得越来越流行,github,gitlab等代码托管平台都提供webhook功能.关于webhook这里不做详细介绍,大家可以参阅读相关互联网书籍或者材料来更深了解.可以把它简单理解为某一事件完成以后的一个回调.

在持续集成环境里,我们可以使用Sonarqube的webhook功能来实现持续发布和发布包归档功能.大致思路是当项目构建成功后我们可以通过webhook通知服务器构建任务已完成,接下来web 服务器可以根据webhook传递的参数决定要处理的包是哪个项目的包(通过项目的key来判断),如何对包进行归档以及如何把包发布到远程服务器(通过http,ftp等方式).

Web服务器搭建

要想实现webhook,必须有一个预先设计好的web服务器供回调.我们预先建好了一个web项目(新建一个mvc项目即可)

由于是测试,我们这里就用Visual的模板生成一个mvc项目,然后在Home控制器下新建一个Action,代码如下:

    public IActionResult HookTest([FromBody]SonarQubeVm sonar)        {            return new EmptyResult();        }

由于Sonarqube webhook是通过post方式提交,因此action必须支持Post方式请求.

参数sonar是SonarQubeVm类型的参数,是根据Sonarqube请求规格文档构建的,代码如下:

 public class SonarQubeVm    {        public DateTime? AnalysedAt { get; set; }        public SonarProjectInfo project { get; set; }        public string ServerUrl { get; set; }        public string Status { get; set; }        public string TaskId { get; set; }    }    public class SonarProjectInfo    {        public string Key { get; set; }        public string Name { get; set; }    }

注意以上参数并不完全包含Sonarqube返回的所有参数,我们只取了部分.关于Sonarqube webhook完整请求参数请查看http://localhost:9000/documentation/webhooks,localhost:9000是默认的服务器的端口号,如果你更改了端口号或者从外网请求,则要更改为实际的ip地址(或者域名)加上指定的端口号.

WebHook调用

在Sonarqube里可以通过两种方式调用webhook,全局模式和项目模式.全局模式每当一个构建成功后就会触发.项目模式则只有指定的项目构建以后才会触发.

全局模式

09d6880bc6a5a5a8bbe9440dd6b3a5df.png

如上图示,我们点击全局Administration然后点击configuration在出现的下拉列表里选择WebHooks,此时右上角有一个create按钮,点击后出现一个弹出框,要求输入名称和url,然后点击确定.

22547d2019f1716c42a3e4543a42fc47.png

我们以调试模式启动web项目,然后执行一个Sonarqube项目构建,执行完成后看看是否有请求到达web服务器.

MSBuild.SonarQube.Runner.exe begin /k:"mytest" /n:"mytest" /v:"v3.0" /d:sonar.cs.opencover.reportsPaths="%CD%estcover.xml"msbuild.exe"E:personalprojectewTest2018ConsoleApp1packagesOpenCover.4.6.519oolsOpenCover.Console.exe" -output:"%CD%estcover.xml" -register:user -target:"C:Program Files (x86)Microsoft Visual Studio2017EnterpriseCommon7IDECommonExtensionsMicrosoftTestWindowvstest.console.exe" -targetargs:"%CD%binDebugNunitTest.dll"MSBuild.SonarQube.Runner.exe end

以上是我们上一节讲单元测试的时候执行的代码只修改了版本号.我们执行它.

等等以上代码都执行完成,稍等片刻我们就可以看到http请求击中断点

68fa79e5cc837bd468f824805f6872e8.png

通过serverurl是来自localhost:9000,我们可以确定是Sonarqube发来的请求.项目的key和name都是我们设定的mytest

以上仅是个示例程序,没有有用代码,实际项目中我们可以根据webhook请求的key来获取到构建的是哪个项目,然后根据预先设定的逻辑决定把它归档到哪里,以及把它发布到哪些web服务器下的哪些目录里(前面我们讲过通过ftt方式发布web项目,可以在这里使用)

项目模式

项目模式与全局模式设置完全一样,只是入口不同,项目模式需要进入项目的Administration标签里进行设置.仍然以mytest项目为例子,我们打开mytest项目,进入到Administration标签里选择webhooks即可.

b98fc75820c54c97264e44403574d217.png

设置和全局设置一样,这里不再赘述.

请求认证

通过以上配置,我们成功搞好了webhook功能,然而以上代码根本无法使用到生产环境中,因为没有对请求进行认证,如果任何人都可以调用构建服务器地址则后果不堪设想.我们必须对请求进行认证,然后再决定是否执行相应逻辑.

由于sonaqube不支持设置header,因此我们无法使用复杂的请求认证.只能使用基本的http认证

我们在服务端增加以下类

 public class BasicAuthenticationAttribute: ActionFilterAttribute    {        protected string Username { get; set; } = "sto";        protected string Password { get; set; } = "sto";        public override void OnActionExecuting(ActionExecutingContext filterContext)        {            var req = filterContext.HttpContext.Request;            var auth = req.Headers["Authorization"].ToString();            if (!String.IsNullOrEmpty(auth))            {                var cred = System.Text.Encoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':');                var user = new { Name = cred[0], Pass = cred[1] };                if (user.Name == Username && user.Pass == Password) return;            }            filterContext.Result = new UnauthorizedResult();        }    }

以上代码中,我们通过硬编码方式指定了用户名和密码,实际生产环境中我们可以通过查询数据库来获取用户名和密码. 在OnActionExecuting重写方法中我们通过头信息Authorization获取加密的Base64字符串,然后通过:分割获取到用户名和密码.然后和真实用户名密码做对比然后决定下一步动作.

我们把这个filter加到请求方法上.

改造后的代码如下:

        [BasicAuthentication]        public IActionResult HookTest([FromBody]SonarQubeVm sonar)        {            return new EmptyResult();        }

我们把webhook的url更新为如下:

http://sto:sto1@localhost:49442/home/HookTest

实际上服务端逻辑要求账户和密码都必须是sto能请求,我们故意把密码改为sto1看看请求是否能成功.

我们仍然执行前面的构建代码,只是把版本号增加一下.

我们再进入webhook管理界面,可以看到请求失败了

e9122a130477a7211f98642f7fda3f02.png

我们点击失日期后面的四框图标,可以看到失败的状态是401

f489f8c1f11101d9beaee93070e4e996.png

我们把请求地址更改为如下

http://sto:sto@localhost:49442/home/HookTest

这里sto1改为服务器期待的sto,请求就能成功了.

<think>我们正在讨论如何将SonarQube与GitLab集成,实现在开发分支合并到测试基线分支时自动触发代码扫描并推送结果。 根据用户提供的引用[1],我们有一个.gitlab-ci.yml的配置示例,用于在GitLab CI/CD流水线中运行SonarScanner。 用户的需求是:在开发分支(例如dev)合并到测试基线分支(例如test)时触发扫描。 步骤概述: 1. 确保已经安装并配置好SonarQube服务器,并创建了项目。 2. 在GitLab中为项目配置CI/CD变量(如SONAR_TOKEN)。 3. 在项目根目录下创建或修改.gitlab-ci.yml文件,定义在合并到测试分支时触发的作业。 4. 作业中运行SonarScanner,并配置sonar.qualitygate.wait=true以等待质量阈检查结果。 详细步骤: 步骤1:准备SonarQube - 在SonarQube服务器上生成一个令牌(Token),用于GitLab作业与SonarQube的认证。 - 记录SonarQube服务器的URL。 步骤2:配置GitLab CI/CD变量 - 在GitLab项目的Settings -> CI/CD -> Variables中,添加以下变量: SONAR_HOST_URL: SonarQube服务器的URL(如果引用中示例需要,也可以直接写在yml中,但推荐用变量) SONAR_TOKEN: 在SonarQube生成的令牌(注意选择Masked保护) 步骤3:编写.gitlab-ci.yml - 根据引用[1]中的示例,我们可以定义一个作业,该作业在合并请求(Merge Request)被合并到目标分支(测试分支)时触发,或者在推送到测试分支时触发。但用户要求是在合并到测试基线分支时进行扫描,因此我们可以设置规则(rules)来触发。 示例配置如下: ```yaml stages: - test sonarqube-check: stage: test image: name: sonarsource/sonar-scanner-cli:latest entrypoint: [""] variables: SONAR_HOST_URL: "http://your_sonarqube_server_url" # 也可以用变量替换,例如:$SONAR_HOST_URL(需在GitLab CI/CD变量中定义) SONAR_PROJECT_KEY: "your_project_key" SONAR_PROJECT_NAME: "your_project_name" script: - sonar-scanner -Dsonar.qualitygate.wait=true -Dsonar.login=$SONAR_TOKEN -Dsonar.projectKey=$SONAR_PROJECT_KEY -Dsonar.projectName=$SONAR_PROJECT_NAME # 可以根据需要添加更多参数,例如指定分支 -Dsonar.branch.name=$CI_COMMIT_REF_NAME rules: - if: $CI_COMMIT_BRANCH == "test" # 当推送到测试分支时触发(注意:合并操作会触发向目标分支的推送) # 或者使用合并请求事件,但注意合并请求被接受后,会向目标分支(test)推送,所以也可以根据分支来触发 # 或者使用合并请求事件:当合并请求被合并时,会触发流水线,且此时目标分支是test分支,所以也可以这样: # - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "test" # 但用户要求是合并到测试基线分支时,所以两种方式都可以考虑,但更直接的是监听推送到test分支(因为合并完成后就会在test分支上有新的提交) allow_failure: false # 如果质量门失败,则作业失败,进而可以阻止后续流程(可选) ``` 注意:上面的规则(rules)部分有两种方式: 方式1:监听推送到test分支的事件(包括合并后的推送)。这样只要代码推送到test分支,就会触发扫描。 方式2:监听合并请求事件,并且目标分支是test分支。这样在合并请求被合并时触发。 用户的需求是“开发分支合并到测试基线分支时”,所以更倾向于在合并完成后的推送事件。因此,我们可以采用方式1:当有代码推送到test分支时触发扫描。 但是,如果希望在合并请求过程中就进行扫描(即在合并前),则可以在创建合并请求时触发扫描,这样可以在合并前发现问题。不过用户要求的是合并到测试基线分支时,所以这里按照合并后推送到测试分支来配置。 步骤4:推送结果 - 上面的配置已经会运行扫描并将结果推送到SonarQube服务器。由于设置了`sonar.qualitygate.wait=true`,作业会等待SonarQube的质量阈检查完成,并根据结果决定作业是否成功。 - 如果质量阈失败,作业会失败,这样如果配置了后续步骤(如部署到测试环境),则不会执行,起到拦截作用。 步骤5:可选:在GitLab中显示SonarQube结果 - 如果需要将SonarQube的结果(如质量阈状态、漏洞数量等)显示在GitLab的合并请求页面,可以配置SonarQube的GitLab插件,或者使用GitLab的Quality Reports功能。 - 在SonarQube中,可以配置GitLab的集成,将分析结果作为注释发送到合并请求。这需要额外的配置,包括在SonarQube中设置GitLab的Personal Access Token。 由于用户有要求显示在合并请求中,这里先不展开。如果需要,可以后续补充。 总结:通过以上配置,当开发分支合并到测试分支(即代码推送到测试分支)时,GitLab CI会触发SonarScanner作业,执行代码扫描并等待质量阈结果,从而保证合并到测试分支的代码质量。 注意:在实际项目中,请替换示例中的占位符(如SonarQube服务器地址、项目密钥等)。 相关问题: §§相关问题§§ 1. 如何生成SonarQube的令牌(Token)? 2. 如何配置SonarQube的质量阈(Quality Gate)? 3. 如何将SonarQube分析结果集成到GitLab合并请求(Merge Request)界面? 4. 如果扫描失败,如何阻止后续的部署流程? 5. 如何优化SonarScanner在GitLab CI中的执行速度?</think>### SonarQube 集成 GitLab 实现分支合并自动扫描配置指南 以下是实现开发分支合并到测试基线分支时自动触发 SonarQube 扫描的完整配置流程: --- #### 1. **前置条件准备** - **SonarQube 服务器**:已部署并配置好项目([创建项目指南](https://docs.sonarqube.org/latest/user-guide/projects/)) - **GitLab 项目**:需启用 CI/CD 功能 - **SonarScanner**:安装 CLI 工具或使用 Docker 镜像 --- #### 2. **配置 GitLab CI/CD 变量** 在 GitLab 项目设置中配置以下敏感变量: ```bash Settings → CI/CD → Variables ``` | 变量名 | 值 | 保护级别 | |--------|----|----------| | `SONAR_HOST_URL` | `http://your-sonarqube-server` | ✅ | | `SONAR_TOKEN` | `sqp_xxxxxxxxxxxx` (SonarQube 生成的令牌) | ✅ | | `SONAR_PROJECT_KEY` | `your_project_key` | ✅ | > 注:SonarQube 令牌在 **User → My Account → Security** 生成[^1] --- #### 3. **配置 `.gitlab-ci.yml` 文件** ```yaml stages: - test - sonarqube # 测试基线分支保护规则 workflow: rules: - if: $CI_COMMIT_REF_NAME == "test-baseline" # 测试基线分支名 # SonarQube 扫描任务 sonarqube-scan: stage: sonarqube image: sonarsource/sonar-scanner-cli:latest variables: SONAR_PROJECT_VERSION: "${CI_COMMIT_SHORT_SHA}" script: - sonar-scanner -Dsonar.projectKey=${SONAR_PROJECT_KEY} -Dsonar.projectName="${CI_PROJECT_NAME}" -Dsonar.branch.name="${CI_COMMIT_REF_NAME}" -Dsonar.qualitygate.wait=true # 阻塞直到质量门结果 -Dsonar.login=${SONAR_TOKEN} rules: - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "test-baseline" # 合并到测试分支时触发 allow_failure: false # 质量门失败则中断流水线 ``` 关键配置说明: 1. **触发条件**:`$CI_MERGE_REQUEST_TARGET_BRANCH_NAME` 确保只在合并到测试分支时运行 2. **质量门阻塞**:`sonar.qualitygate.wait=true` 强制等待扫描结果 3. **分支关联**:`sonar.branch.name` 绑定当前分支分析 --- #### 4. **SonarQube 质量阈配置** 在 SonarQube 控制台配置质量阈规则: ```bash Quality Gates → Create ``` 建议规则: - 严重漏洞 > 0 → 失败 - 覆盖率 < 80% → 警告 - 重复代码率 > 10% → 警告 --- #### 5. **结果推送与通知** **GitLab Merge Request 集成**: 1. 在 SonarQube 安装 **GitLab 插件** 2. 配置 **Webhook**: ```bash Settings → Configuration → Webhooks ``` - URL: `https://gitlab.example.com/api/v4/projects/:id/merge_requests/:merge_request_iid/notes` - 事件勾选:`Scan completed` 合并请求中将自动显示扫描结果: ``` ✅ Quality Gate Passed | 🐞 0 Bugs | 🧪 85% Coverage ``` --- #### 常见问题解决 1. **扫描未触发**: - 检查 `rules` 条件是否匹配分支名 - 确认 GitLab Runner 标签匹配 2. **认证失败**: ```bash # 验证令牌有效性 curl -u ${SONAR_TOKEN}: http://sonarqube/api/project_analyses/search ``` 3. **超时问题**: ```yaml variables: SONAR_SCANNER_OPTS: "-Dsonar.connection.timeout=300" ``` > 最佳实践:建议在开发分支启用 **PR 预扫描**,避免合并后阻塞[^1] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值