Skip to content

feat(seer): migration for SeerProjectRepository and SeerProjectRepositoryBranchOverride models#110542

Merged
srest2021 merged 4 commits intomasterfrom
srest2021/AIML-2603
Mar 12, 2026
Merged

feat(seer): migration for SeerProjectRepository and SeerProjectRepositoryBranchOverride models#110542
srest2021 merged 4 commits intomasterfrom
srest2021/AIML-2603

Conversation

@srest2021
Copy link
Member

@srest2021 srest2021 commented Mar 12, 2026

Fixes AIML-2603

Add a join table linking Project to Repository with per-repo Seer configuration (branch_name, instructions, branch_overrides). This is Phase 1 of migrating Seer project preferences into the Sentry DB.

Tech Spec

Add a join table linking Project to Repository with per-repo Seer
configuration (branch_name, instructions, branch_overrides). This is
Phase 1 of migrating Seer project preferences into the Sentry DB.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@linear-code
Copy link

linear-code bot commented Mar 12, 2026

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Mar 12, 2026
@github-actions
Copy link
Contributor

Backend Test Failures

Failures on 00d12f8 in this run:

tests/sentry/backup/test_exports.py::ScopingTests::test_global_export_scopinglog
tests/sentry/backup/test_exports.py:399: in test_global_export_scoping
    self.verify_model_inclusion(unencrypted, ExportScope.Global)
