While trying to make use of our initial webhook implementation, I am struggling with getting GitHub's events to do the Expected Thing™ in AWX.
There is the option to "Send me everything." or "Let me select individual events.", but unfortunately the latter option does not behave intuitively in a(t least one) key way: Checking "Pull requests" will send you events for:
Pull request opened, closed, reopened, edited, assigned, unassigned, review requested, review request removed, labeled, unlabeled, synchronized, ready for review, locked, or unlocked.
Note the absence of "comment" here. In order to receive a webhook when someone comments on a Pull request, you must select "Issue comments". This would mean we launch a job for every comment, whether or not it is on an Issue or Pull request. Ouch.
The more I explore this feature, it seems to me that we need some type of pre-launch filtering to allow AWX (or the user via configuration?) to decide whether or not we launch a job for any given event. It would be great to be able to check "Send me everything" and have AWX be smart enough to launch a job or ignore it, as I don't think the example I've provided here will be the only scenario where we need this type of functionality.
In fact with gitlab the scope of a webhook is rather large.
It would be very useful to be able to create conditions based on the request body to launch the job or not.
Moreover it would be very useful to be able to inject extra variables extracted from the request body.
I would like to give an example of a specific use-case that this feature might be able to solve. Just being able to access a webhook's payload from within a job/playbook would be a massively huge improvement.
First of all, I want to show my long-hauled appreciation for Ansible. I absolutely love it. Our team uses Ansible exclusively for almost all of our application configuration and deployments and we try to adhere to Ansible best-practices as much as possible. We have a strict custom git-flow centered around code branches that represent environments and Ansible as our IaaC. And we have even gone so far as to write a custom jenkins library that helps us enforce this custom git-flow. The library can define a mapping of git branch names to ansible inventory names, install external/internal shared-roles, run playbooks... and much more.
To summarize the current state of things:
Github, by itself, does not provide a user with a way of triggering a "specific" webhook when a PUSH event happens on some "specific" branch. All PUSH events on a repository trigger whatever single webhook you have enabled with the PUSH event selected. Github sends a huge payload.. which is practically BEGGING to get parsed/filtered on the receiving end. We all know this, nuff said.
The problem:
We are not able to conditionally launch a job based on the "branch" of the most recent git push event that triggered the webhook POST to AWX. With the additions of workflow templates and webhooks, this is currently the ONLY thing keeping our team from using solely AWX as our CI/CD tool, without the help of anything other tool or middleware.
Our Team's Goal:
Completely move away from Jenkins as the "glue" language between Github and Ansible. We want to use ONLY AWX for our entire CI/CD flow.
Solution:
AWX solves most of this, since it natively has an RBAC, rest api, and jobs/workflows that can be triggered with webhooks, however AWX webhook filtering would open the doors to so many more options/customizations!
Okay shorly after some playing around with it, I just found out that github event payloads are indeed transferred over into the job as extra vars, this was not clear to me before 👍
Okay shorly after some playing around with it, I just found out that github event payloads are indeed transferred over into the job as
extra vars, this was not clear to me before
Sounds like room for docs improvement
is there the same kind of behaviour for gitlab ?
@rmanibus the full payload is provided in all cases
is there anyway to only run the workflow if the action=opened?
the problem i have not is that using the "enable webhook" method, i receive multiple actions from PRs, and i need to do a when condition in the playbook for action=opened for the PR.
This works, but is not ideal since for 1 PR it runs the workflow 4 times, the tasks are skipped for 3 of the times, and only run when the PR action=opened.
is there anyway to only run the workflow if the action=opened?
@benjaminhon - not currently.. an admittedly non-optimal solution right now would be to have a job template that inspects the webhook payload (injected via extra vars) and fails, preventing the workflow from proceeding.
i see that seems the best solution now, thx
I was really surprised to not find this, it basically implies we should go github -> some ci -> AWX because it's the only way to control the triggers. For people in future, the really simple version of this i've done in my repo is:
Our job history is pretty much destroyed because there are a lot of job runs that basically end up with the whole play skipped. It also means i have a seperate job template that executes main.yml directly for human control.
It's not pretty but it does work.
A bit hacky since you have to target a host but I did an intermediate template in the workflow that only launches this
- name: validate webhook
assert:
that:
- "{{ tower_webhook_payload.context | default('') == 'ci/circleci: build' }}"
- "{{ tower_webhook_payload.state | default('') == 'success' }}"
- "{{ tower_webhook_payload.branches[0].name | default('') == project_branch }}" # aka 'master'
when: validate_webhook | default(false)
tags: validate_webhook
Most helpful comment
I was really surprised to not find this, it basically implies we should go github -> some ci -> AWX because it's the only way to control the triggers. For people in future, the really simple version of this i've done in my repo is:
```webhook.yml
when:
```
Our job history is pretty much destroyed because there are a lot of job runs that basically end up with the whole play skipped. It also means i have a seperate job template that executes
main.ymldirectly for human control.It's not pretty but it does work.