ABP VNext + GitHub Actions:CI/CD 全流程自動化

🌟 ABP VNext + GitHub Actions:CI/CD 全流程自動化


📚 目錄

  • 🌟 ABP VNext + GitHub Actions:CI/CD 全流程自動化
    • 🤩 TL;DR
    • 🔄 全局流程概覽
    • 1?? 準備工作與項目結構
      • 1.1 🛠? 工具鏈與 Secrets
      • 1.2 📁 項目目錄示例
    • 2?? 🔨 Build & Test(并行編譯與單測)
        • 🔄 子流程圖
    • 3?? 🕵? Static Analysis(SonarCloud & CodeQL)
        • 🔄 子流程圖
    • 4?? 📦 Package & Publish(NuGet 與 Docker)
    • 5?? 🚀 Deploy to Staging(預發布環境)
    • 6?? 🏭 Deploy to Production(生產環境)
    • 7?? ? Rollback & Alert(自動回滾與告警)
      • Rollback Staging
      • Rollback Production
    • 🔧 ABP VNext 專屬集成示例
      • Program.cs 示例
      • Helm Chart 探針示例 (`charts/myapp/values.yaml`)
    • 📦 附錄:配置文件
      • sonar-project.properties
      • CodeQL 配置 (`.github/codeql/codeql-config.yml`)


🤩 TL;DR

  • 🚀 端到端流水線:Push → 并行編譯/測試 → 靜態掃描 (SonarCloud/CodeQL) → NuGet/Docker 打包 → 分環境部署 → 自動回滾
  • 🔒 嚴格審批:在 GitHub Environments 中分別為 stagingproduction 配置 Required Reviewers
  • ? 性能優化:NuGet 緩存、actions/cache、Docker Layer 緩存、并行 Jobs、Concurrency 控制
  • 🛠? 深度契合 ABP VNext:自動執行 EF Core 遷移、Swagger/UI、Health Checks 與 AKS 探針

🔄 全局流程概覽

Yes
No
Yes
No
🛎? Push 代碼
🔨 Build & Test
🕵? Static Scan
📦 Package & Publish
🚀 Deploy to Staging
? Staging OK?
🏭 Deploy to Production
? Rollback Staging
? Production OK?
🎉 完成
? Rollback Production

1?? 準備工作與項目結構

1.1 🛠? 工具鏈與 Secrets

在倉庫 Settings → Secrets 添加以下憑據:

  • AZURE_CREDENTIALS:Azure Service Principal JSON(az ad sp create-for-rbac … --sdk-auth
  • NUGET_API_KEY:NuGet.org 發布 Key
  • SONAR_TOKEN:SonarCloud Access Token
  • SLACK_WEBHOOK_URL:Slack Incoming Webhook URL
  • GITHUB_TOKEN(Actions 內置,用于 GHCR)

🎯 示例 CLI:

az ad sp create-for-rbac \--name "abp-ci-sp" \--role contributor \--scopes /subscriptions/<SUB_ID>/resourceGroups/<RG_NAME> \--sdk-auth > azure-credentials.json

1.2 📁 項目目錄示例

.
├─ .github/workflows/ci-cd.yml
├─ src/
│    ├─ MyApp.Domain/
│    ├─ MyApp.Application/
│    ├─ MyApp.EntityFrameworkCore/
│    └─ MyApp.HttpApi.Host/
└─ tests/└─ MyApp.Tests/

2?? 🔨 Build & Test(并行編譯與單測)

📝 本 Job 目標:并行 Restore/Build/Test,上傳測試報告

build-test:name: 🔨 Build & Testruns-on: ubuntu-lateststrategy:matrix:dotnet-version: ['8.0.x']steps:- name: Checkout Codeuses: actions/checkout@v3- name: Cache NuGet packagesuses: actions/cache@v3with:path: ~/.nuget/packageskey: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}restore-keys: ${{ runner.os }}-nuget-- name: Setup .NET SDKuses: actions/setup-dotnet@v3with:dotnet-version: ${{ matrix.dotnet-version }}cache: true- name: Restore Dependenciesrun: dotnet restore src/MyApp.sln --locked-mode- name: Build Solutionrun: dotnet build src/MyApp.sln --no-restore --configuration Release- name: Run Unit Testsrun: dotnet test tests/MyApp.Tests/MyApp.Tests.csproj \--no-build --configuration Release --logger "trx"- name: Upload Test Resultsuses: actions/upload-artifact@v3with:name: test-resultspath: '**/*.trx'retention-days: 7
🔄 子流程圖
? Checkout
🗄? Cache NuGet
📦 Setup SDK
🔄 Restore
🏗? Build
🧪 Test
💾 Upload Artifacts

