给出以下示例 Github 操作工作流程
name: My workflow
on: pull_request
jobs:
foo:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: 1.19
- name: Foo
run: echo "foo"
bar:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: 1.19
- name: Bar
run: echo "bar"
Run Code Online (Sandbox Code Playgroud)
我希望这些工作Foo和Bar并行运行。但正如您所看到的,它们有一些共同的步骤。
是否可以创建一个运行结帐和设置步骤并提供自身的作业Foo,Bar以便他们只需运行自己的命令?(这会节省一些时间,但我认为这是不可能的,因为这两个作业都在单独的容器中运行)
如果这是不可能的,有没有办法提取“重复”行并将它们移动到我可以在工作中调用的“步骤函数”,这样我就不必一遍又一遍地编写这些步骤?
您可以使用缓存来节省一些时间:https://docs.github.com/en/actions/using-workflows/caching-dependency-to-speed-up-workflows并合并“YAML 文件中的重复行”在每项工作中,您可能都希望有一个复合动作,您基本上可以在其中提取
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: 1.19
Run Code Online (Sandbox Code Playgroud)
您可以在工作流程文件中使用的新操作如下所示:
name: My workflow
on: pull_request
jobs:
foo:
runs-on: ubuntu-latest
steps:
- name: My composite action
uses: path/to/action
- name: Foo
run: echo "foo"
bar:
runs-on: ubuntu-latest
steps:
- name: My composite action
uses: path/to/action
- name: Bar
run: echo "bar"
Run Code Online (Sandbox Code Playgroud)
请注意,如果您想在同一个存储库中创建此复合操作,则必须在actions/checkout@v3使用相对 URL 调用它之前使用。
所以它将是:
name: My workflow
on: pull_request
jobs:
foo:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: My composite action
uses: ./.github/actions/my-action.yaml
- name: Foo
run: echo "foo"
bar:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: My composite action
uses: ./.github/actions/my-action.yaml
- name: Bar
run: echo "bar"
Run Code Online (Sandbox Code Playgroud)
是的,如果您只有几步,这种方法可能不会给您带来太大价值。因为您可能只在 YAML 文件中保存几行,并且只能缓存您的依赖项安装。
而且,这并不意味着您的“共享/复合”操作只会运行一次,Github 将为调用它们的每个作业重新运行每个步骤(foo在bar您的情况下)。
另一种方法是,整合您在管道中运行的某些步骤,即创建一个将在其中运行您的操作的Docker 映像,此基础 Docker 映像可能具有您所需的设置,例如:GoLang,以及您必要的构建和测试模块安装。
name: My workflow
on: pull_request
jobs:
foo:
runs-on: ubuntu-latest
container: mydocker.image.uri/name:version
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Foo
run: echo "foo"
bar:
runs-on: ubuntu-latest
container: mydocker.image.uri/name:version
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Bar
run: echo "bar"
Run Code Online (Sandbox Code Playgroud)
这种方法的好处是,您可以从工作流程文件中删除一些行,并将一些设置步骤提取到基础 Docker 映像中,您将在其中运行操作。
关于缺点,构建一个稳定的基础映像以及运行步骤所需的设置可能有点困难。此外,您还需要维护 CI/CD 管道的另一部分。
另一种解决方案是使用执行矩阵(带有 缓存依赖文件和构建输出),它将为每个矩阵值运行并行作业(它们将根据运行程序的可用性或您的max-parallel值进行并行化)
name: My workflow
on: pull_request
jobs:
foo:
runs-on: ubuntu-latest
strategy:
matrix:
greeting: ["hello", "bonjour"]
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: 1.19
cache: true
- name: Saying ${{ matrix.greeting }}
run: echo "${{ matrix.greeting }}!"
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,所有步骤都会重新运行:
如果您要做的不仅仅是 GoLang 设置,而是执行可能需要花费大量时间的步骤,这可能并不有趣
我想到的最后一个选择是使用依赖作业,这可能不适用于此用例。但是,如果您可以重新设计工作流程以生成输出,或者从第一步调用的二进制文件,那么这可能是一个解决方案,baz那么您的工作流程将具有
foo:
runs-on: ubuntu-latest
needs: baz
steps:
- name: Something
run: echo "baz is saying: ${{ needs.baz.outputs.greeting }}"
Run Code Online (Sandbox Code Playgroud)
我希望这对您有所帮助或给您更多关于如何进一步优化此工作流程的想法!
| 归档时间: |
|
| 查看次数: |
2477 次 |
| 最近记录: |