tests/sentry/backup/test_exports.py:182: in verify_model_inclusion
    raise AssertionError(
E   AssertionError: The following models were not included in the export: ${<class 'sentry.seer.models.project_repository.SeerProjectRepository'>}; this is despite it being included in at least one of the following relocation scopes: {<RelocationScope.Config: 4>, <RelocationScope.Organization: 3>, <RelocationScope.Global: 5>, <RelocationScope.User: 2>}
tests/sentry/backup/test_exports.py::ScopingTests::test_organization_export_scopinglog
tests/sentry/backup/test_exports.py:263: in test_organization_export_scoping
    self.verify_model_inclusion(unencrypted, ExportScope.Organization)
tests/sentry/backup/test_exports.py:182: in verify_model_inclusion
    raise AssertionError(
E   AssertionError: The following models were not included in the export: ${<class 'sentry.seer.models.project_repository.SeerProjectRepository'>}; this is despite it being included in at least one of the following relocation scopes: {<RelocationScope.Organization: 3>, <RelocationScope.User: 2>}
tests/sentry/backup/test_imports.py::ScopingTests::test_global_import_scopinglog
tests/sentry/backup/test_imports.py:885: in test_global_import_scoping
    self.verify_model_inclusion(ImportScope.Global)
tests/sentry/backup/test_imports.py:813: in verify_model_inclusion
    assert model.objects.count() > 0
E   AssertionError: assert 0 > 0
E    +  where 0 = <bound method QuerySet.count of <sentry.db.models.manager.base.BaseManager object at 0x7f8b0e6c38c0>>()
E    +    where <bound method QuerySet.count of <sentry.db.models.manager.base.BaseManager object at 0x7f8b0e6c38c0>> = <sentry.db.models.manager.base.BaseManager object at 0x7f8b0e6c38c0>.count
E    +      where <sentry.db.models.manager.base.BaseManager object at 0x7f8b0e6c38c0> = <class 'sentry.seer.models.project_repository.SeerProjectRepository'>.objects
tests/sentry/backup/test_imports.py::ScopingTests::test_organization_import_scopinglog
tests/sentry/backup/test_imports.py:845: in test_organization_import_scoping
    self.verify_model_inclusion(ImportScope.Organization)
tests/sentry/backup/test_imports.py:813: in verify_model_inclusion
    assert model.objects.count() > 0
E   AssertionError: assert 0 > 0
E    +  where 0 = <bound method QuerySet.count of <sentry.db.models.manager.base.BaseManager object at 0x7f8b0e6c38c0>>()
E    +    where <bound method QuerySet.count of <sentry.db.models.manager.base.BaseManager object at 0x7f8b0e6c38c0>> = <sentry.db.models.manager.base.BaseManager object at 0x7f8b0e6c38c0>.count
E    +      where <sentry.db.models.manager.base.BaseManager object at 0x7f8b0e6c38c0> = <class 'sentry.seer.models.project_repository.SeerProjectRepository'>.objects

@github-actions
Copy link
Contributor

github-actions bot commented Mar 12, 2026

This PR has a migration; here is the generated SQL for src/sentry/seer/migrations/0003_add_seerprojectrepository.py

for 0003_add_seerprojectrepository in seer

--
-- Create model SeerProjectRepository
--
CREATE TABLE "seer_projectrepository" ("id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, "date_updated" timestamp with time zone NOT NULL, "date_added" timestamp with time zone NOT NULL, "branch_name" text NULL, "instructions" text NULL, "project_id" bigint NOT NULL, "repository_id" bigint NOT NULL);
--
-- Create model SeerProjectRepositoryBranchOverride
--
CREATE TABLE "seer_projectrepositorybranchoverride" ("id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, "date_updated" timestamp with time zone NOT NULL, "date_added" timestamp with time zone NOT NULL, "tag_name" text NOT NULL, "tag_value" text NOT NULL, "branch_name" text NOT NULL, "seer_project_repository_id" bigint NOT NULL);
CREATE UNIQUE INDEX CONCURRENTLY "seer_projectrepository_project_id_repository_id_f08c56d6_uniq" ON "seer_projectrepository" ("project_id", "repository_id");
ALTER TABLE "seer_projectrepository" ADD CONSTRAINT "seer_projectrepository_project_id_repository_id_f08c56d6_uniq" UNIQUE USING INDEX "seer_projectrepository_project_id_repository_id_f08c56d6_uniq";
ALTER TABLE "seer_projectrepository" ADD CONSTRAINT "seer_projectrepository_project_id_9b6ca557_fk_sentry_project_id" FOREIGN KEY ("project_id") REFERENCES "sentry_project" ("id") DEFERRABLE INITIALLY DEFERRED NOT VALID;
ALTER TABLE "seer_projectrepository" VALIDATE CONSTRAINT "seer_projectrepository_project_id_9b6ca557_fk_sentry_project_id";
ALTER TABLE "seer_projectrepository" ADD CONSTRAINT "seer_projectreposito_repository_id_1c1c52ec_fk_sentry_re" FOREIGN KEY ("repository_id") REFERENCES "sentry_repository" ("id") DEFERRABLE INITIALLY DEFERRED NOT VALID;
ALTER TABLE "seer_projectrepository" VALIDATE CONSTRAINT "seer_projectreposito_repository_id_1c1c52ec_fk_sentry_re";
CREATE INDEX CONCURRENTLY "seer_projectrepository_project_id_9b6ca557" ON "seer_projectrepository" ("project_id");
CREATE INDEX CONCURRENTLY "seer_projectrepository_repository_id_1c1c52ec" ON "seer_projectrepository" ("repository_id");
CREATE UNIQUE INDEX CONCURRENTLY "seer_projectrepositorybr_seer_project_repository__e53d101f_uniq" ON "seer_projectrepositorybranchoverride" ("seer_project_repository_id", "tag_name", "tag_value");
ALTER TABLE "seer_projectrepositorybranchoverride" ADD CONSTRAINT "seer_projectrepositorybr_seer_project_repository__e53d101f_uniq" UNIQUE USING INDEX "seer_projectrepositorybr_seer_project_repository__e53d101f_uniq";
ALTER TABLE "seer_projectrepositorybranchoverride" ADD CONSTRAINT "seer_projectreposito_seer_project_reposit_b6516aa2_fk_seer_proj" FOREIGN KEY ("seer_project_repository_id") REFERENCES "seer_projectrepository" ("id") DEFERRABLE INITIALLY DEFERRED NOT VALID;
ALTER TABLE "seer_projectrepositorybranchoverride" VALIDATE CONSTRAINT "seer_projectreposito_seer_project_reposit_b6516aa2_fk_seer_proj";
CREATE INDEX CONCURRENTLY "seer_projectrepositorybran_seer_project_repository_id_b6516aa2" ON "seer_projectrepositorybranchoverride" ("seer_project_repository_id");

Add comparator and test data for SeerProjectRepository so backup
scoping tests include the new model in export/import verification.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Contributor

Backend Test Failures

Failures on d092b25 in this run:

tests/sentry/backup/test_exports.py::ScopingTests::test_organization_export_scopinglog
tests/sentry/backup/test_exports.py:263: in test_organization_export_scoping
    self.verify_model_inclusion(unencrypted, ExportScope.Organization)
tests/sentry/backup/test_exports.py:182: in verify_model_inclusion
    raise AssertionError(
E   AssertionError: The following models were not included in the export: ${<class 'sentry.seer.models.project_repository.SeerProjectRepository'>}; this is despite it being included in at least one of the following relocation scopes: {<RelocationScope.Organization: 3>, <RelocationScope.User: 2>}
tests/sentry/backup/test_imports.py::ScopingTests::test_organization_import_scopinglog
tests/sentry/backup/test_imports.py:845: in test_organization_import_scoping
    self.verify_model_inclusion(ImportScope.Organization)
tests/sentry/backup/test_imports.py:813: in verify_model_inclusion
    assert model.objects.count() > 0
E   AssertionError: assert 0 > 0
E    +  where 0 = <bound method QuerySet.count of <sentry.db.models.manager.base.BaseManager object at 0x7f5a3c6b7770>>()
E    +    where <bound method QuerySet.count of <sentry.db.models.manager.base.BaseManager object at 0x7f5a3c6b7770>> = <sentry.db.models.manager.base.BaseManager object at 0x7f5a3c6b7770>.count
E    +      where <sentry.db.models.manager.base.BaseManager object at 0x7f5a3c6b7770> = <class 'sentry.seer.models.project_repository.SeerProjectRepository'>.objects

Repository has RelocationScope.Global, so SeerProjectRepository must
also be Global-scoped. Otherwise, during Organization-scoped exports,
Repository PKs aren't in the pk_map and SeerProjectRepository objects
get silently filtered out.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
relevant for a project and any per-repo overrides (branch, instructions).
"""

__relocation_scope__ = RelocationScope.Global
Copy link
Member Author

@srest2021 srest2021 Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must be global (not organization) scope because of the repository FK. RepositorySettings model is similarly scoped to global.

@srest2021 srest2021 marked this pull request as ready for review March 12, 2026 18:22
@srest2021 srest2021 requested review from a team as code owners March 12, 2026 18:22
Copy link
Member

@JoshFerge JoshFerge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

table schema makes sense to me.

…ranchOverride table

Split branch_overrides from a JSON blob on SeerProjectRepository into
a separate 1-M table for queryability and proper DB constraints. Each
row stores a tag_name/tag_value/branch_name triple with a unique
constraint on (seer_project_repository, tag_name, tag_value).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
wedamija
wedamija approved these changes Mar 12, 2026
@srest2021 srest2021 changed the title feat(seer): Add SeerProjectRepository model and migration feat(seer): migration for SeerProjectRepository and SeerProjectRepositoryBranchOverrides models Mar 12, 2026
@srest2021 srest2021 changed the title feat(seer): migration for SeerProjectRepository and SeerProjectRepositoryBranchOverrides models feat(seer): migration for SeerProjectRepository and SeerProjectRepositoryBranchOverride models Mar 12, 2026
@srest2021 srest2021 merged commit 32cbff0 into master Mar 12, 2026
83 checks passed
@srest2021 srest2021 deleted the srest2021/AIML-2603 branch March 12, 2026 21:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants