Skip to content
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

user_groups: Add markdown rendering for group descriptions. #32873

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

reharsh
Copy link
Collaborator

@reharsh reharsh commented Jan 2, 2025

This PR adds support for rendered descriptions for user groups.

Changes

  1. Updated the NamedUserGroup model to include a rendered description.
  2. Refactored backend functions to handle rendered descriptions for user groups.
  3. Updated tests and documentation.
  4. Added rendered descriptions to user group settings.
  5. Group descriptions are saved and rendered on update.
  6. Rendered descriptions are shown in places like:
  • Group list Item
  • Group Settings
  • Typeahead
  • Popovers
  • DM

The rendered description is also sent wherever the group's description is used.

Fixes: #32559

Screenshots

User Group Settings Changes visible in alignment and hover
Direct Messages dm
Group List Item dm
Typeahead dm
Popover dm
Screen Recordings
  • Update/Edit user group
edit_recording.mov
  • Create user group with link in description
Screen.Recording.2024-12-29.at.8.24.41.PM.mov
Self-review checklist
  • Self-reviewed the changes for clarity and maintainability
    (variable names, code reuse, readability, etc.).

Communicate decisions, questions, and potential concerns.

  • Explains differences from previous plans (e.g., issue description).
  • Highlights technical choices and bugs encountered.
  • Calls out remaining decisions and concerns.
  • Automated tests verify logic where appropriate.

Individual commits are ready for review (see commit discipline).

  • Each commit is a coherent idea.
  • Commit message(s) explain reasoning and motivation for changes.

Completed manual review and testing of the following:

  • Visual appearance of the changes.
  • Responsiveness and internationalization.
  • Strings and tooltips.
  • End-to-end functionality of buttons, interactions and flows.
  • Corner cases, error conditions, and easily imagined bugs.

@zulipbot zulipbot added size: XL area: settings (user groups) User groups related settings issues labels Jan 2, 2025
@reharsh
Copy link
Collaborator Author

reharsh commented Jan 2, 2025

Hey @alya , this PR is ready for review. Could you please take a look when you have a moment? Thanks!

@alya
Copy link
Contributor

alya commented Jan 2, 2025

The screenshots look great! Please resolve the conflicts to prepare this for review.

@reharsh
Copy link
Collaborator Author

reharsh commented Jan 3, 2025

@alya done, please check!

@alya
Copy link
Contributor

alya commented Jan 3, 2025

@sahil839 could you please take a look at this one? I haven't tested.

@alya alya added the maintainer review PR is ready for review by Zulip maintainers. label Jan 3, 2025
displaying this content so that emoji, LaTeX, and other syntax
work correctly. And any client-side security logic for
user-generated message content should be applied when displaying
this HTML as though it were the body of a Zulip message.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This and other changes in docs needs a "Changes" entry. Also, changelog.md and version.py should be updated accordingly.

}

