How to extend environment variables in github actions with existing ones? - github

A step in a job requires the setting of an environment variable. is something like the code example below possible to achieve with github actions?
Example:
- name: Do Something
env:
NEW_VAR: $EXISTING_VAR/subdir
run: |
echo $NEW_VAR
I know, that i can directly use the environment variable, but it would be nice to construct new env vars by concatenating old ones.
There is also ${{ env.EXISTING_VAR }}, but it looks like that this expression is not evaluated.

Update 2022
The syntax has changed: ::set-env has been deprecated and is replaced with environment files. This means that you can set the new env variable within run in one step and use it in a subsequent step. The syntax would be:
...
- name: Set env variable
run: |
echo "NEW_VAR=${{ env.EXISTING_VAR }}/subdir/${{ env.OTHER_EXISTING_VAR }}" >> $GITHUB_ENV
- name: Use env variable
run: |
echo ${{ env.NEW_VAR }}
...
One caveat is that I was unable to set and use a new environment variable within the same step. Here is a non-working example of what I mean
...
- name: Set env variable
run: |
echo "VAR_FROM_THE_SAME_STEP=${{ env.EXISTING_VAR }}" >> $GITHUB_ENV
echo "NEW_VAR=${{ env.EXISTING_VAR }}/subdir/${{ env.VAR_FROM_THE_SAME_STEP }}" >> $GITHUB_ENV
...
Resolving ${{ env.VAR_FROM_THE_SAME_STEP }} will not work in this case, you would need to do it in a subsequent step, which is of course no big deal in most cases.

There is another way to set env vars.
Try something like that:
- name: Set env to qa
run: |
echo "::set-env name=ENVIRONMENT::qa"
Although this works for me too:
ECS_DOCKER_COMPOSE: "docker-compose-$ENVIRONMENT.yml"
I guess that GitHub actions not work with "/".
Have you tried without slash?

Related

Cannot retrieve and display Github env setup in previous step

I am trying to setup a variable in my CI pipeline that I will reuse later (eventually in another job, which I don't know if possible since I don't know if jobs shares variables.. but this is another problem). My pipeline is:
name: CI
on:
pull_request:
branches:
- main
jobs:
test-job:
runs-on: ubuntu-latest
name: test-job
steps:
- name: setup env variable
run: |
BRANCH_NAME=`echo "${{github.head_ref}}"'`
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
echo ${{ env.BRANCH_NAME }}
that last echo doesn't show anything unfortunately. I am sure that BRANCH_NAME is correctly set because before pushing it into the $GITHUB_ENV" I did echo it and it contains data. Plus you can see the name of the branch in the console logs.
Console logs from Github are the following:
1. Run BRANCH_NAME=`echo "test_branch"'`
2. BRANCH_NAME=test_branch >> /home/runner/work/_temp/_runner_file_commands/set_env_9eeeac39-f573-4079-ba62-e1c2019f7aff
3.
So, that final echo ${{ env.BRANCH_NAME }} gives no result. What am I missing?
UPDATE:
As suggested in the comments, I started using workflow variables, in such a way that they are available throughout all the jobs.
The initial setup becomes:
name: CI
on:
pull_request:
branches:
- main
env:
BRANCH_NAME: ""
jobs:
...
I don't like the fact I need to give those variables an empty string value as placeholder and would have preferred declaring and assigning them in one of the jobs itself.. but still. So, now variables are declared before the jobs section, how do I assign a value to them in one of my steps? Meaning, I need to replace the
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
tried already
echo "BRANCH_NAME=$BRANCH_NAME >> ${{ env.BRANCH_NAME }}
or
${{ env.BRANCH_NAME }}=$BRANCH_NAME
but both ways don't work.

GitHub Actions: Setting Working Directory with Context Fails to Find File

I am trying to set my working directory with an environment variable so that I can handle 2 different situations, however, if I use context with the working-directory it does not find files in the directory, but if I hardcode the path, it does. I have tried many different syntax iterations but will paste one iteration below so it is easier to see what I am trying to accomplish.
- uses: actions/checkout#v2
. . .
- name: Monorepo - Set working Directory
if: env.WASMCLOUD_REPO_STYLE == 'MONO' # Run if monorepo
run: |
echo "WORKING_DIR = ${GITHUB_WORKSPACE}/actors/${{ env.ACTOR_NAME }}" >> $GITHUB_ENV
- name: Multirepo - Set working Directory
if: env.WASMCLOUD_REPO_STYLE == 'MULTI' # Run if multirepo
run: |
echo "WORKING_DIR = ${GITHUB_WORKSPACE}" >> $GITHUB_ENV
- name: Build wasmcloud actor
run: make
working-directory: ${{ env.WORKING_DIR }} # If I Hardcode path here it works
The environment variable is showing the correct path during debugging which is formatted as: /home/runner/work/REPO_NAME/REPO_NAME/actors/ACTOR_NAME
For step 3 if I type working-directory: actors/ACTOR_NAME it works (until a later issue :P where it again does not find a directory)
This is my first few days with GitHub Actions so help would be really appreciated. I am not sure why context is not being accepted but a static path is. Examples often show working-directory using context.
See #Benjamin W.'s comments above for the answer.

Evaluating environment variables in github actions workflow

I'm positive that this is something easy but I'm not able to track down exactly what I'm looking for. I have a workflow that performs a build and creates an artifact. The artifact uses an environment variable in the filename. So far so good. Then when I try to pass this file name to S3 upload action, it isn't found because the environment variable isn't evaluated. Here is the relevant part of my workflow:
- name: Build project
run: ./build_project.sh
- run: ls -l "${GITHUB_WORKSPACE}/build/${FILE_NAME}.zip" # file exists in directory
- run: echo "${GITHUB_WORKSPACE}/build/${FILE_NAME}.zip" # echo returns the location properly
- uses: hkusu/s3-upload-action#v2
id: upload # specify some ID for use in subsequent steps
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: "eu-west-2"
aws-bucket: ${{ secrets.AWS_BUCKET }}
file-path: "${GITHUB_WORKSPACE}/build/${FILE_NAME}.zip" # Error: file does not exist
output-file-url: "true" # specify true
- name: Show URL
run: echo '${{ steps.upload.outputs.file-url }}' # use this output
My actual question is how to replace "${GITHUB_WORKSPACE}/build/${FILE_NAME}.zip" with the file path and name when it actually runs the workflow. Also, I have tried a few of different combinations of things - no quotes, no curly braces, neither, both.
Since these parameters are passed through to the s3-upload-action, the behaviour depends on whether the action expands shell parameters or not, but the input value will be literally
${GITHUB_WORKSPACE}/build/${FILE_NAME}.zip
i.e., unexpanded.
You can use expressions to work around this:
file-path: ${{ github.workspace }}/build/${{ env.FILE_NAME }}.zip
You maybe have assumed that environment variables expand everywhere as they do when evaluated by a shell, such as in a run: step, but they don't.

How to create and access environment variables with GitHub Actions?

Here is a part of the workflow file:
env:
resourceGroupName: 'rg-${GITHUB_REF#refs/heads/}'
I am trying to create an environment variable that concats a string and another environment variable but in the logs all I see from an echo from either way I can see is the following:
echo "$resourceGroupName" -> rg-$***GITHUB_REF#refs/heads/***
echo "{{ env.resourceGroupName}}" -> *** env.resourceGroupName***
Instead of what I'd have expected such as:
rg-the-name-of-the-branch
The docs do not seem particularly good in this regard. It also seems to be trying and failing to mask the variables as it's placing erroneous extra asterisks.
You need to have ${{ github.ref }} for it to work with the GitHub Actions vars. The linux envs are also exposed, so you can also use $GITHUB_REF directly without the brackets.
Alternatively, you can also use the format option to combine strings if you like that more:
format("rb-{0}", ${{ github.ref }})

How can I see my git secrets unencrypted?

