GitHub actions: env value in branches names (i.e. on push) - github

I need to run only on branches what ends with specified env variable.
Let's pretend that we are on feat/project-name branch and this is may workflow.yml:
env:
PROJECT: project-name
on:
push:
# only for branches what ends with given project name
branches:
- "**$PROJECT"
Above not work. Below, hard coded is OK:
env:
PROJECT: project-name
on:
push:
# only for branches what ends with given project name
branches:
- "**project-name"
Tried with: "**${{ env.PROJECT }}" and other configuration and nothing works.

You can configure env variables at the workflow level, but you can't use them at that level.
According to the documentation (reference 1 and reference 2):
Environment variables (at the workflow level) are available to the steps of all jobs in the workflow.
In your example, the environment variable is used at the workflow level (in the trigger on configuration), not inside a job steps, and the GitHub interpreter doesn't interpolate the value at that level.
You would need to hardcode the value at that level, or receive it as input (${{ inputs.value }}) from another workflow (or from the GitHub API).

Related

Github Actions Environment Variables

I'm sure this must be really simple, but I just can't see it and would appreciate any assistance.
Lets say I have a really simple pipeline like this:
name: Deploy to App Engine
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
PROJECT_ID: stankardian
REGION: europe-west2
APP_NAME: tootler
jobs:
deploy:
name: Test Deployments To App Engine
runs-on: ubuntu-latest
steps:
# Checkout the repo code:
- name: Checkout repository
uses: actions/checkout#v3
with:
ref: main
What I am trying to do is re-use the same pipeline for multiple deployment scenarios where the deployment steps can can the same, but I need to be able to use different values in the deployment steps.
For example the APP_NAME below is 'tootler'. Lets say I need to deploy this to dev, test and preprod. For dev the app name would be 'dev-tootler', in test it would be 'test-tootler, but in preprod it might need to be 'preprod-tootler-v4' or some such.
Ideally I would like to set a single variable somewhere to control the environment I'm deploying into then depending on the value of that variable then load a range of other environment variables with the specific values pertaining to that environment. The example is grossly simplified, but I might need to load 40 variables for each environment and each of those might be a different value (but the same env variable name).
In an ideal world I would like to package the env variables and values in the app directory and load the correct file based on the evaluation of the control variable. E.g.
|
|-- dev.envs
|-- test.envs
|-- preprod.envs
along with :
$env_to_load_for = $env:control_variable
load_env_variables_file($env_to_load_for)
In that pseudocode the value of $env_to_load_for evaluates to the correct filename for the environment I need to work with,then the correct environment varibles get loaded.
I have tried running a bash shell script which exports the variables I need, but I'm finding that those variables only exist for the specific step in the pipeline. By the time I list out the environment variables in the next step, they are gone.
Does that makes sense? This kind of scenario must be very common, but I cant seem to locate any patterns that explain how to accomplish this. I don't want to do down the route of managing different yaml files per environment when the actions are identical.
Would be very grateful for any assistance.
After a lot of experimentation I think I came up with a good way to achieve this. Posting as an answer in case this information helps someone else in the future.
What I did was:
Add a bash step immediately after the checkout
Use that step to run a shell script, I called the script 'target_selector.sh'
In 'target_selector.sh' I evaluate an existing environment variable which I set already at either the job or workflow scope. This is set to either 'dev', 'test' or 'preprod' and wil be used to set the context for everything in one single easy to manage value.
I used a case block to then, depending on the value of that variable, dot source either 'dev.sh', 'test.sh' or 'preprod.sh' depending on what was evaluated. These files I put in a /targets folder.
This is where the magic happens, in those .sh files (in the /targets folder), I added the environment variables I need, for that context, using this syntax:
echo "DEPLOY_TARGET=dev" >> $GITHUB_ENV
echo "APP_NAME=dev_appname" >> $GITHUB_ENV
Turns out that this syntax will write the output of the expression up to the workflow scope. This means that subsequent steps in the workflow can use those variables.
Its a little bit of a faff, but it works and is clearly extremely powerful.
Hope it helps someone, someday.

How to exclude certain branches for a path pattern within Github Actions?

