简体   繁体   English

如何在 github-actions 中使用变量 docker 图像?

[英]How to use a variable docker image in github-actions?

I am trying to write a custom github-action that runs some commands in a docker container but allows the user to select which docker container they are run in (ie so I can run the same build instructions across different versions of the runtime environment)我正在尝试编写一个自定义 github 操作,该操作在 docker 容器中运行一些命令,但允许用户使用 select 其中 docker 容器它们可以在不同版本的运行时运行 IDA4E6Z

My gut instinct was to have my .github/actions/main/action.yml file as我的直觉是将我的.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

However this errors with: ##[error](Line: 7, Col: 10): Unrecognized named-value: 'inputs'. Located at position 1 within expression: inputs.dockerfile但是,此错误: ##[error](Line: 7, Col: 10): Unrecognized named-value: 'inputs'. Located at position 1 within expression: inputs.dockerfile ##[error](Line: 7, Col: 10): Unrecognized named-value: 'inputs'. Located at position 1 within expression: inputs.dockerfile

Any help would be appreciated !任何帮助,将不胜感激 !

File References文件参考

My .github/workflow/build_and_test.yml file is:我的.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

And my Dockerfile .github/actions/main/Dockerfile_r_latest is:而我的 Dockerfile .github/actions/main/Dockerfile_r_latest是:

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

Interesting approach!有趣的方法! I'm not sure if it's possible to use expressions in the image field of the action metadata.我不确定是否可以在动作元数据的image字段中使用表达式。 I would guess that the only fields that can take expressions instead of hardcoded strings are the args for the image so that the inputs can be passed.我猜想唯一可以采用表达式而不是硬编码字符串的字段是图像的args ,以便可以传递inputs

For reference this is the args section of the action.yml metadata.作为参考,这是action.yml元数据的args部分。 https://help.github.com/en/articles/metadata-syntax-for-github-actions#args https://help.github.com/en/articles/metadata-syntax-for-github-actions#args

I think there are other ways to achieve what you want to do.我认为还有其他方法可以实现您想要做的事情。 Have you tried using the jobs.<job_id>.container syntax?您是否尝试过使用jobs.<job_id>.container语法? That allows you to specify an image that the steps of a job will run in. It will require that you publish the image to a public repository, though.这允许您指定作业步骤将在其中运行的图像。不过,这将要求您将图像发布到公共存储库。 So take care not to include any secrets.所以请注意不要包含任何秘密。

For example, if you published your image to Docker Hub at gowerc/r-latest your workflow might look something like this:例如,如果您将图像发布到gowerc/r-latest的 Docker Hub,您的工作流程可能如下所示:

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

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

Alternatively, you can also specify your image at the step level with uses .或者,您也可以uses在步骤级别指定图像。 You could then pass a command via args to execute your script.然后,您可以通过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"

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

In addition to @peterevans answer, I would add there's a 3rd option where you can use a simple docker run command and pass any env that you have defined.除了@peterevans的回答,我还要添加第三个选项,您可以在其中使用简单的docker run命令并传递您定义的任何env

That helped to solve 3 things:这有助于解决三件事:

  • Reuse a custom docker image being build within the steps for testing actions.重用在测试操作的步骤中构建的自定义 docker 映像。 It seems not possible to do so with uses as it first tries to pull that image that doesn't exist yet in a Setup job step that occurs before any steps of the job.似乎不可能这样做,因为uses首先尝试在作业的任何步骤之前发生的Setup job步骤中提取尚不存在的图像。
  • This specific image can also be stored in a private docker registry此特定图像也可以存储在私有 docker 注册表中
  • Be able to use a variable for the docker image能够为 docker 图像使用变量

My workflow looks like this:我的工作流程如下所示:

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

Here is another approach.这是另一种方法。 The Docker image to use is passed to a cibuild shell script that takes care of pulling the right image.要使用的 Docker 映像被传递给负责拉取正确映像的cibuild shell 脚本。

GitHub workflow file: 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 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!"

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM