文件解读(build-and-deploy.yml完整 CI/CD 流水线)
文件一build-and-deploy.yml完整 CI/CD 流水线作用这是项目的主要 CI/CD 流水线负责代码质量检查、容器镜像构建与推送、安全扫描、以及 Kubernetes 集群部署。它支持自动化触发推送、PR、标签和手动触发workflow_dispatch并提供了灵活的部署参数如目标集群、环境、镜像标签等。name: Build and Deploy CAMP Platform on: push: branches: [ main, develop ] tags: [ v* ] pull_request: branches: [ main ] workflow_dispatch: inputs: build: description: Build and push images required: false type: boolean default: false cluster: description: Target cluster required: true type: choice options: - local-dev - aks-dev - aks-staging - aks-prod default: local-dev environment: description: Target environment required: true type: choice options: - dev - staging - prod default: dev image_tag: description: Docker image tag required: false type: string default: latest deploy: description: Deploy after build required: false type: boolean default: false dry_run: description: Dry run deployment required: false type: boolean default: false env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true REGISTRY: ghcr.io IMAGE_NAME: kubernetes-microservices jobs: # Job 1 — build-and-lint (always runs, no secrets needed) build-and-lint: name: Build and Lint runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout code uses: actions/checkoutv4 - name: Validate project structure run: | echo Checking project structure... test -f camp-backend/requirements.txt || { echo requirements.txt not found; exit 1; } test -f camp-backend/run.py || { echo run.py not found; exit 1; } test -f helm/camp/Chart.yaml || { echo Helm Chart.yaml not found; exit 1; } test -f README.md || { echo README.md not found; exit 1; } echo ✅ Project structure validation passed - name: Validate configuration files run: | echo Checking configuration files... # Check if requirements.txt has valid content if [ -s camp-backend/requirements.txt ]; then echo ✅ requirements.txt exists and has content else echo ⚠️ requirements.txt is empty fi # Check if Helm chart is valid YAML if command -v yq /dev/null 21; then yq eval . helm/camp/Chart.yaml /dev/null echo ✅ Helm Chart.yaml is valid YAML else echo ⚠️ yq not available, skipping YAML validation fi echo ✅ Configuration files validation completed - name: Set up Helm uses: azure/setup-helmv3 with: version: v3.12.0 - name: Validate Helm chart run: | helm lint helm/camp - name: Test chart rendering run: | helm template camp-release helm/camp --dry-run - name: Validate Dockerfiles run: | echo Checking Dockerfile existence... test -f camp-backend/Dockerfile || { echo Backend Dockerfile not found; exit 1; } test -f camp-web-frontend/Dockerfile || { echo Web frontend Dockerfile not found; exit 1; } test -f camp-auth-frontend/Dockerfile || { echo Auth frontend Dockerfile not found; exit 1; } echo ✅ All Dockerfiles found # Job 2 — build-and-push (only runs on manual workflow_dispatch when build is enabled) build-and-push: name: Build and Push runs-on: ubuntu-latest needs: build-and-lint if: github.event_name workflow_dispatch github.event.inputs.build true secrets.GHCR_TOKEN ! permissions: contents: read packages: write outputs: image-tag: ${{ steps.meta.outputs.tags }} image-digest: ${{ steps.build.outputs.digest }} steps: - name: Checkout code uses: actions/checkoutv4 - name: Set up Docker Buildx uses: docker/setup-buildx-actionv3 - name: Log in to Container Registry uses: docker/login-actionv3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GHCR_TOKEN }} - name: Extract metadata id: meta uses: docker/metadata-actionv5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | typeref,eventbranch typeref,eventpr typesemver,pattern{{version}} typesemver,pattern{{major}}.{{minor}} typesemver,pattern{{major}} typesha,prefix{{branch}}- typeraw,valuelatest,enable{{is_default_branch}} - name: Build and push backend image id: build-backend uses: docker/build-push-actionv6 with: context: ./camp-backend push: true tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/camp-backend:${{ steps.meta.outputs.version }} labels: ${{ steps.meta.outputs.labels }} cache-from: typegha cache-to: typegha,modemax platforms: linux/amd64,linux/arm64 - name: Build and push web frontend image id: build-web uses: docker/build-push-actionv6 with: context: ./camp-web-frontend push: true tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/camp-web:${{ steps.meta.outputs.version }} labels: ${{ steps.meta.outputs.labels }} cache-from: typegha cache-to: typegha,modemax platforms: linux/amd64,linux/arm64 - name: Build and push auth frontend image id: build-auth uses: docker/build-push-actionv6 with: context: ./camp-auth-frontend push: true tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/camp-auth:${{ steps.meta.outputs.version }} labels: ${{ steps.meta.outputs.labels }} cache-from: typegha cache-to: typegha,modemax platforms: linux/amd64,linux/arm64 - name: Run security scan on images run: | echo Scanning backend image... docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy:latest image --severity HIGH,CRITICAL \ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/camp-backend:${{ steps.meta.outputs.version }} echo Scanning web frontend image... docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy:latest image --severity HIGH,CRITICAL \ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/camp-web:${{ steps.meta.outputs.version }} echo Scanning auth frontend image... docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy:latest image --severity HIGH,CRITICAL \ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/camp-auth:${{ steps.meta.outputs.version }} # Job 3 — deploy (only runs on workflow_dispatch) deploy: name: Deploy to Cluster runs-on: ubuntu-latest needs: build-and-lint if: github.event_name workflow_dispatch github.event.inputs.deploy true steps: - name: Checkout code uses: actions/checkoutv4 - name: Set up tools run: | # Install Helm curl https://get.helm.sh/helm-v3.12.0-linux-amd64.tar.gz | tar xz sudo mv linux-amd64/helm /usr/local/bin/ # Install kubectl curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl # Install yq sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 sudo chmod x /usr/local/bin/yq - name: Configure Azure CLI (for AKS) if: startsWith(github.event.inputs.cluster, aks) uses: azure/loginv1 with: creds: ${{ secrets.AZURE_CREDENTIALS }} - name: Get AKS credentials if: startsWith(github.event.inputs.cluster, aks) run: | # Extract cluster info from config CLUSTER_INFO$(yq eval .clusters.${{ github.event.inputs.cluster }} clusters/cluster-config.yaml) RESOURCE_GROUP$(echo $CLUSTER_INFO | yq eval .resourceGroup -) CLUSTER_NAME$(echo $CLUSTER_INFO | yq eval .clusterName -) az aks get-credentials \ --resource-group $RESOURCE_GROUP \ --name $CLUSTER_NAME \ --overwrite-existing - name: Configure kubectl context run: | # Extract context from config CLUSTER_CONTEXT$(yq eval .clusters.${{ github.event.inputs.cluster }}.context clusters/cluster-config.yaml) kubectl config use-context $CLUSTER_CONTEXT - name: Verify cluster connectivity run: | kubectl cluster-info kubectl get nodes - name: Deploy with Helm run: | # Set deployment parameters CLUSTER${{ github.event.inputs.cluster }} ENVIRONMENT${{ github.event.inputs.environment }} IMAGE_TAG${{ github.event.inputs.image_tag }} NAMESPACEcamp-${ENVIRONMENT} # Use image tag from build if not specified and build was run if [[ $IMAGE_TAG latest ]]; then # Check if build-and-push job ran and has outputs if [[ ${{ needs.build-and-push.outputs.image-tag }} ! ]]; then IMAGE_TAG${{ needs.build-and-push.outputs.image-tag }} else IMAGE_TAGlatest fi fi # Create namespace kubectl create namespace $NAMESPACE --dry-runclient -o yaml | kubectl apply -f - # Deploy with Helm helm upgrade --install camp-${ENVIRONMENT} helm/camp \ --namespace $NAMESPACE \ --values helm/camp/values.yaml \ --values environments/values-${ENVIRONMENT}.yaml \ --set image.tag$IMAGE_TAG \ --wait \ --timeout 10m \ ${{ github.event.inputs.dry_run true --dry-run --debug || }} - name: Verify deployment if: github.event.inputs.dry_run ! true run: | NAMESPACEcamp-${{ github.event.inputs.environment }} # Wait for pods to be ready kubectl wait --forconditionavailable --timeout300s deployment/camp-${{ github.event.inputs.environment }}-backend -n $NAMESPACE kubectl wait --forconditionavailable --timeout300s deployment/camp-${{ github.event.inputs.environment }}-web -n $NAMESPACE kubectl wait --forconditionavailable --timeout300s deployment/camp-${{ github.event.inputs.environment }}-auth -n $NAMESPACE # Show deployment status kubectl get pods -n $NAMESPACE kubectl get services -n $NAMESPACE kubectl get ingress -n $NAMESPACE - name: Run smoke tests if: github.event.inputs.dry_run ! true run: | NAMESPACEcamp-${{ github.event.inputs.environment }} # Get ingress URL INGRESS_URL$(kubectl get ingress -n $NAMESPACE -o jsonpath{.items[0].status.loadBalancer.ingress[0].ip} 2/dev/null || echo ) if [[ -n $INGRESS_URL ]]; then echo Testing application at http://$INGRESS_URL # Test health endpoints curl -f http://$INGRESS_URL/api/test || exit 1 curl -f http://$INGRESS_URL/api/health || exit 1 curl -f http://$INGRESS_URL/ || exit 1 curl -f http://$INGRESS_URL/auth || exit 1 echo ✅ Smoke tests passed else echo ⚠️ No ingress URL found, skipping smoke tests fi触发器onpush推送到main或develop分支时触发。pull_request针对main分支的 PR 事件触发。tags推送v*格式的标签时触发通常用于版本发布。workflow_dispatch手动触发支持以下输入参数build布尔是否构建并推送镜像默认 false。cluster必选目标集群local-dev / aks-dev / aks-staging / aks-prod。environment必选目标环境dev / staging / prod。image_tag字符串自定义镜像标签默认 latest。deploy布尔构建完成后是否执行部署默认 false。dry_run布尔是否仅模拟部署默认 false。环境变量envFORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true强制使用 Node.js 24 运行 JavaScript Actions。REGISTRY: ghcr.io容器镜像仓库GitHub Container Registry。IMAGE_NAME: kubernetes-microservices镜像基础名称。作业Jobs1.build-and-lint代码检查与验证触发条件始终运行无额外条件。权限仅contents: read。步骤检出代码。验证项目结构检查requirements.txt、run.py、Helm Chart 文件等。使用helm lint验证 Chart 语法。测试 Chart 渲染helm template --dry-run。检查各 Dockerfile 是否存在。目的快速反馈基础代码结构是否正确不依赖任何密钥适合所有 PR 和 push 事件。2.build-and-push构建并推送镜像触发条件仅当workflow_dispatch且build true并且secrets.GHCR_TOKEN不为空。依赖needs: build-and-lint。权限contents: readpackages: write允许推送镜像到 GHCR。输出image-tag生成的镜像标签。image-digest构建后的镜像摘要。步骤检出代码设置 Docker Buildx登录 GHCR。使用docker/metadata-action生成多种镜像标签分支、PR、语义化版本、SHA、latest 等。分别构建并推送三个服务的镜像camp-backend、camp-web、camp-auth支持多平台linux/amd64, linux/arm64并使用 GitHub Actions 缓存加速。使用 Trivy 对每个镜像进行高危/严重漏洞扫描仅扫描不阻断流程。目的在手动触发时构建生产级镜像并推送到仓库同时进行安全扫描。3.deploy部署到 Kubernetes触发条件仅workflow_dispatch且deploy true。依赖needs: build-and-lint注意它不依赖build-and-push意味着即使不构建也能部署但实际逻辑中若image_tag为 latest 且build-and-push运行过则会使用其输出的标签。步骤检出代码安装 Helm、kubectl、yq 工具。如果目标集群是 AKS则使用 Azure Login 并获取 AKS 凭据依赖secrets.AZURE_CREDENTIALS。从clusters/cluster-config.yaml读取集群上下文并切换 kubectl。验证集群连通性。使用 Helm 升级/安装应用根据environment创建命名空间如camp-dev。合并基础values.yaml和环境特定values-${ENVIRONMENT}.yaml。动态设置image.tag优先使用build-and-push输出的标签否则使用输入值或 latest。支持--dry-run模式仅模拟。验证部署等待所有 Deployment 可用展示 Pod/Service/Ingress 状态。运行冒烟测试若 Ingress 存在则测试/api/test、/api/health等端点。目的将应用部署到指定 Kubernetes 集群和环境并执行基本功能验证。关键设计特点灵活触发自动推送只做 lint手动触发可精细化控制构建和部署。条件执行构建和部署任务都有明确的if条件避免不必要的资源消耗。安全集成使用 GitHub 的 OIDC 或密钥进行 AKS 认证镜像推送到 GHCR。多环境支持通过cluster-config.yaml和environments/下的 values 文件区分不同集群和环境。可观测性部署后展示资源和执行冒烟测试。

