CI/CD 管道中的并行性,如 GitHub 操作
Parallelism in CI/CD Pipelines like GitHub Actions
你好,感谢你阅读我的问题,这是我的第一个问题。
我使用 CI/CD 管道已经一年了,我认为它们对于开发网站和其他东西来说非常好而且方便。但在过去的几个月里,我在创建快速、高效和智能的管道时遇到了越来越多的问题,而无需安装冗余依赖项或类似的东西。所以我想使用尽可能少的计算资源,同时仍然有快速构建。我想并行化步骤并在另一个最后步骤中使用它们的工件。例如以下 GitHub 操作工作流程:
我使用此工作流程的目标是构建一个 VueJS 单页应用程序并将其部署到 IBM Cloud。为此,我需要安装 npm 依赖项并构建 Vue 应用程序,还需要安装 IBM Cloud CLI。完成这两个步骤后,应将构建的应用程序推送到 IBM Cloud。
我可以像这样简单地 运行 所有步骤:
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Use Node.js 10.X
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Cache Node Modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm ci
- name: Build Page
run: npm run build
- name: Install IBM Cloud CLI
run: curl -fsSL https://clis.cloud.ibm.com/install/linux | sh
shell: bash
- name: Install Cloud Foundry CLI
run: ibmcloud cf install
shell: bash
- name: Authenticate with IBM Cloud CLI
run: ibmcloud login --apikey "${{ secrets.IBM_CLOUD_API_KEY }}" --no-region -g Default
shell: bash
- name: Target a Cloud Foundry org and space
run: ibmcloud target --cf-api "${{ secrets.IBM_CLOUD_CF_API }}" -o "${{ secrets.IBM_CLOUD_CF_ORG }}" -s "${{ secrets.IBM_CLOUD_CF_SPACE }}"
shell: bash
- name: Deploy to Cloud Foundry
run: ibmcloud cf push
shell: bash
但在我看来这是非常丑陋的,可以改进。所以我试图将工作分成 3 个部分:构建、预部署和部署。构建作业安装并构建 Vue 应用程序。 Predeploy 作业安装 IBM CLI。这两个工作不相互依赖,因此可以并行化。但最后一项工作部署取决于两者,因此我向其添加了 needs: [build, predeploy]
值。所以我有以下工作流程来存档:
### This will not work!
name: Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Use Node.js 10.X
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Cache Node Modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm ci
- name: Build Page
run: npm run build
predeploy:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Install IBM Cloud CLI
run: curl -fsSL https://clis.cloud.ibm.com/install/linux | sh
- name: Install Cloud Foundry CLI
run: ibmcloud cf install
- name: Authenticate with IBM Cloud CLI
run: ibmcloud login --apikey "${{ secrets.IBM_CLOUD_API_KEY }}" --no-region -g Default
- name: Target a Cloud Foundry org and space
run: ibmcloud target --cf-api "${{ secrets.IBM_CLOUD_CF_API }}" -o "${{ secrets.IBM_CLOUD_CF_ORG }}" -s "${{ secrets.IBM_CLOUD_CF_SPACE }}"
deploy:
needs: [build, predeploy]
runs-on: ubuntu-latest
steps:
- name: Deploy to Cloud Foundry
# Error: 'ibmcloud: command not found'
run: ibmcloud cf push
shell: bash
在 GUI 上看起来像:
[![GUI 上我的 GitHub 工作流程][1]][1]
但是这个工作流程会出错,因为最后一个作业与其他作业不共享相同的环境。我知道我可以使用 GitHub Actions 的 up/download Artifact 功能,但在我看来这会占用大量资源。但我不想为我的管道使用大量资源,我不需要很多不同的虚拟环境或构建矩阵。 (我知道它们对于大型项目非常有用,但对于我的小网站来说它们似乎有点矫枉过正)
所以这是我的最后两个问题:
为什么 CI/CD 中的并行性通常很复杂而不是直截了当?
如何在没有冗余执行的情况下通过并行改进我当前的管道?
我很高兴收到每条有用的建议或 link。谢谢你。 :)
[1]: https://i.stack.imgur.com/qEqLs.png
我认为您原来的工作流程已经非常高效了。正如您提到的,不同的作业在不同的 运行 人员上执行,有时工作流之间 synchronization/logic 的额外复杂性和工作量超过了并行性的好处。在你的情况下,我认为并行 运行 你的工作没有多大意义。
对于您的第一个问题,我认为这不是 CI/CD 管道特有的问题。我在这里有点超出范围,但是您在任何并行工作的代码中都有类似的问题,或者事实上在任何地方并行完成的任何一般工作中都有类似的问题。作为工厂、团队、代码、CI 管道,一旦工作被拆分,就会有某种机制来管理工作分配并跟踪其进度。这将使它变得更加复杂。
为什么 GH 工作流程看起来不如其他系统那么简单似乎是一个更好的问题,我认为它已经存在了多长时间。这是对 github 的最新补充,随着新功能的逐步添加,它变得越来越容易使用。
关于您的工作流程的其他优化,如果不需要,我建议尽量避免每次工作流程 运行 重做相同的工作。您已经使用 npm 的缓存操作执行此操作。但是,例如,您可以构建一个 docker 图像,甚至更好的操作,其中包含您的 IBM CLI,并完全删除预部署阶段。只需拥有:
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Use Node.js 10.X
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Cache Node Modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm ci
- name: Build Page
run: npm run build
- name: Deploy to Cloud Foundry
uses: my-action:v1
with:
api-key: ${{ secrets.IBM_CLOUD_API_KEY }}
cf-api: ${{ secrets.IBM_CLOUD_CF_API }}
cf-org: ${{ secrets.IBM_CLOUD_CF_ORG }}
cf-space: ${{ secrets.IBM_CLOUD_CF_SPACE }}
你好,感谢你阅读我的问题,这是我的第一个问题。
我使用 CI/CD 管道已经一年了,我认为它们对于开发网站和其他东西来说非常好而且方便。但在过去的几个月里,我在创建快速、高效和智能的管道时遇到了越来越多的问题,而无需安装冗余依赖项或类似的东西。所以我想使用尽可能少的计算资源,同时仍然有快速构建。我想并行化步骤并在另一个最后步骤中使用它们的工件。例如以下 GitHub 操作工作流程:
我使用此工作流程的目标是构建一个 VueJS 单页应用程序并将其部署到 IBM Cloud。为此,我需要安装 npm 依赖项并构建 Vue 应用程序,还需要安装 IBM Cloud CLI。完成这两个步骤后,应将构建的应用程序推送到 IBM Cloud。
我可以像这样简单地 运行 所有步骤:
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Use Node.js 10.X
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Cache Node Modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm ci
- name: Build Page
run: npm run build
- name: Install IBM Cloud CLI
run: curl -fsSL https://clis.cloud.ibm.com/install/linux | sh
shell: bash
- name: Install Cloud Foundry CLI
run: ibmcloud cf install
shell: bash
- name: Authenticate with IBM Cloud CLI
run: ibmcloud login --apikey "${{ secrets.IBM_CLOUD_API_KEY }}" --no-region -g Default
shell: bash
- name: Target a Cloud Foundry org and space
run: ibmcloud target --cf-api "${{ secrets.IBM_CLOUD_CF_API }}" -o "${{ secrets.IBM_CLOUD_CF_ORG }}" -s "${{ secrets.IBM_CLOUD_CF_SPACE }}"
shell: bash
- name: Deploy to Cloud Foundry
run: ibmcloud cf push
shell: bash
但在我看来这是非常丑陋的,可以改进。所以我试图将工作分成 3 个部分:构建、预部署和部署。构建作业安装并构建 Vue 应用程序。 Predeploy 作业安装 IBM CLI。这两个工作不相互依赖,因此可以并行化。但最后一项工作部署取决于两者,因此我向其添加了 needs: [build, predeploy]
值。所以我有以下工作流程来存档:
### This will not work!
name: Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Use Node.js 10.X
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Cache Node Modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm ci
- name: Build Page
run: npm run build
predeploy:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Install IBM Cloud CLI
run: curl -fsSL https://clis.cloud.ibm.com/install/linux | sh
- name: Install Cloud Foundry CLI
run: ibmcloud cf install
- name: Authenticate with IBM Cloud CLI
run: ibmcloud login --apikey "${{ secrets.IBM_CLOUD_API_KEY }}" --no-region -g Default
- name: Target a Cloud Foundry org and space
run: ibmcloud target --cf-api "${{ secrets.IBM_CLOUD_CF_API }}" -o "${{ secrets.IBM_CLOUD_CF_ORG }}" -s "${{ secrets.IBM_CLOUD_CF_SPACE }}"
deploy:
needs: [build, predeploy]
runs-on: ubuntu-latest
steps:
- name: Deploy to Cloud Foundry
# Error: 'ibmcloud: command not found'
run: ibmcloud cf push
shell: bash
在 GUI 上看起来像:
[![GUI 上我的 GitHub 工作流程][1]][1]
但是这个工作流程会出错,因为最后一个作业与其他作业不共享相同的环境。我知道我可以使用 GitHub Actions 的 up/download Artifact 功能,但在我看来这会占用大量资源。但我不想为我的管道使用大量资源,我不需要很多不同的虚拟环境或构建矩阵。 (我知道它们对于大型项目非常有用,但对于我的小网站来说它们似乎有点矫枉过正)
所以这是我的最后两个问题:
为什么 CI/CD 中的并行性通常很复杂而不是直截了当?
如何在没有冗余执行的情况下通过并行改进我当前的管道?
我很高兴收到每条有用的建议或 link。谢谢你。 :) [1]: https://i.stack.imgur.com/qEqLs.png
我认为您原来的工作流程已经非常高效了。正如您提到的,不同的作业在不同的 运行 人员上执行,有时工作流之间 synchronization/logic 的额外复杂性和工作量超过了并行性的好处。在你的情况下,我认为并行 运行 你的工作没有多大意义。
对于您的第一个问题,我认为这不是 CI/CD 管道特有的问题。我在这里有点超出范围,但是您在任何并行工作的代码中都有类似的问题,或者事实上在任何地方并行完成的任何一般工作中都有类似的问题。作为工厂、团队、代码、CI 管道,一旦工作被拆分,就会有某种机制来管理工作分配并跟踪其进度。这将使它变得更加复杂。 为什么 GH 工作流程看起来不如其他系统那么简单似乎是一个更好的问题,我认为它已经存在了多长时间。这是对 github 的最新补充,随着新功能的逐步添加,它变得越来越容易使用。
关于您的工作流程的其他优化,如果不需要,我建议尽量避免每次工作流程 运行 重做相同的工作。您已经使用 npm 的缓存操作执行此操作。但是,例如,您可以构建一个 docker 图像,甚至更好的操作,其中包含您的 IBM CLI,并完全删除预部署阶段。只需拥有:
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Use Node.js 10.X
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Cache Node Modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm ci
- name: Build Page
run: npm run build
- name: Deploy to Cloud Foundry
uses: my-action:v1
with:
api-key: ${{ secrets.IBM_CLOUD_API_KEY }}
cf-api: ${{ secrets.IBM_CLOUD_CF_API }}
cf-org: ${{ secrets.IBM_CLOUD_CF_ORG }}
cf-space: ${{ secrets.IBM_CLOUD_CF_SPACE }}