mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
Replace the single default_branch with an ordered environments ladder
(list[{name,branch}]; first=head=PR target, last=prod=release target,
middle=intermediates). Migration 073 adds nullable JSONB projects.environments;
a read-time shim (roboco/models/env_branches.py) synthesizes a degenerate
single-branch ladder from default_branch when environments is null, so
behavior is unchanged until the operator declares a real split in the panel.
Wired through Project/ProjectCreate/ProjectUpdate models (normalize_environments
validator: rejects empty name/branch + dup branches), ProjectTable column,
API request/response schemas, create+update routes + service. EnvSyncEngine
+ consumer rewires follow.
43 lines
1.5 KiB
Python
43 lines
1.5 KiB
Python
"""Per-project ordered environment ladder column.
|
|
|
|
Replaces the single ``default_branch`` as the source of truth for a project's
|
|
PR target (head rung) and release target (prod rung). The ladder is an ordered
|
|
``list[{name, branch}]``: index 0 = head (where dev/cell/leaf PRs land), index
|
|
-1 = prod (where the gated release executor commits + tags), middle rungs =
|
|
intermediates (qa/stag). The ``EnvSyncEngine`` cascades prod→…→head so dev
|
|
never falls behind prod, and the CEO-gated release promotes the full chain
|
|
head→…→prod before bumping.
|
|
|
|
Additive and nullable: an unset (null) ``environments`` falls back to a
|
|
degenerate single-branch ladder synthesized from ``default_branch`` at read
|
|
time (``roboco/services/env_branches.py``), so every existing project keeps
|
|
behaving byte-for-byte as before until the operator declares a real ladder
|
|
in the panel. ``default_branch`` is retained as the legacy/shim source.
|
|
|
|
Revision ID: 073_project_environments
|
|
Revises: 072_project_sandbox_extensions
|
|
Create Date: 2026-07-15
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
from sqlalchemy.dialects import postgresql
|
|
|
|
revision = "073_project_environments"
|
|
down_revision = "072_project_sandbox_extensions"
|
|
branch_labels: dict[str, str] | None = None
|
|
depends_on: dict[str, str] | None = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.add_column(
|
|
"projects",
|
|
sa.Column("environments", postgresql.JSONB(), nullable=True),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_column("projects", "environments")
|