Only run GitHub Actions manually while blocking Pull Request - github

I have a set of GitHub Actions configured to block pull requests from being merged until the Actions complete successfully. However, every time a new commit is pushed to a PR, the Actions are run again, which can be very wasteful if the author is not yet ready to merge, and intends to make future changes. Is there any way to have a GitHub Action still block a PR being merged but also not run the Action automatically?

With this recent update you can now convert pull requests back to draft status. So you could do that when you need to make changes and disable the CI for drafts. Then convert the draft to a pull request after the changes are complete to rerun CI.
on: pull_request
jobs:
build:
if: github.event.pull_request.draft == 'false'
runs-on: ubuntu-latest
steps:
...

One workaroound would be for the Action to look for a specific comment (for example: "[TO MERGE]: this commit is about ...), and:
return immediately if '[TO MERGE]' is not found, minimizing the action overhead on each commit
go on with checks, if '[TO MERGE]' is found.

Related

Configuration of GitHub Actions: Avoid running CI twice when merging PR into main

I am using GitHub a
ctions to manage my CI and the following events trigger my workflow:
on:
pull_request:
branches: main
push:
branches: main
I observed the following "problem":
When I create a PR, the CI is run. If the test passes and I merge it into main, the tests are run again (which I don'
t want in specific cases). How can I setup my workflow such that the CI is not triggered when merging a PR, where the CI already passed for the PR?
Thanks in advance!
You might consider an if conditional in your case:
jobs.<job_id>.if
You can use the jobs.<job_id>.if conditional to prevent a job from running unless a condition is met. You can use any supported context and expression to create a conditional.
When you use expressions in an if conditional, you may omit the expression syntax (${{ }}) because GitHub automatically evaluates the if conditional as an expression. For more information, see "Expressions".
jobs:
build:
if: github.event.pull_request.merged == false
. . .
That would still trigger the workflow, but it can skip the jobs in the workflow.
Alternatives exist in this thread, which deals with the opposite requirements ("Trigger workflow only on pull request merge"): it can be adapted to do what you need (not trigger a workflow, or at least do the same job twice, on PR merge)

Using env variable github.ref_name doesn't give me branch name

When I use in my workflow github.ref_name it doesn't provide me a branch name from where I triggered this workflow. I get 16/merge. Why? When I use github.ref_type I clearly see that my ref type is branch so why I don't get branch name?
Also it's showing when I use $GITHUB_REF or git symbolic-ref HEAD (and separating refs/heads/ off). Ah and I tried github.event.push.ref but it's not showing me anything.
How to get always branch name from where I triggered the workflow?
For following code:
Run echo running on branch ${GITHUB_REF##*/} ${GITHUB_REF}
When your workflow runs becuase of push event you will get:
running on branch main refs/heads/main
But for pulr request event it would be:
running on branch merge refs/pull/3/merge
Why's that?
If the repository is on GitHub and you have any Pull Requests that have been opened, you’ll get these references that are prefixed with refs/pull/. These are basically branches, but since they’re not under refs/heads/ you don’t get them normally when you clone or fetch from the server — the process of fetching ignores them normally.
You can also check this question here

GitHub action branch creation for code review pull request

I'm trying to create a GitHub workflow that will run ONLY when a new branch is created with a pattern. The purpose of this is to create a Code Review Pull Request when a new branch is pushed to origin, but only on the first time the branch is created, so using a push event will not work and why I'm looking at create.
All of these combinations fail where any new branch created will run, instead of those just matching the pattern
name: "Create Code Review PR"
on:
create:
branches: ['feature/**']
or
name: "Create Code Reivew PR"
on:
create:
branches:
- 'feature/**'
- 'support/**'
- 'hotfix/**'
In both of these scenarios, if push a new branch called no-code-review, the above workflow will still run, but my expected behavior is that it wont run, but it should when a new branch such as these: feature/new-branch, support/new-support-branch or hotfix/fix-this ONLY.
The create event does not support a branch filter.
The alternative would be using an if condition on your step or job:
if: ${{ contains(github.ref, 'refs/heads/releases/') }}
Here's more information: https://github.community/t/trigger-job-on-branch-created/16878/5

Within what limits Github actions/cache work?

I don't quite understand the extent to which Github actions/cache works, what I mean:
Caching works fine if I make a pull request and then in the same pull request I add 1 more commit, but if I create a new pull request in the same branch - the caching is reset and starts again, but why?
Is there any way to extend file caching to all yml files and so that each pull request uses existing caching?
Because to speed up the work it turns out - that developers always need to pour their work into one branch, and it somehow sounds like some nonsense.
Info
My caching key is formed as follows
- uses: actions/cache#v2
id: composer-cache
with:
path: .github/docker/development/php-cli/composer/cache
key: ${{ runner.os }}-develop-composer-${{ hashFiles('src/composer.lock') }}
restore-keys: |
${{ runner.os }}-develop-composer-
Yeah, GitHub's cache action has unintuitive behavior across branches. Pull request workflows don't share, and tag workflows never get a cache hit.
Per the docs (useful bit made bold):
A workflow can access and restore a cache created in the current branch, the base branch (including base branches of forked repositories), or the default branch (usually main). For example, a cache created on the default branch would be accessible from any pull request. Also, if the branch feature-b has the base branch feature-a, a workflow triggered on feature-b would have access to caches created in the default branch (main), feature-a, and feature-b.
So the solution then is to make a separate workflow triggered by pushes to main — plus any base branches you like — just to keep a fresh cache available to pull requests and tags.

How to trigger a GitHub Action workflow for every successful commit

I want to run a GitHub Actions workflow for every successful commit (e.g. after all check suites have ran successfully).
It seems like the check_suite events will be fired for each individual check suite, and contain no information about the other suites. I want to wait for all registered check suites.
The status event seems to be exactly what I want:
Statuses can include a context to indicate what service is providing that status. For example, you may have your continuous integration service push statuses with a context of ci, and a security audit tool push statuses with a context of security. You can then use the combined status endpoint to retrieve the whole status for a commit.
But the status lives completely unrelated to the check_suites events, and most CI services now uses the check_suites (including GitHub Actions itself), and not status.
How can I, with a GitHub Actions workflow, check that all check_suites finished and the commit has successfully passed all checks and tests?
You can use the GitHub API to list the check suites belonging to a ref: https://octokit.github.io/rest.js/#octokit-routes-checks-list-suites-for-ref.
So, within your action (triggered by check_suite), you can list all the suites for the current ref, check they're all successful and then run your code.
If you're building a javascript action it could look like this:
import * as github from "#actions/github";
const response = await client.checks.listSuitesForRef({
owner: github.context.repo.owner,
repo: github.context.repo.repo,
ref: sha
});
const passes = response.data.check_suites.every(...)
if (passes) { ... }
The major drawback of this approach is that this very action is itself a check suite belonging to the current commit, so it will appear in response.data.check_suites (and will never be successful at this point ... because it's still running!). I don't have a solution for this part yet...
It looks like you are now able to trigger actions based on commit status (reference).
on:
status
jobs:
if_error_or_failure:
runs-on: ubuntu-latest
if: >-
github.event.state == 'error' ||
github.event.state == 'failure'
steps:
- env:
DESCRIPTION: ${{ github.event.description }}
run: |
echo The status is error or failed: $DESCRIPTION