I am new to github actions, and I see two things used for configuring the steps (correct me if i am wrong), with and env.
What is the difference between these two and how they are used.
uses: someAction
with:
x: 10
y: 20
env:
x1: 30
y2: 40
with - is specifically used for passing parameters to the action
env - is used specifically for introducing environment variables that can be accessed depending on scope of the resource
workflow envs - can be accessed by all resources in the workflow except services
job envs - can be accessed by all resources under job except services
step envs - can be accessed by any resource within the step
Here is an example on how parameters are handled
Let's say an action is created with following parameter in action.yaml
name: 'Npm Audit Action'
inputs:
dirPath:
description: 'Directory path of the project to audit'
required: true
default: './'
Then we will provide this parameter through the with tag in our workflow
- name: Use the action
uses: meroware/npm-audit-action#v1.0.2
with:
dirPath: vulnerable-project
Then in the action code we would handle it as such if building a Node.js action
const core = require("#actions/core");
const dirPath = core.getInput("dirPath");
Envs within actions are accessed differently, let's say we are building a Node.js action, then we would access it through process.env. Going back to our example action
name: 'Npm Audit Action'
env:
SOME_ENV: 'hey I am an env'
Then this could be accessed as
const { someEnv: SOME_ENV } = process.env
You can see in the documentation with: used to define a variable.
While env defines an environmnent variable, as defined here and in jobs.<job_id>.env
an environment variable defined in a step will override job and workflow variables with the same name, while the step executes.
A variable defined for a job will override a workflow variable with the same name, while the job executes.
You need both to access secrets:
steps:
- name: Hello world action
with: # Set the secret as an input
super_secret: ${{ secrets.SuperSecret }}
env: # Or as an environment variable
super_secret: ${{ secrets.SuperSecret }}
Related
I have a workflow yml file. At the top I have a section above where the jobs are defined to make them global across jobs:
env:
DBT_REPO: ${{ vars.DBT_REPO }}
This var is a repo variable and I have confirmed it is already set. Pretend it's value is fruits/apples.
Then, in one of my jobs I try to reference this var in a step:
- name: Checkout DBT repo
uses: actions/checkout#v2
with:
repository: ${{ env.DBT_REPO }}
token: ${{ secrets.WORKFLOW_TOKEN }}
ref: ${{ env.DBT_REPO_BRANCH }}
path: ./${{ env.DBT_REPO }}
- name: Run DBT
uses: ./${{ env.DBT_REPO }}/dbt-action
The last line is line 169.
Then, when I try to run this workflow I get an error:
Invalid workflow file: .github/workflows/main.yml#L169
The workflow is not valid. .github/workflows/main.yml (Line: 169, Col: 15): Unrecognized named-value: 'DBT_REPO'. Located at position 1 within expression: DBT_REPO
If I hard code it like so: uses: ./fruits/apples/dbt-action then things work fine. It's only when I attempt to use a variable.
How can I reference a variable in my uses keyword?
This is not possible because the env context is not available to uses. In fact, based on documentation no contexts are available to the uses key.
See: https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
I believe this is an architectural limitation of GitHub Actions, it appears they want to resolve all workflows/actions at the start of all jobs and thus dynamic resolution isn't possible.
How to define a topic trigger in a .yaml for Github actions for deploying a Google Cloud Function?
A working file with http (the default) is:
# This is a basic workflow to help you get started with Actions
name: CD
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [main]
pull_request:
branches: [main]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "deploy"
deploy:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Add "id-token" with the intended permissions.
permissions:
contents: "read"
id-token: "write"
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout#v2
- id: "auth"
name: "Authenticate to Google Cloud"
uses: "google-github-actions/auth#v0"
with:
# Replace with your Workload Identity Provider Location
workload_identity_provider: "${PROJECT_VALUE}"
# Replace with your GitHub Service Account
service_account: "github-actions-service-account#${PROJECT_NAME}.iam.gserviceaccount.com"
- id: "deploy"
uses: "google-github-actions/deploy-cloud-functions#v0"
with:
# Name of the Cloud Function, same as the entry point name
name: "${FUNCTION_NAME}"
# Runtime to use for the function
runtime: "nodejs16"
This thread has some suggestions but getting the topic ID is unclear
https://github.com/google-github-actions/deploy-cloud-functions/issues/5
adding the following works
- id: "deploy"
uses: "google-github-actions/deploy-cloud-functions#v0"
with:
# Name of the Cloud Function, same as the entry point name
name: "${FUNCTION_NAME}"
# Runtime to use for the function
runtime: "nodejs16"
event_trigger_type: "google.pubsub.topic.publish"
event_trigger_resource: "projects/${PROJECT_VALUE}/topics/${TOPIC_ID}" //ie the string identifying the topic
event_trigger_service: "pubsub.googleapis.com"
The final issue was that having deployed a GCF with http trigger, that one had to be deleted before the above would successfully deploy
I'm reading this quickstart guide.
The guide provides an example actions.yml:
# action.yml
name: 'Hello World'
description: 'Greet someone and record the time'
inputs:
who-to-greet: # id of input
description: 'Who to greet'
required: true
default: 'World'
outputs:
time: # id of output
description: 'The time we greeted you'
runs:
using: 'docker'
image: 'Dockerfile'
args:
- ${{ inputs.who-to-greet }}
My question concerns the last section in this file, runs:. My workflow will use multiple docker images. What's the 'right' way to do this? Should I create multiple actions.yml? Should I use multiple repos? Or can I somehow reference multiple Dockerfile's within runs:?
The docs only mention the usage of a single docker image in a docker action.
It is however possible to run docker containers in a step of a normal workflow as stated in this Stackoverflow thread. This means you can create a composite action to make use of the same features provided by a normal workflow.
name: CI
on: [push]
jobs:
myjob:
runs-on: ubuntu-latest # linux required if you want to use docker
steps:
- uses: docker://continuumio/anaconda3:2019.07 # runs anaconda image from DockerHub
Here's a GitHub Actions workflow file for a Python project named spam:
name: PyInstaller
on:
[...]
jobs:
create_release:
[...]
make_artifact:
needs: create_release
strategy:
matrix:
os: [ ubuntu-latest, windows-latest ]
runs-on: ${{ matrix.os }}
env:
ARTIFACT_PATH: dist/spam.zip
ARTIFACT_NAME: spam-${{ runner.os }}.zip
steps:
[...]
When this runs, the workflow fails at startup with this:
The workflow is not valid. [...]:
Unrecognized named-value: 'runner'. Located at position 1 within expression: runner.os
I'm attempting to use the os attribute of the runner context. This SO Q&A mentions that the env context can only be used in specific places, so I suspect something similar is happening here. However, I can't find any official documentation addressing this.
Is there any way to reference the runner context to set an environment variable within the env clause of a job, as shown above?
I'm looking for a way to set the environment variable for all steps in the job, so an env inside a step item won't do.
The workaround I've got for now is to add a step specifically to set environment variables:
steps:
- name: Setup environment
run: |
echo "ARTIFACT_NAME=spam-${{ runner.os }}.zip" >> $GITHUB_ENV
however this only works on the Linux runner.
If you scroll down a bit further in the GitHub Actions docs you linked, there's an example workflow printing different contexts to the log.
- name: Dump runner context
env:
RUNNER_CONTEXT: ${{ toJson(runner) }}
I set up a test repo with a workflow demonstration:
on: push
jobs:
one:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- 'ubuntu-latest'
- 'windows-latest'
- 'macos-latest'
steps:
- name: Dump runner context
env:
RUNNER_CONTEXT: ${{ toJson(runner) }}
run: echo "$RUNNER_CONTEXT"
- name: Get runner OS
env:
RUNNER_OS: ${{ runner.os }}
run: echo "$RUNNER_OS"
- name: Create file with runner OS in name
env:
OS_FILENAME: 'spam-${{ runner.os }}.zip'
run: |
echo "OS_FILENAME=spam-${{ runner.os }}.zip" >> $GITHUB_ENV
touch "./${{ env.OS_FILENAME }}"
touch blah.txt
- name: List created file
run: ls -l "./${{ env.OS_FILENAME }}"
It looks like you can also set and access env in steps, and those persist across workflow steps. For example, I set the environment variable $OS_FILENAME in step 3 using the echo syntax, and reference it in step 4. This works across all the OS options offered on GitHub Actions.
Note that the GitHub Actions docs state that "Environment variables must be explicitly referenced using the env context in expression syntax or through use of the $GITHUB_ENV file directly; environment variables are not implicitly available in shell commands.". Basically, it means you can't implicitly refer to env variables like $FOO and instead must refer to them as ${{ env.FOO }} in shell commands.
So for your scenario, does it satisfy your requirements if you set $ARTIFACT_NAME in the first step of the job? I wonder if the reason might be that the runner context isn't created until the first step - I'm not sure I have a way of testing this.
I encountered issue that env defined by secret env is empty. I want to use secret env in run syntax. I defined env of secret env like here.
- name: Deploy
env:
GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
run: |
date_time=`date +%Y%m%d%H%M%S`
IMAGE=gcr.io/$GCP_PROJECT_ID/web-api-server:$date_time
but $GCP_PROJECT_ID is empty.
invalid argument "gcr.io//web-api-server:20200718163842" for "-t, --tag" flag: invalid reference format
See 'docker build --help'
of course. I confirmed that $GCP_PROJECT_ID is defined at a secret.
The reason is here.
Organization secrets can only be used by public repositories on your plan.
If you would like to use organization secrets in a private repository, you will need to upgrade your plan.