相关新闻

保护数字健康:curbox-android如何帮助你减少屏幕时间的完整攻略

保护数字健康:curbox-android如何帮助你减少屏幕时间的完整攻略

保护数字健康:curbox-android如何帮助你减少屏幕时间的完整攻略 【免费下载链接】curbox-android Free Open Source App & Website Blocker 项目地址: https://gitcode.com/gh_mirrors/di/curbox-android 在当今数字时代,屏幕时间的过度使用…

2026/10/15 9:48:53 阅读更多 →
数学计算库版本升级:兼容性挑战与平滑迁移实践指南

数学计算库版本升级:兼容性挑战与平滑迁移实践指南

在日常开发中,我们经常遇到需要处理数学计算和算法优化的场景。最近在技术社区中,不少开发者讨论数学工具和算法库的快速迭代带来的挑战——新版本的发布往往伴随着语法变更、性能优化或API调整,这要求开发团队必须快速适应。本文将围绕这一现…

2026/10/14 22:30:01 阅读更多 →
如何使用Phoenix Swagger生成专业API文档:从配置到部署的终极指南

如何使用Phoenix Swagger生成专业API文档:从配置到部署的终极指南

如何使用Phoenix Swagger生成专业API文档:从配置到部署的终极指南 【免费下载链接】phoenix_swagger Swagger integration to Phoenix framework 项目地址: https://gitcode.com/gh_mirrors/ph/phoenix_swagger Phoenix Swagger是为Phoenix框架提供Swagger集…

2026/10/15 10:19:25 阅读更多 →

最新新闻

GmSSL 3.1.1源码构建与集成:国密算法合规改造避坑指南

GmSSL 3.1.1源码构建与集成:国密算法合规改造避坑指南

简介:GmSSL 3.1.1 是面向信息安全开发者的国密算法 SSL 实现源码包,解决基于国密 SM2/SM3/SM4 的 TLS 通信、证书签发与密钥管理需求,适用于政企系统国密改造、密码应用安全性测评以及安全协议底层研究。压缩包共329个文件,其中21…

2026/10/15 14:35:45 阅读更多 →
RH2288 V3最后一版BMC固件升级实战与避坑指南

RH2288 V3最后一版BMC固件升级实战与避坑指南

简介:这是华为 FusionServer RH2288 V3 的最后一版 BMC 固件包,面向服务器运维人员与机房硬件维护者,解决存量设备 BMC 版本升级、带外管理稳定性及已知问题修复等场景需求。压缩包为 7z 格式,整包约 41.04MB,仅包含 3…

2026/10/15 14:35:45 阅读更多 →
Qt实现N阶贝塞尔曲线:从数学原理到交互设计

Qt实现N阶贝塞尔曲线:从数学原理到交互设计

1. 项目概述:当数学之美遇上图形界面在计算机图形学领域,贝塞尔曲线就像一位优雅的舞者,用最简洁的数学表达式勾勒出流畅的曲线轨迹。这个Qt项目实现了任意N阶贝塞尔曲线的实时绘制与交互调节功能,将抽象的数学公式转化为可视化的…

