Github actions How to only run a step when merging into master - github-actions

I have been trying to get this right for hours, and nothing I have managed to find has helped. I am trying to setup a github action that will run tests on every pull request into master and any changes to the master branch, but only run the deploy step when there are changes to the master branch.
Here is a simple reproduction of what I am trying to do.
name: Main
on:
push:
branches:
- "main"
pull_request:
branches:
- "main"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Test
run: echo "running tests"
- name: Deploy
run: echo "Deploying"
if: github.head_ref == 'main'
I have tried multiple conditionals I have found here / on other forums, I have tried moving the if statement above and below run I am completely out of ideas. Everything I have tried either runs the deploy step on both pull request and merge or skips the deploy step on both pull request and merge.

Just use:
github.ref == 'refs/heads/master'
or:
github.ref == 'refs/heads/main'
Depending on which branch you want to check

This is what I do:
build:
runs-on: [...]
steps:
- name: Echo on merging to master
if: ${{ github.ref == 'refs/heads/master' }}
run: echo "I'm merging!"

Related

What github action can i use in the event of push to get changes that were a part of the commit that was pushed?

Currently, my GitHub workflow looks as follows:
name: learn-github-actions
run-name: ${{ github.actor }} is learning GitHub Actions
on:
push:
branches:
- main
jobs:
update-x:
runs-on: ubuntu-latest
steps:
- name: Git checkout
uses: actions/checkout#v2
with:
# fetch depth is needed since we will be taking git diff with HEAD^1
fetch-depth: 2
- name: Run script
run: scripts/x/x-version-bump.sh
Instead of using git diff in my x-version-bump.sh script I would like to get the changes of the commit pushed via a GitHub action and pass it on to the script. I cannot find a way currently in Github actions to do the same.

Run a certain job depending on the source branch from a PR

I have a GitHub action workflow for a swift package that runs whenever something is merged to the main branch.
My goal is to check the for a source branch and depending on its prefix (i.e. patch/something) determine wow to tag and release it.
This is how I have it configured so far:

name: Release
on:
push:
branches:
- main
jobs:
build:
runs-on: macos-latest
patch-release-on-push:
needs: build
if: contains(github.head_ref, 'patch')
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- id: release
uses: rymndhng/release-on-push-action#master
with:
bump_version_scheme: patch
The problem with this is that github.head_ref is null. I only get a value on it if I switch the workflow to be triggered on a pull_request instead of push which wouldn’t really work given that the release would be out before the PR was merged.

What’s the right approach for achieving this?


I would suggest you to use an existing action like EthanSK/git-branch-name-action, as example:
on: [push, pull_request]
jobs:
main_job:
runs-on: ubuntu-latest
steps:
- name: Git branch name
id: git-branch-name
uses: EthanSK/git-branch-name-action#v1
- name: Echo the branch name
run: echo "Branch name ${GIT_BRANCH_NAME}"
and use also like
if: ${{ contains(env.GIT_BRANCH_NAME, 'patch') }}
Link to the marketplace here

Prevent GitHub Action to run for each tag on a commit

I have a publish workflow that is supposed to push the dists to PyPi if a commit on main is tagged with either frontend-v* or backend-v* (both are separate packages)
However, if a commit has changes on both the front- and backend and I add two tags to the commit, the workflow is triggered twice.
I understand that I could simply split the workflow into two, but I have another job that should run if either frontend or backend or both were updated which should only be ran once, thus I want to keep this in one workflow.
Can I somehow circumvent this to run this only once?
Thank you very much!
on:
workflow_dispatch:
push:
branches: [ main ]
tags:
- frontend*
- backend*
jobs:
backend:
name: Publish backend
if: ${{contains(github.ref_name, 'backend') }}
runs-on: ubuntu-latest
steps:
...
frontend:
name: Publish frontend
if: ${{contains(github.ref_name, 'frontend') }}
runs-on: ubuntu-latest
steps:
...
housekeeping: # this should only be ran once for the commit
name: House Keeping
runs-on: ubuntu-latest
steps:
...

