How do I disable github workflow cancellation? - github-actions

The documentation doesn't specify how to prevent workflow cancellation, however, it'd be useful for my case.
In my opinion it would make sense to have a configuration option to either hide or disable the 'Cancel workflow' button when the given workflow is running.

Posting this here as an answer for visibility (please if someone from Github is reading this, update me):
Apparently, this feature is not yet implemented, for now you can only use if: ${{ cancelled() }} or if: ${{ always() }} to run operations even if the workflow is canceled, note that the jobs will be killed after 5min from receiving the signal (source)
After the 5 minutes cancellation timeout period, the server will force
terminate all jobs and steps that don't finish running or fail to
complete the cancellation process.
Also, as you may know: Runs can be only manually triggered and cancelled by the contributors. So you may consider limiting the access to your organisations
See:
https://docs.github.com/en/organizations/managing-organization-settings/disabling-or-limiting-github-actions-for-your-organization
https://github.com/orgs/community/discussions/26064

Related

github check suite to enforce a minimum pull request review period

Our project has maintainers and reviewers with a 12 hour time difference. We have agreed to allow PRs to remain open for at least 24 hours so that everyone has a chance to review and comment. Unfortunately, this is easy to forget or overlook, especially for small PRs.
We would like to automate this as a check.
Is there an existing action, app, or check suite to enforce a minimum PR review period? (I am not interested in writing my own.)
If you're on an enterprise plan, you can use environment protection rules.
More specifically, configure a new environment pr-sleeper and set the wait time to 24 hours (1440 minutes):
The second step is to create a workflow that uses the environment:
name: Wait for 24h
on: pull_request
jobs:
wait:
runs-on: ubuntu-latest
environment: pr-sleeper
steps:
- run: echo done
Essentially, this means the job is blocked for 24 hours and then automatically proceeds to print 'done'.
So when you now create it a PR, you'll see a check like so:
If you want to ensure nobody can merge before the 24 have passed, also create a branch protection rule for the target branch and add this as a required check.

How can I reuse a GitHub Actions workflow from the branch I'm currently working on?

