mirror of
https://github.com/vleeuwenmenno/supplements.git
synced 2025-09-11 18:29:12 +02:00
574 lines
24 KiB
Python
Executable File
574 lines
24 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import subprocess
|
|
import os
|
|
import sys
|
|
import re
|
|
import fileinput
|
|
from datetime import datetime
|
|
|
|
def get_project_root():
|
|
"""Finds the project root directory containing .git"""
|
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
# Go up one level from bin/
|
|
project_root = os.path.dirname(current_dir)
|
|
if os.path.isdir(os.path.join(project_root, '.git')):
|
|
return project_root
|
|
else:
|
|
print("Error: Could not find project root (.git directory).", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
def get_version(project_root):
|
|
"""Reads the version from pubspec.yaml"""
|
|
pubspec_path = os.path.join(project_root, 'pubspec.yaml')
|
|
try:
|
|
with open(pubspec_path, 'r') as f:
|
|
for line in f:
|
|
if line.strip().startswith('version:'):
|
|
# Extract version string after 'version:'
|
|
version_match = re.search(r'version:\s*([\w\.\+\-]+)', line)
|
|
if version_match:
|
|
return version_match.group(1).strip()
|
|
print(f"Error: Could not find 'version:' line in {pubspec_path}", file=sys.stderr)
|
|
sys.exit(1)
|
|
except FileNotFoundError:
|
|
print(f"Error: {pubspec_path} not found.", file=sys.stderr)
|
|
sys.exit(1)
|
|
except Exception as e:
|
|
print(f"Error reading {pubspec_path}: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
def check_tag_exists(tag_name, project_root):
|
|
"""Checks if a git tag already exists"""
|
|
try:
|
|
# Use cwd=project_root to run git in the correct directory
|
|
result = subprocess.run(['git', 'rev-parse', '--verify', '--quiet', tag_name],
|
|
cwd=project_root,
|
|
check=False, # Don't raise exception on non-zero exit
|
|
capture_output=True)
|
|
return result.returncode == 0
|
|
except FileNotFoundError:
|
|
print("Error: 'git' command not found. Make sure Git is installed and in your PATH.", file=sys.stderr)
|
|
sys.exit(1)
|
|
except Exception as e:
|
|
print(f"Error checking git tag: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
def check_git_dirty(project_root):
|
|
"""Checks if the git working directory is dirty"""
|
|
try:
|
|
result = subprocess.run(['git', 'status', '--porcelain'],
|
|
cwd=project_root,
|
|
check=True,
|
|
capture_output=True,
|
|
text=True)
|
|
if result.stdout:
|
|
print("Warning: Git working directory is dirty:", file=sys.stderr)
|
|
print(result.stdout.strip(), file=sys.stderr)
|
|
return True # Dirty
|
|
return False # Clean
|
|
except FileNotFoundError:
|
|
print("Error: 'git' command not found. Make sure Git is installed and in your PATH.", file=sys.stderr)
|
|
sys.exit(1) # Exit if git isn't found
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error checking git status: {e}", file=sys.stderr)
|
|
# Decide if we should exit or just warn and continue? Let's exit for safety.
|
|
sys.exit(1)
|
|
except Exception as e:
|
|
print(f"An unexpected error occurred checking git status: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
|
|
def update_pubspec_version(project_root, new_version):
|
|
"""Updates the version in pubspec.yaml"""
|
|
pubspec_path = os.path.join(project_root, 'pubspec.yaml')
|
|
print(f"Updating {pubspec_path} to version: {new_version}")
|
|
try:
|
|
# Read lines, update the version line, write back
|
|
updated = False
|
|
lines = []
|
|
with open(pubspec_path, 'r') as f:
|
|
lines = f.readlines()
|
|
|
|
with open(pubspec_path, 'w') as f:
|
|
for line in lines:
|
|
if line.strip().startswith('version:'):
|
|
f.write(f"version: {new_version}\n")
|
|
updated = True
|
|
else:
|
|
f.write(line)
|
|
|
|
if not updated:
|
|
print(f"Warning: 'version:' line not found in {pubspec_path}. File not updated.", file=sys.stderr)
|
|
return updated
|
|
|
|
except Exception as e:
|
|
print(f"Error updating {pubspec_path}: {e}", file=sys.stderr)
|
|
return False
|
|
|
|
|
|
def run_command(command_list, cwd, error_message_prefix):
|
|
"""Runs a command and handles errors"""
|
|
print(f"Running: {' '.join(command_list)}")
|
|
try:
|
|
result = subprocess.run(command_list, cwd=cwd, check=True, capture_output=True, text=True)
|
|
print(result.stdout)
|
|
if result.stderr:
|
|
print(result.stderr, file=sys.stderr) # Show stderr even on success if present
|
|
return True
|
|
except FileNotFoundError:
|
|
print(f"\nError: '{command_list[0]}' command not found. Make sure it's installed and in your PATH.", file=sys.stderr)
|
|
return False
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"\n{error_message_prefix}:", file=sys.stderr)
|
|
print(f" Command: {' '.join(e.cmd)}", file=sys.stderr)
|
|
print(f" Return code: {e.returncode}", file=sys.stderr)
|
|
if e.stdout:
|
|
print(f" Stdout:\n{e.stdout}", file=sys.stderr)
|
|
if e.stderr:
|
|
print(f" Stderr:\n{e.stderr}", file=sys.stderr)
|
|
return False
|
|
except Exception as e:
|
|
print(f"\nAn unexpected error occurred while running {' '.join(command_list)}: {e}", file=sys.stderr)
|
|
return False
|
|
|
|
|
|
def get_release_notes():
|
|
"""Prompts the user for multi-line release notes"""
|
|
print("Enter release notes (press Ctrl+D on a new line when finished):")
|
|
lines = []
|
|
try:
|
|
while True:
|
|
line = sys.stdin.readline()
|
|
if not line: # EOF detected (Ctrl+D)
|
|
break
|
|
lines.append(line)
|
|
except KeyboardInterrupt:
|
|
print("\nAborted note entry.")
|
|
return None # Indicate abortion if needed, or handle differently
|
|
return "".join(lines).strip()
|
|
|
|
def get_git_remotes(project_root):
|
|
"""Gets all git remotes"""
|
|
try:
|
|
result = subprocess.run(['git', 'remote', '-v'],
|
|
cwd=project_root,
|
|
check=True,
|
|
capture_output=True,
|
|
text=True)
|
|
remotes = {}
|
|
for line in result.stdout.strip().split('\n'):
|
|
if line and '(fetch)' in line:
|
|
parts = line.split('\t')
|
|
if len(parts) >= 2:
|
|
remote_name = parts[0]
|
|
remote_url = parts[1].replace(' (fetch)', '')
|
|
remotes[remote_name] = remote_url
|
|
return remotes
|
|
except FileNotFoundError:
|
|
print("Error: 'git' command not found. Make sure Git is installed and in your PATH.", file=sys.stderr)
|
|
sys.exit(1)
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error getting git remotes: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
except Exception as e:
|
|
print(f"An unexpected error occurred getting git remotes: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
def is_gitea_remote(remote_url):
|
|
"""Checks if a remote URL appears to be a Gitea instance"""
|
|
# This is a heuristic - you might want to adjust this based on your setup
|
|
gitea_indicators = ['gitea', 'tea', 'git.mvl.sh']
|
|
return any(indicator in remote_url.lower() for indicator in gitea_indicators)
|
|
|
|
def is_github_remote(remote_url):
|
|
"""Checks if a remote URL is GitHub"""
|
|
return 'github.com' in remote_url.lower()
|
|
|
|
def select_remotes_for_push(remotes):
|
|
"""Allows user to select which remotes to push to"""
|
|
if not remotes:
|
|
print("No remotes found.")
|
|
return []
|
|
|
|
print("\nAvailable remotes:")
|
|
remote_list = list(remotes.keys())
|
|
for i, remote in enumerate(remote_list, 1):
|
|
print(f" {i}. {remote} ({remotes[remote]})")
|
|
|
|
while True:
|
|
selection = input(f"\nSelect remotes to push to (comma-separated numbers, 'all', or 'none') [all]: ").strip()
|
|
|
|
if not selection or selection.lower() == 'all':
|
|
return remote_list
|
|
|
|
if selection.lower() == 'none':
|
|
return []
|
|
|
|
try:
|
|
selected_indices = [int(x.strip()) for x in selection.split(',')]
|
|
selected_remotes = []
|
|
for idx in selected_indices:
|
|
if 1 <= idx <= len(remote_list):
|
|
selected_remotes.append(remote_list[idx - 1])
|
|
else:
|
|
print(f"Invalid selection: {idx}. Please try again.")
|
|
break
|
|
else:
|
|
return selected_remotes
|
|
except ValueError:
|
|
print("Invalid input. Please enter numbers separated by commas, 'all', or 'none'.")
|
|
|
|
def select_remote_for_release(remotes):
|
|
"""Allows user to select which remote to create the release on"""
|
|
if not remotes:
|
|
print("No remotes found.")
|
|
return None
|
|
|
|
# Filter remotes that might support releases (Gitea or GitHub)
|
|
release_capable_remotes = {}
|
|
for name, url in remotes.items():
|
|
if is_gitea_remote(url) or is_github_remote(url):
|
|
release_capable_remotes[name] = url
|
|
|
|
if not release_capable_remotes:
|
|
print("No remotes found that appear to support releases (Gitea or GitHub).")
|
|
return None
|
|
|
|
if len(release_capable_remotes) == 1:
|
|
remote_name = list(release_capable_remotes.keys())[0]
|
|
print(f"\nUsing {remote_name} for release creation ({release_capable_remotes[remote_name]})")
|
|
return remote_name
|
|
|
|
print("\nAvailable remotes for release creation:")
|
|
remote_list = list(release_capable_remotes.keys())
|
|
for i, remote in enumerate(remote_list, 1):
|
|
remote_type = "Gitea" if is_gitea_remote(release_capable_remotes[remote]) else "GitHub"
|
|
print(f" {i}. {remote} ({remote_type}: {release_capable_remotes[remote]})")
|
|
|
|
while True:
|
|
try:
|
|
selection = input(f"\nSelect remote for release creation [1]: ").strip()
|
|
if not selection:
|
|
return remote_list[0]
|
|
|
|
idx = int(selection)
|
|
if 1 <= idx <= len(remote_list):
|
|
return remote_list[idx - 1]
|
|
else:
|
|
print(f"Invalid selection: {idx}. Please try again.")
|
|
except ValueError:
|
|
print("Invalid input. Please enter a number.")
|
|
|
|
def create_github_release(tag_name, title, notes, is_prerelease, project_root, remote_name, remotes):
|
|
"""Creates a GitHub release using gh CLI"""
|
|
# Get the repository URL from the remote
|
|
remote_url = remotes[remote_name]
|
|
|
|
# Extract owner/repo from GitHub URL
|
|
repo_info = None
|
|
if 'github.com' in remote_url:
|
|
# Handle both SSH and HTTPS URLs
|
|
if remote_url.startswith('git@github.com:'):
|
|
# SSH format: git@github.com:owner/repo.git
|
|
repo_part = remote_url.replace('git@github.com:', '').replace('.git', '')
|
|
repo_info = repo_part
|
|
elif 'github.com/' in remote_url:
|
|
# HTTPS format: https://github.com/owner/repo.git
|
|
repo_part = remote_url.split('github.com/')[-1].replace('.git', '')
|
|
repo_info = repo_part
|
|
|
|
gh_command = ['gh', 'release', 'create', tag_name, '--title', title]
|
|
if repo_info:
|
|
gh_command.extend(['--repo', repo_info])
|
|
|
|
if is_prerelease:
|
|
gh_command.append('--prerelease')
|
|
if notes:
|
|
gh_command.extend(['--notes', notes])
|
|
else:
|
|
gh_command.append('--generate-notes')
|
|
|
|
print(f"\nCreating GitHub release on {remote_name}...")
|
|
if repo_info:
|
|
print(f"Repository: {repo_info}")
|
|
print(f"Running: {' '.join(gh_command)}")
|
|
|
|
try:
|
|
result = subprocess.run(gh_command, cwd=project_root, check=True, capture_output=True, text=True)
|
|
print("\nGitHub release created successfully!")
|
|
print(result.stdout)
|
|
return True
|
|
except FileNotFoundError:
|
|
print("\nError: 'gh' command not found. Make sure GitHub CLI is installed and authenticated.", file=sys.stderr)
|
|
return False
|
|
except subprocess.CalledProcessError as e:
|
|
print("\nError creating GitHub release:", file=sys.stderr)
|
|
print(f" Return code: {e.returncode}", file=sys.stderr)
|
|
if e.stdout:
|
|
print(f" Stdout:\n{e.stdout}", file=sys.stderr)
|
|
if e.stderr:
|
|
print(f" Stderr:\n{e.stderr}", file=sys.stderr)
|
|
return False
|
|
except Exception as e:
|
|
print(f"\nAn unexpected error occurred creating GitHub release: {e}", file=sys.stderr)
|
|
return False
|
|
|
|
def create_gitea_release(tag_name, title, notes, is_prerelease, project_root, remote_name):
|
|
"""Creates a Gitea release using tea CLI"""
|
|
tea_command = ['tea', 'release', 'create', '--tag', tag_name, '--title', title, '--remote', remote_name]
|
|
if is_prerelease:
|
|
tea_command.append('--prerelease')
|
|
if notes:
|
|
tea_command.extend(['--note', notes])
|
|
|
|
print(f"\nCreating Gitea release on {remote_name}...")
|
|
print(f"Running: {' '.join(tea_command)}")
|
|
|
|
try:
|
|
result = subprocess.run(tea_command, cwd=project_root, check=True, capture_output=True, text=True)
|
|
print("\nGitea release created successfully!")
|
|
print(result.stdout)
|
|
return True
|
|
except FileNotFoundError:
|
|
print("\nError: 'tea' command not found. Make sure Gitea CLI is installed and configured.", file=sys.stderr)
|
|
return False
|
|
except subprocess.CalledProcessError as e:
|
|
print("\nError creating Gitea release:", file=sys.stderr)
|
|
print(f" Return code: {e.returncode}", file=sys.stderr)
|
|
if e.stdout:
|
|
print(f" Stdout:\n{e.stdout}", file=sys.stderr)
|
|
if e.stderr:
|
|
print(f" Stderr:\n{e.stderr}", file=sys.stderr)
|
|
return False
|
|
except Exception as e:
|
|
print(f"\nAn unexpected error occurred creating Gitea release: {e}", file=sys.stderr)
|
|
return False
|
|
|
|
def main():
|
|
project_root = get_project_root()
|
|
|
|
# --- Get remotes information ---
|
|
remotes = get_git_remotes(project_root)
|
|
print(f"Found {len(remotes)} remote(s):")
|
|
for name, url in remotes.items():
|
|
print(f" {name}: {url}")
|
|
|
|
# --- Check Git Status ---
|
|
if check_git_dirty(project_root):
|
|
dirty_confirm = input("Working directory is dirty. Continue anyway? [y/N]: ").strip().lower()
|
|
if dirty_confirm != 'y':
|
|
print("Aborted due to dirty working directory.")
|
|
sys.exit(0)
|
|
print("Continuing with dirty working directory...")
|
|
# --- End Check Git Status ---
|
|
|
|
original_version = get_version(project_root)
|
|
tag_name = f"v{original_version}"
|
|
version_to_use = original_version # This might change if tag exists
|
|
|
|
print(f"Detected version: {original_version}")
|
|
print(f"Tag to create based on pubspec: {tag_name}")
|
|
|
|
# Ask if user wants to use detected version or specify a new one
|
|
use_detected = input(f"\nUse detected version '{original_version}'? [Y/n]: ").strip().lower()
|
|
if use_detected == 'n':
|
|
while True:
|
|
new_base_version_input = input("Enter a new base version tag (e.g., v1.2.0): ").strip()
|
|
# Validate the base version input (starts with v, numbers, dots)
|
|
if not re.match(r'^v\d+(\.\d+)*$', new_base_version_input):
|
|
print("Invalid format. Please use 'v' followed by numbers and dots (e.g., v1.2.0). Try again.", file=sys.stderr)
|
|
continue # Ask again
|
|
|
|
# Get current date in ddMMyyyy format
|
|
current_date = datetime.now().strftime('%d%m%Y')
|
|
# Construct the full version string (without leading 'v' for pubspec)
|
|
version_to_use = f"{new_base_version_input[1:]}+{current_date}" # Remove leading 'v'
|
|
tag_name = f"v{version_to_use}" # Add 'v' back for the tag
|
|
print(f"New version string: {version_to_use}")
|
|
print(f"New tag to check/create: {tag_name}")
|
|
|
|
# Check if this new tag already exists
|
|
if check_tag_exists(tag_name, project_root):
|
|
print(f"\nWarning: Tag '{tag_name}' already exists.")
|
|
continue # Ask for a different version
|
|
else:
|
|
break # Tag doesn't exist, we can use this version
|
|
else:
|
|
# User wants to use detected version, but check if tag already exists
|
|
if check_tag_exists(tag_name, project_root):
|
|
print(f"\nWarning: Tag '{tag_name}' already exists.")
|
|
while True:
|
|
new_base_version_input = input("Enter a new base version tag (e.g., v1.2.0): ").strip()
|
|
# Validate the base version input (starts with v, numbers, dots)
|
|
if not re.match(r'^v\d+(\.\d+)*$', new_base_version_input):
|
|
print("Invalid format. Please use 'v' followed by numbers and dots (e.g., v1.2.0). Try again.", file=sys.stderr)
|
|
continue # Ask again
|
|
|
|
# Get current date in ddMMyyyy format
|
|
current_date = datetime.now().strftime('%d%m%Y')
|
|
# Construct the full version string (without leading 'v' for pubspec)
|
|
version_to_use = f"{new_base_version_input[1:]}+{current_date}" # Remove leading 'v'
|
|
tag_name = f"v{version_to_use}" # Add 'v' back for the tag
|
|
print(f"New version string: {version_to_use}")
|
|
print(f"New tag to check/create: {tag_name}")
|
|
|
|
# Check if this new tag already exists
|
|
if check_tag_exists(tag_name, project_root):
|
|
print(f"\nWarning: Tag '{tag_name}' already exists.")
|
|
continue # Ask for a different version
|
|
else:
|
|
break # Tag doesn't exist, we can use this version
|
|
|
|
print(f"\nFinal version: {version_to_use}")
|
|
print(f"Final tag: {tag_name}")
|
|
|
|
# --- Optional: Update pubspec, pub get, commit ---
|
|
commit_changes_input = input(f"\nUpdate pubspec to {version_to_use}, run 'flutter pub get', commit, and push? [y/N]: ").strip().lower()
|
|
if commit_changes_input == 'y':
|
|
print("\n--- Starting update, commit, and push process ---")
|
|
# 1. Update pubspec.yaml
|
|
if not update_pubspec_version(project_root, version_to_use):
|
|
print("Aborting due to error updating pubspec.yaml.", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# 2. Run flutter pub get
|
|
if not run_command(['flutter', 'pub', 'get'], project_root, "Error running 'flutter pub get'"):
|
|
print("Aborting due to error running 'flutter pub get'.", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# 3. Git add
|
|
if not run_command(['git', 'add', 'pubspec.yaml', 'pubspec.lock'], project_root, "Error running 'git add'"):
|
|
print("Aborting due to error running 'git add'.", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# 4. Git commit
|
|
commit_message = f"chore: bump version to {version_to_use}"
|
|
if not run_command(['git', 'commit', '-m', commit_message], project_root, "Error running 'git commit'"):
|
|
print("Aborting due to error running 'git commit'.", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# 5. Select remotes to push to
|
|
selected_remotes = select_remotes_for_push(remotes)
|
|
if not selected_remotes:
|
|
print("No remotes selected for push. Skipping push step.")
|
|
else:
|
|
# Push to selected remotes
|
|
for remote in selected_remotes:
|
|
print(f"\nPushing to {remote}...")
|
|
if not run_command(['git', 'push', remote], project_root, f"Error pushing to {remote}"):
|
|
print(f"Failed to push to {remote}. Continuing with other remotes...", file=sys.stderr)
|
|
else:
|
|
print(f"Successfully pushed to {remote}")
|
|
|
|
print("--- Update, commit, and push process finished ---")
|
|
else:
|
|
print("Skipping pubspec update, pub get, commit, and push.")
|
|
# --- End optional update ---
|
|
|
|
|
|
# Ask about pre-release
|
|
prerelease_input = input("\nMark as pre-release? [Y/n]: ").strip().lower()
|
|
is_prerelease = prerelease_input == '' or prerelease_input == 'y'
|
|
|
|
# Ask about release notes
|
|
notes = ""
|
|
notes_input = input("Add release notes? [y/N]: ").strip().lower()
|
|
if notes_input == 'y':
|
|
notes = get_release_notes()
|
|
if notes is None: # Handle potential abortion during note entry
|
|
print("Release aborted during note entry.")
|
|
sys.exit(1)
|
|
|
|
# Select remote for release creation
|
|
release_remote = select_remote_for_release(remotes)
|
|
if not release_remote:
|
|
print("No suitable remote found for release creation. Exiting.")
|
|
sys.exit(1)
|
|
|
|
remote_url = remotes[release_remote]
|
|
is_github = is_github_remote(remote_url)
|
|
is_gitea = is_gitea_remote(remote_url)
|
|
|
|
# Create the git tag locally first
|
|
print(f"\nCreating git tag '{tag_name}'...")
|
|
if not run_command(['git', 'tag', tag_name], project_root, f"Error creating tag {tag_name}"):
|
|
print(f"Failed to create tag {tag_name}.", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# Push the tag to the release remote
|
|
print(f"Pushing tag '{tag_name}' to {release_remote}...")
|
|
if not run_command(['git', 'push', release_remote, tag_name], project_root, f"Error pushing tag to {release_remote}"):
|
|
print(f"Failed to push tag to {release_remote}. Cannot create release without the tag.", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# Ask for confirmation
|
|
platform = "GitHub" if is_github else "Gitea" if is_gitea else "Unknown platform"
|
|
confirm_input = input(f"\nProceed with creating the release on {release_remote} ({platform})? [Y/n]: ").strip().lower()
|
|
if confirm_input != '' and confirm_input != 'y':
|
|
print("Aborted by user.")
|
|
sys.exit(0)
|
|
|
|
# Create the release
|
|
success = False
|
|
if is_github:
|
|
success = create_github_release(tag_name, tag_name, notes, is_prerelease, project_root, release_remote, remotes)
|
|
elif is_gitea:
|
|
success = create_gitea_release(tag_name, tag_name, notes, is_prerelease, project_root, release_remote)
|
|
else:
|
|
print(f"Unsupported remote type for {release_remote}. Only GitHub and Gitea are supported.", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
if not success:
|
|
print("Release creation failed.", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# Ask about creating releases on other platforms
|
|
release_capable_remotes = {}
|
|
for name, url in remotes.items():
|
|
if is_gitea_remote(url) or is_github_remote(url):
|
|
release_capable_remotes[name] = url
|
|
|
|
print(f"\nAll release-capable remotes found: {release_capable_remotes}")
|
|
|
|
# Remove the already used remote
|
|
remaining_remotes = {k: v for k, v in release_capable_remotes.items() if k != release_remote}
|
|
|
|
print(f"Remaining remotes after removing {release_remote}: {remaining_remotes}")
|
|
|
|
if remaining_remotes:
|
|
print(f"\nOther release-capable remotes available:")
|
|
for name, url in remaining_remotes.items():
|
|
remote_type = "GitHub" if is_github_remote(url) else "Gitea"
|
|
print(f" {name} ({remote_type}: {url})")
|
|
|
|
create_more = input(f"\nCreate release on other platforms? [y/N]: ").strip().lower()
|
|
if create_more == 'y':
|
|
for remote_name, remote_url in remaining_remotes.items():
|
|
remote_is_github = is_github_remote(remote_url)
|
|
remote_is_gitea = is_gitea_remote(remote_url)
|
|
remote_platform = "GitHub" if remote_is_github else "Gitea" if remote_is_gitea else "Unknown"
|
|
|
|
create_on_remote = input(f"\nCreate release on {remote_name} ({remote_platform})? [Y/n]: ").strip().lower()
|
|
if create_on_remote == '' or create_on_remote == 'y':
|
|
# Push tag to this remote too
|
|
print(f"Pushing tag '{tag_name}' to {remote_name}...")
|
|
if not run_command(['git', 'push', remote_name, tag_name], project_root, f"Error pushing tag to {remote_name}"):
|
|
print(f"Failed to push tag to {remote_name}. Skipping release creation.", file=sys.stderr)
|
|
continue
|
|
|
|
# Create release on this remote
|
|
if remote_is_github:
|
|
create_github_release(tag_name, tag_name, notes, is_prerelease, project_root, remote_name, remotes)
|
|
elif remote_is_gitea:
|
|
create_gitea_release(tag_name, tag_name, notes, is_prerelease, project_root, remote_name)
|
|
else:
|
|
print(f"Skipping release creation on {remote_name}")
|
|
else:
|
|
print("\nNo other release-capable remotes found.")
|
|
|
|
print("\nRelease process completed!")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|