Skip to content

feat(nimbus): add state machine for rollouts#16097

Open
moibra05 wants to merge 1 commit into
mainfrom
15085
Open

feat(nimbus): add state machine for rollouts#16097
moibra05 wants to merge 1 commit into
mainfrom
15085

Conversation

@moibra05

@moibra05 moibra05 commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Because

  • Rollouts need dedicated lifecycle transitions, including a rollout specific Disabled state

This commit

  • Adds rollout transition forms, views, routes, validation, and test coverage for all valid and invalid rollout state transitions
  • Adds the Disabled status and updates rollout state filters
  • Stages phase changes until Remote Settings approval, then advances or ends the active phase
  • Supports disabling and re-enabling rollouts through the review workflow
  • Updates API documentation and model choices

Fixes #15085

@freshstrangemusic

Copy link
Copy Markdown
Member

Only rollouts that are isFirefoxLabsRollout: true can be paused. Regular rollouts do not support pausing enrollments.

@moibra05

Copy link
Copy Markdown
Contributor Author

Blocked on mermaid diagram updates

@RJAK11 RJAK11 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall this looks amazing and everything seemed mostly correct to me!! I just noticed a few things that we might want to consider

required_status_next = None
required_publish_status = NimbusExperiment.PublishStatus.IDLE

status = NimbusExperiment.Status.PREVIEW

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Based on first part of Cancel from Preview diagram I think we need:

Suggested change
status = NimbusExperiment.Status.PREVIEW
status = NimbusExperiment.Status.DRAFT

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

oh i just noticed. are there supposed to be another set of diagrams for launching from the preview state? that specific transition doesnt look like it has a corresponding mermaid diagram even though i believe it should be a valid transition

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

disregard last comment i just read your explanation oops

publish_status = NimbusExperiment.PublishStatus.REVIEW

def get_changelog_message(self):
return f"{self.request.user} requested rollout launch without Preview"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
return f"{self.request.user} requested rollout launch without Preview"
return f"{self.request.user} requested rollout launch from Preview"

def get_changelog_message(self):
return f"{self.request.user} requested rollout launch without Preview"


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would we actually need PreviewReviewApproveRolloutForm and PreviewReviewRejectForm? Based on the "Cancel from Preview" diagram, I think launching from Preview sends the rollout back to Draft first so the rollout would be in the same Draft/Live/Review state as a Draft launch, so these forms might technically duplicate DraftReviewApproveRolloutForm and DraftReviewRejectForm. Maybe we could mirror the old UI and combine them if that seems right?

experiment = super().save(commit=commit)
experiment.stage_rollout_phase_advance()
experiment.allocate_bucket_range()
nimbus_synchronize_preview_experiments_in_kinto.apply_async(countdown=5)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I assume we don't need this since we are going from Live to Live

Suggested change
nimbus_synchronize_preview_experiments_in_kinto.apply_async(countdown=5)

@transaction.atomic
def save(self, commit=True):
experiment = super().save(commit=commit)
experiment.disable_rollout()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here we disable the rollout but if the changes were to be rejected in remote settings I don't think we would restore them based on:

def handle_rejection(applications, kinto_client):

I assume we would need to make changes in that function as well

@transaction.atomic
def save(self, commit=True):
experiment = super().save(commit=commit)
experiment.stage_rollout_phase_advance(copy_current_if_missing=True)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same thing here as mentioned above since we would advance the phase but not restore the original one if it gets rejected in remote settings


def disable_rollout(self):
if self.is_rollout:
self.population_percent = 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not fully sure but I thought disable meant unpublish from remote settings to avoid piling up too many recipes based on the slack conversation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rollout State Machine Refactor

3 participants