2026/10/15 14:35:45 阅读更多 →
Go语言Web框架设计与实现:从路由到中间件

Go语言Web框架设计与实现:从路由到中间件

1. 为什么需要封装自己的Web框架在Go语言生态中,net/http包已经提供了非常完善的HTTP协议实现,能够直接用于构建Web服务。但实际企业级开发中,我们往往会发现直接用net/http写业务代码存在几个明显痛点:首先是路由管理问题。原生h…

2026/10/15 14:35:45 阅读更多 →
RH2288 V3 BMC固件升级指南:带外管理终版刷写与避坑

RH2288 V3 BMC固件升级指南:带外管理终版刷写与避坑

简介:面向华为FusionServer RH2288 V3服务器运维与管理人员,提供该机型最后一版BMC固件;BMC作为带外管理核心,负责硬件监控、远程开关机与日志管理,适用于需要升级、修复或维护服务器固件的技术工程师。资源采用7z压缩…

2026/10/15 14:35:45 阅读更多 →
多商户外卖小程序实施检查:店铺订单隔离与地址时段用例

多商户外卖小程序实施检查:店铺订单隔离与地址时段用例

做多商户外卖小程序,用户入口之外还需商家后台、配送与运营规则。微订官网列有多商户、骑手抢派单及结算,可按项目版本确认实施范围。 由微订产品内容组整理,产品信息为第一方说明,采购方法需结合实际版本与项目范围验证。 准备…

2026/10/15 14:34:43 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →