如何利用 GitHub Actions、Docker 和 Google Cloud Run 学习持续集成与持续交付 CI/CD

如何利用 GitHub Actions、Docker 和 Google Cloud Run 学习持续集成与持续交付(CI/CD)

大家好!如果你身处技术领域,一定听过类似持续集成(Continuous Integration,CI)、持续交付(Continuous Delivery,CD)和持续部署(Continuous Deployment)这样的术语,也大概率接触过自动化流水线(pipeline)、测试环境(staging)、生产环境(production)以及测试流程(workflow)等概念。

起初,这些名词可能显得有点复杂,或者彼此之间的区别不够明确,让你困惑:它们究竟是什么意思?彼此之间有何差异?

在这篇文章中,我将用通俗易懂的方式分解这些概念,帮助你在脑海中建立清晰的图景。随后,我们会进行一次实战演练,手把手教你如何一步步搭建一个 CI/CD 工作流

我们会一起完成:

  • 搭建一个 Node.js 项目 ✨
  • 使用 Jest 和 Supertest 实现自动化测试 🛠️
  • 使用 GitHub Actions 设置 CI/CD 工作流,并在 push、pull request 或新发布版本时触发 ⚙️
  • 构建并将应用的 Docker 镜像发布到 Docker Hub 📦
  • 将应用部署到测试环境(staging)中进行验证 🚀
  • 最后,部署到生产环境(production),正式上线 🌐

读完本文后,你不仅能理解 CI/CD 概念间的区别,还能亲手为自己的项目搭建一条自动化交付流水线。😃

目录

  1. 什么是持续集成、持续交付和持续部署?
  2. 持续集成、持续交付和持续部署的差异
  3. [如何搭建一个带自动化测试的 Node.js 项目](#如何搭建一个带自动化测试的 Node.js 项目 "#%E5%A6%82%E4%BD%95%E6%90%AD%E5%BB%BA%E4%B8%80%E4%B8%AA%E5%B8%A6%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95%E7%9A%84-nodejs-%E9%A1%B9%E7%9B%AE")
  4. [如何创建 GitHub 仓库来托管代码](#如何创建 GitHub 仓库来托管代码 "#%E5%A6%82%E4%BD%95%E5%88%9B%E5%BB%BA-github-%E4%BB%93%E5%BA%93%E6%9D%A5%E6%89%98%E7%AE%A1%E4%BB%A3%E7%A0%81")
  5. [如何在项目中设置 CI 与 CD 工作流](#如何在项目中设置 CI 与 CD 工作流 "#%E5%A6%82%E4%BD%95%E5%9C%A8%E9%A1%B9%E7%9B%AE%E4%B8%AD%E8%AE%BE%E7%BD%AE-ci-%E4%B8%8E-cd-%E5%B7%A5%E4%BD%9C%E6%B5%81")
  6. [为项目在 Docker Hub 创建镜像仓库并生成访问令牌](#为项目在 Docker Hub 创建镜像仓库并生成访问令牌 "#%E4%B8%BA%E9%A1%B9%E7%9B%AE%E5%9C%A8-docker-hub-%E5%88%9B%E5%BB%BA%E9%95%9C%E5%83%8F%E4%BB%93%E5%BA%93%E5%B9%B6%E7%94%9F%E6%88%90%E8%AE%BF%E9%97%AE%E4%BB%A4%E7%89%8C")
  7. [创建 Google Cloud 账户、项目和付费账户(Billing Account)](#创建 Google Cloud 账户、项目和付费账户(Billing Account) "#%E5%88%9B%E5%BB%BA-google-cloud-%E8%B4%A6%E6%88%B7%E9%A1%B9%E7%9B%AE%E5%92%8C%E4%BB%98%E8%B4%B9%E8%B4%A6%E6%88%B7billing-account")
  8. [创建 Google Cloud 服务账号,实现将 Node.js 应用部署到 Google Cloud Run](#创建 Google Cloud 服务账号,实现将 Node.js 应用部署到 Google Cloud Run "#%E5%88%9B%E5%BB%BA-google-cloud-%E6%9C%8D%E5%8A%A1%E8%B4%A6%E5%8F%B7%E5%AE%9E%E7%8E%B0%E5%B0%86-nodejs-%E5%BA%94%E7%94%A8%E9%83%A8%E7%BD%B2%E5%88%B0-google-cloud-run")
  9. [创建 Staging 分支并将 Feature 分支合并进入(CI + CD)](#创建 Staging 分支并将 Feature 分支合并进入(CI + CD) "#%E5%88%9B%E5%BB%BA-staging-%E5%88%86%E6%94%AF%E5%B9%B6%E5%B0%86-feature-%E5%88%86%E6%94%AF%E5%90%88%E5%B9%B6%E8%BF%9B%E5%85%A5ci--cd")
  10. [将 Staging 分支合并到 Main 分支(CI + CD)](#将 Staging 分支合并到 Main 分支(CI + CD) "#%E5%B0%86-staging-%E5%88%86%E6%94%AF%E5%90%88%E5%B9%B6%E5%88%B0-main-%E5%88%86%E6%94%AFci--cd")
  11. 总结

什么是持续集成、持续交付和持续部署?

持续集成(Continuous Integration,CI)

想象你所在的团队有 6 个开发者在同一个项目中协作。如果没有合理的管理方式,就会乱作一团:

  • A 同事在做登录功能
  • B 同事在修复搜索栏的 Bug
  • C 同事在修改仪表盘 UI

所有人都在修改同一个"文件夹"(代码库),很容易出现"谁刚才又把应用搞崩了?"的混乱局面。😱

为避免这种情况,团队会使用像 GitHub、GitLab、BitBucket 等版本控制系统(VCS),它就像一个数字化协作空间,允许每个人独立工作,不会互相干扰。

持续集成在其中扮演重要角色:

  1. Main 分支:又称"主分支",是最终且稳定的代码库,一般对应线上生产环境。只有通过测试和审核的代码才会合并到这里。
  2. Feature 分支:当 A 同事要开发新功能时,会从 main 分支拉取一个 feature 分支,在这里开发、测试,不影响主分支。B、C 等人也各自拥有自己的 feature 分支。
  3. 合并流程
    • 在 feature 分支开发完毕后,A 不会直接将代码粗暴地合入主分支,而是会发起合并请求(Pull Request)。
    • 此时 CI 工具会自动拉起测试流程。比如跑自动化测试、构建校验等。如果测试通过,就可以安全地合并到主分支。若不通过,则说明有 Bug,需要继续修复。

这种不断将新功能分支合并回主分支并进行自动检测的过程,就叫做持续集成。

持续交付(Continuous Delivery,CD)

持续交付常常和持续部署(Continuous Deployment)混淆,虽然它们确实很相似,但各自扮演的角色有所不同。

为了理解持续交付,让我们先看看为什么需要一个中间环境(staging)

在前面的持续集成环节中,我们主要关注了 feature 分支与主分支的合并与测试。但如果直接把 feature 分支合并到主分支,然后立刻上线到真实用户环境,还是有风险------因为自动化测试并不万能,仍可能有各种边界情况或 Bug 被忽略。这就是为什么需要 staging 分支和一个测试环境

  • Staging 分支:在将功能上线之前,先合并到 staging 分支并部署到"预发布环境"(staging environment)。
  • 预发布环境:是一个几乎与生产环境一致的测试环境,QA(质量保证)团队会在这里手动测试功能,检查使用体验、潜在 Bug 以及自动测试可能漏掉的问题。
  • 持续交付:指的就是把通过 CI 流程的代码部署到预发布环境的过程。与持续部署不同的是,持续交付在最终生产环境上线之前,往往需要人工审批或测试团队验证,通过后才会正式部署到生产环境。

持续部署(Continuous Deployment,CD)

持续部署可以说是自动化的极致。在这里,与持续交付最大的不同在于:没有额外的人工审批

当 staging 环境的测试都顺利通过后,系统会自动将改动部署到生产环境,对应真正的线上用户可访问的网站。

  • 最后一步(部署到线上)不再需要人工点击"确认",只要满足设定条件(比如 PR 合并到 main 分支,或发布了一个新版本),管道会自动执行从构建、测试到最终部署的过程。对团队来说,这大大节省了时间,但也需要对测试、监控和回滚机制有足够信心,才能放心地做到完全自动化。

持续集成、持续交付和持续部署的差异

方面 持续集成(CI) 持续交付(CD) 持续部署(CD)
主要关注点 将 feature 分支合并到 main / staging 等公共分支 将测试通过的代码部署到预发布环境(staging)供 QA 测试 自动部署到生产环境,无需人工审批
自动化程度 自动化测试和构建 自动化部署到测试环境 完全自动化部署到生产
测试范围 在合并到 main / staging 前进行自动化测试 自动化测试 + QA 手动测试 也会进行自动化测试,但无人工审批,直接上线
涉及的分支 feature 分支 -> main / staging staging 分支 -> 预发布环境 main 分支 -> 生产环境
目标环境 本地或构建流水线中模拟的环境 预发布环境(与生产相似) 生产环境(真正在用户端运行)
审批流程 不需要(测试通过即可合并) 需要 QA 或其他人员验收后再上线 不需要,完全自动化上线
示例触发 开发者合并 feature 分支到 main / staging staging 分支通过自动测试后部署到测试环境 当有新 release 或合并到 main 时自动上线

如何搭建一个带自动化测试的 Node.js 项目

我们将创建一个带有 Jest 自动化测试的 Node.js Web 服务器。然后使用 GitHub Actions 配置 CI/CD 流水线,让每次向 staging、main 分支发起的 Pull Request 都自动化测试。如果测试通过,就会构建并推送镜像到 Docker Hub,最后再部署到 Google Cloud Run(先部署到 staging 测试,再部署到生产)。

准备好了吗?让我们开始吧。🚀

第 1 步:安装 Node.js

  1. 访问 Node.js 官网
  2. 选择对应的操作系统(Windows、macOS 或 Linux),下载并安装。
  3. 安装完成后,打开终端执行 node -v,查看是否正确安装。

第 2 步:克隆示例仓库

我们会使用一个预先准备好的代码模板。

  1. 如果本地还没安装 Git,请先从 Git 官方下载

  2. 完成后,在终端执行:

    bash 复制代码

git clone --single-branch --branch initial github.com/onukwilip/c... cd ci-cd-tutorial

perl 复制代码
这样就会把项目下载到本地。

### 第 3 步:安装依赖

在项目目录下,运行:

```bash
npm install --force

第 4 步:运行自动化测试

在项目目录执行:

bash 复制代码
npm test

如果看到 2 个测试通过的结果,就说明测试环境已经正常配置好了。

第 5 步:启动 Web 服务器

bash 复制代码
npm start

然后在浏览器打开 http://localhost:5000,就能看到启动成功的页面。


如何创建 GitHub 仓库来托管代码

第 1 步:登录 GitHub

  1. 打开浏览器访问 GitHub
  2. 如果没有 GitHub 账号,可以注册一个。

第 2 步:新建一个仓库

登录后,点击右上角的"+"号,选择"New repository"。

设置:

  • Repository Name:例如 ci-cd-tutorial
  • Description:可选,填上简要说明
  • Visibility:选择 public 或 private 都行
  • 不要勾选"Add a README file"

点击"Create repository"完成。

第 3 步:修改远程仓库地址并推送

在你本地的项目目录:

bash 复制代码
git remote set-url origin <your-repo-url>

<your-repo-url> 是你刚才创建的 GitHub 仓库地址。

如果当前分支不是 main,可以改名:

bash 复制代码
git branch -M main

然后提交并推送到远程:

bash 复制代码
git add .
git commit -m 'Created boilerplate'
git push -u origin main

这样本地代码就上传到新的 GitHub 仓库了。


如何在项目中设置 CI 与 CD 工作流

接下来我们要创建 CI 和 CD 工作流文件,放在 .github/workflows 目录下。当我们推送代码到远程仓库后,GitHub Actions 会自动识别并在云端运行这些工作流。

第 1 步:准备工作流目录

先在代码仓库中创建一个新分支:

bash 复制代码
git checkout -b feature/ci-cd-pipeline

然后在项目根目录下新建 .github 文件夹,再在 .github 中新建 workflows 文件夹。所有 YAML 文件放在这里都会被 GitHub Actions 检测为工作流。

第 2 步:创建持续集成(CI)工作流

workflows 目录中创建 ci-pipeline.yml,并粘贴以下内容:

yaml 复制代码
name: CI Pipeline to staging/production environment
on:
  pull_request:
    branches:
      - staging
      - main
jobs:
  test:
    runs-on: ubuntu-latest
    name: Setup, test, and build project
    env:
      PORT: 5001
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Install dependencies
        run: npm ci

      - name: Test application
        run: npm test

      - name: Build application
        run: |
          echo "Run command to build the application if present"
          npm run build --if-present
解释
  • name: CI 流水线的名称
  • on.pull_request.branches : 当针对 mainstaging 分支发起 PR 时触发。
  • jobs : 定义要运行的一系列任务,本例中只有一个 job 叫 test
    • runs-on: ubuntu-latest: 使用 Ubuntu 最新环境。
    • env.PORT=5001: 设置环境变量。
    • steps: 工作流的具体步骤:
      1. Checkout: 拉取代码
      2. Install dependencies: 安装依赖
      3. Test application: 运行 npm test
      4. Build application: 可选步骤,若无构建脚本不会报错。

第 3 步:持续交付和持续部署(CD)工作流

.github/workflows 中新建 cd-pipeline.yml 文件,并粘贴:

yaml 复制代码
name: CD Pipeline to Google Cloud Run (staging and production)
on:
  push:
    branches:
      - staging
  workflow_dispatch: {}
  release:
    types: published

env:
  PORT: 5001
  IMAGE: ${{vars.IMAGE}}:${{github.sha}}
jobs:
  test:
    runs-on: ubuntu-latest
    name: Setup, test, and build project
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Install dependencies
        run: npm ci

      - name: Test application
        run: npm test
  build:
    needs: test
    runs-on: ubuntu-latest
    name: Setup project, Authorize GitHub Actions to GCP and Docker Hub, and deploy
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Authenticate for GCP
        id: gcp-auth
        uses: google-github-actions/auth@v0
        with:
          credentials_json: ${{ secrets.GCP_SERVICE_ACCOUNT }}

      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v0

      - name: Authenticate for Docker Hub
        id: docker-auth
        env:
          D_USER: ${{secrets.DOCKER_USER}}
          D_PASS: ${{secrets.DOCKER_PASSWORD}}
        run: |
          docker login -u $D_USER -p $D_PASS
      - name: Build and tag Image
        run: |
          docker build -t ${{env.IMAGE}} .
      - name: Push the image to Docker hub
        run: |
          docker push ${{env.IMAGE}}
      - name: Enable the Billing API
        run: |
          gcloud services enable cloudbilling.googleapis.com --project=${{secrets.GCP_PROJECT_ID}}
      - name: Deploy to GCP Run - Production environment (If a new release was published from the master branch)
        if: github.event_name == 'release' && github.event.action == 'published' && github.event.release.target_commitish == 'main'
        run: |
          gcloud run deploy ${{vars.GCR_PROJECT_NAME}} \
          --region ${{vars.GCR_REGION}} \
          --image ${{env.IMAGE}} \
          --platform "managed" \
          --allow-unauthenticated \
          --tag production
      - name: Deploy to GCP Run - Staging environment
        if: github.ref != 'refs/heads/main'
        run: |
          echo "Deploying to staging environment"
          gcloud run deploy ${{vars.GCR_STAGING_PROJECT_NAME}} \
          --region ${{vars.GCR_REGION}} \
          --image ${{env.IMAGE}} \
          --platform "managed" \
          --allow-unauthenticated \
          --tag staging

这是一个结合了持续交付和持续部署的工作流。它在 push 到 staging 分支时触发,或者手动触发 (workflow_dispatch),或者发布新版本时触发(release: published)。

  • test job: 先做自动化测试,通过后再进行下一步。
  • build job :
    • 先做 GCP 和 Docker Hub 的身份验证(使用 GitHub Secrets)。
    • 构建并推送 Docker 镜像到 Docker Hub。
    • 如果是 staging 分支推送,就部署到 staging 环境。
    • 如果是发布 release 且目标分支是 main,就部署到生产环境。

为什么要把敏感信息放到 Secrets?

因为工作流文件是会提交到仓库的,如果把凭证写死在里面,很容易泄露。通过 GitHub Secrets 可以安全地存储和使用这些敏感数据。


为项目在 Docker Hub 创建镜像仓库并生成访问令牌

第 1 步:注册 / 登录 Docker Hub

  1. 打开 Docker Hub 官网
  2. 如果没账号,就点击 "Sign Up" 注册。
  3. 注册完成后,点击 "Sign In" 登录。

第 2 步:生成访问令牌

  1. 点击右上角头像,选择 "Account Settings"。
  2. 在左侧菜单选择 "Security"。
  3. 点击 "New Access Token",填写描述(比如 "GitHub Actions CI/CD"),然后选择权限(如 Read/Write)。
  4. 生成后复制该 Token(只会显示一次)。

第 3 步:在 GitHub 中添加 Secrets

  • 回到 GitHub 仓库,进入 "Settings" -> "Secrets and variables" -> "Actions"。
  • 点击 "New repository secret",创建 DOCKER_PASSWORD,值为刚才复制的 Token。
  • 同样创建 DOCKER_USER,值为你的 Docker Hub 用户名。

第 4 步:创建 Dockerfile

在项目根目录创建 Dockerfile

dockerfile 复制代码
FROM node:18-slim

WORKDIR /app

COPY package.json .

RUN npm install -f

COPY . .

EXPOSE 5001

CMD ["npm", "start"]

其含义:

  • FROM node:18-slim: 基于 Node.js 18 的轻量镜像
  • WORKDIR /app: 设置容器内的工作目录
  • COPY package.json .: 复制 package.json
  • RUN npm install -f: 安装依赖
  • COPY . .: 复制项目的所有文件到容器
  • EXPOSE 5001: 暴露端口 5001
  • CMD ["npm", "start"]: 运行应用

创建 Google Cloud 账户、项目和付费账户(Billing Account)

第 1 步:创建或登录 Google Cloud

  1. 打开 Google Cloud Console
  2. 如果没账号,需要创建并绑定支付方式(Google 有 300 美元的免费试用额度)。

第 2 步:创建新项目

  1. 在控制台左上角点击下拉,选择 "New Project"。
  2. 输入项目名称(如 gcr-ci-cd-project)。
  3. 点击 "Create"。

第 3 步:访问新项目

创建成功后,回到控制台,确保选择你刚创建的项目。

第 4 步:关联付费账户

在侧边栏找到 "Billing",根据提示关联或创建付费账户。


创建 Google Cloud 服务账号,实现将 Node.js 应用部署到 Google Cloud Run

为什么要创建服务账号和密钥?

因为 CI/CD 流程需要以某种"身份"访问 Google Cloud 的资源,而服务账号正好可以授予有限的角色权限,例如部署到 Cloud Run。

第 1 步:打开服务账号页面

进入 Google Cloud Console,选择你创建的项目。

导航到 "IAM & Admin" -> "Service Accounts"。

第 2 步:创建新服务账号

点击 "Create Service Account",输入:

  • Name: ci-cd-sa
  • ID: 自动生成
  • Description: "Used for deploying Node.js app to Cloud Run"

然后点击 "Create and Continue"。

第 3 步:分配角色

给这个服务账号添加:

  • Cloud Run Admin
  • Service Account User
  • Service Usage Admin
  • Viewer

然后点击 "Continue"。

第 4 步:跳过授权其他用户

点击 "Done"。

第 5 步:生成服务账号密钥

回到服务账号列表,找到刚才创建的 ci-cd-sa,点击右侧三个点,选择 "Manage Keys"。

点击 "Add Key" -> "Create New Key",选择 JSON 类型。点击"Create"后会下载 .json 文件。

务必妥善保管!

第 6 步:将密钥添加到 GitHub Secrets

  1. 打开下载的 JSON 文件,复制全部内容。
  2. 打开 GitHub 仓库 -> Settings -> Secrets -> Actions -> New repository secret。
  3. Name:GCP_SERVICE_ACCOUNT,Value:粘贴 JSON 内容。
  4. 同理,再创建一个名为 GCP_PROJECT_ID 的 secret,值是你的 Google Cloud 项目的 ID。

第 7 步:添加外部变量

继续在 "Settings" -> "Secrets and variables" -> "Actions" -> "Variables" 中添加:

  • GCR_PROJECT_NAME: 生产环境 Cloud Run 服务名,例如 gcr-ci-cd-app
  • GCR_STAGING_PROJECT_NAME: 测试环境服务名,例如 gcr-ci-cd-staging
  • GCR_REGION: 部署区域,如 us-central1
  • IMAGE: <dockerhub-username>/ci-cd-tutorial-app

启用 Service Usage API

  1. 在 Google Cloud Console -> APIs & Services -> Library 中搜索 "Service Usage API"。
  2. 点击 "Enable" 启用。

创建 Staging 分支并将 Feature 分支合并进入(CI + CD)

  1. 在 GitHub 上打开你的仓库,在分支下拉列表里,先切到 main 分支。
  2. 输入 staging 并创建这个新分支。
  3. 把你本地的 feature/ci-cd-pipeline 分支提交并推送到远端。然后在 GitHub 仓库页面,你会看到"Compare & Pull Request"的提示。
  4. 选择 staging 作为 base 分支,feature/ci-cd-pipeline 作为 compare 分支。写好标题和说明后,创建 Pull Request。
  5. GitHub Actions 会自动触发 CI 工作流(ci-pipeline.yml),跑测试。
  6. 测试通过后,可以 Merge PR。合并后,CD 工作流(cd-pipeline.yml)会自动部署到 staging 环境。

在 Google Cloud Run 上查看 staging 环境

  1. 打开 Google Cloud Console,选择对应项目。
  2. 左侧导航选择 Cloud Run,找到你的 staging 服务(如 gcr-ci-cd-staging)。
  3. 查看服务详情中的 URL,访问即可看到部署结果。

将 Staging 分支合并到 Main 分支(CI + CD)

当我们确认 staging 环境测试完成后,就可以把 staging 分支合并到 main 分支,并最终触发部署到生产环境。

  1. 在 GitHub 上发起 PR,把 staging 合并到 main。
  2. CI 工作流会再次跑测试。
  3. 若要触发部署到生产环境,需要发布一个新版本(Release) 。在 GitHub 上进入 "Releases",点击 "Draft a new release",将 Target branch 设为 main,输入 Tag(例如 v1.0.0),点击 "Publish Release"。
  4. 这会触发我们的 cd-pipeline.yml 中的 release 逻辑,将应用部署到生产环境。

为什么选择在发布 Release 时触发?

这样可以保证只有在团队真正决定"准备好了"时,才会部署到生产环境。平时对 main 的普通提交或合并不会立即上线,从而避免将半成品功能暴露给用户。


总结

在本文中,我们从零开始为一个 Node.js 应用构建并自动化了 CI/CD 流程:

  • 使用 GitHub Actions、Docker Hub、Google Cloud Run
  • 先在 Pull Request 阶段进行自动化测试(CI)
  • 合并到 staging 分支后自动构建并部署到测试环境(CD),进行进一步的验证
  • 对 main 分支发布 release 后再自动部署到生产环境(持续部署)

这样,团队就能更灵活地在 main 分支上合并和测试各种功能,而不会影响真实用户的使用体验。直到确认功能稳定后,才在发布时把它推向线上的生产环境。

如果你想深入了解 CI/CD,可以参考:

作者简介

Prince,是一名软件工程师,热衷于构建可扩展的应用,并在技术社区分享知识。如果你喜欢这篇文章,欢迎访问我的 [LinkedIn 主页](#LinkedIn 主页 "#") 了解更多我的博客与项目。也可以访问我的个人网站阅读更多文章,期待和你交流!😊


相关推荐
糖醋_诗酒17 小时前
CI/CD
ci/cd
码农葫芦侠1 天前
GitLab CI/CD学习教程(第四章gitlab-ci.yml)
学习·ci/cd·gitlab
qq_413691351 天前
CI/CD(六) helm部署ingress-nginx(阿里云)
nginx·阿里云·ci/cd·helm·ingress-nginx
佳腾_2 天前
Docker技术系列文章,第七篇——Docker 在 CI/CD 中的应用
ci/cd·docker·容器
Aixbox3 天前
宝塔Webhook: 轻松实现自动化部署
后端·ci/cd
WIN赢3 天前
【持续集成和持续部署】
ci/cd·自动化
qq_349523264 天前
持续集成(CI)/持续部署(CD)
ci/cd
FreeBuf_4 天前
GitHub供应链攻击事件:Coinbase遭袭,218个仓库暴露,CI/CD密钥泄露
ci/cd·github
NEUMaple6 天前
CI/CD管道
spring·spring cloud·ci/cd·微服务