Add Gitea CI and automatic dev deployment
This commit is contained in:
1 parent
543564a29c
commit
b4f29d4966
20 files changed
+1109
-29
No files matched your search
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Reconcile all business Git references from Gitea to GitHub under one lock."""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shlex
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
from ci import SOURCE, locked, request_json, require, run, save
|
||||
|
||||
TARGET = '[email protected]:eezd/AlphaPulse.git'
|
||||
DIRECTORY = Path('/docker/gitea/mirrors/AlphaPulse')
|
||||
|
||||
|
||||
def refs(repository, remote=None, env=None):
|
||||
args = ['ls-remote', remote, 'refs/heads/*', 'refs/tags/*'] if remote else [
|
||||
'for-each-ref', '--format=%(objectname)\t%(refname)', 'refs/heads/', 'refs/tags/']
|
||||
output = run('git', '-C', repository, *args, env=env)
|
||||
return {ref: sha for line in output.splitlines() for sha, ref in [line.split()] if not ref.endswith('^{}')}
|
||||
|
||||
|
||||
def synchronize(directory, source, target, env=None):
|
||||
directory = Path(directory)
|
||||
with locked(directory / '.mirror.lock'):
|
||||
repository = directory / 'repository.git'
|
||||
if not repository.exists():
|
||||
run('git', 'init', '--bare', repository)
|
||||
for _ in range(3):
|
||||
run('git', '-C', repository, 'fetch', '--prune', '--no-tags', source,
|
||||
'+refs/heads/*:refs/heads/*', '+refs/tags/*:refs/tags/*', env=env)
|
||||
snapshot = refs(repository)
|
||||
require('refs/heads/main' in snapshot, 'Source main is missing; refusing destructive synchronization')
|
||||
if run('git', '-C', repository, 'log', '--all', '--format=', '--name-only', '--', '.gitattributes', '**/.gitattributes'):
|
||||
run('git', '-C', repository, 'lfs', 'fetch', '--all', source, env=env)
|
||||
run('git', '-C', repository, 'lfs', 'push', '--all', target, env=env)
|
||||
run('git', '-C', repository, 'push', '--atomic', '--prune', target,
|
||||
'+refs/heads/*:refs/heads/*', '+refs/tags/*:refs/tags/*', env=env)
|
||||
require(refs(repository, target, env) == snapshot, 'GitHub references differ from the selected source snapshot')
|
||||
if refs(repository, source, env) == snapshot:
|
||||
save(directory / 'last-sync.json', {'refs': snapshot, 'verified_at': time.time()})
|
||||
return
|
||||
raise RuntimeError('Source kept changing; retry the mirror')
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.parse_args()
|
||||
# A write-enabled deploy key limits GitHub access to this repository.
|
||||
with tempfile.TemporaryDirectory(prefix='ap-mirror-auth-') as temporary:
|
||||
key = Path(temporary) / 'key'
|
||||
key.write_text(os.environ['ALPHAPULSE_GITHUB_SSH_KEY'])
|
||||
key.chmod(0o600)
|
||||
hosts = Path(temporary) / 'known_hosts'
|
||||
hosts.write_text(''.join('github.com ' + entry + '\n' for entry in request_json('https://api.github.com/meta')['ssh_keys']))
|
||||
command = ['ssh', '-i', str(key), '-o', 'IdentitiesOnly=yes', '-o', 'StrictHostKeyChecking=yes',
|
||||
'-o', 'UserKnownHostsFile=' + str(hosts)]
|
||||
env = {**os.environ, 'GIT_SSH_COMMAND': shlex.join(command), 'GIT_TERMINAL_PROMPT': '0'}
|
||||
synchronize(DIRECTORY, SOURCE, TARGET, env)
|
||||
print('GitHub business references and history verified')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in new issue
Block a user