blob: 70dc03ff1c550f3c84d38a402085fee5b4fc98ff [file] [log] [blame] [edit]
"""Helper script to download source archives and upload them to the Eigen GitLab generic package registry."""
import os
import requests
import hashlib
import argparse
import sys
import tempfile
EIGEN_PROJECT_ID = 15462818 # Taken from the gitlab project page.
def calculate_sha256(filepath: str):
"""Calculates the SHA256 checksum of a file."""
sha256_hash = hashlib.sha256()
with open(filepath, "rb") as f:
# Read and update hash in chunks of 4K
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
def upload_to_generic_registry(
gitlab_private_token: str, package_name: str, package_version: str, filepath: str
):
"""Uploads a file to the GitLab generic package registry."""
headers = {"PRIVATE-TOKEN": gitlab_private_token}
filename = os.path.basename(filepath)
upload_url = f"https://gitlab.com/api/v4/projects/{EIGEN_PROJECT_ID}/packages/generic/{package_name}/{package_version}/{filename}"
print(f"Uploading {filename} to {upload_url}...")
try:
with open(filepath, "rb") as f:
response = requests.put(upload_url, headers=headers, data=f)
response.raise_for_status()
print(f"Successfully uploaded {filename}.")
return True
except requests.exceptions.RequestException as e:
print(f"Error uploading {filename}: {e}")
if e.response is not None:
print(f"Response content: {e.response.text}")
return False
def main():
"""Main function to download archives and upload them to the registry."""
parser = argparse.ArgumentParser(
description="Download GitLab release archives for Eigen and upload them to the generic package registry."
)
parser.add_argument(
"--gitlab_private_token",
type=str,
help="GitLab private API token. Defaults to the GITLAB_PRIVATE_TOKEN environment variable if set.",
)
parser.add_argument(
"--version",
required=True,
help="Specify a single version (tag name) to process.",
)
parser.add_argument(
"--download-dir", help=f"Directory to store temporary downloads (optional)."
)
args = parser.parse_args()
if not args.gitlab_private_token:
args.gitlab_private_token = os.getenv("GITLAB_PRIVATE_TOKEN")
if not args.gitlab_private_token:
print("Could not determine GITLAB_PRIVATE_TOKEN.", file=sys.stderr)
parser.print_usage()
sys.exit(1)
# Create download directory if it doesn't exist.
cleanup_download_dir = False
if args.download_dir:
if not os.path.exists(args.download_dir):
cleanup_download_dir = True
os.makedirs(args.download_dir)
else:
args.download_dir = tempfile.mkdtemp()
cleanup_download_dir = True
for ext in ["tar.gz", "tar.bz2", "tar", "zip"]:
archive_filename = f"eigen-{args.version}.{ext}"
archive_url = f"https://gitlab.com/libeigen/eigen/-/archive/{args.version}/{archive_filename}"
archive_filepath = os.path.join(args.download_dir, archive_filename)
# Download the archive
print(f"Downloading {archive_url}...")
try:
response = requests.get(archive_url, stream=True)
response.raise_for_status()
with open(archive_filepath, "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
print(f"Downloaded to {archive_filepath}")
except requests.exceptions.RequestException as e:
print(f"Error downloading {archive_url}: {e}. Skipping.")
continue
# Calculate SHA256 sum
sha256_sum = calculate_sha256(archive_filepath)
print(f"SHA256 sum: {sha256_sum}")
# Create SHA256 sum file
sha_filename = f"{archive_filename}.sha256"
sha_filepath = os.path.join(args.download_dir, sha_filename)
with open(sha_filepath, "w") as f:
f.write(f"{sha256_sum} {archive_filename}\n")
print(f"Created SHA256 file: {sha_filepath}")
# Upload archive to generic registry
if not upload_to_generic_registry(
args.gitlab_private_token, "eigen", args.version, archive_filepath
):
# If upload fails, clean up and move to the next release
os.remove(archive_filepath)
os.remove(sha_filepath)
continue
# Upload SHA256 sum file to generic registry
upload_to_generic_registry(
args.gitlab_private_token, "eigen", args.version, sha_filepath
)
# Clean up downloaded files
print("Cleaning up local files...")
os.remove(archive_filepath)
os.remove(sha_filepath)
# Clean up the download directory if it's empty
if cleanup_download_dir and not os.listdir(args.download_dir):
os.rmdir(args.download_dir)
if __name__ == "__main__":
main()