diff --git a/tasks/collector.py b/tasks/collector.py index 35e26e0b0f28b9..434bdc397fb0d6 100644 --- a/tasks/collector.py +++ b/tasks/collector.py @@ -509,7 +509,7 @@ def update(self): @task(post=[tidy]) -def update(ctx): +def update(_): updater = CollectorVersionUpdater() updater.update() print("Update complete.") @@ -518,12 +518,12 @@ def update(ctx): @task() def pull_request(ctx): # Save current Git configuration - original_config = {'user.name': get_git_config('user.name'), 'user.email': get_git_config('user.email')} + original_config = {'user.name': get_git_config(ctx, 'user.name'), 'user.email': get_git_config(ctx, 'user.email')} try: # Set new Git configuration - set_git_config('user.name', 'github-actions[bot]') - set_git_config('user.email', 'github-actions[bot]@users.noreply.github.com') + set_git_config(ctx, 'user.name', 'github-actions[bot]') + set_git_config(ctx, 'user.email', 'github-actions[bot]@users.noreply.github.com') # Perform Git operations ctx.run('git add .') @@ -554,4 +554,4 @@ def pull_request(ctx): print("No changes detected, skipping PR creation.") finally: # Revert to original Git configuration - revert_git_config(original_config) + revert_git_config(ctx, original_config) diff --git a/tasks/libs/common/git.py b/tasks/libs/common/git.py index 52e0d2809606fc..9c2b33beb67d58 100644 --- a/tasks/libs/common/git.py +++ b/tasks/libs/common/git.py @@ -1,7 +1,6 @@ from __future__ import annotations import os -import subprocess import sys import tempfile from contextlib import contextmanager @@ -304,18 +303,21 @@ def get_last_release_tag(ctx, repo, pattern): return last_tag_commit, last_tag_name -def get_git_config(key): - result = subprocess.run(['git', 'config', '--get', key], capture_output=True, text=True) - return result.stdout.strip() if result.returncode == 0 else None +def get_git_config(ctx, key): + try: + result = ctx.run(f'git config --get {key}') + except Exit: + return None + return result.stdout.strip() if result.return_code == 0 else None -def set_git_config(key, value): - subprocess.run(['git', 'config', key, value]) +def set_git_config(ctx, key, value): + ctx.run(f'git config {key} {value}') -def revert_git_config(original_config): +def revert_git_config(ctx, original_config): for key, value in original_config.items(): if value is None: - subprocess.run(['git', 'config', '--unset', key]) + ctx.run(f'git config --unset {key}', hide=True) else: - subprocess.run(['git', 'config', key, value]) + ctx.run(f'git config {key} {value}', hide=True) diff --git a/tasks/libs/common/utils.py b/tasks/libs/common/utils.py index 20a8df30423f9d..19975ae7f7a94d 100644 --- a/tasks/libs/common/utils.py +++ b/tasks/libs/common/utils.py @@ -23,7 +23,7 @@ from tasks.libs.common.color import Color, color_message from tasks.libs.common.constants import ALLOWED_REPO_ALL_BRANCHES, REPO_PATH -from tasks.libs.common.git import get_commit_sha, get_default_branch +from tasks.libs.common.git import get_commit_sha, get_default_branch, set_git_config from tasks.libs.releasing.version import get_version from tasks.libs.types.arch import Arch @@ -501,6 +501,15 @@ def is_pr_context(branch, pr_id, test_name): return True +def set_gitconfig_in_ci(ctx): + """ + Set username and email when runing git "write" commands in CI + """ + if running_in_ci(): + set_git_config(ctx, 'user.name', 'github-actions[bot]') + set_git_config(ctx, 'user.email', 'github-actions[bot]@users.noreply.github.com') + + @contextmanager def gitlab_section(section_name, collapsed=False, echo=False): """ diff --git a/tasks/release.py b/tasks/release.py index a6d3d5f2408d3a..72b48f6c58b366 100644 --- a/tasks/release.py +++ b/tasks/release.py @@ -36,11 +36,11 @@ get_last_commit, get_last_release_tag, is_agent6, - set_git_config, try_git_command, ) from tasks.libs.common.gomodules import get_default_modules from tasks.libs.common.user_interactions import yes_no_question +from tasks.libs.common.utils import running_in_github_actions, set_gitconfig_in_ci from tasks.libs.common.worktree import agent_context from tasks.libs.pipeline.notifications import ( DEFAULT_JIRA_PROJECT, @@ -206,6 +206,7 @@ def tag_modules( if push: tags_list = ' '.join(tags) + set_gitconfig_in_ci(ctx) for idx in range(0, len(tags), TAG_BATCH_SIZE): batch_tags = tags[idx : idx + TAG_BATCH_SIZE] ctx.run(f"git push origin {' '.join(batch_tags)}{force_option}") @@ -250,6 +251,7 @@ def tag_version( with agent_context(ctx, release_branch, skip_checkout=release_branch is None): tags = __tag_single_module(ctx, get_default_modules()["."], agent_version, commit, force_option, devel) + set_gitconfig_in_ci(ctx) # create or update the qualification tag using the force option (points tag to next RC) if is_agent6(ctx) and (start_qual or is_qualification(ctx, "6.53.x")): if FINAL_VERSION_RE.match(agent_version): @@ -323,6 +325,7 @@ def finish(ctx, release_branch, upstream="origin"): commit_message = f"'Final updates for release.json and Go modules for {new_version} release'" + set_gitconfig_in_ci(ctx) ok = try_git_command(ctx, f"git commit -m {commit_message}") if not ok: raise Exit( @@ -394,12 +397,6 @@ def create_rc(ctx, release_branch, patch_version=False, upstream="origin", slack with agent_context(ctx, release_branch): github = GithubAPI(repository=GITHUB_REPO_NAME) - github_action = os.environ.get("GITHUB_ACTIONS") - - if github_action: - set_git_config('user.name', 'github-actions[bot]') - set_git_config('user.email', 'github-actions[bot]@users.noreply.github.com') - upstream = f"https://x-access-token:{os.environ.get('GITHUB_TOKEN')}@github.com/{GITHUB_REPO_NAME}.git" # Get the version of the highest major: useful for some logging & to get # the version to use for Go submodules updates @@ -454,10 +451,10 @@ def create_rc(ctx, release_branch, patch_version=False, upstream="origin", slack ctx.run("git add release.json") ctx.run("git ls-files . | grep 'go.mod$' | xargs git add") + set_gitconfig_in_ci(ctx) ok = try_git_command( ctx, f"git commit --no-verify -m 'Update release.json and Go modules for {new_highest_version}'", - github_action, ) if not ok: raise Exit( @@ -673,6 +670,7 @@ def _main(): # Step 2 - Push newly created release branch to the remote repository print(color_message("Pushing new branch to the upstream repository", "bold")) + set_gitconfig_in_ci(ctx) res = ctx.run(f"git push --set-upstream {upstream} {release_branch}", warn=True) if res.exited is None or res.exited > 0: raise Exit( @@ -863,6 +861,7 @@ def cleanup(ctx, release_branch): ctx.run("git add release.json") commit_message = f"Update last_stable to {version}" + set_gitconfig_in_ci(ctx) ok = try_git_command(ctx, f"git commit -m '{commit_message}'") if not ok: raise Exit( @@ -1175,6 +1174,7 @@ def check_for_changes(ctx, release_branch, warning_mode=False): with clone(ctx, repo_name, repo['branch'], options="--filter=blob:none --no-checkout"): # We can add the new commit now to be used by release candidate creation print(f"Creating new tag {next_version} on {repo_name}", file=sys.stderr) + set_gitconfig_in_ci(ctx) ctx.run(f"git tag {next_version}") ctx.run(f"git push origin tag {next_version}") # This repo has changes, the next check is not needed @@ -1350,13 +1350,10 @@ def bump_integrations_core(ctx, slack_webhook=None): Create a PR to bump the integrations core fields in the release.json file """ github_workflow_url = "" - if os.environ.get("GITHUB_ACTIONS"): - set_git_config('user.name', 'github-actions[bot]') - set_git_config('user.email', 'github-actions[bot]@users.noreply.github.com') - github_server_url = os.environ.get("GITHUB_SERVER_URL") - github_run_id = os.environ.get("GITHUB_RUN_ID") - github_workflow_url = f"{github_server_url}/{GITHUB_REPO_NAME}/actions/runs/{github_run_id}" - + if running_in_github_actions(): + github_workflow_url = ( + f"{os.environ.get('GITHUB_SERVER_URL')}/{GITHUB_REPO_NAME}/actions/runs/{os.environ.get('GITHUB_RUN_ID')}" + ) commit_hash = get_git_references(ctx, "integrations-core", "HEAD").split()[0] rj = load_release_json() @@ -1372,6 +1369,7 @@ def bump_integrations_core(ctx, slack_webhook=None): ctx.run("git add release.json") commit_message = "bump integrations core to HEAD" + set_gitconfig_in_ci(ctx) ok = try_git_command(ctx, f"git commit -m '{commit_message}'") if not ok: raise Exit( diff --git a/tasks/unit_tests/release_tests.py b/tasks/unit_tests/release_tests.py index ee22a0bbd8f1af..8450cc877f1c77 100644 --- a/tasks/unit_tests/release_tests.py +++ b/tasks/unit_tests/release_tests.py @@ -1,5 +1,6 @@ from __future__ import annotations +import os import re import sys import unittest @@ -786,6 +787,7 @@ def test_no_changes(self, version_mock, print_mock, _): } ), ) + @patch.dict(os.environ, {'GITLAB_CI': 'true'}) @patch('os.chdir', new=MagicMock()) def test_changes_new_commit_first_repo(self, version_mock, print_mock, _): with mock_git_clone(): @@ -796,6 +798,8 @@ def test_changes_new_commit_first_repo(self, version_mock, print_mock, _): c = MockContext( run={ 'git rev-parse --abbrev-ref HEAD': Result("main"), + 'git config user.name github-actions[bot]': Result(""), + 'git config user.email github-actions[bot]@users.noreply.github.com': Result(""), 'git ls-remote -h https://github.com/DataDog/omnibus-software "refs/heads/main"': Result( "4n0th3rc0mm1t9 refs/heads/main" ), @@ -867,6 +871,7 @@ def test_changes_new_commit_first_repo(self, version_mock, print_mock, _): ), ) @patch('os.chdir', new=MagicMock()) + @patch.dict(os.environ, {'GITLAB_CI': 'false'}) def test_changes_new_commit_all_repo(self, version_mock, print_mock, _): with mock_git_clone(): next = MagicMock() @@ -1018,6 +1023,7 @@ def test_changes_new_release_one_repo(self, version_mock, print_mock, _): } ), ) + @patch.dict(os.environ, {'GITLAB_CI': 'true'}) @patch('os.chdir', new=MagicMock()) def test_changes_new_commit_second_repo_branch_out(self, version_mock, print_mock, _): with mock_git_clone(): @@ -1028,6 +1034,8 @@ def test_changes_new_commit_second_repo_branch_out(self, version_mock, print_moc c = MockContext( run={ 'git rev-parse --abbrev-ref HEAD': Result("main"), + 'git config user.name github-actions[bot]': Result(""), + 'git config user.email github-actions[bot]@users.noreply.github.com': Result(""), 'git ls-remote -h https://github.com/DataDog/omnibus-software "refs/heads/7.55.x"': Result( "4n0th3rc0mm1t0 refs/heads/main" ), @@ -1264,6 +1272,7 @@ def test_update_module_optional_in_agent_7(self): class TestTagModules(unittest.TestCase): @patch('tasks.release.__tag_single_module', new=MagicMock(side_effect=[[str(i)] for i in range(2)])) @patch('tasks.release.agent_context', new=MagicMock()) + @patch.dict(os.environ, {'GITLAB_CI': 'false'}) def test_2_tags(self): c = MockContext(run=Result("yolo")) with patch('tasks.release.get_default_modules') as mock_modules: @@ -1276,6 +1285,7 @@ def test_2_tags(self): @patch('tasks.release.__tag_single_module', new=MagicMock(side_effect=[[str(i)] for i in range(3)])) @patch('tasks.release.agent_context', new=MagicMock()) + @patch.dict(os.environ, {'GITLAB_CI': 'false'}) def test_3_tags(self): c = MockContext(run=Result("yolo")) with patch('tasks.release.get_default_modules') as mock_modules: @@ -1288,6 +1298,7 @@ def test_3_tags(self): @patch('tasks.release.__tag_single_module', new=MagicMock(side_effect=[[str(i)] for i in range(4)])) @patch('tasks.release.agent_context', new=MagicMock()) + @patch.dict(os.environ, {'GITLAB_CI': 'false'}) def test_4_tags(self): c = MockContext(run=Result("yolo")) with patch('tasks.release.get_default_modules') as mock_modules: @@ -1304,6 +1315,7 @@ def test_4_tags(self): @patch('tasks.release.__tag_single_module', new=MagicMock(side_effect=[[str(i)] for i in range(100)])) @patch('tasks.release.agent_context', new=MagicMock()) + @patch.dict(os.environ, {'GITLAB_CI': 'false'}) def test_100_tags(self): c = MockContext(run=Result("yolo")) with patch('tasks.release.get_default_modules') as mock_modules: