背景
在.gitlab-ci.yml里面,我们有4个场景
- dotnet build、dotnet pack和dotnet push
- 单元测试
- SSH到http服务器,更新对应的版本号文件里面的版本数字
- 触发下游
Gitlab里面的“变量”
这个“变量”,最好是放在Group里
.gitlab-ci.yml
内容如下
# This file is a template, and might need editing before it works on your project.
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
# This is a sample GitLab CI/CD configuration file that should run without any modifications.
# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts,
# it uses echo commands to simulate the pipeline execution.
#
# A pipeline is composed of independent jobs that run scripts, grouped into stages.
# Stages run in sequential order, but jobs within stages run in parallel.
#
# For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages
stages: # List of stages for jobs, and their order of execution
- build
- test
- update-version
- trigger-other-project
variables:
EVENT_RECORDER_VERSION_ID : 2022.51.$CI_PIPELINE_IID
EVENT_RECORDER_NUPKG_OUTPUT_DIR : $CI_PROJECT_DIR/nupkg
# Use no compression for caches
CACHE_COMPRESSION_LEVEL: "fastest"
build-job: # This job runs in the build stage, which runs first.
stage: build
before_script:
- bash $DOWNLOAD_ALL_DIRECTORY_BUILD_PROPS_FILES $DIRECTORY_BUILD_DIST_SERVER_DIRECTORYNAME
script:
- echo "Compiling the code..."
- cd .
- dotnet build "src/Yee.Change.EventRecorder.Application/Yee.Change.EventRecorder.Application.csproj" --force -c Release -p:Version=$EVENT_RECORDER_VERSION_ID
- dotnet build "src/Yee.Change.EventRecorder.Application.Contracts/Yee.Change.EventRecorder.Application.Contracts.csproj" --force -c Release -p:Version=$EVENT_RECORDER_VERSION_ID
- dotnet build "src/Yee.Change.EventRecorder.Blazor/Yee.Change.EventRecorder.Blazor.csproj" -c Release --force -p:Version=$EVENT_RECORDER_VERSION_ID
- dotnet build "src/Yee.Change.EventRecorder.BlazorServerUI/Yee.Change.EventRecorder.BlazorServerUI.csproj" -c Release --force -p:Version=$EVENT_RECORDER_VERSION_ID
- dotnet build "src/Yee.Change.EventRecorder.Blazor.Server/Yee.Change.EventRecorder.Blazor.Server.csproj" --force -c Release -p:Version=$EVENT_RECORDER_VERSION_ID
- dotnet build "src/Yee.Change.EventRecorder.Blazor.WebAssembly/Yee.Change.EventRecorder.Blazor.WebAssembly.csproj" --force -c Release -p:Version=$EVENT_RECORDER_VERSION_ID
- dotnet build "src/Yee.Change.EventRecorder.Domain/Yee.Change.EventRecorder.Domain.csproj" --force -c Release -p:Version=$EVENT_RECORDER_VERSION_ID
- dotnet build "src/Yee.Change.EventRecorder.Domain.Shared/Yee.Change.EventRecorder.Domain.Shared.csproj" --force -c Release -p:Version=$EVENT_RECORDER_VERSION_ID
- dotnet build "src/Yee.Change.EventRecorder.EntityFrameworkCore/Yee.Change.EventRecorder.EntityFrameworkCore.csproj" --force -c Release -p:Version=$EVENT_RECORDER_VERSION_ID
- dotnet build "src/Yee.Change.EventRecorder.HttpApi/Yee.Change.EventRecorder.HttpApi.csproj" --force -c Release -p:Version=$EVENT_RECORDER_VERSION_ID
- dotnet build "src/Yee.Change.EventRecorder.HttpApi.Client/Yee.Change.EventRecorder.HttpApi.Client.csproj" --force -c Release -p:Version=$EVENT_RECORDER_VERSION_ID
- dotnet build "src/Yee.Change.EventRecorder.Web/Yee.Change.EventRecorder.Web.csproj" --force -c Release -p:Version=$EVENT_RECORDER_VERSION_ID
- dotnet pack "src/Yee.Change.EventRecorder.Application/Yee.Change.EventRecorder.Application.csproj" -c Release --no-build -o $EVENT_RECORDER_NUPKG_OUTPUT_DIR -p:PackageVersion=$EVENT_RECORDER_VERSION_ID
- dotnet pack "src/Yee.Change.EventRecorder.Application.Contracts/Yee.Change.EventRecorder.Application.Contracts.csproj" -c Release --no-build -o $EVENT_RECORDER_NUPKG_OUTPUT_DIR -p:PackageVersion=$EVENT_RECORDER_VERSION_ID
- dotnet pack "src/Yee.Change.EventRecorder.Blazor/Yee.Change.EventRecorder.Blazor.csproj" -c Release --no-build -o $EVENT_RECORDER_NUPKG_OUTPUT_DIR -p:PackageVersion=$EVENT_RECORDER_VERSION_ID
- dotnet pack "src/Yee.Change.EventRecorder.BlazorServerUI/Yee.Change.EventRecorder.BlazorServerUI.csproj" -c Release --no-build -o $EVENT_RECORDER_NUPKG_OUTPUT_DIR -p:PackageVersion=$EVENT_RECORDER_VERSION_ID
- dotnet pack "src/Yee.Change.EventRecorder.Blazor.Server/Yee.Change.EventRecorder.Blazor.Server.csproj" -c Release --no-build -o $EVENT_RECORDER_NUPKG_OUTPUT_DIR -p:PackageVersion=$EVENT_RECORDER_VERSION_ID
- dotnet pack "src/Yee.Change.EventRecorder.Blazor.WebAssembly/Yee.Change.EventRecorder.Blazor.WebAssembly.csproj" -c Release --no-build -o $EVENT_RECORDER_NUPKG_OUTPUT_DIR -p:PackageVersion=$EVENT_RECORDER_VERSION_ID
- dotnet pack "src/Yee.Change.EventRecorder.Domain/Yee.Change.EventRecorder.Domain.csproj" -c Release --no-build -o $EVENT_RECORDER_NUPKG_OUTPUT_DIR -p:PackageVersion=$EVENT_RECORDER_VERSION_ID
- dotnet pack "src/Yee.Change.EventRecorder.Domain.Shared/Yee.Change.EventRecorder.Domain.Shared.csproj" -c Release --no-build -o $EVENT_RECORDER_NUPKG_OUTPUT_DIR -p:PackageVersion=$EVENT_RECORDER_VERSION_ID
- dotnet pack "src/Yee.Change.EventRecorder.EntityFrameworkCore/Yee.Change.EventRecorder.EntityFrameworkCore.csproj" -c Release --no-build -o $EVENT_RECORDER_NUPKG_OUTPUT_DIR -p:PackageVersion=$EVENT_RECORDER_VERSION_ID
- dotnet pack "src/Yee.Change.EventRecorder.HttpApi/Yee.Change.EventRecorder.HttpApi.csproj" -c Release --no-build -o $EVENT_RECORDER_NUPKG_OUTPUT_DIR -p:PackageVersion=$EVENT_RECORDER_VERSION_ID
- dotnet pack "src/Yee.Change.EventRecorder.HttpApi.Client/Yee.Change.EventRecorder.HttpApi.Client.csproj" -c Release --no-build -o $EVENT_RECORDER_NUPKG_OUTPUT_DIR -p:PackageVersion=$EVENT_RECORDER_VERSION_ID
- dotnet pack "src/Yee.Change.EventRecorder.Web/Yee.Change.EventRecorder.Web.csproj" -c Release --no-build -o $EVENT_RECORDER_NUPKG_OUTPUT_DIR -p:PackageVersion=$EVENT_RECORDER_VERSION_ID
- echo "Deploying application..."
- cd $EVENT_RECORDER_NUPKG_OUTPUT_DIR
- dotnet nuget push *.$EVENT_RECORDER_VERSION_ID.nupkg -k $NUGET_API_KEY -s $NEXUS_REPO
- echo "Application successfully deployed."
更新版本号: # This job runs in the test stage.
stage: update-version # It only starts when the job in the build stage completes successfully.
script:
- echo "SSH到http服务器,更新文件里的版本号……"
- bash $DIRECTORY_BUILD_UPDATE_VERSION_SH $DIRECTORY_BUILD_DIST_SERVER_USER $DIRECTORY_BUILD_DIST_SERVER $DIRECTORY_BUILD_DIST_SERVER_DIRECTORYNAME "Directory.Build.Change.EasyComment.props" $EASY_COMMENT_VERSION_ID
触发下游:
stage: trigger-other-project
trigger:
project: change/wechat-mp
branch: main
上述文件,解释如下:
1、EVENT_RECORDER_VERSION_ID : 2022.51.$CI_PIPELINE_IID
这是版本号,一个解决方案下,所有的项目,版本号是相同的。这里用到了Gitlab提供的变量$CI_PIPELINE_IID。您可以使用自己的命名规范,按需求使用其它的Gitlab提供的变量。
2、EVENT_RECORDER_NUPKG_OUTPUT_DIR : $CI_PROJECT_DIR/nupkg
dotnet pack命令的输出目录。打包好的文件是放在这里的。$CI_PROJECT_DIR这个变量也是Gitlab提供的,表示“作业”执行时,当前解决方案的根目录。
3、bash $DOWNLOAD_ALL_DIRECTORY_BUILD_PROPS_FILES $DIRECTORY_BUILD_DIST_SERVER_DIRECTORYNAME
$DOWNLOAD_ALL_DIRECTORY_BUILD_PROPS_FILES是我们制作的docker-linux-dotnet8.0的image中,download.sh的绝对路径。
$DIRECTORY_BUILD_DIST_SERVER_DIRECTORYNAME是我们分发Directory.Build.props及其相关文件的网站的主机名字。
4、dotnet nuget push *.$EVENT_RECORDER_VERSION_ID.nupkg -k $NUGET_API_KEY -s $NEXUS_REPO
$NEXUS_REPO就是nuget存储库的网址
$NUGET_API_KEY是nuget存储库里,用户的Api Key。有了这个key,dotnet nuget push就能在命令行里直接上传。
这里有个知识点,上述Api Key只能用于“上传”,对“下载”是没有作用的。NuGet.Config文件里面,配置登入nuget服务器,只能使用用户名和迷惑。或者把nuget服务器配置为允许匿名访问。
5、bash $DIRECTORY_BUILD_UPDATE_VERSION_SH $DIRECTORY_BUILD_DIST_SERVER_USER $DIRECTORY_BUILD_DIST_SERVER $DIRECTORY_BUILD_DIST_SERVER_DIRECTORYNAME "Directory.Build.Change.EasyComment.props" $EASY_COMMENT_VERSION_ID
$DIRECTORY_BUILD_UPDATE_VERSION_SH
就是制作docker-linux-dotnet8.0时,update-remote-version-number.sh的绝对路径
$DIRECTORY_BUILD_DIST_SERVER_USER
http服务器上的linux用户,SSH的时候要用到
$DIRECTORY_BUILD_DIST_SERVER
http服务器的IP地址或者DNS名称
$DIRECTORY_BUILD_DIST_SERVER_DIRECTORYNAME
SSH登入远程服务器后,去这个目录下操作。为了让服务器更安全,我们的docker-linux-dotnet8.0的image里面,规范(写死了)网站的集中存放的根目录,这里的参数只能写子目录的名字。
"Directory.Build.Change.EasyComment.props"
这个只有在当前stage里面才用到一次,所以没有做成变量。就是去上述目录下,操作这个具体的文件。
$EASY_COMMENT_VERSION_ID
版本号。
额外说明
为什么dotnet push的动作,放在dotnet pack的“作业”里?
因为我们可能有多个Gitlab Runner的实例,不同实例的工作目录是不同的。只有在一个“作业”里,才能去相同的$EVENT_RECORDER_NUPKG_OUTPUT_DIR目录下操作你期望的包文件。放在同一个stage里添加dependencies依赖关系都不行。
为什么更新版本号不放在dotnet push这个作业里?
因为dotnet pack出来的产品,虽然推送到了nuget存储库,但是这些包是没有经过单元测试的,难以保证质量。所以要放在“单元测试”的场景之后。
本文的.gitlab-ci.yml忽略了单元测试的场景的定义。