How to apply branches-ignore and paths-ignore on GitHub Actions? For example, if I have the following source tree:
|-src\
|----reports\
|-------<foo>DailyReports.ts
I want to only deploy that to production (master branch) but NOT staging (staging branch).
Any advice and insight is appreciated.
You won't be able to achieve what you want with ON trigger configuration alone. Therefore the implementation below wouldn't work as it would trigger for push to the specified path OR for push to the master branch, but not only for both:
on:
push:
path:
- 'src/reports/*DailyReports.ts'
branches:
- master
In that case, you could do it by using only one trigger at the workflow level, and check the other condition with an IF expression.
For example by doing this:
on:
push:
path:
- 'src/reports/*DailyReports.ts'
jobs:
job1:
runs-on: ...
if: github.ref == 'refs/heads/master' # run this job only for the master branch
steps:
...
Or by checking the branch at the workflow level, and then use something like this path-filter action to check if the file or directory has been updated or not before performing some operation.
I personally suggest the first option (cf example), as it's less verbose.
Note: If the src/reports/*DailyReports.ts path isn't working as expected, you can use the filter pattern cheat sheet to find the right expression.

Approval & Checks on Azure Repos Git are ignored

I placed a checks configuration on my git repository.
Then I added a yaml pipeline to the same directory.
If I run the pipeline all checks or approvals are ignored independent of the type as if they don't exist.
In the log of the job I can see that the repositoy is accessed (default checkout of self).
Do checks on resources with type repository get only executed under special circumstances?
Am I missing something?
I want to force the pipeline to extend a dedicated template regardless which environment is used.
here the pipeline source, that I expected to fail:
trigger:
- main
- users/*/*
- features/*
pool:
vmImage: ubuntu-latest
steps:
- bash: echo "hello world"
displayName: echo something
I checked the same checks on the agent pool and that works as expected. It fails the pipeline if that does not extend the template.
template check configuration

Only release changed projects in GitHub Actions

I have 5 small Function Apps in 1 solution. I set up GitHub Actions to get them released automatically to Azure.
Every time I push new code, it runs all the actions because they are all in the same repository. But most of the time I only changed code in one of the projects.
How can I make sure that only changed Function Apps are released?
I know that I can split them up into separate repositories and solve it that way, but I am looking for a solution where I don't have to do that.
You may create multiple workflow files for each function and specify the paths option to trigger your workflow. If at least one path matches a pattern in the paths filter, the workflow runs.
I assume your directory structure is as follows;
|_azure-functions
|_ function1
|_ function2
with the above sub-directories, you can define each workflow as follows.
# .github/workflows/function1-ci.yml
name: Publish Function1
on:
push:
branches: [ main ]
paths:
- "function1/**"
# .github/workflows/function2-ci.yml
name: Publish Function2
on:
push:
branches: [ main ]
paths:
- "function2/**"
Additionally, there is a paths-ignore option too available for excluding changes from locations defined. You can use a combination of this option aswell.

How to have workflow specific environment in a GitHub workflow yml file

I am creating a /.github/<workflow>.yml and am struggling with the environment.
from https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#env
A map of environment variables that are available to all jobs and steps in the workflow. You can also set environment variables that are only available to a job or step. For more information, see jobs.<job_id>.env and jobs.<job_id>.steps.env.
When more than one environment variable is defined with the same name, GitHub uses the most specific environment variable. For example, 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.
From https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-environment-variables
To set custom environment variables, you need to specify the variables in the workflow file. You can define environment variables for a step, job, or entire workflow using the jobs.<job_id>.steps.env, jobs.<job_id>.env, and env keywords. For more information, see "Workflow syntax for GitHub."
How do I set up environment variables for the entire workflow (multiple jobs)?
on: push
env:
MY_ENV: value
jobs:
job1:
runs-on: ubuntu-latest
steps:
- run: echo "MY_ENV_1 = $MY_ENV"
job2:
runs-on: ubuntu-latest
steps:
- run: echo "MY_ENV_2 = $MY_ENV"
I'm 100% sure this one works, and 95% sure that you'll getting "invalid workflow" error due to mistake in other part of workflow or some minor syntax error (missing space, = instead of : when declaring variable, value starts with non-alphanumeric character and it's not inside '', etc).
Error report page is currently broken (at least for me) - whole message is in single line with no way to see more than just a beginning. If that's a case for you as well, use 'inspect element' in you browser, so you can see it in all its glory.
How do I set up environment variables for the entire workflow (multiple jobs)?
Well, you can't with the keyword env if you want to setup the environnement once. Ontherwise, you set the env in each job, like that :
jobs:
build:
runs-on: ubuntu-18.04
env:
- FOO: foo
- BAR: bar
steps:
- uses: actions/checkout#v1
- name: Do something
test:
runs-on: ubuntu-18.04
env:
- FOO: foo
- BAR: bar
steps:
- uses: actions/checkout#v1
- name: Do something else
But it depends if it's what you really want to do. A MRE would be appreciate, if it's not what you need, as jonrsharpe said.