-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
API v3: add build parity fields and cold-storage commands #12794
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
cd78a96
6467ebd
b3d7972
35b7d09
3fca286
8cb9674
13b174b
3e815e4
b5a5123
8006cc0
8da108e
0dcb44a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,9 +12,11 @@ | |||||||||||||||||||||||||||||||||
| from taggit.serializers import TaggitSerializer | ||||||||||||||||||||||||||||||||||
| from taggit.serializers import TagListSerializerField | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| from readthedocs.api.v2.utils import normalize_build_command | ||||||||||||||||||||||||||||||||||
| from readthedocs.builds.constants import LATEST | ||||||||||||||||||||||||||||||||||
| from readthedocs.builds.constants import STABLE | ||||||||||||||||||||||||||||||||||
| from readthedocs.builds.models import Build | ||||||||||||||||||||||||||||||||||
| from readthedocs.builds.models import BuildCommandResult | ||||||||||||||||||||||||||||||||||
| from readthedocs.builds.models import Version | ||||||||||||||||||||||||||||||||||
| from readthedocs.core.permissions import AdminPermission | ||||||||||||||||||||||||||||||||||
| from readthedocs.core.resolver import Resolver | ||||||||||||||||||||||||||||||||||
|
|
@@ -143,6 +145,32 @@ def get_version(self, obj): | |||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| class BuildCommandSerializer(serializers.ModelSerializer): | ||||||||||||||||||||||||||||||||||
| run_time = serializers.ReadOnlyField() | ||||||||||||||||||||||||||||||||||
| command = serializers.SerializerMethodField() | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| class Meta: | ||||||||||||||||||||||||||||||||||
| model = BuildCommandResult | ||||||||||||||||||||||||||||||||||
| fields = [ | ||||||||||||||||||||||||||||||||||
| "id", | ||||||||||||||||||||||||||||||||||
| "build", | ||||||||||||||||||||||||||||||||||
| "command", | ||||||||||||||||||||||||||||||||||
| "description", | ||||||||||||||||||||||||||||||||||
| "output", | ||||||||||||||||||||||||||||||||||
| "exit_code", | ||||||||||||||||||||||||||||||||||
| "start_time", | ||||||||||||||||||||||||||||||||||
| "end_time", | ||||||||||||||||||||||||||||||||||
| "run_time", | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+155
to
+163
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can probably remove these fields since we are not using them.
Suggested change
|
||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| def get_command(self, obj): | ||||||||||||||||||||||||||||||||||
| return normalize_build_command( | ||||||||||||||||||||||||||||||||||
| obj.command, | ||||||||||||||||||||||||||||||||||
| obj.build.project.slug, | ||||||||||||||||||||||||||||||||||
| obj.build.get_version_slug(), | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| class BuildConfigSerializer(FlexFieldsSerializerMixin, serializers.Serializer): | ||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||
| Render ``Build.config`` property without modifying it. | ||||||||||||||||||||||||||||||||||
|
|
@@ -177,6 +205,10 @@ class BuildSerializer(FlexFieldsModelSerializer): | |||||||||||||||||||||||||||||||||
| state = BuildStateSerializer(source="*") | ||||||||||||||||||||||||||||||||||
| _links = BuildLinksSerializer(source="*") | ||||||||||||||||||||||||||||||||||
| urls = BuildURLsSerializer(source="*") | ||||||||||||||||||||||||||||||||||
| builder = serializers.CharField(read_only=True) | ||||||||||||||||||||||||||||||||||
| docs_url = serializers.SerializerMethodField() | ||||||||||||||||||||||||||||||||||
| commit_url = serializers.SerializerMethodField() | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+209
to
+210
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These attributes should be inside the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, we should use |
||||||||||||||||||||||||||||||||||
| commands = BuildCommandSerializer(many=True, read_only=True) | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| class Meta: | ||||||||||||||||||||||||||||||||||
| model = Build | ||||||||||||||||||||||||||||||||||
|
|
@@ -191,6 +223,10 @@ class Meta: | |||||||||||||||||||||||||||||||||
| "success", | ||||||||||||||||||||||||||||||||||
| "error", | ||||||||||||||||||||||||||||||||||
| "commit", | ||||||||||||||||||||||||||||||||||
| "builder", | ||||||||||||||||||||||||||||||||||
| "docs_url", | ||||||||||||||||||||||||||||||||||
| "commit_url", | ||||||||||||||||||||||||||||||||||
| "commands", | ||||||||||||||||||||||||||||||||||
| "_links", | ||||||||||||||||||||||||||||||||||
| "urls", | ||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||
|
|
@@ -212,6 +248,18 @@ def get_success(self, obj): | |||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| def get_docs_url(self, obj): | ||||||||||||||||||||||||||||||||||
| if obj.version: | ||||||||||||||||||||||||||||||||||
| return obj.version.get_absolute_url() | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| def get_commit_url(self, obj): | ||||||||||||||||||||||||||||||||||
| if obj.commit: | ||||||||||||||||||||||||||||||||||
| return obj.get_commit_url() | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| class NotificationMessageSerializer(serializers.Serializer): | ||||||||||||||||||||||||||||||||||
| id = serializers.SlugField() | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,8 +12,10 @@ | |
| from rest_framework.authtoken.models import Token | ||
| from rest_framework.test import APIClient | ||
|
|
||
| from readthedocs.builds.constants import LATEST, TAG | ||
| from readthedocs.builds.models import Build, Version | ||
| from readthedocs.builds.constants import LATEST | ||
| from readthedocs.builds.constants import TAG | ||
| from readthedocs.builds.models import Build | ||
| from readthedocs.builds.models import Version | ||
| from readthedocs.core.notifications import MESSAGE_EMAIL_VALIDATION_PENDING | ||
| from readthedocs.doc_builder.exceptions import BuildCancelled | ||
| from readthedocs.notifications.models import Notification | ||
|
|
@@ -104,13 +106,14 @@ def setUp(self): | |
| state="finished", | ||
| error="", | ||
| success=True, | ||
| _config={"property": "test value"}, | ||
| version=self.version, | ||
| project=self.project, | ||
| builder="builder01", | ||
| commit="a1b2c3", | ||
| length=60, | ||
| ) | ||
| self.build.config = {"property": "test value"} | ||
| self.build.save() | ||
|
Comment on lines
+115
to
+116
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are we moving this outside the |
||
|
|
||
| self.other = fixture.get(User, projects=[]) | ||
| self.others_token = fixture.get(Token, key="other", user=self.other) | ||
|
|
@@ -134,13 +137,14 @@ def setUp(self): | |
| state="finished", | ||
| error="", | ||
| success=True, | ||
| _config={"property": "test value"}, | ||
| version=self.others_version, | ||
| project=self.others_project, | ||
| builder="builder01", | ||
| commit="a1b2c3", | ||
| length=60, | ||
| ) | ||
| self.others_build.config = {"property": "test value"} | ||
| self.others_build.save() | ||
|
|
||
| # Make all non-html true so responses are complete | ||
| self.project.versions.update( | ||
|
|
@@ -245,7 +249,11 @@ def _get_response_dict(self, view_name, filepath=None): | |
| filename = Path(filepath).absolute().parent / "responses" / f"{view_name}.json" | ||
| return json.load(open(filename)) | ||
|
|
||
| def assertDictEqual(self, d1, d2): | ||
| # Keep unittest.TestCase signature compatibility. | ||
| # assertEqual() dispatches dict comparisons to assertDictEqual and passes | ||
| # `msg` as a keyword argument: | ||
| # https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertEqual | ||
| def assertDictEqual(self, d1, d2, msg=None): | ||
| """ | ||
| Show the differences between the dicts in a human readable way. | ||
|
|
||
|
|
@@ -258,4 +266,10 @@ def assertDictEqual(self, d1, d2): | |
| message = datadiff.diff(d1, d2) | ||
| except ImportError: | ||
| pass | ||
|
|
||
| if msg and message: | ||
| message = f"{message}\n{msg}" | ||
| elif msg: | ||
| message = msg | ||
|
|
||
| return super().assertDictEqual(d1, d2, message) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems we are changing the logic here when not
settings.RTD_SAVE_BUILD_COMMANDS_TO_STORAGE.The old code runs
return super().retrieve(*args, **kwargs)and now we will be running returnResponse(serializer.data)instead.Is that the same?