full_members_group_info = {
"name": SystemGroups.FULL_MEMBERS,
"description": "Members of this organization, not including new accounts and guests",
"rendered_description": "<p>Members of this organization, not including new accounts and guests</p>",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead of doing this, can we just use render_group_description when creating the system groups?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I used render_group_description instead but, there was circular import issue, so I tried importing from zerver.actions.user_groups import render_group_description in function, it seems to work. can you please confirm if it is permitted?

zerver/views/user_groups.py Show resolved Hide resolved
render_typeahead_item({
primary: user_groups.get_display_group_name(user_group.name),
secondary: user_group.description,
// eslint-disable-next-line unicorn/prefer-string-replace-all
secondary_html: user_group.rendered_description.replace(/^<p>|<\/p>$/g, ""),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why does this need replace but we do not do the same for streams?

@reharsh reharsh force-pushed the issue-32559 branch 3 times, most recently from 9b21d22 to 74a0f01 Compare January 8, 2025 19:39
@reharsh
Copy link
Collaborator Author

reharsh commented Jan 8, 2025

Hello @sahil839, I have made the changes, sorry I was busy for a few days. can you please take a look again, when you get time. thanks!

Copy link
Collaborator

@sahil839 sahil839 left a comment

Choose a reason for hiding this comment

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

Posted a couple of comments. Can do a complete review along with manual testing once you rebase the PR to resolve merge conflicts.

@@ -899,6 +902,13 @@ def create_system_user_groups_for_realm(realm: Realm) -> dict[str, NamedUserGrou
everyone_on_internet_group_info,
]

from zerver.actions.user_groups import render_group_description
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we just define render_group_description in this file itself, ie. zerver/lib/user_groups.py if that doesn't result in any import cycles?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

   from zerver.lib.markdown import markdown_convert
ImportError: cannot import name 'markdown_convert' from partially initialized module 'zerver.lib.markdown' (most likely due to a circular import) (/srv/zulip/zerver/lib/markdown/__init__.py)

    from zerver.lib.mention import render_group_description
ImportError: cannot import name 'render_group_description' from partially initialized module 'zerver.lib.mention' (most likely due to a circular import) (/srv/zulip/zerver/lib/mention.py)
ERROR:root:Failed to forward GET /json/events to port 9993: Cannot connect to host 127.0.0.1:9993 ssl:default 

....

    from zerver.lib.user_groups import (
ImportError: cannot import name 'get_group_setting_value_for_api' from partially initialized module 'zerver.lib.user_groups' (most likely due to a circular import) (/srv/zulip/zerver/lib/user_groups.py)

....

    from zerver.lib.user_groups import (
ImportError: cannot import name 'get_group_setting_value_for_api' from partially initialized module 'zerver.lib.user_groups' (most likely due to a circular import)  #(/srv/zulip/zerver/lib/user_groups.py)

tried this! still encountering circular import error, also tried modifying other related files too, haven't got anywhere.
It'll be great if you can find time to check it out.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok, this seems fine for now then.

rendered_description:
type: string
description: |
The description of the user group rendered as HTML.
Copy link
Collaborator

Choose a reason for hiding this comment

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

You would need to add **Changes** entry for all these added blocks.

@reharsh
Copy link
Collaborator Author

reharsh commented Jan 10, 2025

@sahil839 , made the changes, can you please take a look again. thanks!

user-generated message content should be applied when displaying
this HTML as though it were the body of a Zulip message.

**Changes**: Prior to Zulip 10.0 (feature level 338), markdown rendering
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think "New in Zulip 10.0 (feature level 338), for adding support for markdown rendering of group descriptions." would be a better phrasing.

@@ -278,9 +287,13 @@ def do_update_user_group_description(
extra_data={
RealmAuditLog.OLD_VALUE: old_value,
RealmAuditLog.NEW_VALUE: description,
"property": "description",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is this needed? We already have a different event type for description.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

oh.. right, removed!

@@ -2001,7 +2003,7 @@ def check_update_user_group(
promote_new_full_members()
check_update_user_group(
"help",
"Troubleshooting team",
"Troubleshooting team\n",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would be good to add a test for checking we don't embed url previews similar to the test we have for streams.

group.description = event.data.description;
group.rendered_description = event.data.rendered_description;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess clean_up_group_description needs to be called here as well for the new value.

Copy link
Collaborator

Choose a reason for hiding this comment

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

There is no need to update the event.data.rendered_description field here, doing group.rendered_description = clean_up_group_description(event.data.rendered_description) will be better.

rendered_description: postprocess_content(group.rendered_description),
});
$edit_container.find(".group-description-wrapper").html(html);
$group_row.find(".description").html(html);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need to set the value rendered by render_user_group_description here? This is for the left panel of groups UI and I guess that is handled by browse_user_groups_list_item and it handles no description case using data-no-description attribute.

render_typeahead_item({
primary: user_groups.get_display_group_name(user_group.name),
secondary: user_group.description,
secondary_html: user_group.rendered_description,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I can see that the description is not aligned correctly with the name in mention typeahead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

can you please repopulate your dev db, this is because earlier created groups don't have clean_up_descriptions

Copy link
Collaborator

Choose a reason for hiding this comment

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

There exists groups in production as well, so we cannot do that here. I missed this before but existing groups should be handled using migrations.

@@ -899,6 +902,13 @@ def create_system_user_groups_for_realm(realm: Realm) -> dict[str, NamedUserGrou
everyone_on_internet_group_info,
]

from zerver.actions.user_groups import render_group_description
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok, this seems fine for now then.

@reharsh reharsh force-pushed the issue-32559 branch 2 times, most recently from af67481 to 5437bb3 Compare January 12, 2025 12:08
@reharsh
Copy link
Collaborator Author

reharsh commented Jan 12, 2025

@sahil839 made the changes, PTAL.

@reharsh
Copy link
Collaborator Author

reharsh commented Jan 15, 2025

Hello, @sahil839! I've modified migration script, please take a look when you have time.

from zerver.actions.user_groups import render_group_description

NamedUserGroup = apps.get_model("zerver", "NamedUserGroup")
all_named_user_groups = NamedUserGroup.objects.exclude(description="")
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think batching might be needed here and probably updating the group objects in bulk as well like we do in migrations for setting defaults of group settings, for deploying this if there are large number of user groups having description.

Also, would be better to have this as a separate migration file for deployment ease.

@@ -76,6 +80,13 @@ export function remove(user_group: UserGroup): void {
user_group_by_id_dict.delete(user_group.id);
}

export function clean_up_group_description(rendered_description: string): string {
if (rendered_description !== undefined) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this be undefined because the type of rendered_description above is string.

group.description = event.data.description;
group.rendered_description = event.data.rendered_description;
Copy link
Collaborator

Choose a reason for hiding this comment

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

There is no need to update the event.data.rendered_description field here, doing group.rendered_description = clean_up_group_description(event.data.rendered_description) will be better.

@@ -469,7 +471,10 @@ export function handle_member_edit_event(group_id: number, user_ids: number[]):
export function update_group_details(group: UserGroup): void {
const $edit_container = get_edit_container(group);
$edit_container.find(".group-name").text(user_groups.get_display_group_name(group.name));
$edit_container.find(".group-description").text(group.description);
const html = render_user_group_description({
rendered_description: postprocess_content(group.rendered_description),
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am not sure why we do postprocess_content only here when updating the description in right panel and not in other cases. I guess we do the same for streams as well, but we should check why is this required only here and not in other places.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

looks like render_browse_user_group_list_item html somehow contains postprocessed content already, like with title,target etc. and postprocess_content here doesn't really make any difference.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes. Since we are passing the rendered template here, I guess this is not need since rendered_markdown helper used in templates handles this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

found it!
there is this handlebars helper in template.ts

Handlebars.registerHelper(
    "rendered_markdown",
    (content: string) => new Handlebars.SafeString(postprocess_content(content)),
);

which already does postprocessing for rendered_desc everywhere (left_sidebar, right_sidebar, typeaheads, popovers), same for stream desc, so we don't really need this postprocess_content.

also trying to figure out migration bit, but no luck yet, can't understand why the same thing worked for 0206_stream_rendered_description.py:(

@reharsh
Copy link
Collaborator Author

reharsh commented Jan 16, 2025

Hii @sahil839, I've made the changes, but getting an error while trying to migrate with new migration script.

migration file
from django.db import migrations, transaction
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from django.db.migrations.state import StateApps
from django.db.models import F, Max, Min, OuterRef

def render_all_user_group_descriptions(
    apps: StateApps, schema_editor: BaseDatabaseSchemaEditor
) -> None:
    # FIXME: Application code should not be imported from migrations.
    from zerver.actions.user_groups import render_group_description

    NamedUserGroup = apps.get_model("zerver", "NamedUserGroup")
    BATCH_SIZE = 1000
    max_id = NamedUserGroup.objects.exclude(description="").aggregate(Max("id"))[
        "id__max"
    ]
    if max_id is None:
        # Do nothing if there are no user groups on the server.
        return
    
    lower_bound = NamedUserGroup.objects.exclude(description="").aggregate(Min("id"))[
        "id__min"
    ]

    while lower_bound <= max_id:
        upper_bound = lower_bound + BATCH_SIZE - 1
        print(f"Processing batch {lower_bound} to {upper_bound} for NamedUserGroup")

        with transaction.atomic():
            all_named_user_groups = NamedUserGroup.objects.exclude(
                id__gte=lower_bound, id__lt=upper_bound, description="")
            for user_group in all_named_user_groups:
                user_group.rendered_description = render_group_description(
                user_group.description, user_group.realm
                )
            NamedUserGroup.objects.bulk_update(all_named_user_groups, fields=["rendered_description"], batch_size=BATCH_SIZE)

        lower_bound += BATCH_SIZE


class Migration(migrations.Migration):

    dependencies = [
        ("zerver", "0649_namedusergroup_rendered_description"),
    ]

    operations = [
        migrations.RunPython(
            render_all_user_group_descriptions,
            reverse_code=migrations.RunPython.noop,
            elidable=True,
        ),
    ]
Traceback
(zulip-py3-venv) vagrant@4b23a8f20b01:/srv/zulip$ ./manage.py migrate
Operations to perform:
  Apply all migrations: analytics, auth, confirmation, contenttypes, corporate, otp_static, otp_totp, pgroonga, phonenumber, sessions, social_django, zerver, zilencer
Running migrations:
  Applying zerver.0650_set_namedusergroup_rendered_description...Processing batch 33 to 1032 for NamedUserGroup
Traceback (most recent call last):
  File "/srv/zulip/./manage.py", line 150, in <module>
    execute_from_command_line(sys.argv)
  File "/srv/zulip/./manage.py", line 115, in execute_from_command_line
    utility.execute()
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/core/management/base.py", line 413, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/core/management/base.py", line 459, in execute
    output = self.handle(*args, **options)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/core/management/base.py", line 107, in wrapper
    res = handle_func(*args, **kwargs)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/core/management/commands/migrate.py", line 356, in handle
    post_migrate_state = executor.migrate(
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/db/migrations/executor.py", line 135, in migrate
    state = self._migrate_all_forwards(
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/db/migrations/executor.py", line 167, in _migrate_all_forwards
    state = self.apply_migration(
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/db/migrations/executor.py", line 252, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/db/migrations/migration.py", line 132, in apply
    operation.database_forwards(
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/db/migrations/operations/special.py", line 193, in database_forwards
    self.code(from_state.apps, schema_editor)
  File "/srv/zulip/zerver/migrations/0650_set_namedusergroup_rendered_description.py", line 35, in render_all_user_group_descriptions
    user_group.rendered_description = render_group_description(
  File "/srv/zulip/zerver/actions/user_groups.py", line 174, in render_group_description
    return markdown_convert(text, message_realm=realm, no_previews=True).rendered_content
  File "/srv/zulip/zerver/lib/markdown/__init__.py", line 2824, in markdown_convert
    ret = do_convert(
  File "/srv/zulip/zerver/lib/markdown/__init__.py", line 2736, in do_convert
    realm_url=message_realm.url,
AttributeError: 'Realm' object has no attribute 'url'

these groups seem to have no host so I added:

realm_host = getattr(user_group.realm, 'host', None)
if not realm_host:
        print(f"Skipping user group {user_group.name}: realm host is missing")
        continue
output is... Skipping user group role:nobody: realm host is missing Skipping user group role:owners: realm host is missing Skipping user group role:administrators: realm host is missing Skipping user group role:moderators: realm host is missing Skipping user group role:fullmembers: realm host is missing Skipping user group role:members: realm host is missing Skipping user group role:everyone: realm host is missing Skipping user group role:internet: realm host is missing Skipping user group role:nobody: realm host is missing Skipping user group role:owners: realm host is missing Skipping user group role:administrators: realm host is missing Skipping user group role:moderators: realm host is missing Skipping user group role:fullmembers: realm host is missing Skipping user group role:members: realm host is missing Skipping user group role:everyone: realm host is missing Skipping user group role:internet: realm host is missing Skipping user group hamletcharacters: realm host is missing Skipping user group role:nobody: realm host is missing Skipping user group role:owners: realm host is missing Skipping user group role:administrators: realm host is missing Skipping user group role:moderators: realm host is missing Skipping user group role:fullmembers: realm host is missing Skipping user group role:members: realm host is missing Skipping user group role:everyone: realm host is missing Skipping user group role:internet: realm host is missing Skipping user group new bolds: realm host is missing Skipping user group new italics: realm host is missing Skipping user group this is link: realm host is missing

If you have time can you please look into it.

Copy link
Collaborator

@sahil839 sahil839 left a comment

Choose a reason for hiding this comment

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

Posted a couple of comments.

Regarding migration, I tried running ./manage.py migrate with the migration file that you have in this PR without any changes and it gives the same error that you mentioned. I think it is because uri is a property on Realm and not a DB field, but am not sure.

@@ -469,7 +471,10 @@ export function handle_member_edit_event(group_id: number, user_ids: number[]):
export function update_group_details(group: UserGroup): void {
const $edit_container = get_edit_container(group);
$edit_container.find(".group-name").text(user_groups.get_display_group_name(group.name));
$edit_container.find(".group-description").text(group.description);
const html = render_user_group_description({
rendered_description: postprocess_content(group.rendered_description),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes. Since we are passing the rendered template here, I guess this is not need since rendered_markdown helper used in templates handles this.

export let render_user_group = (user_group: {
name: string;
rendered_description: string;
description: string;
Copy link
Collaborator

Choose a reason for hiding this comment

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

description is not used anymore.

This commit adds support for rendered descriptions for user groups.
changes:
    1. Updated the NamedUserGroup model to include a
    rendered description.
    2. Refactored backend functions to handle rendered
    descriptions for user groups.
    3. Updated tests and documentation.
    4. Added rendered descriptions to user group settings.
    5. Group descriptions are saved and rendered on update.
    6. Rendered descriptions are shown in places like:
        - Group list
        - Group Settings
        - Typeahead
        - Popovers

The rendered description is also sent wherever the group's
description is used.

Fixes: zulip#32559
@reharsh
Copy link
Collaborator Author

reharsh commented Jan 17, 2025

Thank you, @sahil839, for your time on this!

I just figured out that running all migrations together (./tools/provision --force) resolves the issue, likely due to a model state inconsistency with the custom RunPython code was causing it. It seems consistent with other files too, I think this is expected, given migrations are applied sequentially. Let me know if you have any other thoughts.
again thank you so much -- I've made the changes—please review them whenever you have time.

@sahil839
Copy link
Collaborator

You can do provisioning and rebuild the DB in development environment, but that cannot be done in production. Same migration file for stream description works, so am not sure how to fix this.

@reharsh
Copy link
Collaborator Author

reharsh commented Jan 18, 2025

Ok... then I'll continue to look for a fix,
but while running stream_rendered_description by ./manage.py migrate zerver 0206_stream_rendered_description or any other old migrations it gives me following error. I can't run those too... like you said it works for you. any insights?

traceback
(zulip-py3-venv) vagrant@4b23a8f20b01:/srv/zulip$ ./manage.py migrate zerver 0206_stream_rendered_description
Operations to perform:
  Target specific migration: 0206_stream_rendered_description, from zerver
Traceback (most recent call last):
  File "/srv/zulip/./manage.py", line 150, in <module>
    execute_from_command_line(sys.argv)
  File "/srv/zulip/./manage.py", line 115, in execute_from_command_line
    utility.execute()
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/core/management/base.py", line 413, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/core/management/base.py", line 459, in execute
    output = self.handle(*args, **options)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/core/management/base.py", line 107, in wrapper
    res = handle_func(*args, **kwargs)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/core/management/commands/migrate.py", line 301, in handle
    pre_migrate_state = executor._create_project_state(with_applied_migrations=True)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/db/migrations/executor.py", line 91, in _create_project_state
    migration.mutate_state(state, preserve=False)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/db/migrations/migration.py", line 91, in mutate_state
    operation.state_forwards(self.app_label, new_state)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/db/migrations/operations/fields.py", line 165, in state_forwards
    state.remove_field(app_label, self.model_name_lower, self.name)
  File "/srv/zulip-venv-cache/14cbac6fefe6ac8472cebd0e64812b1d7d6157fc/zulip-py3-venv/lib/python3.10/site-packages/django/db/migrations/state.py", line 258, in remove_field
    old_field = model_state.fields.pop(name)
KeyError: 'create_public_stream_policy'

@sahil839
Copy link
Collaborator

I meant I have not seen any previous discussion of any such failure when the stream rendered description work was done. The way you are trying to run the single migration run will expectedly not work because the Database structure has change a lot since that migration.

I think would be better to ask for suggestions on CZO if you cannot get a fix.

@zulipbot
Copy link
Member

Heads up @reharsh, we just merged some commits that conflict with the changes you made in this pull request! You can review this repository's recent commits to see where the conflicts occur. Please rebase your feature branch against the upstream/main branch and resolve your pull request's merge conflicts accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: settings (user groups) User groups related settings issues has conflicts maintainer review PR is ready for review by Zulip maintainers. size: XL
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

Allow Markdown in group descriptions
4 participants