Param
Param

Reputation: 729

How to pass environment variable received from GitHub actions

In my action.yml I defined an input:

name: 'test action'
author: Param Thakkar
description: 'test'

inputs: 
  test_var:
    description: 'A test variable'
    required: true

runs:
  using: 'docker'
  image: 'Dockerfile'

And in my workflow I passed the test_var:

name: CI

on: [push]

jobs:
  build:

runs-on: ubuntu-latest

steps:
  - name: Test the GH action
    uses: paramt/github-actions-playground@master
    with:
      test_var: "this is just a test"

So there should be an environment variable that's created when the workflow runs, right? But when I run this short python script:

import os

print(os.getenv('TEST_VAR'))
print("It works!")

exit(0)

It prints:

None
It works!

I think that I have to pass the ENV variable through my Dockerfile... Right now my Dockerfile looks like this: 

FROM python:latest

# Add files to the image
ADD entrypoint.py /entrypoint.py
ADD requirements.txt /requirements.txt

# Save ENV var in a temp file
RUN $TEST_VAR > /temp_var

# Install dependencies and make script executable
RUN pip install -r requirements.txt
RUN chmod +x entrypoint.py

RUN echo "temp var: "
RUN cat /temp_var

# Run script with the ENV var
ENTRYPOINT export TEST_VAR="$TEST_VAR"; /entrypoint.py

But the variable isn't echoed and isn't passed to the pythons script either.. am I missing something? When I tried to set my $TEMP_VAR to a random piece of string, it is sent through to the Python script. Is this a mistake on my behalf or is the GitHub action not working as intended?

Here's the link to the test repo

Upvotes: 19

Views: 38319

Answers (4)

Bharadwaj Giridhar
Bharadwaj Giridhar

Reputation: 1237

Edit: This approach is not secure. I was using it on a dummy-dev project. See explanation from Sun (in the reply) and check Peter Evan's answer

However, in my case, none of the answers worked. Here's how I fixed it.

---
name: Build and Push Docker Image to AWS ECR
on:
  push:
    branches: [ master ]

env:
  FOO: '${{ secrets.FOO }}'

jobs:
  build-and-push:
    name: Build Project and Push to AWS ECR
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
        
        ... 
        
      - name: Build and Push to AWS ECR
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        run: |
          docker build --build-arg FOO=$FOO -t $ECR_REGISTRY/crew-charge-app:latest .
          docker push $ECR_REGISTRY/crew-charge-app:latest

I first had to get the FOO variable from github secrets using ${{secrets.FOO}} then pass it onto the docker file using docker build --build-arg FOO=$FOO --build-arg BAR=$BAR -t .

Then inside the docker file I had to declare both as an ARG and ENV to be available at all times.

FROM node:14

ARG FOO=${FOO}

ENV FOO=${FOO}

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

COPY package.json /usr/src/app

RUN yarn install

COPY . /usr/src/app

RUN FOO=$FOO yarn build

EXPOSE 80

CMD ["yarn", "start" ]

Important part was to RUN FOO=$FOO yarn build because setting the ENV alone doesn't pass it onto the container.

Upvotes: 3

Rich Pauloo
Rich Pauloo

Reputation: 8402

Keep env vars secret by specifying them in Settings -> Secrets in the repo, and then calling them in the workflow:

For example, consider a workflow that runs an R script followed by a Python script. First, in .github/workflows/my_job.yml notice the MY_VAR variable, which points to a stored secret with ${{ secrets.MY_VAR}}. The rest is standard code (run on cron, specify Ubuntu OS and Docker image, define workflow steps).

on:
  schedule:
    - cron:  '0 17 * * *'
jobs:
  my_job:
    name: my job
    env:
      MY_VAR: ${{ secrets.MY_VAR }}
    runs-on: ubuntu-18.04
    container:
     image: docker.io/my_username/my_image:my_tag
    steps:
      - name: checkout_repo
        uses: actions/checkout@v2
      - name: run some code
        run: bash ./src/run.sh 

Next, in the scripts that compose your workflow, you can access the env var specified in the workflow file above as you would locally.

For example, in the repo, let's assume src/run.sh calls an R script followed by a Python script.

In R access the env var and store as an object:

my_var <- Sys.getenv("MY_VAR")

.
.
.

In Python access the env var and store as an object:

import os

my_var = os.getenv("MY_VAR")
.
.
.

See the docs here.

Upvotes: 5

Quentin
Quentin

Reputation: 359

A bit late but for the next one, you can also use the env field :

name: CI

on: [push]

jobs:
  build:

runs-on: ubuntu-latest

steps:
  - name: Test the GH action
    uses: paramt/github-actions-playground@master
    env:
      test_var: "this is just a test"

which will be included during the creation of your docker and pass without the prefix INPUT_

Upvotes: 9

peterevans
peterevans

Reputation: 41950

I think you are trying to read the wrong environment variable name. GitHub Actions adds INPUT_ to the name of the input variable. So try the following:

print(os.getenv('INPUT_TEST_VAR'))

From the documentation:

When you specify an input to an action in a workflow file or use a default input value, GitHub creates an environment variable for the input with the name INPUT_. The environment variable created converts input names to uppercase letters and replaces spaces with _ characters.

For example, if a workflow defined the numOctocats and octocatEyeColor inputs, the action code could read the values of the inputs using the INPUT_NUMOCTOCATS and INPUT_OCTOCATEYECOLOR environment variables.

https://help.github.com/en/articles/metadata-syntax-for-github-actions#inputs

Upvotes: 13

Related Questions