3?? 🕵? Static Analysis(SonarCloud & CodeQL)

📝 本 Job 目標:Shift‐Left 質量與安全保障

static-scan:name: 🕵? Static Analysisruns-on: ubuntu-latestneeds: build-teststrategy:matrix:tool: ['sonarcloud','codeql']steps:- name: Checkout Full Historyuses: actions/checkout@v3with:fetch-depth: 0# SonarCloud- if: matrix.tool == 'sonarcloud'name: SonarCloud Prepareuses: SonarSource/sonarcloud-github-action@v1.9.0- if: matrix.tool == 'sonarcloud'name: Build for SonarCloudrun: dotnet build src/MyApp.sln --configuration Release- if: matrix.tool == 'sonarcloud'name: SonarCloud Publishuses: SonarSource/sonarcloud-github-action@v1.9.0# CodeQL- if: matrix.tool == 'codeql'name: Initialize CodeQLuses: github/codeql-action/init@v2with:languages: csharpconfig-file: .github/codeql/codeql-config.yml- if: matrix.tool == 'codeql'name: Autobuilduses: github/codeql-action/autobuild@v2- if: matrix.tool == 'codeql'name: Perform CodeQL Analysisuses: github/codeql-action/analyze@v2
🔄 子流程圖
SonarCloud
CodeQL
👥 Checkout
🔍 Tool?
📊 Run SonarCloud
?? Init CodeQL
🚧 Autobuild
🔎 Analyze

4?? 📦 Package & Publish(NuGet 與 Docker)

📝 本 Job 目標:僅在 Push 時執行包與鏡像發布

package-publish:name: 📦 Package & Publishif: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop')runs-on: ubuntu-latestneeds: static-scansteps:- name: Checkout Codeuses: actions/checkout@v3# NuGet- name: Pack NuGet Packagerun: dotnet pack src/MyApp.Application/MyApp.Application.csproj \--no-build -o ./artifacts- uses: NuGet/setup-nuget@v2- name: Push to NuGet.orgrun: dotnet nuget push ./artifacts/*.nupkg \--api-key ${{ secrets.NUGET_API_KEY }} \--source https://api.nuget.org/v3/index.json# Docker (GHCR)- name: Login to GHCRuses: docker/login-action@v3with:registry: ghcr.iousername: ${{ github.repository_owner }}password: ${{ secrets.GITHUB_TOKEN }}- name: Build & Push Docker Imageuses: docker/build-push-action@v4with:context: src/MyApp.HttpApi.Hostfile: src/MyApp.HttpApi.Host/Dockerfilepush: truetags: |ghcr.io/${{ github.repository_owner }}/myapp:${{ github.sha }}ghcr.io/${{ github.repository_owner }}/myapp:latestcache-from: type=gha,scope=src-MyApp.HttpApi.Hostcache-to: type=gha,mode=max,scope=src-MyApp.HttpApi.Host

5?? 🚀 Deploy to Staging(預發布環境)

📝 本 Job 目標:在 develop 分支推送時執行,需審批

deploy-staging:name: 🚀 Deploy to Stagingruns-on: ubuntu-latestneeds: package-publishif: github.ref == 'refs/heads/develop'environment: stagingsteps:- name: Azure Loginuses: azure/login@v1with:creds: ${{ secrets.AZURE_CREDENTIALS }}- name: Set AKS Contextuses: azure/aks-set-context@v2with:creds: ${{ secrets.AZURE_CREDENTIALS }}cluster-name: myClusterresource-group: myRG- name: Install EF CLIrun: |dotnet tool install --global dotnet-ef --version 8.* echo "$HOME/.dotnet/tools" >> $GITHUB_PATH- name: Run EF Core Migrationsrun: dotnet ef database update \--project src/MyApp.EntityFrameworkCore/MyApp.EntityFrameworkCore.csproj \--startup-project src/MyApp.HttpApi.Host/MyApp.HttpApi.Host.csproj \--configuration Release- name: Helm Upgrade (Staging)run: |helm upgrade myapp-staging ./charts/myapp \--namespace staging --install \--set image.tag=${{ github.sha }}

