-
Notifications
You must be signed in to change notification settings - Fork 13
Add Publish Side Effects #307
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
Closed
Closed
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,4 +2,4 @@ | |
Open edX Learning ("Learning Core"). | ||
""" | ||
|
||
__version__ = "0.26.0" | ||
__version__ = "0.27.0" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
openedx_learning/apps/authoring/publishing/migrations/0009_create_publishsideeffect.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# Generated by Django 4.2.16 on 2025-04-17 08:47 | ||
|
||
import django.db.models.deletion | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("oel_publishing", "0008_alter_draftchangelogrecord_options_and_more"), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterModelOptions( | ||
name="draftchangelogrecord", | ||
options={ | ||
"verbose_name": "Draft Change Log Record", | ||
"verbose_name_plural": "Draft Change Log Records", | ||
}, | ||
), | ||
migrations.AlterModelOptions( | ||
name="draftsideeffect", | ||
options={ | ||
"verbose_name": "Draft Side Effect", | ||
"verbose_name_plural": "Draft Side Effects", | ||
}, | ||
), | ||
migrations.AlterField( | ||
model_name="draftchangelogrecord", | ||
name="draft_change_log", | ||
field=models.ForeignKey( | ||
on_delete=django.db.models.deletion.CASCADE, | ||
related_name="records", | ||
to="oel_publishing.draftchangelog", | ||
), | ||
), | ||
migrations.AlterField( | ||
model_name="draftsideeffect", | ||
name="effect", | ||
field=models.ForeignKey( | ||
on_delete=django.db.models.deletion.RESTRICT, | ||
related_name="affected_by", | ||
to="oel_publishing.draftchangelogrecord", | ||
), | ||
), | ||
migrations.CreateModel( | ||
name="PublishSideEffect", | ||
fields=[ | ||
( | ||
"id", | ||
models.BigAutoField( | ||
auto_created=True, | ||
primary_key=True, | ||
serialize=False, | ||
verbose_name="ID", | ||
), | ||
), | ||
( | ||
"cause", | ||
models.ForeignKey( | ||
on_delete=django.db.models.deletion.RESTRICT, | ||
related_name="causes", | ||
to="oel_publishing.publishlogrecord", | ||
), | ||
), | ||
( | ||
"effect", | ||
models.ForeignKey( | ||
on_delete=django.db.models.deletion.RESTRICT, | ||
related_name="affected_by", | ||
to="oel_publishing.publishlogrecord", | ||
), | ||
), | ||
], | ||
options={ | ||
"verbose_name": "Publish Side Effect", | ||
"verbose_name_plural": "Publish Side Effects", | ||
}, | ||
), | ||
migrations.AddConstraint( | ||
model_name="publishsideeffect", | ||
constraint=models.UniqueConstraint( | ||
fields=("cause", "effect"), name="oel_pub_pse_uniq_c_e" | ||
), | ||
), | ||
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
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.
I think this comment needs to be clarified, because I am confused by it.
Publishing a component does not automatically nor necessarily "publish" any containers that use it, and we even have test cases that verify that - which still seem to be passing after this change. So I think either this is wrong, or I misunderstood something here.
Again, I don't think that's the case? But I would say "When a component is published, we may need to perform post-publish actions on containers where that component is a descendant. For example, publishing the last unpublished component in a Unit may make both the unit and its parent section no longer "contain unpublished changes", and that may require an update to the metadata about those containers in the search index used by Studio."
Hmm, I would expect the opposite: when a container is not in the(misunderstanding - see below)PublishLog
(neither it nor any ancestor was directly published) but it has a descendant that was published, it will be added as aPublishSideEffect
, because the publish could affect it but it is not itself changed, but it will not appear in thePublishLog
. If the container or an ancestor was changed as part of this publish, it will be included directly in thePublishLog
. I would never expect any container to appear in both the directPublishLog
and thePublishSideEffect
list.I'm also wondering if you could open a related PR to show how https://github.com/openedx/edx-platform/blob/ba47f1fae5094d9608d7d2299f778afe023533e1/openedx/core/djangoapps/content_libraries/tasks.py#L99-L104 can be updated once this PR is merged?
Uh oh!
There was an error while loading. Please reload this page.
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.
+1, I have the same question as @bradenmacdonald .
This confuses me @bradenmacdonald , because PublishSideEffect joins together two PublishLogRecord rows (
cause
andeffect
). So, wouldn't the container necessarily have to have a PublishLogRecord so it could appear as theeffect
of the PublishSideEffect?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.
(@ormsbee For the never-published container K and its child C, to capture the PublishSideEffect of C -> K, would we need
effect
to be a new PublishLogRecord withentity=K
,old_version==null
andnew_version==null
?)Uh oh!
There was an error while loading. Please reload this page.
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.
Ah OK, I definitely misunderstood that part. Please ignore that part of my comments. I was mostly reading the description and got confused by assuming that PublishSideEffect just listed any container implicitly affected by a publish, in a way completely analogous to PublishLogEntry.
Now that I (hopefully) understand it, I'm wondering if we [will] actually have a use case for tracking which children caused each particular parent to be included in the PublishLog that otherwise wouldn't be? i.e. when would we read
PublishSideEffect
? But either way, the comment about how it works at least makes sense to me.Uh oh!
There was an error while loading. Please reload this page.
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.
I'm still not sure about this. I feel like we're overloading the term "published" to mean two different things:
IMO, scenario (1) makes sense to call "publishing". Scenario (2) does not. I don't know what to call it exactly, but does that distinction make sense @bradenmacdonald @ormsbee ?
Uh oh!
There was an error while loading. Please reload this page.
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.
Update to this, per this Slack thread, @jmakowski1123 confirms that a container is considered to have been "last published" at whatever time that container or any of its children/descendants are published. Copying the exact text of what was agreed to for context in case anyone is looking at this a few years down the line:
I'll try to rewrite the docstring to be clearer on how this works and why.
Uh oh!
There was an error while loading. Please reload this page.
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.
@ormsbee Ok, I think I understand the justification for why publishing a child propagates up to publishing the parent container.
But where does this up-propagation end? E.g
Plus, we still need to address this TODO to publish down through all the children of a container.
Would also help to see test cases for these.. Please let me know how I can help out?
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.
A couple of things:
The Section's "last published" date gets updated, but Component B is not published. This is reading "last published" as "the last time my published state has changed in some way" and not "the last time I published all my children via a publish action at the top level".
Yes.
I paused work on this PR to work on a version that modeled publishing dependencies more explicitly, using the ideas outlined in #317. I'm unlikely to pick that up again until after the conference, so if you want to build on top of that, it would be amazing.
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.
@pomegranited: FWIW, the bulk of the new logic would be in set_draft_dependencies and _calculate_state_hash in the
api
module.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.
@ormsbee
Oohhhh.. ok, that makes much more sense, thank you!
Will see how far I get on openedx/frontend-app-authoring#1977 before then, but I'm hoping to help out there.