如何在Github Actions中使用可变的Docker镜像?

9

我正在尝试编写一个自定义的Github Action,该Action在Docker容器中运行一些命令,但允许用户选择要在哪个Docker容器中运行(即,我可以在不同版本的运行时环境中运行相同的构建说明)。

我的直觉是将我的.github/actions/main/action.yml文件设置为:

name: 'Docker container command execution'
inputs:
  dockerfile:
    default: Dockerfile_r_latest
runs:
  using: 'docker' 
  image: '${{ inputs.dockerfile }}'
  args:
   - /scripts/commands.sh

然而,出现了以下错误: ##[error](Line: 7, Col: 10): 无法识别的命名值:'inputs'。位于表达式中位置1:inputs.dockerfile 任何帮助将不胜感激!
文件引用
我的.github/workflow/build_and_test.yml文件如下:
name: Test Package

on: 
  [push, pull_request]

jobs:

  R_latest:

    name: Test on latest
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
        name: Checkout project

      - uses: ./.github/actions/main
        name: Build and test
        with:
          dockerfile: Dockerfile_r_latest

我的 Dockerfile .github/actions/main/Dockerfile_r_latest 如下:

FROM rocker/verse:latest
ADD scripts /scripts
ENTRYPOINT [ "bash", "-c" ]
3个回答

5
有趣的方法!我不确定在操作元数据的image字段中是否可以使用表达式。我猜想,只有args可以采用表达式而不是硬编码字符串,以便可以传递inputs
供参考,这是action.yml元数据的args部分。 https://help.github.com/en/articles/metadata-syntax-for-github-actions#args 我认为还有其他方法可以实现你想要做的事情。你试过使用jobs.<job_id>.container语法吗?这允许你指定一个步骤将在其中运行的映像。但是,它需要你将映像发布到公共存储库中,因此请注意不要包含任何机密信息。
例如,如果你将映像发布到Docker Hub上,位置为gowerc/r-latest,那么你的工作流可能如下所示:
name: Test Package

on: 
  [push, pull_request]

jobs:

  R_latest:

    name: Test on latest
    runs-on: ubuntu-latest
    container: gowerc/r-latest
    steps:
      - uses: actions/checkout@master
        name: Checkout project

      - name: Build and test
        run: ./scripts/commands.sh

参考: https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobsjob_idcontainer

或者,您也可以在步骤级别使用uses指定您的镜像。然后,您可以通过args传递命令来执行您的脚本。

name: my workflow
on: push
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - name: Check container
        uses: docker://alpine:3.8
        with:
          args: /bin/sh -c "cat /etc/alpine-release"

参考: https://help.github.com/cn/github/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#example-using-a-docker-hub-action


2
除了@peterevans的答案外,我想补充一下第三种选项,您可以使用简单的docker run命令并传递您定义的任何env来解决以下三个问题:
  • 重复使用在测试操作步骤中构建的自定义docker镜像。似乎无法通过uses这样做,因为它首先尝试在Setup job步骤中拉取该尚不存在的镜像。
  • 该特定镜像也可以存储在私有docker注册表中。
  • 能够使用变量来指定docker镜像。
我的工作流程如下:
name: Build-Test-Push
on:
push:
    branches:
    - master
env:
    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    ECR_REGISTRY: ${{ secrets.AWS_ECR_REGISTRY }}
    ECR_REPOSITORY: myproject/myimage
    IMAGE_TAG: ${{ github.sha }}

jobs:

build-and-push:
    runs-on: ubuntu-latest
    steps:
    - name: Checking out
    uses: actions/checkout@v2
    with:
        ref: master

    - name: Login to AWS ECR
    id: login-ecr
    uses: aws-actions/amazon-ecr-login@v1

    - name: Build
    run: |
        docker pull $ECR_REGISTRY/$ECR_REPOSITORY || true
        docker build . -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -t $ECR_REGISTRY/$ECR_REPOSITORY:latest

    - name: Test
    run: |
        docker run $ECR_REGISTRY/$ECR_REPOSITORY:latest /bin/bash -c "make test"

    - name: Push
    run: |
        docker push $ECR_REGISTRY/$ECR_REPOSITORY

1
这里有另一种方法。使用的Docker镜像是通过传递给 shell脚本来处理拉取正确镜像的。
GitHub工作流文件:
name: 'GH Actions CI'

on:
  push:
    branches: ['*master', '*0.[0-9]?.x']
  pull_request:
    # The branches below must be a subset of the branches above
    branches: ['*master', '*0.[0-9]?.x']

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest

    strategy:
      fail-fast: true
      matrix:
        include:
          - FROM:     'ubuntu:focal'
          - FROM:     'ubuntu:bionic'
          - FROM:     'ubuntu:xenial'
          - FROM:     'debian:buster'
          - FROM:     'debian:stretch'
          - FROM:     'opensuse/leap'
          - FROM:     'fedora:33'
          - FROM:     'fedora:32'
          - FROM:     'centos:8'

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2
      with:
        # We must fetch at least the immediate parents so that if this is
        # a pull request then we can checkout the head.
        fetch-depth: 2

    # If this run was triggered by a pull request event, then checkout
    # the head of the pull request instead of the merge commit.
    - run: git checkout HEAD^2
      if: ${{ github.event_name == 'pull_request' }}

    - name: Run CI
      env:
        FROM: ${{ matrix.FROM }}
      run: script/cibuild

Bash脚本 script/cibuild:

#!/bin/bash

set -e

docker run --name my-docker-container $FROM script/custom-script.sh
docker cp my-docker-container:/usr/src/my-workdir/my-outputs .
docker rm my-docker-container

echo "cibuild Done!"

将您的自定义命令放在 script/custom-script.sh 中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接