Skip to content

Commit 1c64ea1

Browse files
pb82AlanCoding
andauthored
AAP-29938 add force flag to refspec (ansible#16173) (ansible#7184)
* add force flag to refspec * Development of git --amend test * Update awx/main/tests/live/tests/conftest.py --------- Co-authored-by: AlanCoding <[email protected]>
1 parent d96bf98 commit 1c64ea1

File tree

4 files changed

+131
-1
lines changed

4 files changed

+131
-1
lines changed

awx/main/tasks/jobs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,7 @@ def build_extra_vars_file(self, project_update, private_data_dir):
12981298
extra_vars['scm_refspec'] = project_update.scm_refspec
12991299
elif project_update.project.allow_override:
13001300
# If branch is override-able, do extra fetch for all branches
1301-
extra_vars['scm_refspec'] = 'refs/heads/*:refs/remotes/origin/*'
1301+
extra_vars['scm_refspec'] = '+refs/heads/*:refs/remotes/origin/*'
13021302

13031303
if project_update.scm_type == 'archive':
13041304
# for raw archive, prevent error moving files between volumes

awx/main/tests/live/tests/conftest.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44
import shutil
55
import tempfile
6+
import logging
67

78
import pytest
89

@@ -18,6 +19,9 @@
1819
from awx.main.models import Project, JobTemplate, Organization, Inventory
1920

2021

22+
logger = logging.getLogger(__name__)
23+
24+
2125
PROJ_DATA = os.path.join(os.path.dirname(data.__file__), 'projects')
2226

2327

@@ -132,6 +136,45 @@ def fn():
132136
return fn
133137

134138

139+
@pytest.fixture
140+
def project_factory(post, default_org, admin):
141+
def _rf(scm_url=None, local_path=None, **extra_kwargs):
142+
proj_kwargs = {}
143+
if local_path:
144+
# manual path
145+
project_name = f'Manual roject {local_path}'
146+
proj_kwargs['scm_type'] = ''
147+
proj_kwargs['local_path'] = local_path
148+
elif scm_url:
149+
project_name = f'Project {scm_url}'
150+
proj_kwargs['scm_type'] = 'git'
151+
proj_kwargs['scm_url'] = scm_url
152+
else:
153+
raise RuntimeError('Need to provide scm_url or local_path')
154+
155+
if extra_kwargs:
156+
proj_kwargs.update(extra_kwargs)
157+
158+
proj_kwargs['name'] = project_name
159+
proj_kwargs['organization'] = default_org.id
160+
161+
old_proj = Project.objects.filter(name=project_name).first()
162+
if old_proj:
163+
logger.info(f'Deleting existing project {project_name}')
164+
old_proj.delete()
165+
166+
result = post(
167+
reverse('api:project_list'),
168+
proj_kwargs,
169+
admin,
170+
expect=201,
171+
)
172+
proj = Project.objects.get(id=result.data['id'])
173+
return proj
174+
175+
return _rf
176+
177+
135178
@pytest.fixture
136179
def run_job_from_playbook(default_org, demo_inv, post, admin):
137180
def _rf(test_name, playbook, local_path=None, scm_url=None, jt_params=None):
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,25 @@
1+
import os
2+
import subprocess
3+
4+
import pytest
5+
6+
from awx.main.tests.live.tests.conftest import wait_for_job
7+
8+
19
def test_git_file_project(live_tmp_folder, run_job_from_playbook):
210
run_job_from_playbook('test_git_file_project', 'debug.yml', scm_url=f'file://{live_tmp_folder}/debug')
11+
12+
13+
@pytest.mark.parametrize('allow_override', [True, False])
14+
def test_amend_commit(live_tmp_folder, project_factory, allow_override):
15+
proj = project_factory(scm_url=f'file://{live_tmp_folder}/debug', allow_override=allow_override)
16+
assert proj.current_job
17+
wait_for_job(proj.current_job)
18+
assert proj.allow_override is allow_override
19+
20+
source_dir = os.path.join(live_tmp_folder, 'debug')
21+
subprocess.run('git commit --amend --no-edit', cwd=source_dir, shell=True)
22+
23+
update = proj.update()
24+
update.signal_start()
25+
wait_for_job(update)

awx/main/tests/unit/test_tasks.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,70 @@ def test_awx_task_env(self, project_update, settings, private_data_dir, scm_type
16071607
assert env['FOO'] == 'BAR'
16081608

16091609

1610+
@pytest.mark.django_db
1611+
class TestProjectUpdateRefspec(TestJobExecution):
1612+
@pytest.fixture
1613+
def project_update(self, execution_environment):
1614+
org = Organization(pk=1)
1615+
proj = Project(pk=1, organization=org, allow_override=True)
1616+
project_update = ProjectUpdate(pk=1, project=proj, scm_type='git')
1617+
project_update.websocket_emit_status = mock.Mock()
1618+
project_update.execution_environment = execution_environment
1619+
return project_update
1620+
1621+
def test_refspec_with_allow_override_includes_plus_prefix(self, project_update, private_data_dir, mock_me):
1622+
"""Test that refspec includes + prefix to allow non-fast-forward updates when allow_override is True"""
1623+
task = jobs.RunProjectUpdate()
1624+
task.instance = project_update
1625+
1626+
# Call build_extra_vars_file which sets the refspec
1627+
with mock.patch.object(Licenser, 'validate', lambda *args, **kw: {}):
1628+
task.build_extra_vars_file(project_update, private_data_dir)
1629+
1630+
# Read the extra vars file to check the refspec
1631+
with open(os.path.join(private_data_dir, 'env', 'extravars')) as fd:
1632+
extra_vars = yaml.load(fd, Loader=SafeLoader)
1633+
1634+
# Verify the refspec includes the + prefix for force updates
1635+
assert 'scm_refspec' in extra_vars
1636+
assert extra_vars['scm_refspec'] == '+refs/heads/*:refs/remotes/origin/*'
1637+
1638+
def test_custom_refspec_not_overridden(self, project_update, private_data_dir, mock_me):
1639+
"""Test that custom user-provided refspec is not overridden"""
1640+
task = jobs.RunProjectUpdate()
1641+
task.instance = project_update
1642+
project_update.scm_refspec = 'refs/pull/*/head:refs/remotes/origin/pr/*'
1643+
1644+
with mock.patch.object(Licenser, 'validate', lambda *args, **kw: {}):
1645+
task.build_extra_vars_file(project_update, private_data_dir)
1646+
1647+
with open(os.path.join(private_data_dir, 'env', 'extravars')) as fd:
1648+
extra_vars = yaml.load(fd, Loader=SafeLoader)
1649+
1650+
# Custom refspec should be preserved
1651+
assert extra_vars['scm_refspec'] == 'refs/pull/*/head:refs/remotes/origin/pr/*'
1652+
1653+
def test_no_refspec_without_allow_override(self, execution_environment, private_data_dir, mock_me):
1654+
"""Test that no refspec is set when allow_override is False"""
1655+
org = Organization(pk=1)
1656+
proj = Project(pk=1, organization=org, allow_override=False)
1657+
project_update = ProjectUpdate(pk=1, project=proj, scm_type='git')
1658+
project_update.websocket_emit_status = mock.Mock()
1659+
project_update.execution_environment = execution_environment
1660+
1661+
task = jobs.RunProjectUpdate()
1662+
task.instance = project_update
1663+
1664+
with mock.patch.object(Licenser, 'validate', lambda *args, **kw: {}):
1665+
task.build_extra_vars_file(project_update, private_data_dir)
1666+
1667+
with open(os.path.join(private_data_dir, 'env', 'extravars')) as fd:
1668+
extra_vars = yaml.load(fd, Loader=SafeLoader)
1669+
1670+
# No refspec should be set
1671+
assert 'scm_refspec' not in extra_vars
1672+
1673+
16101674
class TestInventoryUpdateCredentials(TestJobExecution):
16111675
@pytest.fixture
16121676
def inventory_update(self, execution_environment):

0 commit comments

Comments
 (0)