I am trying to create actions which behave differently depending on the prefix of the origin (head?) branch.
Current use case is sending a Slack message when a branch named bug/<anything> is getting merged into main.
I've tried setting a script up like the following.
report-bugfix.yml
name: Report Bugfix
on:
push:
branches:
- main
jobs:
run_if:
if: startsWith(github.ref_name, 'bug/')
runs-on: self-hosted
steps:
- uses: 8BitJonny/gh-get-current-pr#2.1.0
id: PR
- name: Slack Notify
uses: rtCamp/action-slack-notify#v2.2.0
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_CHANGELOG }}
SLACK_USERNAME: BugBuster Bot
SLACK_COLOR: ${{ job.status }}
SLACK_TITLE: 'A new bug has been fixed! :beetle:'
SLACK_MESSAGE: ${{ steps.PR.outputs.pr_body }}
My action currently gets skipped as the if statement returns false, so I assume my syntax or variable checking is wrong.
Any action sharks who are aware of a elegant solution to my use case?
Edit: Changed following line if: startsWith(github.ref_name, 'bug/**') with if: startsWith(github.ref_name, 'bug/')
However testing with the branchname bug/action-testing the issue still persists
The double asterisk after the bug/ is unnecessary. Unless you only want names like bug/**abcd to pass, the ** will get treated as characters. With the startsWith function, you only need to pass the actual characters to match, and don't need to worry about wildcards.
More info on Github actions expressions: https://docs.github.com/en/actions/learn-github-actions/expressions
So the issue was related to looking for the push event. The event doesn't seem to know about where a push came from, so it was essentially impossible to locate that information for me.
Instead I can use the pull_request event, which sets the github.head_ref variable to the branch which I am creating the request from.
To ensure the action only triggered when the pull request was closed and merged, I used the type closed and github.event.pull_request.merged == true in an if statement.
My final script is as follows:
name: Bug Changelog
on:
pull_request:
types:
- closed
branches:
- 'main'
jobs:
if_merged:
if: github.event.pull_request.merged == true && startsWith(github.head_ref, 'bug/')
runs-on: self-hosted
steps:
- uses: 8BitJonny/gh-get-current-pr#2.1.0
id: PR
- name: Slack Notify
uses: rtCamp/action-slack-notify#v2.2.0
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_CHANGELOG }}
SLACK_USERNAME: BugBuster Bot
SLACK_COLOR: ${{ job.status }}
SLACK_TITLE: 'A new bug has been fixed! :beetle:'
SLACK_MESSAGE: ${{ steps.PR.outputs.pr_body }}
SLACK_FOOTER: ''
MSG_MINIMAL: true
Related
We merge everything to develop. Once a week we merge everything from develop to master. This weekly master merge contains 50+ commits from 10+ issues with 10+ pull requests. In our weekly master merge we want a description with all the related issues or related PRs. I tried different actions, tools or ways to do that. Now Im trying to use the devops-infra action-pull-request (which we already use for the weekly master merge). I tried using different actions where the output should be the related PRs and use this output in the body of your action. I tried using different outputs (url or PR number) of this action but nothing seems to work. The body is just always empty when I look into the logs. Is it a bug? Am I doing something wrong? Is it outdated? Here is my action:
name: weekly master merge
on:
workflow_dispatch:
jobs:
createPullRequest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
with:
fetch-depth: 0
- name: Release Changelog Builder
uses: buildsville/list-pull-requests#v1
id: list
with:
token: ${{ secrets.ALL }}
Labels: '["app/admin"]'
skip_hour: '24'
- name: Set output variables
id: vars
run: |
pr_title="Releases week #$(date +%W)"
body=${{ steps.list.outputs.pulls }}
echo "pr_title=$pr_title" >> $GITHUB_OUTPUT
echo "body=$body >> $GITHUB_OUTPUT
- name: Create Pull Request
uses: devops-infra/action-pull-request#v0.5.3
id: test
with:
github_token: ${{ secrets.ALL }}
source_branch: test
target_branch: main
title: ${{ steps.vars.outputs.pr_title }}
#body: ${{ steps.list.outputs.pulls }}
body: ${{ steps.vars.outputs.outval }}
#body: ${{ steps.test.outputs.* }}
#body: ${{ steps.test.outputs.url }}
It doesnt matter what I do, the PR from this action always has a body full of commits (default body of this action).
This is a test repository with a PAT with most of the permissions. Im just trying to change the body. The comments are some things I tested before but they didnt work either.
Im pretty new to all of this but for my understanding im doing everything correctly. Once again, I tried a bunch of different things...
Need to setup github action for a repository which automatically adds "hacktoberfest-accepted" label once the PR is merged.
Tried with just pull_request_target but the action did not got invoked so added pull_request too but still even on Merging the action is not getting invoked.
Confused about what is causing this issue or is there any other method to achieve the same thing?
Workflow code
on:
pull_request_target:
types:
- closed
pull_request:
types:
- closed
jobs:
label:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
# https://github.com/marketplace/actions/pr-labeler-based-on-multiple-rules
- uses: srvaroa/labeler#v0.8
with:
config_path: .github/labeler_config.yml
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
Config file
version: 1
labels:
- label: "hacktoberfest-accepted"
size-above: 1
Took help from here.
P.S. : Rest of the workflow files are working as expected.
I have two reusable workflows to deploy and destroy GCP resources, which I call from one workflow based on different conditions.
One workflow creates infra and is triggered when the label preview is added to a PR:
on:
pull_request:
types: [opened, reopened, labeled]
jobs:
create-infrastructure:
if: ${{ contains( github.event.pull_request.labels.*.name, 'preview') }}
# Call to a reusable workflow here
The second workflow I need to trigger when the PR is closed or when a specific label is removed; I tried this:
on:
pull_request:
types: [ closed, unlabeled ]
jobs:
destroy_preview:
if: ${{ contains( github.event.pull_request.labels.*.name, 'preview') }}
uses: myrepo/.github/workflows/preview-app-destroy.yml#v0.3.6
with:
project_id: xxx
I don't know how to define unlabeled for a specific label. It would be great if someone has any idea.
The pull request webhook payload doesn't contain the removed label, as far as I can tell, but you can fetch the list of issue events (which work for pull requests, too), filter by unlabeled events, and then look at the label name of the last one.
Using the GitHub CLI in a run step, that might look something like this:
name: Preview removed workflow
on:
pull_request:
types:
- unlabeled
jobs:
destroy_preview:
runs-on: ubuntu-20.04
steps:
- name: Check if "preview" was removed
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
pr=${{ github.event.number }}
label=$(gh api "repos/$GITHUB_REPOSITORY/issues/$pr/events" \
--jq 'map(select(.event == "unlabeled"))[-1].label.name')
if [[ $label == 'preview' ]]; then
echo "The 'preview' label has been removed"
fi
where you'd replace the echo with your infrastructure commands.
Now, if you want to call a reusable workflow when that specific label is removed, you have to somehow find a way to add a condition to the job where the reusable workflow is called.
One option is to make two jobs, one to check the condition and setting the result as a job output. The other job is set up as depending on the first one, and its if condition checks if the output was set to true.
This would look something like this (omitting the name and trigger, as they are identical to above):
jobs:
checklabel:
runs-on: ubuntu-20.04
outputs:
waspreview: ${{ steps.check.outputs.preview }}
steps:
- name: Check if "preview" was removed
id: check
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
pr=${{ github.event.number }}
label=$(gh api "repos/$GITHUB_REPOSITORY/issues/$pr/events" \
--jq 'map(select(.event == "unlabeled"))[-1].label.name')
if [[ $label == 'preview' ]]; then
echo "::set-output name=preview::true"
fi
destroy_preview:
needs: checklabel
if: needs.checklabel.outputs.waspreview
uses: myrepo/.github/workflows/preview-app-destroy.yml#v0.3.6
with:
project_id: xxx
Building a GitHub action based on the commit message I'm trying to base a step on whether the commit message contains a particular string, set it to a variable and then in the next step check with a condition.
My current implementation of my action works:
name: Smoke Test
on:
push:
branches:
- main
permissions:
contents: read
issues: write
jobs:
smoking:
runs-on: [ubuntu-latest]
steps:
- name: Run smoke tests
if: ${{ !contains(github.event.head_commit.message, 'smoke_test') }}
run: |
echo 'Smoke Test not requested'
exit 1
stuff:
needs: smoking
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- uses: JasonEtco/create-an-issue#v2
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
with:
filename: .github/ISSUE_TEMPLATE/smoke-test.md
id: create-issue
- run: 'echo Created issue number ${{ steps.create-issue.outputs.number }}'
- run: 'echo Created ${{ steps.create-issue.outputs.url }}'
but with the implementation of:
exit 1
causes the action to indicate it error'ed out in the action panel and while that works that isn't technically accurate because I don't need it to error I just don't want the remaining steps to run.
I've tried setting a variable:
if: ${{ contains(github.event.head_commit.message, 'smoke_test') }}
with:
run-smoke-test: true
run: |
echo 'Smoke Test requested'
but it's not passing to the next step.
Research
Use environment variable in github action if
How to pass variable between two successive GitHub Actions jobs?
github-action: does the IF have an ELSE?
How to fail a job in GitHub Actions?
GitHub Actions - trigger another action after one action is completed
Without relying on another GitHub action is there a way in step smoking to set an env variable that step stuff would need to validate for before running the step?
Edit
After reading the answer and implementing job outputs I've written:
name: Smoke Test
on:
push:
branches:
- main
permissions:
contents: read
issues: write
jobs:
commitMessage:
runs-on: ubuntu-latest
outputs:
output1: ${{ steps.isSmoke.outputs.test }}
steps:
- id: isSmoke
if: ${{ contains(github.event.head_commit.message, 'smoke_test') }}
run: echo "::set-output name=test::true"
smokeTest:
runs-on: ubuntu-latest
needs: commitMessage
steps:
- uses: actions/checkout#v2
- uses: JasonEtco/create-an-issue#v2
if: steps.isSmoke.output.test == true
env:
GITHUB_TOKEN: ${{ secrets.DEV_TOKEN }}
with:
filename: .github/ISSUE_TEMPLATE/smoke-test.md
but when the commit message of smoke_test is used it bypasses create-an-issue:
and I'm basing my condition after reading "Run github actions step based on output condition" and reading:
Contexts
Expressions
Using conditions to control job execution
Can a condition come before a step and/or what is the correct way to run a step based off the previous step?
You are looking for job outputs, which allow you to send data to the following jobs.
I have a GitHub Actions workflow implemented on the main branch of my repository which creates a new release of my package in GitHub. Then I have another workflow implemented which should be triggered on the creation of a release. This trigger, however, is not working.
Please note that GitHub abandoned their own actions/create-release#v1 project and advises to use the softprops release action.
My workflow template is as follows:
name: Main release
on:
push:
branches:
- main
jobs:
release:
name: 'Release main'
runs-on: ubuntu-latest
steps:
- name: 'Checkout source code'
uses: 'actions/checkout#v2'
with:
ref: ${{ github.ref }
- name: Release
uses: softprops/action-gh-release#v1
with:
draft: false
body_path: CHANGELOG.md
name: ${{ steps.version.outputs.version }}
tag_name: ${{ github.ref }}
token: ${{ github.token }}
My on:release:created trigger workflow is as follows:
name: Act on release created
on:
release:
types: [created]
jobs:
build:
name: Build
environment: dev_environment
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Set env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Test
run: |
echo $RELEASE_VERSION
echo ${{ env.RELEASE_VERSION }}
The release and tags are correctly added in GitHub, so everything looks to work fine except that the workflow that should be triggered on the release is not executed.
How do I solve this?
The GitHub Actions documentation on performing tasks in a workflow states the following:
When you use the repository's GITHUB_TOKEN to perform tasks on behalf of the GitHub Actions app, events triggered by the GITHUB_TOKEN will not create a new workflow run. This prevents you from accidentally creating recursive workflow runs.
This means that you will have to create a personal access token and add this token to you repository secrets.
To generate a new personal access token go to your personal developer settings and generate a new token. Then go to your repository settings and add a new secret containing the personal access token, name it i.e. PAT.
In your release workflow template, replace:
token: ${{ github.token }}
With:
token: ${{ secrets.PAT }}
Now the on release created event the workflow will be triggered!
Note: This approach seems is a bit hacky, but is currently the only known workaround for this issue and can be considered a major design flaw of workflow integrations.
As an addendum to the answer given above, I found the workflow_run event trigger to work well for this use case:
on:
workflow_run:
workflows: ["Main release"]
types: [completed]
You can add conditions for various release tags and all if required apart from this.