-
Notifications
You must be signed in to change notification settings - Fork 980
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
Allow marking projects as "archived" #17005
base: main
Are you sure you want to change the base?
Conversation
78ef39e
to
f22daf0
Compare
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.
Generally, looking good, thanks for scoping it down to a single lifecycle status.
I think something good to add to the owner-facing management page would be a suggestion to publish a new release with a readme update or something to point folks where to go next.
Prior ideas have been to allow user-submitted text in the form, but I like that less, since then we have to figure out where to store that.
I think a warning modal popup confirmation might also be in order when archiving would be a good idea to prevent misclicks.
This also doesn't appear to block users from making further releases to an archived project - is that intentionally excluded? In my head, once Archived, it's in read-only mode - similar to GitHub's Archived.
I also just realized - this probably needs some added notation in the Admin UI/ability to change there as well. I didn't see anything in scope here yet. |
365bced
to
0a59e39
Compare
Signed-off-by: Facundo Tuesca <[email protected]>
0a59e39
to
2c2853b
Compare
I changed the UI to add the suggestion and the modal popup. Since these are specific to archiving a project, I changed the UI so that instead of a dropdown with the backend statuses, the user sees two buttons to archive or unarchive their project (see the updated screenshots)
I'll add the restrictions once the rest is ready. I was thinking to only disallow uploads for now, WDYT?
What should the UI for this look? |
Signed-off-by: Facundo Tuesca <[email protected]>
Pushed a commit to disallow uploads on archived projects |
Signed-off-by: Facundo Tuesca <[email protected]>
Signed-off-by: Facundo Tuesca <[email protected]>
Signed-off-by: Facundo Tuesca <[email protected]>
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.
Coming along nicely, thanks for pushing forward on this. I had some notes inline, mostly structural in nature, but some questions as well - nothing too "heavy".
Let me know if anything isn't clear!
owner2 = DBRoleFactory.create(project=project) | ||
|
||
# Maintainers should not appear in the ACLs, since they only have | ||
# upload permissions, and anchived projects don't allow upload |
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.
typo:
# upload permissions, and anchived projects don't allow upload | |
# upload permissions, and archived projects don't allow upload |
DBRoleFactory.create(project=project, role_name="Maintainer") | ||
DBRoleFactory.create(project=project, role_name="Maintainer") |
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.
minor optimization, useful if same params and return value not used
DBRoleFactory.create(project=project, role_name="Maintainer") | |
DBRoleFactory.create(project=project, role_name="Maintainer") | |
DBRoleFactory.create_batch(2, project=project, role_name="Maintainer") |
if ( | ||
project.lifecycle_status is None | ||
or project.lifecycle_status == LifecycleStatus.QuarantineExit | ||
): | ||
project.lifecycle_status = LifecycleStatus.Archived | ||
project.record_event( | ||
tag=EventTag.Project.ProjectArchiveEnter, | ||
request=request, | ||
additional={ | ||
"submitted_by": request.user.username, | ||
}, | ||
) | ||
request.session.flash("Project archived", queue="success") | ||
else: | ||
request.session.flash( | ||
f"Cannot archive project with status {project.lifecycle_status}", | ||
queue="error", | ||
) |
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.
style: Consider early-exit inversion of the logic, like so (pseudocode):
if not <conditions that must be met>:
flash "cannot archive", error
return
do the work
flash "done", success
thus communicate early on the exit clause, continue normally otherwise.
Removes one layer of indentation for "the work", and makes it simpler to create another if/else when necessary with fewer logical jumps to make.
Similar applies to unarchive_project
for publisher in self.oidc_publishers: | ||
acls.append((Allow, f"oidc:{publisher.id}", [Permissions.ProjectsUpload])) | ||
if self.lifecycle_status != LifecycleStatus.Archived: | ||
# Only allow uploads in non-archived projects | ||
acls.append( | ||
(Allow, f"oidc:{publisher.id}", [Permissions.ProjectsUpload]) | ||
) |
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.
optimize: Adding the if
will now happen on each iteration of the loop per publisher
, but the project's lifecycle happens once, probably can shortcut the loop instead by placing the if
outside.
Most projects only have a single publisher, but just in case, save the iteration if unnecessary.
current_permissions = [ | ||
p for p in current_permissions if p != Permissions.ProjectsUpload | ||
] |
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.
optimize: could this be instead?
current_permissions = [ | |
p for p in current_permissions if p != Permissions.ProjectsUpload | |
] | |
current_permissions.remove(Permissions.ProjectsUpload) |
I think each branch of current_permissions
ends up with ProjectsUpload
, and this might be faster than a list comprehension?
What is this?
Following the discussion here, this PR shows what the implementation could look like for adding "status markers" to projects.
Specifically, this PR allows changing a project's status to "Archived".
Details
The implementation is straightforward, since a
Project.lifecycle_status
field already exists (to mark a project as quarantined). This change adds a new "archived" value for that field, and adds the UI so that users can archive and unarchive their projects.Even though the issue mentioned above proposes more statuses ("deprecated", "finished", etc), those can be ambiguous and overlapping, and would require further discussion to define clearly. "Archived", however, is already widely used on GitHub repos and its meaning should be easy for users to understand:
TODO
Screenshots
Project settings
Project landing page
cc @woodruffw @miketheman