极狐GitLab CI 助力 .Net 项目研发效率和质量双提升

目录

.NET nuget 自动生成测试包(prerelease)版本号

.NET 版本号规范

持续集成自动打包

持续集成自动修改版本号

.NET 行级增量代码规范——拯救老项目

本地全量代码规范

行级增量代码规范


很多团队或开发者都会使用 C#、VB 等语言开发 .Net 应用。.NET 版本号的管理与对应代码的质量管理是一个比较充满挑战的话题。本文将介绍使用极狐GitLab CI 来实现 .NET 应用的版本号自动生成以及代码的增量扫描,从而提高 .NET 应用的研发效率。

.NET nuget 自动生成测试包(prerelease)版本号


NET 包(nuget)的版本号位于项目配置文件中(比如 Foo.csproj),比如这个包是 1.1.0 版本:

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>netstandard2.0</TargetFramework><Version>1.1.0</Version></PropertyGroup>
</Project>

当开发新版时(比如 1.2.0),可能需要发布测试包,供联调和测试,当测试通过时,才会发布正式包。

可以使用这种 Git 工作流(也有其他工作流,大同小异):

  • 开发分支(如 feature-123)或合并请求(MR/PR)时:发布测试包;

  • 主干分支或 Tag 时:发布正式包。

图片

.NET 版本号规范


.NET 测试包的官方术语是 prerelease(预发行版),在 Visual Studio 包管理界面有一个开关:

图片

版本号遵循语义化版本规范,常用如下命名:

  • alpha:Alpha 版本,通常用于在制品和试验品

  • beta:Beta 版本,通常指可用于下一计划版本的功能完整的版本,但可能包含已知 bug。

  • rc:候选发布,通常可能为最终(稳定)版本,除非出现重大 bug。

如果项目测试流程不是很复杂,采用其中一个就够了,本文采用 beta。

所以版本号的变化历程可能是这样的:1.1.0 → 1.2.0-beta.1 → 1.2.0-beta.2 → 1.2.0-beta.3 → 1.2.0

如果手动修改,多次改代码很容易忘记改版本号。

有没有办法自动修改版本号?可以!那就是持续集成。

持续集成自动打包


提交代码,触发程序自动打包,这是持续集成的典型用途。使用 GitLab 持续集成配置 .NET 自动打包非常简单:

vi MyDotnetLibrary/.gitlab-ci.yml

.gitlab-ci.yml 的内容如下:

image: mcr.microsoft.com/dotnet/sdk:6.0default:before_script:- dotnet nuget add source "$CI_SERVER_URL/api/v4/projects/$CI_PROJECT_ID/packages/nuget/index.json" -n GitLab -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD --store-password-in-clear-textbuild_release:stage: buildonly:- mainscript:- rm -rf *.Tests- dotnet pack **/*.csproj -c Release- dotnet nuget push **/bin/Release/*.nupkg -s GitLab

可以看到上面代码判断了 only: - main,也就是主干分支时才打包。

持续集成自动修改版本号


开发新版本时,只需要修改一次版本号(比如 1.2.0):

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>netstandard2.0</TargetFramework><Version>1.2.0</Version></PropertyGroup>
</Project>

然后,让持续集成自动判断:

  • 合并请求:在版本号后面添加测试版本号,变成 1.2.0-beta.123

  • 主干分支:不添加,保持 1.2.0

GitLab 流水线内置了很多变量,有几个适合做测试版本号:

  • CI_PIPELINE_IID:项目内的流水线 ID,从 1 开始自增,每次提交触发流水线都会自增;

  • CI_MERGE_REQUEST_IID:项目内的合并请求 ID,从 1 开始自增,每次新建合并自增,但多次提交不会变。

可以看出 CI_PIPELINE_IID 适合做测试包的构建号。

拼接出想要的格式,使用 sed 命令替换:

export CI_PIPELINE_IID=123
sed "s|</Version>|-beta.$CI_PIPELINE_IID</Version>|g" **/*.csproj

图片

本地跑通命令,再把它复制到 .gitlab-ci.yml 中:

