Skip to content

Conversation

@ajay-sentry
Copy link
Contributor

This PR aims to create our new repository settings table, with a foreign key back to the organization repository table.

Table currently stores if code review is enabled, as well as the triggers associated with it being enabled. The triggers are associated with the enum CodeReviewTrigger, also instantiated on the model

Closes https://linear.app/getsentry/issue/ENG-6089/create-repository-settings-table

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

@ajay-sentry ajay-sentry requested review from a team December 9, 2025 22:54
@ajay-sentry ajay-sentry requested a review from a team as a code owner December 9, 2025 22:54
@linear
Copy link

linear bot commented Dec 9, 2025

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Dec 9, 2025
@codecov
Copy link

codecov bot commented Dec 9, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff             @@
##           master   #104645      +/-   ##
===========================================
+ Coverage   80.51%    80.53%   +0.01%     
===========================================
  Files        9329      9330       +1     
  Lines      400854    400936      +82     
  Branches    25708     25708              
===========================================
+ Hits       322732    322875     +143     
+ Misses      77670     77609      -61     
  Partials      452       452              

Comment on lines +33 to +37
enabled_code_review = models.BooleanField(default=False)
code_review_triggers = ArrayField(
models.CharField(max_length=32, choices=CodeReviewTrigger.as_choices()),
default=list,
)
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense for enable_code_review to be on the Repository, and then have this table be

RepositorySetting
 - id
 - repository_id
 - trigger

unique (repository_id, trigger)

?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was thinking keep it separate in the event we end up adding more repository settings, I think one thing that was brought up in the ecosystem office hours was some org setting that has been commonly asked for to also be a repository setting

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is potentially something we can do w.r.t. having a single column where the presence of anything in the list means enabled and for what triggers, while an empty list could signal disabled, but I think that's a little less intuitive and relies on "triggers" being edible in the future too

Comment on lines 23 to 26
class RepositorySettings(Model):
"""
Stores code review settings for a repository.
"""
Copy link
Member

Choose a reason for hiding this comment

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

Is this ever going to be other settings, or just code review settings? If only code review, might be worth reflecting in the name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The former, general table for repository settings (example in the above comment too)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Realized you meant the comment was saying something separate 🤦 Updated in ffc6047

Copy link
Member

@suejung-sentry suejung-sentry left a comment

Choose a reason for hiding this comment

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

approving on the business logic side, matches what we discussed

__relocation_scope__ = RelocationScope.Global

repository = FlexibleForeignKey(
"sentry.Repository", on_delete=models.CASCADE, unique=True, db_index=True
Copy link
Member

Choose a reason for hiding this comment

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

interesting, today I learned sentry.Repository should be capitalized here to match the model but lowercase in the migration above haha

Copy link
Member

Choose a reason for hiding this comment

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

Yeah django is funny like that.

@region_silo_model
class RepositorySettings(Model):
"""
Stores code review settings for a repository.
Copy link
Member

Choose a reason for hiding this comment

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

Update to "Stores settings for a repository" to reflect it's gonna be generic?

Copy link
Member

Choose a reason for hiding this comment

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

oh oops didn't see the other review - dupe of this comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh crap yeah i totally glanced over that

@github-actions
Copy link
Contributor

This PR has a migration; here is the generated SQL for src/sentry/migrations/1013_add_repositorysettings_table.py

for 1013_add_repositorysettings_table in sentry

--
-- Create model RepositorySettings
--
CREATE TABLE "sentry_repositorysettings" ("id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, "enabled_code_review" boolean NOT NULL, "code_review_triggers" varchar(32)[] NOT NULL, "repository_id" bigint NOT NULL UNIQUE);
ALTER TABLE "sentry_repositorysettings" ADD CONSTRAINT "sentry_repositoryset_repository_id_ac6f0692_fk_sentry_re" FOREIGN KEY ("repository_id") REFERENCES "sentry_repository" ("id") DEFERRABLE INITIALLY DEFERRED NOT VALID;
ALTER TABLE "sentry_repositorysettings" VALIDATE CONSTRAINT "sentry_repositoryset_repository_id_ac6f0692_fk_sentry_re";

__relocation_scope__ = RelocationScope.Global

repository = FlexibleForeignKey(
"sentry.Repository", on_delete=models.CASCADE, unique=True, db_index=True
Copy link
Member

Choose a reason for hiding this comment

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

Yeah django is funny like that.

Comment on lines +41 to +47
("enabled_code_review", models.BooleanField(default=False)),
(
"code_review_triggers",
django.contrib.postgres.fields.ArrayField(
base_field=models.CharField(max_length=32), default=list, size=None
),
),
Copy link
Member

Choose a reason for hiding this comment

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

The Repository has a config json blob field. If you don't need to do filtering/aggregations on these fields you could use the JSON field. Alternatively, you could add these columns to sentry_repository directly.

Copy link
Contributor Author

@ajay-sentry ajay-sentry Dec 10, 2025

Choose a reason for hiding this comment

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

@markstory Spoke to integrations during office hours and we didn't wanna use the config blob for 2 reasons:

  1. That config field is a text field rather than a json column, and is marked as a legacy field in the code too:
    config = LegacyTextJSONField(default=dict)
  2. We wanted to keep the repository table clean of any settings, opting to do a join/expand for any list/get APIs that require this additional information. The current config column looked to just have a "name:" key/value for the most part (GitHub provider repos), other providers might've had different blobs but didn't explicitly scan many of em.

Some more context on what we're building can be found in the doc @suejung-sentry started here
https://www.notion.so/sentry/Seer-Settings-Backend-2bf8b10e4b5d80268863fb6107d5a374

Copy link
Member

@markstory markstory left a comment

Choose a reason for hiding this comment

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

DDL looks good. I personally would have put the settings fields onto sentry_repository as it makes interacting with settings less complicated, but you have reasonable arguments for using a separate table as well.

@ajay-sentry ajay-sentry merged commit be70835 into master Dec 10, 2025
67 checks passed
@ajay-sentry ajay-sentry deleted the Ajay/add-repository-settings-table branch December 10, 2025 18:22
suejung-sentry added a commit that referenced this pull request Dec 12, 2025
…4666)

For seer launch, there's a toggle where an org can turn on auto-enable
code review on repos. As in sentry org turns this toggle on, they add a
new repo in github that has sentry github app installed on it, that
means we should consider this repo enabled for code review.
For new repos, they get written to `sentry_repository` table upon
repositoryCreated gh webhook, or if the user manually adds the repo
using sentry UI.
Instead of doing this by finding every existing repo.objects.create (and
remembering to do it if any new cases arise), probably most durable to
add as a signal. There are downsides to using signals but it seems like
a common pattern across sentry codebase to use these.

Add that signal handler in this PR

Closes
https://linear.app/getsentry/issue/ENG-6094/handle-auto-enable-code-review-org-setting

Depends on #104645
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.

6 participants