1 什麼是 CI/CD?
1.1 CI(Continuous Integration)持續集成
又叫持續整合,是將所有軟件工程師對於軟件的工作副本持續集成到共享主線(mainline)的一種軟件工程流程。
1.2 CD(Continuous Delivery)持續交付
是一種軟件工程手法,讓軟件產品的產出過程在一個短週期內完成,以保證軟件可以穩定、持續的保持在隨時可以釋出的狀況。
1.3 CD(Continuous Deployment)持續部署
是一種軟件工程方法,意指在軟件開發流程中,以自動化方式,頻繁而且持續性的,將軟件部署到生產環境(production environment)中,使軟件產品能夠快速的發展。
從上面可以看出,持續交付和持續部署的主要區別在於:最後部署到生產環境的步驟是“手動”還是“自動”。持續部署意味着所有的變更都會被自動部署到生產環境中。持續交付意味着所有的變更都可以被部署到生產環境中,但是出於業務考慮,可以選擇不部署。如果要實施持續部署,必須先實施持續交付。
2 實現的目標
本地推送代碼到 Github 後,通過其提供的 Actions CI/CD 功能,將代碼進行構建並打包成 Docker 鏡像,最後推送到 Docker Hub 倉庫。
3 所需資源
3.1 環境
3.2 工具
- VS Code、Visual Studio、或Visual Studio for Mac,也可以選擇其他 IDE 或直接使用 .NET Core SDK CLI 提供的命令。
- Git
3.3 相關賬號
4 實現步驟
4.1 項目準備
4.1.1 在 Github 創建倉庫
登錄 Github 並點擊 New 按鈕進入創建倉庫界面,輸入倉庫“名稱”和“描述”後點擊 “Create repository” 按鈕即可創建一個新倉庫。
4.1.2 克隆項目到本地
在 Code 選項卡下,點擊 “Clone or download” 下拉箭頭,並點擊下圖中的複製按鈕複製倉庫地址。
使用 git clone
命令將倉庫克隆到本地,執行過程如下所示:
thiscoder@ThisCoder Desktop % git clone https://github.com/li2008kui/cicd-test.git
Cloning into 'cicd-test'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), done.
4.1.3 創建 .Net Core 項目
- 創建項目
使用cd cicd-test
命令進入上面克隆的 Git 倉庫目錄中,並通過dotnet new webapi
命令創建一個 .Net Core 項目,執行過程如下所示:
thiscoder@ThisCoder cicd-test % dotnet new webapi -f netcoreapp3.1
The template "ASP.NET Core Web API" was created successfully.
Processing post-creation actions...
Running 'dotnet restore' on /Users/thiscoder/Desktop/cicd-test/cicd-test.csproj...
Determining projects to restore...
Restored /Users/thiscoder/Desktop/cicd-test/cicd-test.csproj (in 150 ms).
Restore succeeded.
由於筆者安裝了 .Net 5 預覽版,而本文使用的是 .Net Core 3.1,所以通過 -f
指定 framework 版本爲 netcoreapp3.1。
-
去除https支持
使用code .
命令將項目在 VS Core 中打開並進行編輯:
在 Startup.cs 文件的 Configure 方法中將app.UseHttpsRedirection();
代碼進行註釋或刪除;在 Properties 文件夾中,將 launchSettings.json 啓動配置文件中的
"applicationUrl": "https://localhost:5001;http://localhost:5000",
修改爲"applicationUrl": "http://localhost:5000"
。 -
運行項目
使用dotnet run
命令運行項目,執行過程如下所示:
thiscoder@ThisCoder cicd-test % dotnet run
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: /Users/thiscoder/Desktop/cicd-test
如果安裝了 curl 工具,可以新建一個終端並使用 curl http://localhost:5000/WeatherForecast
命令查看運行,如果運行正常,將看類似以下結果:
thiscoder@ThisCoder ~ % curl http://localhost:5000/WeatherForecast
[{"date":"2020-04-20T13:10:40.471571+08:00","temperatureC":6,"temperatureF":42,"summary":"Hot"},{"date":"2020-04-21T13:10:40.471592+08:00","temperatureC":32,"temperatureF":89,"summary":"Chilly"},{"date":"2020-04-22T13:10:40.471593+08:00","temperatureC":-4,"temperatureF":25,"summary":"Sweltering"},{"date":"2020-04-23T13:10:40.471593+08:00","temperatureC":-2,"temperatureF":29,"summary":"Balmy"},{"date":"2020-04-24T13:10:40.471594+08:00","temperatureC":33,"temperatureF":91,"summary":"Chilly"}]%
也可以直接在瀏覽器中訪問 http://localhost:5000/WeatherForecast
地址查看結果:
[{"date":"2020-04-20T13:07:37.377716+08:00","temperatureC":36,"temperatureF":96,"summary":"Sweltering"},{"date":"2020-04-21T13:07:37.385056+08:00","temperatureC":3,"temperatureF":37,"summary":"Freezing"},{"date":"2020-04-22T13:07:37.385062+08:00","temperatureC":5,"temperatureF":40,"summary":"Mild"},{"date":"2020-04-23T13:07:37.385062+08:00","temperatureC":38,"temperatureF":100,"summary":"Mild"},{"date":"2020-04-24T13:07:37.385063+08:00","temperatureC":-7,"temperatureF":20,"summary":"Warm"}]
結束運行使用Ctrl+C
快捷鍵即可。
4.2 添加 Dockerfile 文件
在 Visual Studio 解決方案中的項目上右鍵單擊,點擊“添加”菜單下的“添加 Docker 支持”,如下圖所示:
將會生成支持 Docker 的相關文件,其中的 Dockerfile 文件內容如下所示:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY cicd-test.csproj ./
RUN dotnet restore "./cicd-test.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "cicd-test.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "cicd-test.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "cicd-test.dll"]
4.3 推送代碼到 Github
使用 git add .
命令將代碼添加到暫存區,並使用 git commit -m "create project"
命令進行提交,最後通過 git push
將代碼推送至 Github 倉庫。如果一切順利,將會看到類似如下提示:
thiscoder@ThisCoder cicd-test % git push
Counting objects: 18, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (17/17), done.
Writing objects: 100% (18/18), 4.73 KiB | 1.58 MiB/s, done.
Total 18 (delta 0), reused 0 (delta 0)
To https://github.com/li2008kui/cicd-test.git
6c10d67..2515640 master -> master
4.4 設置 Secrets
在 Github 倉庫的 Settings 界面中,找到 Secrets 選項卡,點擊 Add a new secret
添加 DOCKER_USERNAME
和DOCKER_PASSWORD
機密變量,該變量爲你登錄 Docker 的用戶名和密碼。
4.5 添加 YML 文件
在 Github 倉庫的 Actions 界面中,我們使用默認提供的 .NET Core CI/CD 工作流模板。
點擊上圖中的 “Set up this workflow” 按鈕,將會準備創建一個 dotnetcore.yml 文件,我們將其內容修改如下:
name: .NET Core CI/CD Test
on: push
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.101
- name: Docker Build & Push to Docker Hub
uses: opspresso/action-docker@master
with:
args: --docker
env:
USERNAME: ${{ secrets.DOCKER_USERNAME }}
PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKERFILE: "Dockerfile"
IMAGE_NAME: "li2008kui/cicd-test"
TAG_NAME: "v0.0.1"
LATEST: "true"
其中 ${{ secrets.DOCKER_USERNAME }}
和 ${{ secrets.DOCKER_PASSWORD }}
用於引用在 Secrets 中設置的機密變量,IMAGE_NAME
請填寫自己的 Docker Hub 用戶名和鏡像名稱,TAG_NAME
爲鏡像版本號。內容修改完成後,點擊 Start commit
按鈕,然後點擊 Commit new file
按鈕即可創建用於 CI/CD 的 YML 文件。
同時,Github 將按照 YML 文件構建並打包 Docker 鏡像,然後將其推送到 Docker Hub 鏡像倉庫中,整個過程大概需要1~2分鐘左右。如果上述過程全部執行正確,登錄 Docker Hub 鏡像倉庫可以看到如下圖所示的結果:
後續你的每一次 git push
都將上述構建打包過程。接下來,你可以使用類似 docker run -p 8080:8080 li2008kui/cicd-test
這樣的命令拉取鏡像到本地並運行。