MAIN ISSUE
While experimenting with github actions, faced an issue such that the default environment variables passed to pre-built actions specifically under the with syntax didn't getting processed, i.e.
- name: variable check
uses: external/action-module#v2
with:
option1: ${{ secrets.ENV_1 }}
option2: ${GITHUB_DEF_VARIABLE}
The secrets(${{ secrets.ENV_1 }}) getting rendered correctly while the github-actions default variables(${GITHUB_DEF_VARIABLE}) failed to render.
BACKGROUND AND REAL CASES
Showing some cases,
When calling an ansible playbook with github actions,
- name: Check ansible playbook execution with module
uses: dawidd6/action-ansible-playbook#v2
with:
playbook: ${{ secrets.ANSIBLE_ROOT }}/Playbooks/ping.yml
inventory: ${{ secrets.ANSIBLE_INVENTORY }}
options: |
--extra-vars github_workpath=${GITHUB_WORKSPACE} other_var=${{ secrets.EXTA_VAR }}
The issue is that the default env variable didn't getting processed (${GITHUB_WORKSPACE}), but the secrets rendering without any issues (${{ secrets.EXTA_VAR }})
Tried the same by setting an env: and then calling ${{ env.VARIABLE }} but that also not worked,
What finally worked for me was by manually calling playbook with inventory after setting the default variable to a global job env.
env:
project_path: ${GITHUB_WORKSPACE}
steps:
- name: Calling Ansible playbook directly
run: >
ansible-playbook
-i ${{ secrets.ANSIBLE_ROOT }}/inventory.yml
${{ secrets.ANSIBLE_ROOT }}/Playbooks/ping.yml
--extra-vars github_workpath=${{ env.project_path }}
Now the ${{ env.project_path }} processed to give the desired output(passing the variable ${GITHUB_WORKSPACE} direct also failed)
The same issue faced when trying to send Job completion web-hook notification, eg
- name: Mattermost Notification
uses: komarnitskyi/action-mattermost-notification#v0.1.2-beta
with:
webhook: ${{ secrets.MATTERMOST_WEBHOOK_URL }}
text: "| ${GITHUB_EVENT_NAME} | ${GITHUB_REF##*/} | ${{ job.status }} |"
The end text displayed as ${GITHUB_EVENT_NAME} | ${GITHUB_REF##*/}, but the ${{ job.status }} rendered correctly as completed/failed.. ,
Can somebody explain this behaviour and any workarounds for this issue.
Related
I am working on a project where I need to create a tweet from an account whenever a certain issue or pull request has a label issue/tweet
I am able to make tweet when label is applied to issue but unable to do so when the same lable is applied to a pr
the .yml file I am working on
name: Send a Tweet
on:
issues:
-label: issue/tweet
pull_request:
types: [labeled]
jobs:
tweet:
if: ${{github.event.label.name == 'issue/tweet'}}
runs-on: ubuntu-latest
steps:
- uses: ethomson/send-tweet-action#v1
with:
status: ${{github.event.issue.html_url}} "#opensource"
consumer-key: ${{ secrets.TWITTER_CONSUMER_API_KEY }}
consumer-secret: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}
access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}
access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
expected to make a tweet when pr is labeled with `issue/tweet'
Let's dissect the important parts...
Workflow sections
on events
You want issues and pull_request to trigger the workflow and I think both of them should have their types set to labeled.
if job condition
The condition needs to be applied to the correct object within github.event. For each of these events, the content is different. It's defined in Webhook events and payloads.
Both issue and pull_request should have github.event.label so I'm not sure why it wouldn't work. It might be a good idea to dump the entire context at the beginning of your job in order to debug it.
However, both events also have github.event.TYPE.labels, an array of label objects. Therefore, it might be a better option to use that and apply contains expression on it:
contains(github.event.TYPE.labels.*.name, 'issue/tweet')
Result
name: Send a Tweet
on:
issues:
types: [labeled]
pull_request:
types: [labeled]
jobs:
tweet:
if: >-
(
contains(github.event.pull_request.labels.*.name, 'issue/tweet') ||
contains(github.event.issue.labels.*.name, 'issue/tweet')
)
runs-on: ubuntu-latest
steps:
- uses: crazy-max/ghaction-dump-context#v1
- uses: ethomson/send-tweet-action#v1
with:
status: ${{github.event.issue.html_url}} "#opensource"
consumer-key: ${{ secrets.TWITTER_CONSUMER_API_KEY }}
consumer-secret: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}
access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}
access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
I have the following workflow in my GitHub actions:
name: Tests e2e iOS App
on:
workflow_dispatch:
inputs:
skip:
type: boolean
required: true
default: false
jobs:
build-simu-ios-zip:
name: Build iOS simulator zip
uses: ./.github/workflows/reusable-e2e-buildsimuioszip.yml
secrets: inherit
with:
environment: ${{ inputs.environment }}
I would like to run the job build-simu-ios-zip conditionnaly, I add the following:
jobs:
build-simu-ios-zip:
name: Build iOS simulator zip
+ if: ${{ inputs.skip == 'false' }}
uses: ./.github/workflows/reusable-e2e-buildsimuioszip.yml
secrets: inherit
with:
environment: ${{ inputs.environment }}
But the job automatically get skipped.
I also tried to pass an input to the reusable workflow and make it conditionnaly it from there, but it also skip.
How can I make a conditionnal reusable workflow in GitHub action?
I made some tests here and using if: ${{ inputs.skip == 'false' }} with single quotes ' doesn't work as you are comparing a boolean type with a string.
However, I found 2 options that worked:
if: ${{ inputs.skip == false }} (no quote)
if: ${{ ! inputs.skip }} (as it's a boolean input, but with !)
Note: I used this workflow for tests.
I have a Chalice (AWS lambda Python framework) project the following CI/CD GitHub Action workflow:
name: Production Workflow
on:
push:
branches:
- "main"
env:
REPO: ${{ github.repository }}
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_SHA: ${{ github.sha }}
jobs:
production:
name: Deploy production
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
- name: Set up Python
uses: actions/setup-python#v1
with:
python-version: "3.9"
- name: Install requirements
run: pip3 install -r requirements.txt
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials#v1
with:
aws-region: ${{ secrets.AWS_REGION }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Check branch
run: echo "${{ env.GITHUB_REF_NAME }}"
- name: Check branch
run: echo "${{ env.GITHUB_SHA }}"
- name: Run tests
run: python3 -m unittest discover -s tests
- name: Deploy with Chalice
run: chalice deploy --stage=production
However, from inside the project, the env variables REPO, GITHUB_REF_NAME and GITHUB_SHA are not accessible (i.e. os.environ.get("GITHUB_REF_NAME", None)). Why?
I also tried setting the env variables not globally, but in the "Deploy with Chalice" step only, with the same result. Also, I can successfully see the branch and commit ID written in GitHub Actions by the "Check branch" and "Check branch" steps.
Other env variables that are set in the Chalice config file .chalice/config.json are accessible.
You need to set up the environment and explicitly list all ENV variables you want to use, like this:
- name: Deploy with Chalice
run: chalice deploy --stage=production
env:
GITHUB_REF_NAME: ${{ secrets.GITHUB_REF_NAME }}
GITHUB_SHA: ${{ secrets.GITHUB_SHA }}
I want to send debug msg output from playbook to Slack and I am running this in GitHub actions.
GitHub Actions yml file (in .github dir)
on:
workflow_dispatch:
schedule:
- cron: '0 2 * * *'
jobs:
scheduled_test:
uses: ./.github/workflows/base.yml
with:
ou_env: sandbox
playbook: ping_hosts
secrets:
approle_id: ${{ secrets.APPROLE_ROLE_ID }}
secret_id: ${{ secrets.APPROLE_SECRET_ID }}
submodule_pat: ${{ secrets.SUBMODULE_PAT}}
slack_webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
Slack step in ./.github/workflows/base.yml looks like.
- name: Send slack notification
uses: act10ns/slack#v1.6.0
with:
webhook-url: ${{ secrets.slack_webhook }}
status: ${{ job.status }}
steps: ${{ toJson(steps) }}
if: always()
Playbook looks like
- hosts: platform_linux:!skipped_group
gather_facts: yes
become: yes
tasks:
- name: Ping Linux host
ansible.builtin.ping:
- name: Print percentage of Linux succeeded hosts
debug:
msg: "Success percentage for Linux is {{ 100 - ((ansible_play_hosts|length)/(ansible_play_hosts_all|length))*100 | round }}"
- name: Print Linux hosts that failed
debug:
msg: "The Linux hosts that failed are {{ ansible_play_hosts_all | difference(ansible_play_hosts) }}"
I am able to send the fail or pass status on Slack, but I am not sure how to send the outputs from debug msg in playbook to Slack via Actions.
Regarding
How to send the outputs from debug msg in playbook to Slack
you could probably use the slack module – Send Slack notifications
- name: Send notification message via Slack
community.general.slack:
token: thetoken/generatedby/slack
msg: 'Success percentage for Linux is {{ 100 - ((ansible_play_hosts|length)/(ansible_play_hosts_all|length))*100 | round }} and the Linux hosts that failed are {{ ansible_play_hosts_all | difference(ansible_play_hosts) }}'
delegate_to: localhost
Further Documentaion
Examples
I'm using GitHub Actions.
I'm trying to create a self-hosted runner that will run on one of several cloud servers, but be able to control which specific server it runs on. This is to do rolling updates on machines that have local resources.
I've setup tags with the self-hosted runners, but so far am having to make 1..N separate YML scripts:
on:
workflow_dispatch:
jobs:
post-to-server1:
runs-on: [self-hosted, server1 ]
Then I have to repeat this script n number of times.
What I'd like to do is this:
name: 'Server Patching'
on:
workflow_dispatch:
inputs:
server-target:
description: 'Target Server:'
required: true
default: 'dev'
jobs:
test-params:
runs-on: [ self-hosted, ${{ github.event.inputs.server-target }}]
steps:
- name: Start cloning of ${{ github.event.inputs.server-target }}
run: |
echo "Starting patching of: '${{ github.event.inputs.server-target }}'"
Check failure on line 12 in .github/workflows/test_workflow.yml
GitHub Actions / .github/workflows/test_workflow.yml
Invalid workflow file
You have an error in your yaml syntax on line 12
Is there a way to do this?
I tagged this YAML also, because the variable substitution seems to be an issue with the YAML syntax as well (although it may be specific for GitHub Actions)
Update: Yes, you can, if you change this line:
runs-on: [ self-hosted, ${{ github.event.inputs.server-target }}]
to:
runs-on: ${{ github.event.inputs.server-target }}
The error actually happens on test-params: not the line below it.
My theory is that the syntax checker fires before the variable substitution?
I'm not sure what makes difference, but it works for me:
runs-on: [ self-hosted, "${{ github.event.inputs.server-target }}" ]
Creating a list like that does not seem to work with dynamic values.
As long as you choose labels that are not already in use by GitHub (e.g. ubuntu-latest, macos-11, ...) you should not have a problem with dropping the self-hosted label. So your current naming pattern should be fine by itself
That way you can just use this:
runs-on: ${{ github.event.inputs.serverToPatch }}