Compare commits

...

3 Commits

Author SHA1 Message Date
Peter Braun
2f80a4e30d update docs 2026-04-09 09:52:02 +02:00
Peter Braun
9c2de57235 add test 2026-04-09 09:37:56 +02:00
Peter Braun
bb2f8cdd01 support bitbucket_dc webhooks 2026-04-09 09:27:31 +02:00
3 changed files with 128 additions and 2 deletions

View File

@@ -276,6 +276,7 @@ options:
- '' - ''
- 'github' - 'github'
- 'gitlab' - 'gitlab'
- 'bitbucket_dc'
webhook_credential: webhook_credential:
description: description:
- Personal Access Token for posting back the status to the service API - Personal Access Token for posting back the status to the service API
@@ -436,7 +437,7 @@ def main():
scm_branch=dict(), scm_branch=dict(),
ask_scm_branch_on_launch=dict(type='bool'), ask_scm_branch_on_launch=dict(type='bool'),
job_slice_count=dict(type='int'), job_slice_count=dict(type='int'),
webhook_service=dict(choices=['github', 'gitlab', '']), webhook_service=dict(choices=['github', 'gitlab', 'bitbucket_dc', '']),
webhook_credential=dict(), webhook_credential=dict(),
labels=dict(type="list", elements='str'), labels=dict(type="list", elements='str'),
notification_templates_started=dict(type="list", elements='str'), notification_templates_started=dict(type="list", elements='str'),

View File

@@ -117,6 +117,7 @@ options:
choices: choices:
- github - github
- gitlab - gitlab
- bitbucket_dc
webhook_credential: webhook_credential:
description: description:
- Personal Access Token for posting back the status to the service API - Personal Access Token for posting back the status to the service API
@@ -828,7 +829,7 @@ def main():
ask_inventory_on_launch=dict(type='bool'), ask_inventory_on_launch=dict(type='bool'),
ask_scm_branch_on_launch=dict(type='bool'), ask_scm_branch_on_launch=dict(type='bool'),
ask_limit_on_launch=dict(type='bool'), ask_limit_on_launch=dict(type='bool'),
webhook_service=dict(choices=['github', 'gitlab']), webhook_service=dict(choices=['github', 'gitlab', 'bitbucket_dc']),
webhook_credential=dict(), webhook_credential=dict(),
labels=dict(type="list", elements='str'), labels=dict(type="list", elements='str'),
notification_templates_started=dict(type="list", elements='str'), notification_templates_started=dict(type="list", elements='str'),

View File

@@ -0,0 +1,124 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import pytest
from awx.main.models import JobTemplate, WorkflowJobTemplate
# The backend supports these webhook services on job/workflow templates
# (see awx/main/models/mixins.py). The collection modules must accept all of
# them in their argument_spec ``choices`` list. This test guards against the
# module's choices drifting from the backend -- see AAP-45980, where
# ``bitbucket_dc`` had been supported by the API since migration 0188 but was
# still being rejected by the job_template/workflow_job_template modules.
WEBHOOK_SERVICES = ['github', 'gitlab', 'bitbucket_dc']
@pytest.mark.django_db
@pytest.mark.parametrize('webhook_service', WEBHOOK_SERVICES)
def test_job_template_accepts_webhook_service(run_module, admin_user, project, inventory, webhook_service):
result = run_module(
'job_template',
{
'name': 'foo',
'playbook': 'helloworld.yml',
'project': project.name,
'inventory': inventory.name,
'webhook_service': webhook_service,
'state': 'present',
},
admin_user,
)
assert not result.get('failed', False), result.get('msg', result)
assert result.get('changed', False), result
jt = JobTemplate.objects.get(name='foo')
assert jt.webhook_service == webhook_service
# Re-running with the same args must be a no-op (idempotence).
result = run_module(
'job_template',
{
'name': 'foo',
'playbook': 'helloworld.yml',
'project': project.name,
'inventory': inventory.name,
'webhook_service': webhook_service,
'state': 'present',
},
admin_user,
)
assert not result.get('failed', False), result.get('msg', result)
assert not result.get('changed', True), result
@pytest.mark.django_db
@pytest.mark.parametrize('webhook_service', WEBHOOK_SERVICES)
def test_workflow_job_template_accepts_webhook_service(run_module, admin_user, organization, webhook_service):
result = run_module(
'workflow_job_template',
{
'name': 'foo-workflow',
'organization': organization.name,
'webhook_service': webhook_service,
'state': 'present',
},
admin_user,
)
assert not result.get('failed', False), result.get('msg', result)
assert result.get('changed', False), result
wfjt = WorkflowJobTemplate.objects.get(name='foo-workflow')
assert wfjt.webhook_service == webhook_service
# Re-running with the same args must be a no-op (idempotence).
result = run_module(
'workflow_job_template',
{
'name': 'foo-workflow',
'organization': organization.name,
'webhook_service': webhook_service,
'state': 'present',
},
admin_user,
)
assert not result.get('failed', False), result.get('msg', result)
assert not result.get('changed', True), result
@pytest.mark.django_db
def test_job_template_rejects_unknown_webhook_service(run_module, admin_user, project, inventory):
result = run_module(
'job_template',
{
'name': 'foo',
'playbook': 'helloworld.yml',
'project': project.name,
'inventory': inventory.name,
'webhook_service': 'not_a_real_service',
'state': 'present',
},
admin_user,
)
assert result.get('failed', False), result
assert 'webhook_service' in result.get('msg', '')
@pytest.mark.django_db
def test_workflow_job_template_rejects_unknown_webhook_service(run_module, admin_user, organization):
result = run_module(
'workflow_job_template',
{
'name': 'foo-workflow',
'organization': organization.name,
'webhook_service': 'not_a_real_service',
'state': 'present',
},
admin_user,
)
assert result.get('failed', False), result
assert 'webhook_service' in result.get('msg', '')