Skip to content

Instantly share code, notes, and snippets.

@mat-1
Last active December 7, 2023 03:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mat-1/5cdfc9dff74d98ac1ce8b290d2f057c5 to your computer and use it in GitHub Desktop.
Save mat-1/5cdfc9dff74d98ac1ce8b290d2f057c5 to your computer and use it in GitHub Desktop.
Automatically run "git pull" and deploy your app when it's pushed to your repo.
{
"user": "mat",
"interval": 5,
"directory": put the directory of your project here,
"deploy": "npm i && npm run compile && node build/index.js"
}
import subprocess
import requests
import signal
import json
import time
import os
print('Starting')
# read config.json
with open('config.json') as f:
config = json.load(f)
USER = config['user']
DIRECTORY = config['directory']
DEPLOY = config['deploy']
INTERVAL = config.get('interval', 5)
# cd into the directory
os.chdir(DIRECTORY)
def run_deploy():
# run deploy script in the background
print('Running', DEPLOY)
return subprocess.Popen(DEPLOY, shell=True, preexec_fn=os.setsid)
def end_deploy(p):
# end deploy script
print('killing deploy script')
os.killpg(os.getpgid(p.pid), signal.SIGTERM)
# p.kill()
deployed_process = run_deploy()
print('Ok, started checking for updates!')
run = True
def handler_stop_signals(signum, frame):
global run
run = False
print('Got signal', signum)
signal.signal(signal.SIGINT, handler_stop_signals)
signal.signal(signal.SIGTERM, handler_stop_signals)
try:
while run:
# git pull and store the result
print('Pulling')
result = subprocess.run(f'sudo -u {USER} git pull', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print('Did git pull')
print(result)
# if there's an stderr, git reset and try again
if result.stderr and result.stdout != b'Already up to date.\n' and (result.stderr.decode().strip().endswith('Aborting') or not result.stdout.startswith(b'Updating ')):
print('There was an error pulling the repo, resetting and trying again.')
print(result)
result = subprocess.run('git reset --hard HEAD', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
time.sleep(5)
continue
# if it doesn't just say "Already up to date." then run our deploy script
if result.stdout.decode('utf-8') != 'Already up to date.\n':
print('Deploying update!', result)
end_deploy(deployed_process)
deployed_process = run_deploy()
print('Returned from deploy')
time.sleep(1)
if deployed_process.poll() is not None: # if it's not None, the process is dead
print(f'Reviving process (status code {deployed_process.poll()})')
deployed_process = run_deploy()
print('Revived process')
# wait the interval before trying again
time.sleep(INTERVAL)
finally:
# end deploy script
end_deploy(deployed_process)
print('Ended')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment