Complete guided release console workflow
Dependency Audit / dependency-audit (push) Successful in 2m35s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 15s

This commit is contained in:
2026-07-31 05:46:50 +02:00
parent b4248a849e
commit f1fd143ef5
13 changed files with 2332 additions and 117 deletions
+39 -2
View File
@@ -170,18 +170,30 @@ def owner_for_versions_dir(versions_dir: Path) -> str:
def parse_migration_file(owner: str, path: Path) -> Migration | None:
tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path))
values: dict[str, Any] = {}
wrapped: Migration | None = None
release_peer = path.parent.parent / "versions" / path.name
if path.parent.name == "dev_versions" and release_peer.is_file():
wrapped = parse_migration_file(owner, release_peer)
for statement in tree.body:
if isinstance(statement, ast.Assign):
for target in statement.targets:
if isinstance(target, ast.Name) and target.id in {"revision", "down_revision", "depends_on", "branch_labels"}:
values[target.id] = ast.literal_eval(statement.value)
values[target.id] = _migration_assignment_value(
target.id,
statement.value,
wrapped=wrapped,
)
elif (
isinstance(statement, ast.AnnAssign)
and isinstance(statement.target, ast.Name)
and statement.target.id in {"revision", "down_revision", "depends_on", "branch_labels"}
and statement.value is not None
):
values[statement.target.id] = ast.literal_eval(statement.value)
values[statement.target.id] = _migration_assignment_value(
statement.target.id,
statement.value,
wrapped=wrapped,
)
revision = values.get("revision")
if not isinstance(revision, str):
return None
@@ -195,6 +207,31 @@ def parse_migration_file(owner: str, path: Path) -> Migration | None:
)
def _migration_assignment_value(
name: str,
value: ast.expr,
*,
wrapped: Migration | None,
) -> Any:
try:
return ast.literal_eval(value)
except (ValueError, TypeError):
if (
wrapped is None
or not isinstance(value, ast.Attribute)
or not isinstance(value.value, ast.Name)
or value.value.id != "_migration"
or value.attr != name
):
return None
return {
"revision": wrapped.revision,
"down_revision": wrapped.down_revisions,
"depends_on": wrapped.depends_on,
"branch_labels": wrapped.branch_labels,
}[name]
def _normalize_revision_tuple(value: Any) -> tuple[str, ...]:
if value is None:
return ()