129 lines
3.8 KiB
Python
129 lines
3.8 KiB
Python
import os
|
|
import re
|
|
import logging
|
|
from configparser import ConfigParser
|
|
|
|
import requests
|
|
|
|
from logger import setup_log
|
|
from package import Package
|
|
|
|
|
|
## Autopkg Apps
|
|
apps = {
|
|
"bitcoinknots": {
|
|
"name": "Bitcoin Knots",
|
|
"url": "https://api.github.com/repos/bitcoinknots/bitcoin/releases/latest",
|
|
"versioningScheme": r"^v(\d+)\.(\d+)\.knots(\d{8})$"
|
|
},
|
|
"electrs": {
|
|
"name": "electrs",
|
|
"url": "https://api.github.com/repos/romanz/electrs/releases/latest"
|
|
}
|
|
}
|
|
|
|
|
|
class Autopkg:
|
|
def __init__(self):
|
|
# Logging Setup
|
|
setup_log()
|
|
|
|
logging.info("Running autopkg (c) 2025 phantom <phantom@shadeouts.net> https://shadeouts.net/")
|
|
|
|
# Environment Setup
|
|
target = os.getenv("APKG_TARGET")
|
|
os.environ["APKG_RUNTIME_DIR"] = os.path.dirname(os.path.abspath(__file__)) # Set runtime directory
|
|
|
|
match target:
|
|
case "prod":
|
|
self.datafile = "/etc/autopkg/data.ini"
|
|
case "test" | "debug":
|
|
logging.warning("Running autopkg in testing mode!")
|
|
|
|
self.datafile = os.getenv("APKG_RUNTIME_DIR") + "/test/data.ini"
|
|
|
|
if os.path.exists(self.datafile): os.remove(self.datafile)
|
|
case _:
|
|
raise ValueError("APKG_TARGET environment variable not setup correctly!")
|
|
|
|
## Config File Setup
|
|
self.data = ConfigParser()
|
|
|
|
self.data.read(self.datafile)
|
|
|
|
|
|
# Write datafile changes
|
|
def write_data(self):
|
|
with open(self.datafile, "w") as f:
|
|
self.data.write(f)
|
|
|
|
|
|
# Main Application
|
|
def main(self):
|
|
# Handle apps
|
|
for app, info in apps.items():
|
|
# Setup INI file
|
|
if f"tags.{app}" not in self.data:
|
|
self.data.add_section(f"tags.{app}")
|
|
|
|
self.write_data()
|
|
|
|
# Grab data from data file
|
|
data_section = f"tags.{app}"
|
|
data_tag = [list.append(i[1]) for i in self.data.items(data_section)]
|
|
|
|
app_name = info["name"]
|
|
|
|
# Ping API
|
|
response = requests.get(info["url"]) # Fetch data from Git API
|
|
|
|
# Parse through JSON data
|
|
if response.status_code == 200:
|
|
json = response.json()
|
|
api_tag = json["tag_name"] # App version from API
|
|
pre_release = json["prerelease"]
|
|
|
|
# Package new versions if available
|
|
api_tag_higher = is_tag_higher(api_tag, data_tag, info)
|
|
|
|
if not pre_release and api_tag_higher[0]:
|
|
logging.info(f"Found new version ({api_tag}) for {app_name}, packaging..")
|
|
|
|
try: # REMOVE!!!
|
|
if Package(app, api_tag).build():
|
|
ini_version = str(api_tag)
|
|
|
|
self.write_data()
|
|
except Exception as e:
|
|
logging.error(f"Error starting docker container for {app_name}")
|
|
else:
|
|
logging.log(f"No new versions were found for {app_name}")
|
|
else:
|
|
logging.error(f"Failed to ping {app_name}'s API.")
|
|
|
|
|
|
def is_tag_higher(api_tag: str, data_tag: list, data_info: dict) -> tuple:
|
|
regular_scheme = r"^v(\d+)\.(\d+)\.(\d+)$"
|
|
|
|
# Derive version from API tag
|
|
try:
|
|
version = re.match(data_info, api_tag)
|
|
except:
|
|
version = re.match(regular_scheme, api_tag)
|
|
|
|
if not version:
|
|
logging.warning(f"New tag for {app_info["name"]} doesn't follow versioning schemes, ignoring..")
|
|
|
|
return (False)
|
|
|
|
# Compare versions
|
|
re_tag = map(int, version.groups())
|
|
is_higher = tuple(map(lambda a, b: a >= b, re_tag, data_tag))
|
|
|
|
return (True, re_tag) if all(is_higher) else (False)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Call main function
|
|
Autopkg().main()
|