6?? 🏭 Deploy to Production(生產環境)

📝 本 Job 目標:在 main 分支推送時執行,需審批

deploy-prod:name: 🏭 Deploy to Productionruns-on: ubuntu-latestneeds: deploy-stagingif: github.ref == 'refs/heads/main'environment: productionsteps:- name: Azure Loginuses: azure/login@v1with:creds: ${{ secrets.AZURE_CREDENTIALS }}- name: Set AKS Contextuses: azure/aks-set-context@v2with:creds: ${{ secrets.AZURE_CREDENTIALS }}cluster-name: myClusterresource-group: myRG- name: Helm Upgrade (Production)run: |helm upgrade myapp-prod ./charts/myapp \--namespace prod --install \--set image.tag=${{ github.sha }}

7?? ? Rollback & Alert(自動回滾與告警)

Rollback Staging

rollback-staging:name: ? Rollback & Notify (Staging)if: failure() && github.ref == 'refs/heads/develop'runs-on: ubuntu-latestneeds: deploy-stagingsteps:- name: Determine Last Successful Revisionid: histrun: |rev=$(helm history myapp-staging -n staging --max 5 \--output json | jq -r '.[] | select(.status=="DEPLOYED") | .revision' | tail -1)if [[ -z "$rev" || "$rev" -le 0 ]]; thenecho "No valid revision to rollback"; exit 1fiecho "::set-output name=revision::$rev"- name: Helm Rollback (Staging)run: helm rollback myapp-staging ${{ steps.hist.outputs.revision }} -n staging- name: Slack Notificationuses: rtCamp/action-slack-notify@v2with:webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}message: ":warning: Staging 部署失敗,已回滾到 revision ${{ steps.hist.outputs.revision }}"

Rollback Production

rollback-prod:name: ? Rollback & Notify (Production)if: failure() && github.ref == 'refs/heads/main'runs-on: ubuntu-latestneeds: deploy-prodsteps:- name: Determine Last Successful Revisionid: histrun: |rev=$(helm history myapp-prod -n prod --max 5 \--output json | jq -r '.[] | select(.status=="DEPLOYED") | .revision' | tail -1)if [[ -z "$rev" || "$rev" -le 0 ]]; thenecho "No valid revision to rollback"; exit 1fiecho "::set-output name=revision::$rev"- name: Helm Rollback (Production)run: helm rollback myapp-prod ${{ steps.hist.outputs.revision }} -n prod- name: Slack Notificationuses: rtCamp/action-slack-notify@v2with:webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}message: ":x: Production 部署失敗,已回滾到 revision ${{ steps.hist.outputs.revision }}"

🔧 ABP VNext 專屬集成示例

Program.cs 示例

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddApplication<MyAppHttpApiHostModule>();
builder.Host.UseAutofac();var app = builder.Build();
app.UseAbpRequestLocalization();
app.UseAbpSwaggerUI(options =>
{options.SwaggerEndpoint("/swagger/v1/swagger.json", "MyApp API V1");
});
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapHealthChecks("/health");
app.MapHealthChecks("/health/ready", new HealthCheckOptions
{Predicate = reg => reg.Name.Contains("ready")
});
app.Run();

Helm Chart 探針示例 (charts/myapp/values.yaml)

livenessProbe:httpGet:path: /healthport: httpinitialDelaySeconds: 30readinessProbe:httpGet:path: /health/readyport: httpinitialDelaySeconds: 10

📦 附錄:配置文件

sonar-project.properties

sonar.projectKey=<YOUR_PROJECT_KEY>
sonar.organization=<YOUR_ORGANIZATION>
sonar.sources=src
sonar.tests=tests
sonar.dotnet.visualstudio.solution.file=src/MyApp.sln

CodeQL 配置 (.github/codeql/codeql-config.yml)

queries:- security-and-quality- security-and-performance

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/89729.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/89729.shtml
英文地址,請注明出處:http://en.pswp.cn/web/89729.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Elasticsearch 重命名索引

