feature: agrego comando release

This commit is contained in:
jt
2025-11-02 17:35:55 -03:00
parent 5bab142074
commit 1bdac67835
+71 -12
View File
@@ -40,6 +40,8 @@ def main():
merge_command() merge_command()
elif command == "tag": elif command == "tag":
tag_command() tag_command()
elif command == "release":
release_command()
elif command == "help": elif command == "help":
help_command() help_command()
else: else:
@@ -83,7 +85,7 @@ COMMIT_TYPES = [
"typo", "typo",
"testing", "testing",
"ignore", "ignore",
"WIP" "wip"
] ]
DEFAULT_REMOTE = "origin" DEFAULT_REMOTE = "origin"
@@ -229,7 +231,7 @@ def merge_command():
print_error("No se pueden mergear ramas de tipo 'wip'") print_error("No se pueden mergear ramas de tipo 'wip'")
return return
target = get_base_branch(branch) (target, _) = get_branch_env_and_type(branch)
status = Git.status() status = Git.status()
remote = Git.flow_config("flow.remote").firstline() remote = Git.flow_config("flow.remote").firstline()
@@ -312,6 +314,37 @@ def parse_url(url: str) -> list[str]:
return [service, repository] return [service, repository]
def get_branch_env_and_type(branch: str) -> tuple[str, str]:
components = branch.split("/")
target_branches = (
Git.flow_config("flow.branches")
.firstline() # dev test main
.split(" ") # [dev, test, main]
[1:] # [test, main] (dev no deberia ser un release)
)
if len(components) == 2:
if components[0] not in BRANCH_TYPES:
raise ValueError(f"Branch inválida, el tipo '{components[0]}' no es válido.")
return (target_branches[0], components[0])
elif len(components) == 4:
if (
components[0] != "release"
or components[1] not in target_branches
or components[2] not in BRANCH_TYPES
):
raise ValueError(
"Branch release inválido, debe tener el siguiente formato: "
"release/<env>/<type>/<name>, pero es: " + branch
)
return (components[1], components[2])
else:
raise ValueError("Branch inválido: " + branch)
def tag_command(): def tag_command():
ensure_initialized() ensure_initialized()
ci = len(sys.argv) == 3 # ./git-flow tag <BEARER> ci = len(sys.argv) == 3 # ./git-flow tag <BEARER>
@@ -357,16 +390,8 @@ def tag_command():
until_dash = last_version.index("-") if "-" in last_version else None until_dash = last_version.index("-") if "-" in last_version else None
[major, minor, patch] = map(int, last_version[from_major:until_dash].split(".")) [major, minor, patch] = map(int, last_version[from_major:until_dash].split("."))
components = merged_branch.split("/") (_, merged_branch_type) = get_branch_env_and_type(merged_branch)
increment = BRANCH_TYPES_INCREMENT[merged_branch_type]
if len(components) not in [2, 4]:
raise RuntimeError("Branch mergeado es inválido: " + merged_branch)
elif len(components) == 4 and components[0] != "release":
raise RuntimeError("Release branch mergeado es inválido: " + merged_branch)
elif components[-2] not in BRANCH_TYPES:
raise RuntimeError("Tipo de rama mergeado es inválido: " + components[-2])
increment = BRANCH_TYPES_INCREMENT[components[-2]]
if increment == "major": if increment == "major":
major = major + 1 major = major + 1
@@ -390,6 +415,39 @@ def tag_command():
Git("tag", new_version, commit).exec() Git("tag", new_version, commit).exec()
def release_command():
ensure_initialized()
branch = ensure_right_branch()
env_branches = Git.flow_config("flow.branches").firstline().split(" ")
(env, _) = get_branch_env_and_type(branch)
if env == env_branches[-1]:
raise RuntimeError("No se puede hacer release de una rama en el ultimo entorno.")
next_env = env_branches[env_branches.index(env) + 1]
boundary_commits = list(filter(
lambda c: c.startswith("-"), # boundary commits
Git("rev-list", env + "..." + branch, topo_order=True, boundary=True).lines()
))
if not boundary_commits:
raise RuntimeError("No se encontro un commit base para realizar el rebase.")
base = boundary_commits[-1].removeprefix("-")
next_branch = branch.replace(f"/{env}/", f"/{next_env}/") if branch.startswith("release/") else f"release/{next_env}/{branch}"
Git("switch", next_branch, create=True).exec()
commits = int(Git("rev-list", base + ".." + next_branch, count=True).firstline())
if commits > 1 and confirm(f"Desea reemplazar los {commits} commits de la rama por uno solo?"):
Git("reset", base, soft=True).exec()
commit_type = choose("Tipo de commit", COMMIT_TYPES[:-1]) # Solo permitir commits NO wip
Git("commit", m=commit_type + ": " + get_commit_message()).exec()
Git("rebase", base, next_branch, onto=next_env).exec()
def help_command(name: str|None = None): def help_command(name: str|None = None):
if name is not None: if name is not None:
print_error(f"Comando inválido: {name}") print_error(f"Comando inválido: {name}")
@@ -405,6 +463,7 @@ COMANDOS:
commit crea un commit siguiendo el formato de Conventional Commit commit crea un commit siguiendo el formato de Conventional Commit
merge actualiza el changelog y crea un nuevo PR para mergear la rama merge actualiza el changelog y crea un nuevo PR para mergear la rama
tag crea un nuevo tag para el ultimo merge tag crea un nuevo tag para el ultimo merge
release crea una nueva rama release para pasar la rama actual al siguiente entorno
help muestra este texto de ayuda""", file=sys.stderr) help muestra este texto de ayuda""", file=sys.stderr)