Skip to content

Commit

Permalink
feat(release): Set gitconfig before git write operations (#32277)
Browse files Browse the repository at this point in the history
  • Loading branch information
chouetz authored Feb 13, 2025
1 parent fa9884f commit 807b3f7
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 30 deletions.
10 changes: 5 additions & 5 deletions tasks/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ def update(self):


@task(post=[tidy])
def update(ctx):
def update(_):
updater = CollectorVersionUpdater()
updater.update()
print("Update complete.")
Expand All @@ -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 .')
Expand Down Expand Up @@ -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)
20 changes: 11 additions & 9 deletions tasks/libs/common/git.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import os
import subprocess
import sys
import tempfile
from contextlib import contextmanager
Expand Down Expand Up @@ -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)
11 changes: 10 additions & 1 deletion tasks/libs/common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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):
"""
Expand Down
28 changes: 13 additions & 15 deletions tasks/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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}")
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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(
Expand Down
12 changes: 12 additions & 0 deletions tasks/unit_tests/release_tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import os
import re
import sys
import unittest
Expand Down Expand Up @@ -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():
Expand All @@ -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"
),
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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():
Expand All @@ -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"
),
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand Down

0 comments on commit 807b3f7

Please sign in to comment.