Github provides secrets, whose values can be used in workflows. Unfortunately, the values of secrets is protected and we can't easily see it in the repo or debug it in the workflow as it is scrubbed.
Is there a way to define an "environment variable" in the repository that can be easily seen and debugged? My use case is for configuration that can be easily modified if the repo is forked.
You can store environment variables in an .env file like this:
FOO=bar
Then you can write code to append data from that file to $GITHUB_ENV:
name: CI
on:
workflow_dispatch:
jobs:
foo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
- run: cat .env >> $GITHUB_ENV
- name: Use the value
run: echo $FOO
You'll need to do cat .env >> $GITHUB_ENV (and use actions/checkout) for each job where you need to access env vars from that file.
DO NOT STORE SECRETS IN .env -- use it only for storing configurations, etc.
Complete code: https://github.com/brc-dd/env-from-file
You can also change .env to something like .env.github to keep things more organized.
FYI: you can pass secret as env variable inside job.
Sample job where I have added foo as a secret in actions workflow:
name: simple secret
id: secret_env
env:
foo: ${{ secrets.foo}}
run: echo $foo **
above is example but ignore code syntax issues because of comments format here..
Related
I'm trying to keep multiple github actions in the same monorepo using subdirectories, and run them like:
workflow.yml
// [...]
jobs:
run_my_script:
runs-on: ubuntu-latest
steps:
- name: Check out current repo
uses: actions/checkout#v2
- uses: ./my_action2
with:
my_input_var: "david"
./my_action2/action.yml
// [...]
runs:
using: "composite"
steps:
# Checkout files in this repo
- name: Checkout
uses: actions/checkout#v1
- name: Run myscript
run: python myscript.py "${{ inputs.my_input_var }}" # location: ./my_action2/myscript.py
shell: bash
The problem I'm having is that my action uses a python script in it's subdirectory, but the uses: action appears to run from the GITHUB_WORKING_DIR of the workflow and not the directory of the action itself.
python: can't open file 'myscript.py': [Errno 2] No such file or directory
I've looked through most of the working-directory questions surrounding github actions, but I'm still stumped.
I've also tried adding working-directory: ./my_action2 to the job's defaults: but it looks like it's not propagating to run: commands within the uses: step.
My workaround in the meantime has been to add an input for myaction2_working_directory in the workflow, and then add working-directory: ${{ inputs.myaction2_working_directory }} to every run: command in the action. This seems inelegant and repetitive. Is there a better way to do this?
contrary to the answer by Grzegorz, you cannot just run: cd foo and then expect all following steps to have a working directory of foo. as far as i can tell, the only way to do this is with the "workaround" the OP already posted -- add an input named e.g. working-directory to your action and then add working-directory: ${{ inputs.working-directory }} to every step. see https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsworking-directory
I had similar problem and for my composite actions I just added a first step as:
run: cd ${{ inputs.working_directory }}
and then all next steps are running in it.
I couldn't find a better way and having working-directory copy pasted was also something I didn't like.
Hello I'm a little confused if it is possible via Github Actions to get the latest SHA of a file with only its file's name.
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
pull_request:
branches: [ master ]
# 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 "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# 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
with:
fetch-depth: 0
- name: Get specific changed files
id: changed-files-specific
uses: tj-actions/changed-files#v15.1
with:
files: |
*.groovy
files_ignore: |
*.yml
# Runs a set of commands using the runners shell
- name: echo changed files
run: |
echo modified files ---
echo ${{steps.changed-files-specific.outputs.modified_files}}
As you can see with the combination of action changed-files-specific and echo changed files I am able to get the filename. I looked at the documentation of the tj-actions/changed-files library and it does not provide file info support.
Is there an easy way to do this? I tried searching for another action library but it does not seem to be a very common use case.
Many Thanks,
Morgan Morningstar
You are on the right track.
Now when you have all the modified files and their paths - you can just easily do whatever you want with those files.
You can iterate over those files and calculate SHA for each of them using those paths.
Something like this:
for file in ${{ steps. changed-files-specific.outputs.modified_files }}; do
sha=`sha1sum $file | cut -d ' ' -f 1`
echo "sha for $file: $sha"
done
I currently have a GitHub Action that triggers on:
pull_request_review:
types: [submitted]
I then want to run a command, which expects the contents of changes of the Pull Request.
Previously, I was using
on:
push
and I had no issues with the contents of the files being available in the Action context.
However, my command is failing now, and I think it's because the context only includes the commit that the action was triggered on (no file changes.)
Previously I was running this action on push and that was always successful, with the file changes being available in the context.
I'm using:
steps:
- uses: actions/checkout#v2
(https://github.com/actions/checkout)
Is it possible to use this to have all the file changes on the Pull Request within the Action context?
Any help on this would be appreciated!
You can do that by using an open source Action available on marketplace:
jobs:
build:
runs-on: ubuntu-latest # windows-latest | macos-latest
name: Test changed-files
steps:
- uses: actions/checkout#v2
with:
fetch-depth: 0 # OR "2" -> To retrieve the preceding commit.
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files#v14.6
- name: List all changed files
run: |
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
echo "$file was changed"
done
The solution above uses git checkout and git diff to get files changed by PR. Alternatively if you really need just information about paths changed and you don't really need files themselves (no checkout) - you can do it without checkout using gh CLI:
gh pr view XXX --json files -q '.files[].path'
You can run it like this:
jobs:
comment:
runs-on: ubuntu-latest
steps:
- run: gh pr view XXX --json files -q '.files[].path'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
I have a simple workflow:
name: Test CI
env:
path_to_watch_for_commits: 'testdir/testfile'
on:
push:
branches:
- master
paths:
- ${{ env.path_to_watch_for_commits }}
workflow_dispatch:
jobs:
build:
runs-on: ubuntu
steps:
- uses: actions/checkout#v2
I want to use variable path_to_watch_for_commits in paths. But this syntax is wrong. Also i try ${{ path_to_watch_for_commits }} and $path_to_watch_for_commits with no results. What am i doing wrong?
There is a Naming conventions for environment variables explaining that:
Any new environment variables you set that point to a location on the filesystem should have a _PATH suffix. The HOME and GITHUB_WORKSPACE default variables are exceptions to this convention because the words "home" and "workspace" already imply a location.
Regarding the use of environment variables at different levels inside the workflow, here is an example with WORKFLOW, JOB and STEP variables:
name: Example
on: [push, workflow_dispatch]
env:
WORKFLOW_VARIABLE: WORKFLOW
jobs:
test:
runs-on: ubuntu-latest
env:
JOB_VARIABLE: JOB
steps:
- name: Run Commands with various variables
if: ${{ env.WORKFLOW_VARIABLE == 'WORKFLOW' }}
env:
STEP_VARIABLE: STEP
run: |
echo "Hello World"
echo "This is the $WORKFLOW_VARIABLE environment variable"
echo "This is the $JOB_VARIABLE environment variable"
echo "This is the $STEP_VARIABLE environment variable"
Regarding the possibility of the behaviour you want to achieve in your workflow, you can't set variables at the workflow and use them as paths on the same level, because:
Variables are substituted in the runner operating system after the job
is sent to the runner.
Reference
A workaround could be to trigger the workflow every time on push event, using the paths-filter action with an if conditional to execute specific steps if it match your paths.
It's not the best solution regarding optimisation, but it will work.
After reading this answer:this
I tried to do the same.
I have a .net core project and in my case, I am using a repo with a publish version so my appsettings.json is in the root of the repo.
# This is a basic workflow to help you get started with Actions
name: DeployToStaging
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
pull_request:
types: [assigned, opened, synchronize, reopened]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
FTP-Deploy-Action:
name: FTP-Deploy-Action
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2.1.0
with:
fetch-depth: 2
- uses: microsoft/variable-substitution#v1
with:
files: '${{env.DOTNET_ROOT}}/appsettings.json'
env:
ConnectionStrings.ToBudget: 'This is just a test'
- name: FTP Deploy
uses: SamKirkland/FTP-Deploy-Action#3.1.0
with:
ftp-server: <MyServer>
# FTP account username
ftp-username: <MyUsername>
ftp-password: ${{ secrets.FtpPassword }}
So basically I want to transform my connection string (for now it is just a test, in the future I will create a secret) and then push it to the server through FTP.
Everything is working except the variable substitution. The error is: No file matched with specific pattern: /appsettings.json
Any help would be much appreciated
Just found the issue.
instead of files: '${{env.DOTNET_ROOT}}/appsettings.json' I just need to do files: 'appsettings.json'
Now I am having a second issue. SamKirkland/FTP-Deploy-Action#3.1.0 doesn't like the change. It is avoiding uploading because the repo is dirty.
EDIT: regarding the second issue I moved to sebastionpopp/ftpaction