Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 (i.e. so I can run the same build instructions across different versions of the runtime environment)

My gut instinct was to have my .github/actions/main/action.yml file as

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

Any help would be appreciated !

File References

My .github/workflow/build_and_test.yml file is:

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:

FROM rocker/verse:latest
ADD scripts /scripts
ENTRYPOINT [ "bash", "-c" ]
like image 640
gowerc Avatar asked Oct 20 '19 18:10

gowerc


People also ask

How do I run a variable image in Docker?

With a Command Line Argument The command used to launch Docker containers, docker run , accepts ENV variables as arguments. Simply run it with the -e flag, shorthand for --env , and pass in the key=value pair: sudo docker run -e POSTGRES_USER='postgres' -e POSTGRES_PASSWORD='password' ...

How can I run a docker image from a GitHub action?

Instead of something like uses: actions/ checkout@v2, you can instead specify a Docker image from the hub to run in its place. The problem with this one though is that you have to generate a Docker image that runs specifically like a GitHub action expects.

Does GitHub actions support Docker runtimes?

Now, GitHub Actions supports both of those runtimes out of the box, but I had just created a perfectly good Docker image for using Cleaver, and instead wanted to use that. Ultimately it was a mixture of just wanting the fine-grain control that a single Docker image provides, and because, well I just wanted to see how to do it!

Can I use a custom Docker image in a job or step?

For those that are trying to use a custom Docker image published to the new GitHub Docker Container Registry at ghcr.io in one of your jobs or steps, this is what I did. Create a Personal Access Token, as seen on GitHub documentation for the new Docker Container Registry.

How to create a docker workflow in GitHub?

Create a .github/workflows folder. and inside workflows folder create a .yml file, (eg push-docker-image.yaml) After pushing the code to GitHub, go to the Actions section, you will find the workflow you created, you will receive an error because those variables DOCKER_USER and DOCKER_PASSWORD and REPO_NAME are not set.


2 Answers

Interesting approach! I'm not sure if it's possible to use expressions in the image field of the action metadata. 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.

For reference this is the args section of the action.yml metadata. 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? 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:

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

Alternatively, you can also specify your image at the step level with uses. You could then pass a command via args to execute your script.

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

like image 124
peterevans Avatar answered Nov 12 '22 05:11

peterevans


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.

That helped to solve 3 things :

  • Reuse a custom docker image being build within the steps for testing actions. 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.
  • This specific image can also be stored in a private docker registry
  • Be able to use a variable for the docker image

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
like image 29
mehdio Avatar answered Nov 12 '22 06:11

mehdio