Self-hosting feels good and gives me the freedom to access my files even when GitHub experiences issues. In this project, I will create a script to synchronize my files from GitHub to my Gitea instance.
Setup
I prefer using executable scripts as they resemble utilities and provide a polished experience. For this project, I will utilize setuptools. Below is the setup file with comments:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[build-system]
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"
# requires-python = ">=3.8" # not sure yet
[tool.setuptools.packages.find]
where = ["."] # list of folders that contain the packages (["."] by default)
include = ["git_sync*"] # package names should match these glob patterns (["*"] by default)
exclude = ["tests*"] # exclude packages matching these glob patterns (empty by default)
namespaces = false
[project]
name = "git_sync"
version = "0.0.1"
readme = "readme.md"
# My dependencies
dependencies=[
"requests",
"pyaml",
]
[project.scripts]
git_sync = "git_sync.app:main"
Additionally, I provide a requirements.txt
file that includes both development and building requirements:
1
2
3
4
5
6
7
requests
pyaml
# requirements for building
setuptools
setuptools-scm
build
For the application startup, I prefer using argparse
and the standard debugging facility bound to the log level. Here’s an example in Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import argparse
import logging
import os
log_string_format = '%(asctime)s [%(levelname)s]: %(message)s'
def main():
"""
main entry point
"""
parser = argparse.ArgumentParser(description="The app registers for synchro your GitHub repos on a Gitea instance")
parser.add_argument("input", help="the config file for this program", type=str)
parser.add_argument("--verbose", '-v',
help="sets the app in debug mode",
action='store_true')
args = parser.parse_args()
if args.verbose:
logging.basicConfig(level=logging.DEBUG, format=log_string_format)
else:
logging.basicConfig(level=logging.INFO, format=log_string_format)
if __name__ == '__main__':
main()
Feel free to copy and paste the provided snippets as a base for you and others to get started.
To build the project, run the following command:
1
python -m build
This will generate an installable wheel.
Retrieving All of My GitHub Projects
To retrieve all of my GitHub projects, I followed the instructions provided here. I have two notes regarding this process: the default page size is 30, and the page number starts from 1. If, like me, you have numerous repositories, pagination is necessary.
Mirroring Repositories on Gitea
Mirroring the repositories on Gitea was a straightforward process. I simply made API requests with the required data and tokens. Keep in mind that the minimum Gitea update interval is 10 minutes. I used the built-in documentation in Gitea for repo mirroring.
Software package
Here is the zip.