Open itlsoft opened 1 year ago
import os import subprocess
########## Define the repository details repo_owner = "YourGitHubUsername" repo_name = "YourGitHubRepository" branch_name = "main"
########## Define the local folder path local_folder_path = r"C:\Path\To\Your\Folder"
########## Define the log file path log_file_path = r"C:\Path\To\Your\Log\File.log"
########## Clone or pull the latest code from the GitHub repository repo_path = os.path.join(local_folder_path, repo_name)
if not os.path.exists(repo_path): ########## If the repository doesn't exist locally, clone it subprocess.run(["git", "clone", f"https://github.com/{repo_owner}/{repo_name}.git", repo_path]) else: ########## If the repository already exists, pull the latest changes os.chdir(repo_path) subprocess.run(["git", "pull", "origin", branch_name])
########## Compare and replace files using Robocopy robocopy_log = log_file_path + ".robocopy" subprocess.run(["robocopy", repo_path, local_folder_path, "/E", "/XO", "/LOG:" + robocopy_log, "/TEE"])
########## Process the Robocopy log file to identify replaced files replaced_files = [] with open(robocopy_log, "r") as file: for line in file: if "Newer" in line: file_path = line.split()[-1] replaced_files.append(os.path.basename(file_path))
########## Replace older files with the new ones for file in replaced_files: source_path = os.path.join(repo_path, file) destination_path = os.path.join(local_folder_path, file) shutil.copy(source_path, destination_path)
########## Clean up the log file os.remove(robocopy_log)
########## Append the script output to the log file with open(log_file_path, "a") as file: subprocess.run(["python", file], stdout=file)
Make sure to replace the placeholder values (YourGitHubUsername, YourGitHubRepository, C:\Path\To\Your\Folder, and C:\Path\To\Your\Log\File.log) with the appropriate values for your setup. Also, ensure that you have Git and Robocopy installed on your system.
This script clones the repository if it doesn't exist locally, or pulls the latest changes if it does. Then, it uses Robocopy to compare the files in the repository with the existing files in the Windows folder, logging the output to a separate log file. It identifies the replaced files from the Robocopy log and replaces them with the new versions from the repository. Finally, it appends the script output to the main log file.
Note: Ensure that the user executing the script has appropriate permissions to access the repository and the Windows folder, as well as write permissions for the log file.
import os import shutil import subprocess import datetime
repo_owner = "YourGitHubUsername" repo_name = "YourGitHubRepository" branch_name = "main"
local_folder_path = r"C:\Path\To\Your\Folder"
excluded_file_paths = [ r"file1.txt", r"file2.txt", ]
log_file_path = r"C:\Path\To\Your\Log\File.log"
backup_folder_name = "DeploymentBackups"
currentdatetime = datetime.datetime.now().strftime("%y%m%d%H%M%S")
backup_folder_path = os.path.join(local_folder_path, backup_folder_name)
if not os.path.exists(backup_folder_path): os.makedirs(backup_folder_path)
for file_path in excluded_file_paths: file_absolute_path = os.path.join(local_folder_path, file_path) if os.path.isfile(file_absolute_path): backup_file_name = f"{reponame}{currentdatetime}{os.path.basename(file_path)}" backup_file_path = os.path.join(backup_folder_path, backup_file_name) shutil.copy(file_absolute_path, backup_file_path)
repo_path = os.path.join(local_folder_path, repo_name)
if not os.path.exists(repo_path):
subprocess.run(["git", "clone", f"https://github.com/{repo_owner}/{repo_name}.git", repo_path])
else:
os.chdir(repo_path)
subprocess.run(["git", "pull", "origin", branch_name])
existingfiles = [] for root, , files in os.walk(local_folder_path): for file in files: existing_files.append(os.path.join(root, file))
robocopy_log = log_file_path + ".robocopy" for file_path in existing_files: file_relative_path = os.path.relpath(file_path, local_folder_path) if file_relative_path not in excluded_file_paths: source_path = os.path.join(repo_path, file_relative_path) destination_path = file_path subprocess.run(["robocopy", os.path.dirname(source_path), os.path.dirname(destination_path), os.path.basename(source_path), "/XO", "/LOG:" + robocopy_log, "/TEE"])
replaced_files = [] with open(robocopy_log, "r") as file: for line in file: if "Newer" in line: file_path = line.split()[-1] file_path = os.path.normpath(file_path) ##### Normalize path separators for Windows if file_path not in excluded_file_paths: replaced_files.append(os.path.basename(file_path))
for file in replaced_files: source_path = os.path.join(repo_path, file) destination_path = os.path
import os import shutil import subprocess import datetime
repo_owner = "YourGitHubUsername" repo_name = "YourGitHubRepository" branch_name = "main"
local_folder_path = r"C:\Path\To\Your\Folder"
excluded_file_paths = [ r"file1.txt", r"file2.txt", ]
log_file_path = r"C:\Path\To\Your\Log\File.log"
backup_folder_name = "DeploymentBackups"
currentdatetime = datetime.datetime.now().strftime("%y%m%d%H%M%S")
backup_folder_path = os.path.join(local_folder_path, backup_folder_name)
if not os.path.exists(backup_folder_path): os.makedirs(backup_folder_path)
repo_backup_name = f"{reponame}{current_datetime}.7z" repo_backup_path = os.path.join(backup_folder_path, repo_backup_name) subprocess.run(["7z", "a", "-r", repo_backup_path, os.path.join(local_folder_path, repo_name)])
repo_path = os.path.join(local_folder_path, repo_name)
if not os.path.exists(repo_path):
subprocess.run(["git", "clone", f"https://github.com/{repo_owner}/{repo_name}.git", repo_path])
else:
os.chdir(repo_path)
subprocess.run(["git", "pull", "origin", branch_name])
existingfiles = [] for root, , files in os.walk(local_folder_path): for file in files: existing_files.append(os.path.join(root, file))
robocopy_log = log_file_path + ".robocopy" for file_path in existing_files: file_relative_path = os.path.relpath(file_path, local_folder_path) if file_relative_path not in excluded_file_paths: source_path = os.path.join(repo_path, file_relative_path) destination_path = file_path subprocess.run(["robocopy", os.path.dirname(source_path), os.path.dirname(destination_path), os.path.basename(source_path), "/XO", "/LOG:" + robocopy_log, "/TEE"])
replaced_files = [] with open(robocopy_log, "r") as file: for line in file: if "Newer" in line: file_path = line.split()[-1] file_path = os.path.normpath(file_path) ##### # Normalize path separators for Windows if file_path not in excluded_file_paths: replaced_files.append(os.path.basename(file_path))
for file in replaced_files: source_path = os.path.join(repo_path, file) destination_path = os.path.join(local_folder_path, file) shutil.copy(source_path, destination_path)
os.remove(robocopy_log)
with open(log_file_path, "a") as file: subprocess.run(["python", file], stdout=file)
previous version
import os import subprocess
repo_owner = "YourGitHubUsername" repo_name = "YourGitHubRepository" branch_name = "main"
local_folder_path = r"C:\Path\To\Your\Folder"
folders_to_check = [ "Folder1", "Folder2", "Folder3", ]
folders_to_exclude = [ "Folder2", "Folder3", ]
log_file_path = r"C:\Path\To\Your\Log\File.log"
repo_path = os.path.join(local_folder_path, repo_name)
if not os.path.exists(repo_path):
subprocess.run(["git", "clone", f"https://github.com/{repo_owner}/{repo_name}.git", repo_path])
else:
os.chdir(repo_path)
subprocess.run(["git", "pull", "origin", branch_name])
robocopy_log = log_file_path + ".robocopy" for folder in folders_to_check: if folder not in folders_to_exclude: source_folder = os.path.join(repo_path, folder) destination_folder = os.path.join(local_folder_path, folder) subprocess.run(["robocopy", source_folder, destination_folder, "/E", "/XO", "/LOG:" + robocopy_log, "/TEE"])
replaced_files = [] with open(robocopy_log, "r") as file: for line in file: if "Newer" in line: file_path = line.split()[-1] replaced_files.append(os.path.basename(file_path))
for file in replaced_files: for folder in folders_to_check: if folder not in folders_to_exclude: source_path = os.path.join(repo_path, folder, file) destination_path = os.path.join(local_folder_path, folder, file) shutil.copy(source_path, destination_path)
os.remove(robocopy_log)
with open(log_file_path, "a") as file: subprocess.run(["python", file], stdout=file)
import os
import shutil
import logging
import subprocess
from datetime import datetime
from git import Repo
import requests
#### Set up logging
logging.basicConfig(filename='script.log', level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s')
#### Define the GitHub repository details
repo_owner = 'username'
repo_name = 'repository'
repo_url = f'https://github.com/{repo_owner}/{repo_name}.git'
#### Define the local folder paths to be checked and compared
folder_paths = [
'C:/Path/To/Folder1',
'C:/Path/To/Folder2',
'C:/Path/To/Folder3',
'C:/Path/To/RepositoryRoot'
]
#### Clone or pull the GitHub repository
repo_dir = 'temp_repo'
if os.path.exists(repo_dir):
repo = Repo(repo_dir)
logging.info('Pulling the latest changes from the repository...')
repo.remotes.origin.pull()
else:
logging.info('Cloning the repository...')
repo = Repo.clone_from(repo_url, repo_dir)
#### Get the latest commit hash
latest_commit = repo.head.commit.hexsha
logging.info(f'Latest commit hash: {latest_commit}')
#### Get the list of changed files between local and remote repository
changed_files = []
for item in repo.index.diff(None):
changed_files.append(item.a_path)
#### Compare and replace files using Robocopy-like functionality
for folder_path in folder_paths:
logging.info(f'Comparing files in {folder_path}...')
for root, _, files in os.walk(folder_path):
for file in files:
file_path = os.path.join(root, file)
relative_path = os.path.relpath(file_path, folder_path)
if relative_path in changed_files:
#### Backup the existing file
backup_path = f'{file_path}.bak'
shutil.copy2(file_path, backup_path)
logging.info(f'Backed up {file_path} to {backup_path}')
#### Copy the new file from the repository
repo_file_path = os.path.join(repo_dir, relative_path)
shutil.copy2(repo_file_path, file_path)
logging.info(f'Replaced {file_path} with the latest version')
#### Remove the temporary repository directory
shutil.rmtree(repo_dir)
logging.info(f'Removed the temporary repository directory: {repo_dir}')
#!/usr/bin/env python
import json, urlparse, sys, os
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from subprocess import call
class GitAutoDeploy(BaseHTTPRequestHandler):
CONFIG_FILEPATH = './GitAutoDeploy.conf.json'
config = None
quiet = False
daemon = False
@classmethod
def getConfig(myClass):
if(myClass.config == None):
try:
configString = open(myClass.CONFIG_FILEPATH).read()
except:
sys.exit('Could not load ' + myClass.CONFIG_FILEPATH + ' file')
try:
myClass.config = json.loads(configString)
except:
sys.exit(myClass.CONFIG_FILEPATH + ' file is not valid json')
for repository in myClass.config['repositories']:
if(not os.path.isdir(repository['path'])):
sys.exit('Directory ' + repository['path'] + ' not found')
# Check for a repository with a local or a remote GIT_WORK_DIR
if not os.path.isdir(os.path.join(repository['path'], '.git')) \
and not os.path.isdir(os.path.join(repository['path'], 'objects')):
sys.exit('Directory ' + repository['path'] + ' is not a Git repository')
return myClass.config
def do_POST(self):
event = self.headers.getheader('X-Github-Event')
if event == 'ping':
if not self.quiet:
print 'Ping event received'
self.respond(204)
return
if event != 'push':
if not self.quiet:
print 'We only handle ping and push events'
self.respond(304)
return
self.respond(204)
urls = self.parseRequest()
for url in urls:
paths = self.getMatchingPaths(url)
for path in paths:
self.fetch(path)
self.deploy(path)
def parseRequest(self):
length = int(self.headers.getheader('content-length'))
body = self.rfile.read(length)
payload = json.loads(body)
self.branch = payload['ref']
return [payload['repository']['url']]
def getMatchingPaths(self, repoUrl):
res = []
config = self.getConfig()
for repository in config['repositories']:
if(repository['url'] == repoUrl):
res.append(repository['path'])
return res
def respond(self, code):
self.send_response(code)
self.send_header('Content-type', 'text/plain')
self.end_headers()
def fetch(self, path):
if(not self.quiet):
print "\nPost push request received"
print 'Updating ' + path
call(['cd "' + path + '" && git fetch'], shell=True)
def deploy(self, path):
config = self.getConfig()
for repository in config['repositories']:
if(repository['path'] == path):
if 'deploy' in repository:
branch = None
if 'branch' in repository:
branch = repository['branch']
if branch is None or branch == self.branch:
if(not self.quiet):
print 'Executing deploy command'
call(['cd "' + path + '" && ' + repository['deploy']], shell=True)
elif not self.quiet:
print 'Push to different branch (%s != %s), not deploying' % (branch, self.branch)
break
def main():
try:
server = None
for arg in sys.argv:
if(arg == '-d' or arg == '--daemon-mode'):
GitAutoDeploy.daemon = True
GitAutoDeploy.quiet = True
if(arg == '-q' or arg == '--quiet'):
GitAutoDeploy.quiet = True
if(GitAutoDeploy.daemon):
pid = os.fork()
if(pid != 0):
sys.exit()
os.setsid()
if(not GitAutoDeploy.quiet):
print 'Github Autodeploy Service v0.2 started'
else:
print 'Github Autodeploy Service v 0.2 started in daemon mode'
server = HTTPServer(('', GitAutoDeploy.getConfig()['port']), GitAutoDeploy)
server.serve_forever()
except (KeyboardInterrupt, SystemExit) as e:
if(e): # wtf, why is this creating a new line?
print >> sys.stderr, e
if(not server is None):
server.socket.close()
if(not GitAutoDeploy.quiet):
print 'Goodbye'
if __name__ == '__main__':
main()
import os
import shutil
from git import Repo
from github import Github
# Github username and password
username = 'github_username'
password = 'github_password'
github = Github(username, password)
# Github repo name
repo_name = 'EA_TEST'
# Local path to clone the repo
local_path = 'C:\\Temp\\Repo'
# Check if the repo exists on Github
try:
repo = github.get_user().get_repo(repo_name)
except Exception as e:
print(f'Repository {repo_name} does not exist on Github for this user.')
exit(1)
# Check if the path exists, if it does delete the existing folder
if os.path.exists(local_path):
try:
shutil.rmtree(local_path)
print(f'Removed existing repository folder at {local_path}')
except Exception as e:
print(f'Unable to delete the directory {local_path} due to {str(e)}')
exit(1)
# Clone the repository
try:
print('Cloning the repository...')
Repo.clone_from(repo.git_url, local_path)
print(f'Repository cloned successfully at {local_path}')
except Exception as e:
print(f'Failed to clone the repository due to {str(e)}')
import os
import subprocess
from datetime import datetime
# Define the paths for the local git repo and the application
local_repo_path = 'C:\\Temp\\Repo'
app_path = 'C:\\App\\Repo'
# Traverse over the files in the local repo
for foldername, subfolders, filenames in os.walk(local_repo_path):
for filename in filenames:
# Get the full file path for the file in the local repo
file_repo = os.path.join(foldername, filename)
# Get the corresponding file path in the application directory
file_app = file_repo.replace(local_repo_path, app_path)
# If the file exists in the application directory
if os.path.isfile(file_app):
# Get the last modified time for both files
file_repo_time = os.path.getmtime(file_repo)
file_app_time = os.path.getmtime(file_app)
# If the file in the repo is newer, copy it over to the application directory
if file_repo_time > file_app_time:
print(f'Copying newer file {file_repo} to {file_app}...')
try:
# Robocopy command for copy
command = f'robocopy "{os.path.dirname(file_repo)}" "{os.path.dirname(file_app)}" "{filename}" /XO'
subprocess.run(command, shell=True, check=True)
except subprocess.CalledProcessError as e:
print(f'Robocopy failed with error: {e.output}')
# If the file does not exist in the application directory, just copy it over
else:
print(f'Copying new file {file_repo} to {file_app}...')
try:
# Robocopy command for copy
command = f'robocopy "{os.path.dirname(file_repo)}" "{os.path.dirname(file_app)}" "{filename}" /XO'
subprocess.run(command, shell=True, check=True)
except subprocess.CalledProcessError as e:
print(f'Robocopy failed with error: {e.output}')
Test