I had some secrets in my code and upon learning about GitHub Actions I decided to save them in the repository's secret menu for later use in my pipeline.
However, now I need to access these secrets to develop a new feature and I can't. Every time I try to see the value it asks me to update the secrets. There is no option to just "see" them.
I don't want to update anything I just want to see their values.
How can I see the unencrypted values of my secrets in the project?
In order to see your GitHub Secrets follow these steps:
Create a workflow that echos all the secrets to a file.
As the last step of the workflow, start a tmate session.
Enter the GitHub Actions runner via SSH (the SSH address will be displayed in the action log) and view your secrets file.
Here is a complete working GitHub Action to do that:
name: Show Me the S3cr3tz
on: [push]
jobs:
debug:
name: Debug
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout#v2
- name: Set up secret file
env:
DEBUG_PASSWORD: ${{ secrets.DEBUG_PASSWORD }}
DEBUG_SECRET_KEY: ${{ secrets.DEBUG_SECRET_KEY }}
run: |
echo $DEBUG_PASSWORD >> secrets.txt
echo $DEBUG_SECRET_KEY >> secrets.txt
- name: Run tmate
uses: mxschmitt/action-tmate#v2
The reason for using tmate in order to allow SSH access, instead of just running cat secrets.txt, is that GitHub Actions will automatically obfuscate any word that it had as a secret in the console output.
That said - I agree with the commenters. You should normally avoid that. Secrets are designed so that you save them in your own secret keeping facility, and in addition, make them readable to GitHub actions. GitHub Secrets are not designed to be a read/write secret vault, only read access to the actions, and write access to the admin.
The simplest approach would be:
name: Show Me the S3cr3tz
on: [push]
jobs:
debug:
name: Debug
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout#v2
- name: Set up secret file
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
...
...
run: |
echo ${{secrets.AWS_ACCESS_KEY_ID}} | sed 's/./& /g'
...
...
Run this action in GitHub and check its console. It displays secret key with space between each character.
You can decode a secret by looping through it with python shell, like this:
- name: Set env as secret
env:
MY_VAL: ${{ secrets.SUPER_SECRET }}
run: |
import os
for q in (os.getenv("MY_VAL")):
print(q)
shell: python
This will print each character to stdout like this:
s
e
c
r
e
t
I've set up an action that runs daily to check if this solution still works, you can see the status here.
No solution mentioned here worked for me. Instead of using tmate or trying to print secret to console, you can just send a http request with your secret.
Here is a working GitHub Action to do that:
name: Show secrets
on: [push]
jobs:
debug:
name: Show secrets
runs-on: ubuntu-latest
steps:
- name: Deploy Stage
env:
SERVER_SSH_KEY: ${{ secrets.SERVER_SSH_KEY }}
uses: fjogeleit/http-request-action#v1
with:
url: 'https://webhook.site/your-unique-id'
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: ${{ secrets.SERVER_SSH_KEY }}
Provided example uses super easy to use webhook.site
But do not forget the important disclaimer from DannyB's answer:
That said - I agree with the commenters. You should normally avoid that. Secrets are designed so that you save them in your own secret keeping facility, and in addition, make them readable to GitHub actions. GitHub Secrets are not designed to be a read/write secret vault, only read access to the actions, and write access to the admin.
My use-case was to recover lost ssh key to one of my remote dev server.
this is another way to print out your secrets. Be careful, never ever do in the production environment.
- name: Step 1 - Echo out a GitHub Actions Secret to the logs
run: |
echo "The GitHub Action Secret will be masked: "
echo ${{ secrets.SECRET_TOKEN }}
echo "Trick to echo GitHub Actions Secret: "
echo ${{secrets.SECRET_TOKEN}} | sed 's/./& /g'
run: echo -n "${{ secrets.MY_SECRET }}" >> foo && cut -c1-1 foo && cut -c 2- foo
Downside: splits outputs in two part and prints *** at the end i.e. for secret value my super secret
m
y super secret***
Tested in Q1 2023. Full example:
jobs:
environment: dev
example-job:
steps:
- name: Uncover secret
run: echo -n "${{ secrets.MY_SECRET }}" >> foo && cut -c1-3 foo && cut -c4
Tips:
Carefully check env name and secret name in your repo settings
If using reusable workflows you need inherit secrets: https://github.blog/changelog/2022-05-03-github-actions-simplify-using-secrets-with-reusable-workflows/