image: mcr.microsoft.com/dotnet/sdk:6.0default:before_script:- dotnet nuget add source "$CI_SERVER_URL/api/v4/projects/$CI_PROJECT_ID/packages/nuget/index.json" -n GitLab -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD --store-password-in-clear-textbuild_prerelease:stage: buildonly:- merge_requestsscript:- rm -rf *.Tests- sed -i "s|</Version>|-beta.$CI_PIPELINE_IID</Version>|g" **/*.csproj- dotnet pack **/*.csproj -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg -c Debug- dotnet nuget push **/bin/Debug/*.nupkg -s GitLabbuild_release:stage: buildonly:- mainscript:- rm -rf *.Tests- dotnet pack **/*.csproj -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg -c Release- dotnet nuget push **/bin/Release/*.nupkg -s GitLab

运行效果:

图片

图片

.NET 行级增量代码规范——拯救老项目


从 .NET 5 开始,SDK 内置了代码分析器,可以检查 C# 和 Visual Basic 的代码质量和样式问题,无需安装第三方工具,非常方便。

本地全量代码规范


修改项目配置文件(如 Foo.csprojBar.vbproj),加入 AnalysisMode 和 ErrorLog 属性:

<Project><PropertyGroup><AnalysisMode>All</AnalysisMode><ErrorLog>compiler-diagnostics.sarif</ErrorLog></PropertyGroup>
</Project>

AnalysisMode 允许这些值,按照从松到严排序为:

  • None

  • Default

  • Minimum

  • Recommended

  • All

配置完成,即可在编译时检查代码规范,可在 VS 界面点击或使用命令:

dotnet build

图片

如果本地电脑语言为中文,.NET 会输出部分中文(3 条),但大部分信息还是英文的(96 条)。

可以看出全量扫描发现很多问题,怎么办?

  • 一个人清理干净,其他人暂停提交。显然不合适;

  • 所有人暂停工作,一起清理。也不合适,老代码改了可能出 bug;

  • 增量代码规范,逐渐修复。是个好办法,在本地很难做到,可以借助 GitLab 服务端实现。

行级增量代码规范


配置 GitLab 持续集成 .gitlab-ci.yml

image: mcr.microsoft.com/dotnet/sdk:6.0build:stage: buildallow_failure: truescript:- dotnet buildafter_script:- export PATH="/root/.dotnet/tools:$PATH"# 此工具要求 .NET 6.0+,如果项目是 .NET 5.0,也使用 6.0 SDK 构建即可- dotnet tool install --global CodeQualityToGitlab- cq sarif compiler-diagnostics.sarif gl-code-quality-report.json $(pwd)/artifacts:reports:codequality: gl-code-quality-report.json

第一次 MR(提交 .gitlab-ci.yml) 会发现「全量的很多问题」或「代码质量没有变化」,没关系,先合并进去。

图片

第二次 MR(修改老代码)会在 MR 页面提示修改的代码行是否产生了新问题,是否修复了老问题。

图片

这就是 GitLab 的行级增量代码规范功能,它有几个特点:

  • 配置简单——配置全量扫描命令,自动变成增量;

  • 除了报错模式,还支持警告模式(allow_failure)——由评审人员决定「代码不规范时能否合并」,一般不允许合并,如果线上紧急故障可以合并;

  • 提升开发效率——把代码质量问题直接显示在合并请求页面中,而无需到 CI 日志中翻找;

  • 开放——公开代码质量报告 JSON 格式,各种语言的扫描工具都可以对接(很多工具已经有热心开发者对接,比如 Java Checkstyle、pylint、eslint)。

希望本文能帮助更多的开发者拯救老项目,落地代码规范。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/190375.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

02-瑞吉外卖员工表的增删改查

添加员工信息 执行流程 第一步: 用户点击添加员工按钮跳转到add.html页面,然后在页面中输入要添加的员工的信息 第二步: 用户点击保存按钮发送Ajax请求将用户输入的员工信息以json的格式提交到服务端 第三步: 服务端Controller接收页面提交的json格式的数据并转化为java对象…

2022年06月 Python(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 Python中 print(“八进制{: o}”.format(12)) 正确的输出结果是?( ) A: 八进制:O B: 八进制:O14 C: 八进制14O D: 八进制14 答案:D 字符串的format()格式。 第2题 下列的程…

java的类和继承构造

一些小技巧 类和对象 什么是类&#xff0c;对象&#xff0c;方法&#xff1f; 在下面的 Java 代码中&#xff0c;定义了一个名为 Person 的类&#xff0c;并提供了构造方法来初始化对象的属性。类中定义了 eat、sleep 和 work 三个方法&#xff0c;用于表示人的行为。在 main 方…

LINUX入门篇【4】开发篇--开发工具vim的使用

前言&#xff1a; 从这一篇开始&#xff0c;我们将正式进入使用LINUX进行写程序和开发的阶段&#xff0c;可以说&#xff0c;由此开始&#xff0c;我们才开始真正去使用LINUX。 介绍工具&#xff1a; 1.LINUX软件包管理器yum&#xff1a; 1.yum的介绍&#xff1a; 在LINUX…

【FPGA】十进制计数器 | 实现 4-bit 2421 十进制计数器 | 有限状态机(FSM)

目录 Ⅰ. 实践说明 0x00 十进制计数器 0x01 有限状态机&#xff08;FSM&#xff09; Ⅱ. 实践部分 0x00 4-bit 2421 十进制计数器 Ⅰ. 实践说明 0x00 十进制计数器 十进制计数器是一种以十进制运算的计数器&#xff0c;从 0 数到 9&#xff0c;然后返回 0 状态。由于它需…

2023NewStarCTF

目录 一、阳光开朗大男孩 二、大怨种 三、2-分析 四、键盘侠 五、滴滴滴 六、Include? 七、medium_sql 八、POP Gadget 九、OtenkiGirl 一、阳光开朗大男孩 1.题目给出了secret.txt和flag.txt两个文件&#xff0c;secret.txt内容如下&#xff1a; 法治自由公正爱国…

玩转硬件之Micro:bit的玩法(五)——垃圾分类

垃圾分类&#xff0c;为了美好的明天 垃圾是我们生活中不可避免的产物&#xff0c;每天都有大量的垃圾被丢弃&#xff0c;如果不加以处理&#xff0c;就会给环境和人类带来严重的危害。 垃圾分类是一种有效的垃圾管理方式&#xff0c;它是指按照一定的标准或规则&#xff0c;将…

计算机组成原理之概述

概述 计组主要讲的是计算机的硬件实现方式。 机器字长 比如8080处理器&#xff0c;如果想处理16位数的整数运算&#xff0c;就需要执行两次。 可见&#xff0c;机器字长会影响到数据的处理速度。 计算机硬件的基本组成 早期的冯诺依曼机 冯诺依曼提出了“存储程序”的概念&…

Socket网络编程

本文主要讲解Socket网络编程。 首先介绍socket&#xff0c;包括TCP和UDP通信过程&#xff1b;然后介绍常用的函数&#xff1b;最后编写client-server例子&#xff0c;并进行测试。 文章目录 Socket介绍TCP通信过程服务器端通信过程&#xff1a;客户端通信过程&#xff1a; UDP通…

智慧工地源码:助力数字建造、智慧建造、安全建造、绿色建造

智慧工地围绕建设过程管理&#xff0c;建设项目与智能生产、科学管理建设项目信息生态系统集成在一起&#xff0c;该数据在虚拟现实环境中&#xff0c;将物联网收集的工程信息用于数据挖掘和分析&#xff0c;提供过程趋势预测和专家计划&#xff0c;实现工程建设的智能化管理&a…

Golang源码分析 | 程序引导过程

环境说明 CentOS Linux release 7.2 (Final&#xff09; go version go1.16.3 linux/amd64 GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7使用gdb查看程序入口 编写一个简单的go程序 // main.go package mainfunc main() {print("Hello world") } 编译go …

假冒 Skype 应用程序网络钓鱼分析

参考链接: https://slowmist.medium.com/fake-skype-app-phishing-analysis-35c1dc8bc515 背景 在Web3世界中&#xff0c;涉及假冒应用程序的网络钓鱼事件相当频繁。慢雾安全团队此前曾发表过分析此类网络钓鱼案例的文章。由于Google Play在中国无法访问&#xff0c;许多用户…

K8S知识点(十)

&#xff08;1&#xff09;Pod详解-启动命令 创建Pod&#xff0c;里面的两个容器都正常运行 &#xff08;2&#xff09;Pod详解-环境变量 &#xff08;3&#xff09;Pod详解-端口设置 &#xff08;4&#xff09;Pod详解-资源配额 修改&#xff1a;memory 不满足条件是不能正常…

Django之三板斧的使用,全局配置文件介绍,request对象方法,pycharm链接数据库,Django链接数据库,ORM的增删改查

【1】三板斧(3个方法)的使用 Httpresponse() 括号内写什么字符串&#xff0c;返回的就是什么字符串返回的是字符串 render(request&#xff0c; 静态文件 ) request是固定的静态文件是写在templates文件夹里面的&#xff0c;如&#xff0c;HTML文件 redirect( 重定向的地址 ) 重…

Hadoop原理,HDFS架构,MapReduce原理

Hadoop原理&#xff0c;HDFS架构&#xff0c;MapReduce原理 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c…

LeetCode刷题总结(一)

文章目录 前言题型排序问题动态规划 前言 本文把刷题过程中的总结记下来&#xff0c;方便未来回顾的时候继续拓展。 题型 排序问题 排序问题的解决方法有很多。对于简单算法来说&#xff0c;最重要的是记住思路&#xff1b;对于高级算法来说&#xff0c;最重要的是记住细节…

利用LangChain实现RAG

检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;结合了搜寻检索生成能力和自然语言处理架构&#xff0c;透过这个架构&#xff0c;模型可以从外部知识库搜寻相关信息&#xff0c;然后使用这些信息来生成response。要完成检索增强生成主要包含四个步骤…

2023亚太杯数学建模A题思路

文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料5 最后 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 2023年第十三…

【中间件篇-Redis缓存数据库08】Redis设计、实现、redisobject对象设计、多线程、缓存淘汰算法

Redis的设计、实现 数据结构和内部编码 type命令实际返回的就是当前键的数据结构类型&#xff0c;它们分别是&#xff1a;string(字符串)hash(哈希)、list(列表)、set(集合)、zset (有序集合)&#xff0c;但这些只是Redis对外的数据结构。 实际上每种数据结构都有自己底层的…

【DP】背包问题全解

一.简介 DP&#xff08;动态规划&#xff09;背包问题是一个经典的组合优化问题&#xff0c;通常用来解决资源分配的问题&#xff0c;如货物装载、投资组合优化等。问题的核心思想是在有限的资源约束下&#xff0c;选择一组物品以最大化某种价值指标&#xff0c;通常是总价值或…