I'd like to abstract some of my GitHub Actions with a reusable workflow.
In order to do this, I need to call my newly defined callable workflow in the format {owner}/{repo}/{path}/{filename}#{ref}
e.g. (from the docs)
jobs:
call-workflow-1:
uses: octo-org/this-repo/.github/workflows/workflow-1.yml#172239021f7ba04fe7327647b213799853a9eb89
call-workflow-2:
uses: octo-org/another-repo/.github/workflows/workflow-2.yml#v1
However, in practice, I'm working on my branch, some-branch-name, where I'm working on my workflow-1.yml file and I'd like to be able to run my actions as defined in my current branch, Given
`{ref} can be a SHA, a release tag, or a branch name.
It seems like I'd need to use
jobs:
call-workflow-1:
uses: octo-org/this-repo/.github/workflows/workflow-1.yml#some-branch-name
But, I'd like this to work for any branch, so
jobs:
call-workflow-1:
uses: octo-org/this-repo/.github/workflows/workflow-1.yml#${{ github.ref }}
But, it turns out this isn't possible as expressions can't be used in the uses attributes.
How can I achieve this?
EDIT: This is now supported as of 25 January 2022
(check TWiStErRob's answer for more details).
Previous answer (before 2022 update)
It's as you said: It can't be done at the moment as Github Actions doesn't support expressions with uses attributes.
There is no workaround (yet?) because the workflow interpreter (that also checks the workflow syntax when you push the workflow to the repository) can't get the value from the expression at that moment.
It could maybe work if the workflow was recognized by the interpreter, but it doesn't event appear on the Actions tab as it's considered invalid.
For the moment, you can only use tag, branch ref or commit hash after the # symbol, the same way you use any action.
Note that someone else had the same issue here
This is now supported as of 25 January 2022.
https://github.blog/changelog/2022-01-25-github-actions-reusable-workflows-can-be-referenced-locally/
Example usage from blog:
jobs:
call-workflow-in-local-repo:
uses: ./.github/workflows/workflow-2.yml
And a real life example from my opened issue:
https://github.com/TWiStErRob/net.twisterrob.healthcheck/pull/28
Note: With this ./ syntax the reusable workflow definition (.yml file) and the usage (uses from a job) must be in the same repository. See: here for more info.
Update: DO NOT USE THIS, see other answer.
A really hacky (and untested) way to workaround this.
Based on the fact that a workflow can contain multiple jobs, and assuming a low-churn PR environment one could set up something like this:
jobs:
tag-my-workflow:
steps:
- name: git tag ${{ github.ref }} as "current-branch"
uses: see for example https://levelup.gitconnected.com/how-to-move-a-git-tag-using-github-actions-e23a523eb325
call-workflow:
needs: tag-my-workflow
uses: my/repo/.github/workflows/called.yml#current-branch
I used the workflow-dispatch github action described here to successfully trigger a workflow B in the same repo (note that you need to set up a personal access token secret and include ref: ${{ github.event.pull_request.head.ref }} to refer to the current branch).
But unfortunately workflow A continues once workflow B has been triggered, rather than waiting around to see if workflow B succeeds. As suggested in this thread it might be possible to use another github action to make workflow A wait for workflow B to successfully finish, but that seemed like overkill for me... maybe this'll be useful to someone else though. Fingers crossed it gets supported instead :D
We all know that this is untenable and must have a solution in the long term: You're going to want to establish a common pipeline and have perhaps hundreds of repos calling the same workflow. Having to commit to 'main' on your reusable workflow to test it could break every pipeline that depends on it. So GHA will pick up this functionality soon enough simply because it has to.
Workaround: What about forking instead of branching for now? You can develop and test on the fork and submit a PR when it works.

What is the correct set of events for a continuous integration workflow with github actions?

I'm using Github actions to run automated tests on every pull request. However, I don't know what is the correct set of events that I should be using. I've seen many variations of this, but I don't know which one is the proper one.
A) Only the pull_request event
on: [ pull_request ]
B) Only the push event
on: [ push ]
C) Both push and pull_request event
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
I started trying option (A), with only the pull_request event. However, that appears to be incompatible with caching dependencies. Each pull request starts with an empty cache; the cache does not carry over to the next pull request.
I then tried to switch to option (B), with only the push event. The automated tests appear to run correctly for pull requests that are entirely inside my repository. However, if someone opens a pull request from an external fork, the status ends up stuck as "Expected — Waiting for status to be reported". I don't know if this is expected behavior, because when I googled for that message I got very few hits which I don't believe are related to my problem. (I'm not sure, this Github actions stuff is completely baffling.)
Finally, I tried switching to option (C) with both the push event and the pull event, as suggested in the Github starter workflows. However, when I do this every the CI runs twice for every pull request. Once before it is merged and another time after it is merged. This seems terribly redundant and wasteful; I'd prefer if my test scripts only had to run once.
At the end, I'm terribly confused. Option (B) does what I want unless a fork is involved, in which case it fails miserably. Option (C) seems to be the default that Github recommends, but it runs the automated tests twice instead of only once. That can't possibly be right! What is the correct approach here?

Github actions- stop a check if the PR is merged or pushed to again

We have tests that take about an hour to run. If I make a PR that just adds a comment somewhere, I don't want all of these tests to run and waste resources. If a PR is merged, is it possible for github actions to automatically cancel checks?
Also, if I create a PR and then push to that branch again, it runs a test for every push. Is there a way to cancel checks and restart when a commit is pushed to a branch?
It seems like an "auto cancel builds", as it is called and available on other CI services, is not natively supported on GitHub Actions.
There are some non-native alternatives as discussed in this newer StackOverflow answer: https://stackoverflow.com/a/70452560/413924

Enforcing one build for one commit in Jenkins/Hudson

We use Jenkins for doing incremental builds of our project on each commit to the SCM. We would like to get separate builds for every single commit. However, the naive approach (setup SCM and use post-commit hooks to trigger a build) exhibits problem in the following scenario:
Build is triggered.
While build takes place (it can take up to several minutes) two separate commits to the SCM are made by two developers.
One new build is triggered. It receives changes from both of the commits, made during previous build.
This "race condition" complicates finding which one of the commits has broken the build/introduced warnings.
The currently employed solution is checking for changes in one job ("scheduler job") and triggering another job to do the actual checkout and build.
Are there any proper solutions to this problem?
Not yet, there's a Feature Request covering this kind of build, but it's still open: Issue 673
Maybe it misses the point, but we have a pretty nice build process running here.
We use git as our source control system
We use gerrit as our review tool
We use the gerrit trigger to run builds on our jenkins server
We check for changes on the develop branch to run jenkins when a changeset is merged
In short the ideal developer day is like this
developer 1 stars a new branch to do his changes, based on our main develop branch
The developer 1 commits as often as he likes
developer 1 thinks he finished his job, he combines his changes into one change and pushes it to gerrit
A new gerrit change is created and jenkins tries to build exactly this change
When there are no errors during the build, a review is made on this change
When the review is submited, the changeset is merged into the develop branch of the main repository (No change is merged into the develop branch, without review)
Jenkins builds the merged version to be sure, that there are no merge errors
no developer 2 joins the party and tries to do some work
the process is exactly the same both start working, in there branches. Developer 1 is faster and his changes are merged into the develop branch. Now, before developer 2 can publish his changes he has to rebase his changes on top of the changes made by developer 1.
So we are sure, that the build process is triggered for every change made to our codebase.
We use this for our C# development - on windows not on linux
I don't believe what you'd like to do is possible. The "quiet period" mentioned by Daniel Kutik is actually used to tell Hudson/Jenkins how much time to wait, in order to allow other commits to the same project to be picked up. Meaning -- if you set this value to 60 seconds and you've made a commit, it will wait for a minute before starting a new build, allowing time for other commits to be picked up as well (during that one minute).
If you use the rule "NO COMMIT on a broken build‏" and take it to it's logical conclusion, you actually end up with "No commit on a broken build or a build in progress", in which case the problem you describe goes away.
Let me explain. If you have two developers working on the same project and both of them try to commit (or push if you're using DVCS). One of them is going to succeed and and they other will fail and need to update before the commit.
The developer who had to do the update knows from the commit history, that the other commit was recent and thus a build in progress (even if it hasn't checked out yet). They don't know if that build is broken yet of not, so the only safe option is to wait and see.
The only thing that would stop you from using the above approach is if the build takes so long, in which case you might find that your developers never get a chance to commit (it's always building). This is then a driver to split up your build into a pipeline of multiple steps, so that the Post Commit job takes no more than 5 minutes, but is ideally 1 minute.
I think what might help, is to set the Quiet Period (Jenkins > Manage Jenkins > Configure System) to 0 and the SCM Polling to a very short time. But even during that short interval there could be two commits. As of now Jenkins does not have the feature to split build into single builds on multiple SVN commit.
Here is a tutorial about that topic: Quiet Period Feature.
As pointed out by someone in Issue 673 you could try starting a parametrized build with the parameter being the actual git commit you want to build. This in combination with a VCS commit hook.