作者&#xff1a;來自 Elastic Alex Salgado 學習如何使用四種實用方法在 Elasticsearch 中重命名索引。 想獲得 Elastic 認證&#xff1f;看看下一期 Elasticsearch Engineer 培訓什么時候開始&#xff01; Elasticsearch 擁有豐富的新功能&#xff0c;幫助你根據使用場景構建…

高通8255 Android Virtio Virtio-SPI 配置方法

目錄 一&#xff1a;VirtIO和Passthrough的區別 二&#xff1a;配置邏輯 三&#xff1a;配置方法 步驟一&#xff1a;QNX SPI資源配置 & 測試 配置 測試 步驟二&#xff1a;BE配置 &測試 配置 測試 步驟三&#xff1a;Hypervisor配置 配置 測試 步驟四&…

從零手寫紅黑樹(C++實現詳解)

目錄 一、紅黑樹概述 二、紅黑樹節點設計 (1)枚舉紅黑 &#xff08;2&#xff09;紅黑樹的節點設計 三、紅黑樹核心實現:Insert 1.首先將節點遍歷到對應位置創建對應節點并插入到二叉搜索樹對應的位置 2.本文重點的重點 &#xff08;1&#xff09;parent為黑時直接插入即…

【黃山派-SF32LB52】—硬件原理圖學習筆記

目錄 一、硬件介紹 二、芯片主控 1.模組介紹 2.原理圖介紹 3.模組供電電路 三、電源轉換部分 1.OVP過壓保護電路 2.CHG充電電路 3.系統電源橋接電路 4.LDO電路 四、Debug電路 1.一鍵下載電路 五、QSPI屏幕 六、SD卡 七、AUDIO音頻 八、GPIO電路 1.按鍵部分…

從五次方程到計算機:數學抽象如何塑造現代計算

引言 數學的發展往往始于一個具體的問題&#xff0c;而后在尋求解答的過程中&#xff0c;催生出深刻的抽象理論。從五次方程的求解到抽象代數&#xff0c;再到范疇論和λ演算&#xff0c;最終影響圖靈機和現代計算機的設計&#xff0c;這一歷程展現了數學如何從實際問題演變為通…

劇本殺小程序開發:科技賦能,重塑推理娛樂新形態

在科技飛速發展的今天&#xff0c;各個行業都在積極探索與科技的融合&#xff0c;以實現創新發展。劇本殺行業也不例外&#xff0c;劇本殺小程序的開發&#xff0c;正是科技賦能傳統娛樂的生動體現&#xff0c;它重塑了推理娛樂的新形態&#xff0c;為玩家帶來了前所未有的游戲…

機器學習sklearn入門:歸一化和標準化

bg&#xff1a;歸一化&#xff08;Normalization&#xff09;通常指將數據按比例縮放至某個特定范圍&#xff0c;但具體范圍并不一定是固定的 0到1。標準化是將數據轉換成均值為0&#xff0c;標準差為1的分布。使用場景&#xff1a;用歸一化&#xff1a;需要嚴格限定范圍&#…

【Project】kafka+flume+davinci廣告點擊實時分析系統

一、項目需求分析 某電商平臺需實現廣告實時點擊分析系統&#xff0c;核心需求為實時統計以下內容的Top10&#xff1a; 各個廣告的點擊量各個省份的廣告點擊量各個城市的廣告點擊量 通過實時掌握廣告投放效果&#xff0c;為廣告投放策略調整和大規模投入提供依據&#xff0c;以…

JAVA后端開發——success(data) vs toAjax(rows): 何時用

toAjax(int rows)用途&#xff1a;用于不返回任何數據的 “寫” 操作&#xff08;增、刪、改&#xff09;。工作原理&#xff1a;它只接收一個 int 類型的參數&#xff08;通常是數據庫操作影響的行數&#xff09;。它只關心這個數字是不是大于0&#xff0c;然后返回一個通用的…

pdf格式怎么提取其中一部分張頁?

想從PDF里提取幾個頁面&#xff0c;辦法還挺多的&#xff0c;下面給你嘮嘮常見的幾種&#xff0c;保準你一看就懂。一、用專業PDF編輯軟件提取 像Adobe Acrobat&#xff0c;這可是PDF編輯界的“老手”了。你先把要處理的PDF文件在Adobe Acrobat里打開&#xff0c;接著找到菜單欄…

