Skip to content

Commit

Permalink
uplift: port functionality (bug 1915695)
Browse files Browse the repository at this point in the history
  • Loading branch information
zzzeid committed Jan 20, 2025
1 parent 6d0ff8b commit 5229676
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 78 deletions.
4 changes: 2 additions & 2 deletions src/lando/api/legacy/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from lando.api.legacy.api import stacks, transplants
from lando.api.legacy.api import stacks, transplants, uplift

__all__ = ["stacks", "transplants"]
__all__ = ["stacks", "transplants", "uplift"]
52 changes: 9 additions & 43 deletions src/lando/api/legacy/api/uplift.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,28 @@
import logging

from django.http import Http404

from lando.api.legacy.api.stacks import HTTP_404_STRING
from lando.api.legacy.uplift import (
create_uplift_revision,
get_local_uplift_repo,
get_uplift_conduit_state,
get_uplift_repositories,
)
from lando.api.legacy.validation import revision_id_to_int
from lando.main.auth import require_authenticated_user, require_phabricator_api_key
from lando.main.models import Repo
from lando.main.support import problem
from lando.utils.phabricator import PhabricatorClient

logger = logging.getLogger(__name__)


@require_phabricator_api_key(optional=True)
def get(phab: PhabricatorClient):
"""Return the list of valid uplift repositories."""
repos = [
phab.expect(repo, "fields", "shortName")
for repo in get_uplift_repositories(phab)
]

return {"repos": repos}, 201


@require_phabricator_api_key(optional=False)
@require_authenticated_user
def create(phab: PhabricatorClient, data: dict):
@require_phabricator_api_key(optional=False)
def create(phab: PhabricatorClient, request, data: dict):
"""Create new uplift requests for requested repository & revision"""
repo_name = data["repository"]
repository = data["repository"]
repo_name = repository.name
revision_id = revision_id_to_int(data["revision_id"])

# Validate repository.
all_repos = Repo.get_mapping()
repository = all_repos.get(repo_name)
if repository is None:
return problem(
400,
f"Repository {repo_name} is not a repository known to Lando.",
"Please select an uplift repository to create the uplift request.",
type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400",
)

if not repository.approval_required:
return problem(
400,
f"Repository {repo_name} is not an uplift repository.",
"Please select an uplift repository to create the uplift request.",
type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400",
)

try:
logger.info(
"Checking approval state",
Expand All @@ -72,12 +43,7 @@ def create(phab: PhabricatorClient, data: dict):
"Hit an error retreiving uplift state from conduit.",
extra={"error": str(err)},
)
return problem(
404,
"Revision not found",
err.args[0],
type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404",
)
raise Http404(HTTP_404_STRING)

revision_phid = next(
rev["phid"]
Expand Down Expand Up @@ -138,4 +104,4 @@ def create(phab: PhabricatorClient, data: dict):
output = {rev["revision_phid"]: rev for rev in commit_stack}
output["tip_differential"] = commit_stack[-1]

return output, 201
return output
12 changes: 5 additions & 7 deletions src/lando/api/legacy/uplift.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
request_extended_revision_data,
)
from lando.main.models import Repo
from lando.utils.phabricator import PhabricatorClient
from lando.utils.phabricator import PhabricatorClient, get_phabricator_client

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -59,18 +59,16 @@ def get_uplift_request_form(revision: dict) -> Optional[str]:
return bug


# @cache.cached(
# key_prefix="uplift-repositories"
# )
def get_uplift_repositories(phab: PhabricatorClient) -> list:
def get_uplift_repositories() -> list:
# TODO: cache
phab = get_phabricator_client()
repos = phab.call_conduit(
"diffusion.repository.search",
constraints={"projects": ["uplift"]},
)

repos = phab.expect(repos, "data")

return repos
return [phab.expect(repo, "fields", "shortName") for repo in repos]


def get_revisions_without_bugs(phab: PhabricatorClient, revisions: dict) -> set[str]:
Expand Down
13 changes: 6 additions & 7 deletions src/lando/ui/jinja2/stack/stack.html
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ <h2>Landing is blocked:</h2>
{% include "stack/partials/landing-preview.html" %}
</section>
<footer class="modal-card-foot">
<form class="StackPage-form" action="" method="post">
<form class="StackPage-form" action="" method="post">
{{ csrf_input }}
{{ form.landing_path }}
{{ form.confirmation_token }}
Expand All @@ -142,11 +142,10 @@ <h2>Landing is blocked:</h2>
</button>
<button class="StackPage-landingPreview-close button">Cancel</button>
</form>
{# TODO - see bug 1915695 #}
{# {% if user_has_phabricator_token %}
<form class="StackPage-landingPreview-uplift" action="{{ url_for('revisions.uplift') }}" method="post">
{{ uplift_request_form.csrf_token }}
<input type="hidden" name="revision_id" value="{{ revision_id }}" />
{% if user_has_phabricator_token %}
<form class="StackPage-landingPreview-uplift" action="{{ url("uplift-page") }}" method="post">
{{ csrf_input }}
{{ uplift_request_form.revision_id }}
{{ uplift_request_form.repository }}
<button
class="button"
Expand All @@ -159,7 +158,7 @@ <h2>Landing is blocked:</h2>
<i class="fa fa-question-circle"></i>
</span>
</a>
{% endif %} #}
{% endif %}
</footer>
</div>
</div>
Expand Down
31 changes: 29 additions & 2 deletions src/lando/ui/legacy/forms.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from django import forms

from lando.api.legacy.uplift import get_uplift_repositories
from lando.main.models import Repo


class TransplantRequestForm(forms.Form):
landing_path = forms.JSONField(widget=forms.widgets.HiddenInput)
Expand All @@ -12,8 +15,32 @@ class TransplantRequestForm(forms.Form):
class UpliftRequestForm(forms.Form):
"""Form used to request uplift of a stack."""

revision_id = forms.RegexField(regex="D[0-9]+$")
repository = forms.CharField()
revision_id = forms.RegexField(
regex="D[0-9]+$",
widget=forms.widgets.HiddenInput,
required=False,
)
repository = forms.ChoiceField(
widget=forms.Select(),
choices=((repo, repo) for repo in get_uplift_repositories()),
)

def clean_repository(self):
repo_name = self.cleaned_data["repository"]
all_repos = Repo.get_mapping()
repository = all_repos.get(repo_name)
if repository is None:
raise forms.ValidationError(
f"Repository {repo_name} is not a repository known to Lando. "
"Please select an uplift repository to create the uplift request."
)

if not repository.approval_required:
raise forms.ValidationError(
f"Repository {repo_name} is not an uplift repository. "
"Please select an uplift repository to create the uplift request."
)
return repository


class UserSettingsForm(forms.Form):
Expand Down
64 changes: 47 additions & 17 deletions src/lando/ui/legacy/revisions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from lando.main.auth import force_auth_refresh
from lando.ui.legacy.forms import (
TransplantRequestForm,
# UpliftRequestForm,
UpliftRequestForm,
)
from lando.ui.legacy.stacks import Edge, draw_stack_graph, sort_stack_topological
from lando.ui.views import LandoView
Expand All @@ -21,6 +21,49 @@
# revisions.before_request(set_last_local_referrer)


class Uplift(LandoView):
@force_auth_refresh
def post(self, request):
"""Process the uplift request submission."""
uplift_request_form = UpliftRequestForm(request.POST)
errors = []

if not request.user.is_authenticated:
raise PermissionError()

if uplift_request_form.is_valid() and not errors:
revision_id = uplift_request_form.cleaned_data["revision_id"]
repository = uplift_request_form.cleaned_data["repository"]

response = legacy_api.uplift.create(
request,
data={
"revision_id": revision_id,
"repository": repository,
},
)

# Redirect to the tip revision's URL.
# TODO add js for auto-opening the uplift request Phabricator form.
# See https://bugzilla.mozilla.org/show_bug.cgi?id=1810257.
revision_id = response["tip_differential"]["revision_id"]
return redirect("revisions-page", revision_id=revision_id)

if uplift_request_form.errors:
errors += [
f"{field}: {', '.join(field_errors)}"
for field, field_errors in uplift_request_form.errors.items()
]

for error in errors:
messages.add_message(request, messages.ERROR, error)

# Not ideal, but because we do not have access to the revision ID
# we will just redirect the user back to the referring page and
# they will see the flash messages.
return redirect(request.META.get("HTTP_REFERER"))


class Revision(LandoView):
def get(
self, request: HttpRequest, revision_id: int, *args, **kwargs
Expand All @@ -33,13 +76,8 @@ def get(
form = TransplantRequestForm()
errors = []

# TODO - see bug 1915695.
# uplift_request_form = UpliftRequestForm()

# # Get the list of available uplift repos and populate the form with it.
# uplift_request_form.repository.choices = get_uplift_repos(api)
# uplift_request_form.revision_id.data = revision_id
# END TODO.
uplift_request_form = UpliftRequestForm()
uplift_request_form.fields["revision_id"].initial = f"D{revision_id}"

# Build a mapping from phid to revision and identify
# the data for the revision used to load this page.
Expand Down Expand Up @@ -136,7 +174,7 @@ def get(
"form": form,
"flags": target_repo["commit_flags"] if target_repo else [],
"existing_flags": existing_flags,
# "uplift_request_form": uplift_request_form,
"uplift_request_form": uplift_request_form,
}

return TemplateResponse(
Expand All @@ -152,14 +190,6 @@ def post(
form = TransplantRequestForm(request.POST)
errors = []

# TODO - see bug 1915695.
# uplift_request_form = UpliftRequestForm()

# # Get the list of available uplift repos and populate the form with it.
# uplift_request_form.repository.choices = get_uplift_repos(api)
# uplift_request_form.revision_id.data = revision_id
# END TODO.

if not request.user.is_authenticated:
errors.append("You must be logged in to request a landing")

Expand Down
1 change: 1 addition & 0 deletions src/lando/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
path("", pages.Index.as_view()),
path("D<int:revision_id>/", revisions.Revision.as_view(), name="revisions-page"),
path("manage_api_key/", user_settings.manage_api_key, name="user-settings"),
path("uplift/", revisions.Uplift.as_view(), name="uplift-page"),
]

# "API" endpoints ported from legacy API app.
Expand Down

0 comments on commit 5229676

Please sign in to comment.