Only run GitHub Actions step if not a pull request

I have a workflow which needs to execute either on a push or a pull request with the exception of the last step which pushes a package to NuGet (I don't want this to occur on a pull request, even to master).
How can I prevent the Publish NuGet step from running if the workflow is triggered from a pull request?
name: .NET Core
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Setup .NET Core
uses: actions/setup-dotnet#v1
with:
dotnet-version: 3.1.101
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Test
run: dotnet test --no-restore --verbosity normal
- name: Publish NuGet
uses: brandedoutcast/publish-nuget#v2.5.2
with:
PROJECT_FILE_PATH: "Orleans.Sagas/Orleans.Sagas.csproj"
NUGET_KEY: ${{secrets.NUGET_KEY}}
You can inspect the github.event_name context variable which contains the name of the event that triggered the workflow run. (eg, pull_request or push)
In this case, you can run a step for all events whose name is not pull_request with a github.event_name != 'pull_request' conditional on your step.
For example:
- name: Publish NuGet
uses: brandedoutcast/publish-nuget#v2.5.2
with:
PROJECT_FILE_PATH: "Orleans.Sagas/Orleans.Sagas.csproj"
NUGET_KEY: ${{secrets.NUGET_KEY}}
if: github.event_name != 'pull_request'
For future travellers, I found this action that worked quite well. I just needed to do an if: needs.pr-check.outputs.number != 'null' in order to filter by things being a PR or not.
https://github.com/8BitJonny/gh-get-current-pr
github.event_name != 'pull_request' did not work for me because the on.pull_request trigger doesn't exist for workflows that aren't launched by a PR.

How to run GitHub workflow on every commit of a push

I have some tests that I would like to run on every commit of my repository. I have the following script in my repo:
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- run: echo "my tests"
Unfortunately, if I push some new commits to my repository, the tests are only run against the latest commit. Is there a way to test all commits?
It is possible to to this by checking out individual commits and building each one in a single run: step.
In order to do this, the fetch-depth option for the checkout action needs to be 0 to checkout the full git tree.
I did something like this using GitPython to iterate and checkout each commit.
Using just the git command line tool, the rev-list command could be used to create a list of commits.
The tricky part is figuring out the commit range. For pull requests, GitHub actions provides github.head_ref and github.base_ref properties (docs) that could be used to create the commit range. However, these properties are not available for other events, like push (in that case, github.ref could be used with a fixed branch name like origin/main).
Here is a simple example. It may need more a advanced query for rev-list to handle cases where base_ref is not an ancestor of head_ref, but I will leave that for other SO questions to answer.
name: CI
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
with:
fetch-depth: 0
- run: |
for commit in $(git rev-list ${{ github.base_ref }}..${{ github.head_ref }}); do
git checkout $commit
echo "run test"
done
Building on David Lechner's answer:
name: CI
on:
push:
# only trigger on branches, not on tags
branches: '**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
with:
# checkout full tree
fetch-depth: 0
- run: |
for commit in $(git rev-list ${{ github.event.before}}..${{ github.sha}}); do
git checkout $commit
echo "run test"
done
As per the docs on the github context and the docs on the push webhook event data {{github.event.before}} is replaced by the commit sha before the push. {{github.sha}} or {{github.event.after}} is replaced by the sha of the latest commit that was pushed:
Push event payload (for a pushed tag; docs)
{
"ref": "refs/tags/simple-tag",
"before": "6113728f27ae82c7b1a177c8d03f9e96e0adf246",
"after": "0000000000000000000000000000000000000000",
"created": false,
"deleted": true,
"forced": false,
"base_ref": null,
"compare": "https://github.com/Codertocat/Hello-World/compare/6113728f27ae...000000000000",
"commits": [],
"head_commit": null,
[...]
}