@@ -36,18 +36,35 @@ def __init__(self, db_name: str, db_dir: Union[str, Path] = data_dir, use_git: b
36
36
self .repo_branch = os .getenv ("DATA_REPO_BRANCH" , "master" )
37
37
self .db_dir = os .path .join (self .db_dir , "support-bot-data" )
38
38
39
+ # Get Git user configuration from environment variables
40
+ self .git_user_name = os .environ ["GIT_USER_NAME" ]
41
+ self .git_user_email = os .environ ["GIT_USER_EMAIL" ]
42
+
43
+ # Git credentials for authentication (required for private repo)
44
+ self .git_token = os .getenv ("GIT_TOKEN" ) or os .getenv ("GITHUB_TOKEN" )
45
+ if not self .git_token :
46
+ raise ValueError ("GIT_TOKEN or GITHUB_TOKEN must be provided for private repository access" )
47
+
48
+ # Prepare URL with credentials for private repo access
49
+ protocol , repo_path = self .repo_url .split ("://" , 1 )
50
+ clone_url = f"{ protocol } ://{ self .git_user_name } :{ self .git_token } @{ repo_path } "
51
+
39
52
if not os .path .exists (self .db_dir ):
40
53
# Clone repo if it doesn't exist
41
54
print (f"Cloning repository { self .repo_url } to { self .db_dir } " )
42
55
try :
43
56
# Try cloning with the specified branch
44
- self .repo = git .Repo .clone_from (self .repo_url , self .db_dir , branch = self .repo_branch )
57
+ self .repo = git .Repo .clone_from (clone_url , self .db_dir , branch = self .repo_branch )
58
+ # Configure the repo
59
+ self ._configure_repo ()
45
60
except git .exc .GitCommandError as e :
46
61
# Check if the error is due to branch not found
47
62
if "Remote branch" in str (e ) and "not found in upstream origin" in str (e ):
48
63
print (f"Branch '{ self .repo_branch } ' not found in remote. Creating a new empty branch." )
49
64
# Clone with default branch first
50
- self .repo = git .Repo .clone_from (self .repo_url , self .db_dir )
65
+ self .repo = git .Repo .clone_from (clone_url , self .db_dir )
66
+ # Configure the repo
67
+ self ._configure_repo ()
51
68
52
69
# Create a new orphan branch (not based on any other branch)
53
70
self .repo .git .checkout ('--orphan' , self .repo_branch )
@@ -91,6 +108,8 @@ def __init__(self, db_name: str, db_dir: Union[str, Path] = data_dir, use_git: b
91
108
else :
92
109
# Use existing repo
93
110
self .repo = git .Repo (self .db_dir )
111
+ # Configure the repo
112
+ self ._configure_repo ()
94
113
95
114
# Make sure the correct branch is checked out
96
115
if self .repo_branch not in [ref .name .split ('/' )[- 1 ] for ref in self .repo .refs ]:
@@ -136,6 +155,34 @@ def __init__(self, db_name: str, db_dir: Union[str, Path] = data_dir, use_git: b
136
155
indent = 4 ,
137
156
)
138
157
158
+ def _configure_repo (self ):
159
+ """Configure the Git repository with user identity from environment variables."""
160
+ if self .repo :
161
+ with self .repo .config_writer () as config :
162
+ # Set user name and email for this repository
163
+ config .set_value ("user" , "name" , self .git_user_name )
164
+ config .set_value ("user" , "email" , self .git_user_email )
165
+
166
+ # Configure credentials for private repo access
167
+ domain = self .repo_url .split ("://" )[- 1 ].split ("/" )[0 ]
168
+
169
+ # Set credential store helper
170
+ config .set_value ("credential" , "helper" , "store" )
171
+
172
+ # Set credential helper specific to this domain
173
+ if self .git_user_name and self .git_token :
174
+ config .set_value (f"credential \" { domain } \" " , "username" , self .git_user_name )
175
+
176
+ # Update origin URL with credentials to ensure push works
177
+ protocol , repo_path = self .repo_url .split ("://" , 1 )
178
+ new_url = f"{ protocol } ://{ self .git_user_name } :{ self .git_token } @{ repo_path } "
179
+ try :
180
+ origin = self .repo .remote ('origin' )
181
+ origin .set_url (new_url )
182
+ except git .exc .GitCommandError as e :
183
+ print (f"Failed to update remote URL: { str (e )} " )
184
+ # Continue anyway, might work with stored credentials
185
+
139
186
def _check_for_migration (self ):
140
187
# Check if migration is needed (shelve exists but json doesn't)
141
188
# No extension is used on Linux
@@ -253,15 +300,20 @@ def sync(self):
253
300
254
301
# Check if we have anything to commit after adding
255
302
if self .repo .git .status ('--porcelain' ):
303
+ # Ensure the repository is configured with user identity
304
+ self ._configure_repo ()
305
+
256
306
# Commit all changes at once with a general message
257
307
commit_message = "Update database files"
258
308
self .repo .git .commit ('-m' , commit_message )
259
309
print ("Committed changes to git data repository" )
260
310
261
- # Push to remote
311
+ # Push to remote with credentials
262
312
try :
263
- origin = self .repo .remote ('origin' )
264
- origin .push ()
313
+ # Ensure we're using the credentials for push
314
+ protocol , repo_path = self .repo_url .split ("://" , 1 )
315
+ push_url = f"{ protocol } ://{ self .git_user_name } :{ self .git_token } @{ repo_path } "
316
+ self .repo .git .push (push_url , self .repo_branch )
265
317
print ("Pushed changes to remote git data repository" )
266
318
except git .exc .GitCommandError as e :
267
319
print (f"Failed to push changes: { str (e )} " )
0 commit comments