I have the following .github/workflows/ci.yml file for GitHub Actions (some code removed to make it easier to understand for this question):
name: CI
on:
push:
release:
types: [published]
jobs:
test:
runs-on: ubuntu-latest
steps:
# ...
deploy-staging:
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push' && github.ref == 'staging'
steps:
# ...
I went through the following steps:
Make some commits on the develop branch, and push those changes.
After build passes on GitHub Actions I did a fast forward merge from develop into staging.
I expected GitHub Actions to run both the test and deploy-staging jobs after item 2. But instead it just ran test again without running deploy-staging.
As you can see above even after pushing to staging it still ran it on the develop branch instead of the staging branch. I'm kinda assuming this might be due to some weird behavior with fast forward merges. But GitHub obviously recognized that I pushed to staging as it offered to create a PR from that branch into master.
So that makes me rethink my theory about why it's trying to run on develop instead of staging.
Why would this be happening? Is there anyway to fix this so merging into staging actually runs the workflow on staging as opposed to develop?
My approach would be so separate the triggers and related jobs into different workflows.
So, to mimic your example, instead of a ci.yml I would have two files:
test.yml
deploy-staging.yml
In .github/workflows/test.yml:
name: Test
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
# ...
In .github/workflows/release-staging.yml:
name: Release Staging
on:
push:
branches:
- staging
jobs:
deploy-staging:
runs-on: ubuntu-latest
steps:
# test steps ...
# release ...
Admittedly this is annoying because the release doesn't run on the same test run as the test, but you want to make sure the tests all pass before deploying.
If you wanted to chain the test run workflow to run the deploy workflow I might change release-staging to use the Check suite event instead of push.
${{ github.ref }} will be refs/heads/staging not just staging.
The best thing to do in these situations is simply to echo the variable values you want to check in a step before it:
steps:
- name: Check inputs
run: |
echo github.ref is: ${{ github.ref }}
echo github.event_name is: ${{ github.event_name }}
Related
I want to setup continuous deployment pipeline between Github and AWS Lambda. For this, I've added main.yml file # myrepo/.github/workflows/main.yml
This is my main.yml file
name: deploy to lambda
on:
# Trigger the workflow on push or pull request,
# but only for the main branch
push:
branches:
- main
jobs:
deploy_source:
name: deploy lambda from source
runs-on: ubuntu-latest
steps:
- name: checkout source code
uses: actions/checkout#v1
- name: default deploy
uses: appleboy/lambda-action#master
with:
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws_region: ${{ secrets.AWS_REGION }}
function_name: my_function
source: function.py
Now when I push changes to main branch nothing happens. It shows There are no workflow runs yet. I have checked the function_name and it is same as the function in AWS Console.
Your deploy_source job has runs-on: ubuntu-latest which tells Actions to use a GitHub Hosted Runner. As per your comment, you are using GitHub Enterprise Server (GHES) which is a virtual appliance on your company's network. At present, GHES does not support using GitHub Hosted Runners (it's worth noting at the time of this writing, it is on the product roadmap for support).
If you wish to run your workflow, you will need to make use of a self-hosted hosted runner. I would recommend working with your GHES administrator to get this workflow to run as there are potentially other settings and/or steps that may need to be modified or taken for this to work.
As tj-cappelletti said in their answer, you should use your hosted runners.
And also, be sure that your pipeline is on your default branch. Otherwise, you wouldn't see it there.
You need to place workflows in .github/workflows/. Note the dot in front of the folder name .github. So for your case the final path should look like this myrepo/.github/workflows/main.yml.
GitHub Actions support running workflows for pull requests targets specific branches but the names of the branches must be specified, thus if we want it to run on repositories with default branch named main:
pull_request:
branches:
- main
I'm wondering if there's a way to share the same workflow across multiple repositories without the need to asking each repositories to specify their default branch name, and the workflow can work upon renaming default branches. Is there a way to just run the workflow upon pull requests to default branch without specifying all the possible default branch names across these repositories as below?
I want to avoid:
pull_request:
branches:
- main
- master
- develop
- dev
- i-dont-know-what-else
- ${{ remember-to-update-this-after-renaming-default-branch }}
I've tried listing all possible default branch names and use a variable but these are not elegant.
You can achieve this with the conditional github.ref == github.event.repository.default_branch.
Here's an example which only runs when a PR is merged into the default branch.
on:
pull_request:
types:
- closed
jobs:
example:
if: github.event.pull_request.merged && github.ref == github.event.repository.default_branch
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
I'm looking on a way to trigger a GitHub pipeline ONLY on successful pull request merge.
I have to move from Azure DevOps where I had some arguments like these:
condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
But I can't seem to find a way to do something similar on GitHub
EDIT:
So
on:
pull_request:
types: [closed]
jobs:
on-success:
if: ${{ github.event.pull_request.merged }}
steps:
- name: my-step
run: echo "Hello World!"
Works but only on manually accepted PRs, which is not what I need.
The answers should work with git CLI if you do:
git checkout main
git merge dev
and then accept the changes and commit+push
Then the actions should be triggered and these last answers doesn't work with that.
The try using this to double check for sucess.
on:
pull_request:
types: [closed]
branches: [main]
jobs:
on-success:
if: ${{ github.event.pull_request.conclusion == 'success'}}
steps:
https://docs.github.com/en/github-ae#latest/actions/using-workflows/events-that-trigger-workflows#running-your-workflow-when-a-pull-request-merges-1
on:
pull_request_target:
types:
- closed
jobs:
if_merged:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- run: |
echo The PR was merged
IMHO you cannot do this.
When you're running git merge you're just merging branches in git, you're not merging a Pull Request in GitHub. Git is the underlying version control system used by GitHub, but git itself has no concept of pull requests.
If you want to trigger a GitHub action, you need to generate an event on the GitHub pull request, therefore you need to use github's own CLI, not git CLI. See gh pr merge https://cli.github.com/manual/gh_pr_merge
You can use push trigger. Please refer to https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#push
On the branch that the Pull request will be merged, you can add the condition and it will get triggered.
Ex:
on:
push:
branches:
- 'main'
- 'releases/**'
I have a github actions workflow, which lints, builds, tests, releases and deploys the software: common CI/CD steps.
This being a FLOSS project, I want to run some jobs for pull-requests and some only when stuff is pushed to main (master) branch and/or tagged. The latter jobs release and deploy the software, so I want to avoid running those when someone makes a PR at all costs.
For the sake of this question details are omitted and all steps abstracted away in shell scripts. The workflow looks like this:
name: CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
env:
CARGO_TERM_COLOR: always
TAG_FILE: "./job_tags.txt"
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Lint
run: lint.sh
build:
runs-on: ubuntu-latest
steps:
- name: Build
run: build.sh
test:
needs: build
runs-on: ubuntu-latest
steps:
- name: Test
run: test.sh
deploy:
needs: [lint, test, build]
if: startsWith(github.ref, 'refs/tags')
runs-on: ubuntu-latest
steps:
- name: Deploy
run: deploy.sh
There are dependencies (needs:) and one if, witch tries to achieve the following:
For all pull_requests to main, run lint, build, test. but not deploy
For all tagged commits to main, run lint, build, test and deploy.
The things I cannot find in the documentation are:
What if someone branches off, creates commits, tags them and then makes a PR. Will that trigger the tags? Do I need extra protection in place to ensure the tag was made on main, of the repo that I hold, and not a fork?
How can I match this on tags with a pattern only? Say v*, only?
Is this feasible in one workflow file? Or should I split the "run for all PRs" and "run only for tagged commits to main" into separate workflows (I'd rather avoid this as it comes with either a lot of complexity -building own reusable actions- or duplication; since I cannot make a job needs: jobs from other workflows).
Is there a function or expression that I'm overlooking which does exactly what I want: filter if this is "my" repo or someone elses in a PR?
I'd like a Github action to run on Pull Request to a specific base branch, but from another specific head branch.
name: Run production tests
on:
push:
pull_request:
branches:
- main
jobs: ...
However, I specifically want something like this to run when a branch called develop is PR'd against main, not just every time something is PR'd to main.
Is such a workflow possible? I might be missing it, but I don't see a way to target head branches in the docs.
From the documentation, I could not find any filters for the head branch. But this is doable with if conditions for jobs.
For example
name: Run production tests
on:
pull_request:
branches:
- main
jobs:
build:
if: ${{ github.head_ref == 'develop'}}
runs-on: ubuntu-latest
steps:
- name: Run a multi-line script
run: |
echo "Do something here"