Files
roboco/alembic/versions/075_project_git_provider.py
T
388bab2488 feat(forge): Phase 0 — git_provider column + registration-time forge validation (#569)
* feat(forge): Phase 0 — git_provider column + registration-time forge validation

Pointing a project at a GitLab/Gitea git_url used to fail silently, several
steps deep, at first PR. New pure policy module (foundation/policy/forge.py)
detects the provider from the git_url host and validates at the
ProjectService create/update chokepoint: github auto-detects and
auto-stamps, explicit git_provider=github is the GitHub Enterprise escape
hatch, gitlab/gitea are recognized-but-not-yet-supported, unknown hosts get
a loud rejection with guidance. An update changing git_url does NOT inherit
a stored auto-stamped provider (restating the override is required), so a
host swap can't smuggle the escape hatch past validation. Migration 075
adds the nullable projects.git_provider column; the panel project dialogs
show the detected forge. Phase 0 of the forge-providers spec.

* fix(panel): mock-mode forge detection extracts the real host

CodeQL js/incomplete-url-substring-sanitization: the substring check
matched github.com anywhere in the URL. Extract the hostname (URL parse
or scp-form regex, mirroring forge.py) and require an exact match.

---------

Co-authored-by: Renn F <rennf93@users.noreply.github.com>
2026-07-18 19:10:43 +02:00

38 lines
1.2 KiB
Python

"""Add projects.git_provider — Phase 0 of the forge-providers spec.
Nullable ``git_provider`` (plain string, not a pg enum — validated at the
service layer by ``roboco.foundation.policy.forge.validate_project_forge``
instead of a DB constraint, mirroring how ``assigned_cell``-adjacent free-text
columns like ``ci_watch_workflow`` are validated in Python, not SQL). Null
means "auto-detect from git_url host" (github.com -> github; anything else is
a registration-time rejection unless the operator sets this column explicitly
— the GitHub Enterprise escape hatch). Additive and inert: every existing
project keeps resolving to GitHub behavior until GitLab/Gitea providers land
in a later phase.
Revision ID: 075_project_git_provider
Revises: 074_telegram_credentials
Create Date: 2026-07-18
"""
from __future__ import annotations
import sqlalchemy as sa
from alembic import op
revision = "075_project_git_provider"
down_revision = "074_telegram_credentials"
branch_labels: dict[str, str] | None = None
depends_on: dict[str, str] | None = None
def upgrade() -> None:
op.add_column(
"projects",
sa.Column("git_provider", sa.String(16), nullable=True),
)
def downgrade() -> None:
op.drop_column("projects", "git_provider")