Spring監聽器

1、監聽器的原理 ApplicationListener<T>是Spring框架中基于觀察者模式實現的事件監聽接口&#xff0c;用于監聽應用程序中特定類型的事件。該接口是一個函數式接口&#xff0c;從Spring 4.2開始支持Lambda表達式實現。 接口定義如下&#xff1a; FunctionalInterface …

基于Rust游戲引擎實踐(Game)

Rust游戲引擎推薦 以下是一些流行的Rust游戲引擎,適用于不同開發需求: Bevy 特點:數據驅動、模塊化設計,支持ECS架構,適合初學者和復雜項目。 適用場景:2D/3D游戲、原型開發。 Amethyst 特點:成熟的ECS框架,支持多線程,社區活躍。 適用場景:大型游戲或高性能應用。…

PyTorch 數據加載實戰:從 CSV 到圖像的全流程解析

目錄 一、PyTorch 數據加載的核心組件 1.1 Dataset 類的核心方法 1.2 DataLoader 的作用 二、加載 CSV 數據實戰 2.1 自定義 CSV 數據集 2.2 使用 TensorDataset 快速加載 三、加載圖像數據實戰 3.1 自定義圖像數據集 3.2 使用 ImageFolder 快速加載 四、加載官方數據…

程序人生,開啟2025下半年

時光匆匆&#xff0c;2025年已然過去一半。轉眼來到了7月份。 回望過去上半年&#xff0c;可能你也經歷了職場的浮沉、生活的跌宕、家庭的變故。 而下半年&#xff0c;生活依舊充滿了各種變數。 大環境的起起伏伏、生活節奏的加快&#xff0c;都讓未來的不確定性愈發凸顯。 在這…

在 .NET Core 中創建 Web Socket API

要在 ASP.NET Core 中創建 WebSocket API&#xff0c;您可以按照以下步驟操作&#xff1a;設置新的 ASP.NET Core 項目打開 Visual Studio 或您喜歡的 IDE。 創建一個新的 ASP.NET Core Web 應用程序項目。 選擇API模板&#xff0c;因為這將成為您的 WebSocket API 的基礎。在啟…

Python 之地址編碼識別

根據輸入地址&#xff0c;利用已有的地址編碼文件&#xff0c;構造處理規則策略識別地址的編碼。 lib/address.json 地址編碼文件&#xff08;這個文件太大&#xff0c;博客里放不下&#xff0c;需要的話可以到 gitcode 倉庫獲取&#xff1a;https://gitcode.com/TomorrowAndT…

kafka的部署

目錄 一、kafka簡介 1.1、概述 1.2、消息系統介紹 1.3、點對點消息傳遞模式 1.4、發布-訂閱消息傳遞模式 二、kafka術語解釋 2.1、結構概述 2.2、broker 2.3、topic 2.4、producer 2.5、consumer 2.6、consumer group 2.7、leader 2.8、follower 2.9、partition…

小語種OCR識別技術實現原理

小語種OCR&#xff08;光學字符識別&#xff09;技術的實現原理涉及計算機視覺、自然語言處理&#xff08;NLP&#xff09;和深度學習等多個領域的融合&#xff0c;其核心目標是讓計算機能夠準確識別并理解不同語言的印刷或手寫文本。以下是其關鍵技術實現原理的詳細解析&#…

GPT:讓機器擁有“創造力”的語言引擎

當ChatGPT寫出莎士比亞風格的十四行詩&#xff0c;當GitHub Copilot自動生成編程代碼&#xff0c;背后都源于同一項革命性技術——**GPT&#xff08;Generative Pre-trained Transformer&#xff09;**。今天&#xff0c;我們將揭開這項“語言魔術”背后的科學原理&#xff01;…

LeetCode|Day19|14. 最長公共前綴|Python刷題筆記

LeetCode&#xff5c;Day19&#xff5c;14. 最長公共前綴&#xff5c;Python刷題筆記 &#x1f5d3;? 本文屬于【LeetCode 簡單題百日計劃】系列 &#x1f449; 點擊查看系列總目錄 >> &#x1f4cc; 題目簡介 題號&#xff1a;14. 最長公共前綴 難度&#xff1a;簡單…