fix: make sure galaxy requirements are always updated when a new revision is pulled

This commit is contained in:
Peter Braun
2026-07-30 14:56:40 +02:00
parent 82d0978fb3
commit f29becbd98
2 changed files with 83 additions and 1 deletions

View File

@@ -885,7 +885,9 @@ class SourceControlMixin(BaseTask):
# Determine whether or not this project sync needs to populate the cache for Ansible content, roles and collections
has_cache = os.path.exists(os.path.join(project.get_cache_path(), project.cache_id))
# Galaxy requirements are not supported for manual projects
if project.scm_type and ((not has_cache) or branch_override):
# If a source update is scheduled, always include roles/collections because
# the new revision may have different requirements.
if project.scm_type and ((not has_cache) or branch_override or source_update_tag in sync_needs):
sync_needs.extend(['install_roles', 'install_collections'])
return sync_needs

View File

@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import os
import pytest
from unittest import mock
@@ -661,3 +662,82 @@ class TestRunInventoryUpdatePopulateWorkloadIdentityTokens:
# The instance's get_cloud_credential should now return the same object with context
assert task.instance.get_cloud_credential() is cloud_cred
class TestGetSyncNeeds:
"""Tests for SourceControlMixin.get_sync_needs cache behavior."""
def _make_task_and_project(self, tmp_path, scm_revision='abc123', local_head='abc123', cache_exists=True):
"""Create a SourceControlMixin instance and a mock project for testing get_sync_needs."""
project_path = str(tmp_path / 'project')
os.makedirs(project_path, exist_ok=True)
cache_base = str(tmp_path / 'cache')
os.makedirs(cache_base, exist_ok=True)
if cache_exists and scm_revision:
os.makedirs(os.path.join(cache_base, scm_revision), exist_ok=True)
project = mock.MagicMock()
project.scm_type = 'git'
project.scm_revision = scm_revision
project.scm_branch = 'main'
project.get_project_path.return_value = project_path
project.get_cache_path.return_value = cache_base
project.cache_id = scm_revision if scm_revision else 'fallback'
git_repo = mock.MagicMock()
git_repo.head.commit.hexsha = local_head
task = jobs.SourceControlMixin()
task.instance = mock.MagicMock(spec=Job)
return task, project, git_repo
def test_source_update_forces_role_install(self, tmp_path):
"""When a source update is needed (local HEAD differs from project revision),
install_roles and install_collections must be included even if cache exists.
A new revision may have changed requirements.yml."""
task, project, git_repo = self._make_task_and_project(
tmp_path,
scm_revision='abc123',
local_head='def456',
cache_exists=True,
)
with mock.patch('awx.main.tasks.jobs.git.Repo', return_value=git_repo):
sync_needs = task.get_sync_needs(project)
assert 'update_git' in sync_needs
assert 'install_roles' in sync_needs
assert 'install_collections' in sync_needs
def test_no_sync_when_revision_matches_and_cache_exists(self, tmp_path):
"""When local HEAD matches project revision and cache exists, no sync needed."""
task, project, git_repo = self._make_task_and_project(
tmp_path,
scm_revision='abc123',
local_head='abc123',
cache_exists=True,
)
with mock.patch('awx.main.tasks.jobs.git.Repo', return_value=git_repo):
sync_needs = task.get_sync_needs(project)
assert sync_needs == []
def test_cache_miss_triggers_role_install(self, tmp_path):
"""When cache doesn't exist, install_roles and install_collections are needed
even if the git revision matches."""
task, project, git_repo = self._make_task_and_project(
tmp_path,
scm_revision='abc123',
local_head='abc123',
cache_exists=False,
)
with mock.patch('awx.main.tasks.jobs.git.Repo', return_value=git_repo):
sync_needs = task.get_sync_needs(project)
assert 'update_git' not in sync_needs
assert 'install_roles' in sync_needs
assert 'install_collections' in sync_needs