Repository: wagtail/wagtail

Issue:
Can't review or revert to a page's initial revision
### Issue Summary

Using the Page History view, there's no way to restore the very first revision of a page, whether it was first saved as draft, published, or submitted for moderation.

This is because the Page History view is populated from PageLogEntry objects, but Wagtail doesn't log the first revision of a page. Note `log_action=False` in these lines when a new page is saved, published, or submitted for moderation:

https://github.com/wagtail/wagtail/blob/629ced01cabaf0e24e5cbc70bf552b9fc046b5b0/wagtail/admin/views/pages/create.py#L172
https://github.com/wagtail/wagtail/blob/629ced01cabaf0e24e5cbc70bf552b9fc046b5b0/wagtail/admin/views/pages/create.py#L198
https://github.com/wagtail/wagtail/blob/629ced01cabaf0e24e5cbc70bf552b9fc046b5b0/wagtail/admin/views/pages/create.py#L254

A simple fix might be to change these all to `log_action=True`. It does appear that the original implementation [deliberately avoided](https://github.com/wagtail/wagtail/commit/2c2aa68503e798529abe6f86240116263803791f) creating an initial `wagtail.edit` event for new pages. Unfortunately that does seem to make it impossible to review or revert to a page's initial state.

Thanks to Slack user Gabriel for bringing up this issue in chat [here](https://wagtailcms.slack.com/archives/C81FGJR2S/p1649733822692019), and @cnk for helping with the explanation. Per @zerolab a workaround on versions up to 2.15 is to change the page history URL `admin/pages/ID/history/` to `admin/pages/ID/revisions/` to see the old revisions view, but this seems to have been removed in 2.16 in https://github.com/wagtail/wagtail/commit/6931663c7f8b419de77085b918329e23483edd45.

Another limited workaround is that users can "Compare with previous revision" on the 2nd revision of a page - this will at least display the list of field-by-field changes so editors can review the differences. But this is far less useful than being able to review or restore the entire revision.

### Steps to Reproduce

1. Start a new project with `wagtail start myproject`
2. `cd myproject`
3. `./manage.py migrate`
4. `./manage.py createsuperuser` and create an admin user.
5. `./manage.py runserver`
6. Vist http://localhost:8000/admin/pages/add/home/homepage/3/ to create a new page (you'll be asked to log in first)
7. Fill in the title field with something like "Original". Click "Save Draft".
8. Change the title field to something like "Changed". Click "Save Draft" again.
9. Now click on "History". You'll see there's no way to restore the original revision:

![image](https://user-images.githubusercontent.com/654645/163024194-5afc2dcd-e85a-4643-8846-e0106913e912.png)

Alternatively, if you first publish the page instead of saving:

<ol start="7">
<li>Fill in the title field with something like "Original". Click "Publish" in the actions menu in the footer.</li>
<li>Click "Edit" to re-edit the page that was just created.</li>
<li>Change the title field to something like "Changed". Click "Save Draft".</li>
<li>Now click on "History". You'll see there's no way to restore the originally published version:</li>
</ol>

![image](https://user-images.githubusercontent.com/654645/163026306-2285d0dd-6a9d-4a8f-afce-53bede56b959.png)

Alternatively, if you first submit the page for moderation:

<ol start="7">
<li>Fill in the title field with something like "Original". Click "Submit for moderation" in the actions menu in the footer.</li>
<li>Click "Edit" to re-edit the page that was just created.</li>
<li>Change the title field to something like "Changed". Click "Save Draft".</li>
<li>Now click on "History". You'll see there's no way to restore the originally published version:</li>
</ol>

![image](https://user-images.githubusercontent.com/654645/163027048-cd0aba29-62a7-4d03-a59c-538cf532c102.png)

* I have confirmed that this issue can be reproduced as described on a fresh Wagtail project: yes

### Technical details

* Python version: 3.8.12
* Django version: 4.0.4
* Wagtail version: 2.16.2


Discussion:

Resolving patch:
diff --git a/wagtail/admin/views/pages/create.py b/wagtail/admin/views/pages/create.py
--- a/wagtail/admin/views/pages/create.py
+++ b/wagtail/admin/views/pages/create.py
@@ -170,7 +170,7 @@ def save_action(self):
         self.parent_page.add_child(instance=self.page)
 
         # Save revision
-        self.page.save_revision(user=self.request.user, log_action=False)
+        self.page.save_revision(user=self.request.user, log_action=True)
 
         # Save subscription settings
         self.subscription.page = self.page
@@ -196,7 +196,7 @@ def publish_action(self):
         self.parent_page.add_child(instance=self.page)
 
         # Save revision
-        revision = self.page.save_revision(user=self.request.user, log_action=False)
+        revision = self.page.save_revision(user=self.request.user, log_action=True)
 
         # Save subscription settings
         self.subscription.page = self.page
@@ -252,7 +252,7 @@ def submit_action(self):
         self.parent_page.add_child(instance=self.page)
 
         # Save revision
-        self.page.save_revision(user=self.request.user, log_action=False)
+        self.page.save_revision(user=self.request.user, log_action=True)
 
         # Submit
         workflow = self.page.get_workflow()
diff --git a/wagtail/management/commands/create_log_entries_from_revisions.py b/wagtail/management/commands/create_log_entries_from_revisions.py
--- a/wagtail/management/commands/create_log_entries_from_revisions.py
+++ b/wagtail/management/commands/create_log_entries_from_revisions.py
@@ -90,20 +90,19 @@ def handle(self, *args, **options):
                         self.log_page_action("wagtail.publish", previous_revision, True)
 
                 if is_new_page or has_content_changes or published:
+                    actions = []
+
                     if is_new_page:
-                        action = "wagtail.create"
-                    elif published:
-                        action = "wagtail.publish"
-                    else:
-                        action = "wagtail.edit"
+                        actions.append("wagtail.create")
 
-                    if published and has_content_changes:
-                        # When publishing, also log the 'draft save', but only if there have been content changes
-                        self.log_page_action(
-                            "wagtail.edit", revision, has_content_changes
-                        )
+                    if is_new_page or has_content_changes:
+                        actions.append("wagtail.edit")
+
+                    if published:
+                        actions.append("wagtail.publish")
 
-                    self.log_page_action(action, revision, has_content_changes)
+                    for action in actions:
+                        self.log_page_action(action, revision, has_content_changes)
 
             previous_revision = revision
 


Test patch:
diff --git a/wagtail/admin/tests/test_audit_log.py b/wagtail/admin/tests/test_audit_log.py
--- a/wagtail/admin/tests/test_audit_log.py
+++ b/wagtail/admin/tests/test_audit_log.py
@@ -197,7 +197,7 @@ def test_edit_form_has_history_link(self):
         history_url = reverse("wagtailadmin_pages:history", args=[self.hello_page.id])
         self.assertContains(response, history_url)
 
-    def test_create_and_publish_does_not_log_revision_save(self):
+    def test_create_and_publish_logs_revision_save(self):
         self.login(user=self.administrator)
         post_data = {
             "title": "New page!",
@@ -225,7 +225,7 @@ def test_create_and_publish_does_not_log_revision_save(self):
                 .values_list("action", flat=True)
                 .order_by("action")
             ),
-            ["wagtail.create", "wagtail.publish"],
+            ["wagtail.create", "wagtail.edit", "wagtail.publish"],
         )
 
     def test_revert_and_publish_logs_reversion_and_publish(self):
diff --git a/wagtail/tests/test_management_commands.py b/wagtail/tests/test_management_commands.py
--- a/wagtail/tests/test_management_commands.py
+++ b/wagtail/tests/test_management_commands.py
@@ -784,15 +784,28 @@ def test_log_entries_created_from_revisions(self):
 
         # Should not create entries for empty revisions.
         self.assertListEqual(
-            list(PageLogEntry.objects.values_list("action", flat=True)),
-            [
-                "wagtail.publish",
-                "wagtail.edit",
-                "wagtail.create",
-                "wagtail.publish",
-                "wagtail.edit",
-                "wagtail.create",
-            ],
+            list(PageLogEntry.objects.values_list("page_id", "action")),
+            # Default PageLogEntry sort order is from newest event to oldest.
+            # We reverse here to make it easier to understand what is being
+            # tested. The events here should correspond with setUp above.
+            list(
+                reversed(
+                    [
+                        # The SimplePage was created in draft mode, with an initial revision.
+                        (self.page.pk, "wagtail.create"),
+                        (self.page.pk, "wagtail.edit"),
+                        # The SimplePage was edited as a new draft, then published.
+                        (self.page.pk, "wagtail.edit"),
+                        (self.page.pk, "wagtail.publish"),
+                        # The SecretPage was created in draft mode, with an initial revision.
+                        (self.secret_page.pk, "wagtail.create"),
+                        (self.secret_page.pk, "wagtail.edit"),
+                        # The SecretPage was edited as a new draft, then published.
+                        (self.secret_page.pk, "wagtail.edit"),
+                        (self.secret_page.pk, "wagtail.publish"),
+                    ]
+                )
+            ),
         )
 
     def test_command_doesnt_crash_for_revisions_without_page_model(self):