During code review of a merge request, suppose you (an allowed approver), approves the merge request. You realized you missed something and you want to take back your approval. Or you might see something so terrible that you want to block / veto the merge request (#761). Currently GitLab does not provide any of these solutions.
Dependencies
#1262 (closed) re-designs the approvals UI to get ready for this and future features. That issue should be implemented and merged into master before this one is started.
This merge request for this issue should only contain this issue and no other scope.
Smallest iteration in scope
Provide a mechanism to remove your approval for a merge request that hasn't been merged yet.
This only impacts your own approval. It doesn't directly impact the approvals of others.
The merge request state changes automatically based on your unapprove and approve actions. (I.e. if the number of approvals are enough, the merge request can be accepted by someone with permissions to do so.)
Out of scope
When a merge request is approved totally, all pending todos are marked done in the existing functionality. It is not clear what should happen if a merge request subsequently flips back since somebody removed their approval. That is, any secondary consequences to todos are outside of the scope of this issue.
Design considerations
The UI should easily allow you to approve and remove.
The UI should not mislead you to think that your actions will impact other people's approvals.
The UI should not mislead you to think that you can block / veto the merge request.
Design mock-ups
One more approval is required. I can remove my approval.
The number of approvals is fulfilled. I can remove my approval. I don't have permissions to merge the merge request.
The number of approvals is fulfilled. I can remove my approval. I do have permissions to merge the merge request.
I didn't even know approvals was a feature of GitLab haha Neat!
@JobV I'm curious what the reasoning is for having the buttons be different in these different states? Unapproval vs. remove approval - I'm not sure I see the reason for changing these wordings/colors based on whether or not all approvals are submitted?
Side note: Where is the merge button when approvals are needed?
@tauriedavis it's hidden! If approvals are enabled, no-one can merge until the minimum number of approvals has been added.
@hazelyang@JobV I'm a little confused - is 'unapprove' the same as 'remove approval', or is it registering a blocker for the MR? If it's the former, I don't see why these buttons wouldn't be the same.
I am also a bit confused. If both actions are the same, then the only reason I could think of is that we want to discourage "remove approval", which somehow makes sense because then I am certainly the one who blocks this merge request. So I must have a strong reason.
However I might still prefer to just make it a switch -- on or off like how like and unlike works, and use another way to show if the merge requests are approved from all approvers. Because this is less confusing.
@hazelyang I'm confused too, and I would add that on the second screen, it's not clear whether the Unapprove button will unapprove all the votes or just mine.
@smcgivern There could be a state where some is an approver and a merger. So in the second mockup (All the approvals are approved), there could be a merge request button AND a removal approval button. But not for every approver, if they don't have permission to merge. Is this right?
@tauriedavis aha, you're right! Yes, good point - this is indeed complicated. Someone with merge permissions and who has already approved the MR would see both buttons.
"Unapprove" and " Remove my approval" both mean people can remove their approvals until the brach is merged. Maybe we could have the button with the same style and same text for the button?
Still need an approval from the approver
Just a thought: What if we have a dotted circle to indicate the status is pending? I think it's more direct than only has " Require one more approval from...".
One comment though: the dotted circle is within a list preceded by a label called approved by. So perhaps that would confuse people. What about instead, we change approved by to approvers, then add the avatars of people who have approved it first, with a green check on the top right corner, then followed by those dotted circle?
We could even have the avatar of the pending approvals with a ? symbol next to them?
We could even have the avatar of the pending approvals with a ? symbol next to them?
@regisF We have an use case like this: People set up Approvals required: 3 but have 4 approvers. We are disabled to predict 3 of the 4 approvers who will make the approvals. So I think the idea will not work in this case.
I removed the line between "Requires 1000 approvals" and Approvers part since I think they should look like they are in the same group visually.
@godfat I proposed another solution to the question you mentioned.
State01: The link "+990 more" will appear until 10 people approved.
State02: Click "+990 more", and then the modal will appear. The modal contains the approvers.
When there are 1000 approvals, the expanded list is very long and heavy. We could put the whole list of approvers into the modal to solve this problem. However, if the approvers <= 10, there is no need to have a modal.
i really like the way this issue has progressed, and @hazelyang's designs look great! Very easy to see what's going on within the MR.
Question: are there any plans to show Approval info on the Merge Request list page? i tend to revisit a lot of MRs i've already approved because i can't remember which i've completed and which are still waiting. i try to remember to reassign once i've approved so i can utilize the filters, but it would be helpful to have a visual cue on the list showing what i've already approved (or add this as a filter?).
Probably needs a separate issue, but i figured i'd toss the question out there...
I updated the description, summarizing the discussion from the comments up to here, except for the large number of approvers scenario.
Thanks @godfat for bringing up that case. But it's definitely an edge case. We don't anticipate GitLab to be frequently used with a large number of required approvals. (You can have a large number of eligible approvers. But the required number of approvals would not typically be more than a handful of people.) If an organization requires a large number of approvals to review a merge request, then likely they have a process which is outside of the scenarios that we are planning for. In that case, we need to more carefully consider their process, and provide a better solution.
So it's not a good use of our resources to design for and implement a UI to specifically address this right now.
But if it does turn out that someone has this scenario in a rare case, the mockups in the description (and the implementation) would just naturally extend to this, which is totally fine for now. At least it is not broken.
@smcgivern : Will the unapprove action automatically be added to the thread of the merge request? Or should that be called out explicitly in this issue? Or should it be logged as a separate issue to work on?
@awhildy + @hazelyang : What do you think about going with "unapprove" as the consistent verb in this and all future features? So primarily, if we like that term, we should update the mockup to be "Unapprove" and not "Remove my approval".
The primary reason is that then we will be consistent everywhere, and give the user a congruent experience. For example:
Victor approved merge request !12345
Victor unapproved merge request !22345
Which would show up in system notes, emails, etc.
These are probably harder to enforce (style guide-wise), and probably a little messier to code:
Victor approved merge request !12345
Victor removed their approval for merge request !22345
(I'll be adding new issues for email notifications and system notes shortly.)
I'm mainly arguing from a consistency perspective, perhaps sacrificing readability and grammatical correctness in some cases. "Removing" connotes taking away something you already gave, i.e. the approval. Whereas "unapprove" is like flipping a boolean switch. It's a subtle distinction, and "Remove" I think is better for this one specific case. But I ultimately vote for "Unapprove" knowing that going forward, we will have many more features (such as sending fine-grained negative code review signals in a merge request), and perhaps the flipping-a-boolean-switch mental model is easier for users, and easier for text copy.
Just for fun: I believe Stash/Bitbucket uses both "disapprove" and "unapprove" and its variations in different contexts. I remembering submitting a ticket to them expressing my disapproval of them using "disapprove" (pun intended). And they disagreed with me. Please please let's not use "disapprove" because that's a totally different meaning! We can argue about "reapprove" later if it ever comes up.
@victorwu You reminded that I saw someone was using dislike when they actually mean unlike. Yeah unlike doesn't mean unlike, but using dislike looks more wrong to me. For the same reason I prefer unapproved, too. It's just simpler and more consistent.
@godfat@victorwu: While I much more prefer the simplicity of Unapproved, the problem is that Unapprove doesn't seem to be a word (interesting similar conversation: http://forum.wordreference.com/threads/disapprove-unapprove.2767115/). It is alright to say past tense (Victor unapproved this MR), you can't use the present tense verb, which is what the UI needs.
Because of the limits of English, I'd suggest Undo approval as the button in the UI, and Victor unapproved merge request !22345 in the system notes and emails. Thoughts?
@awhildy Ahh yes. English sucks since it wasn't invented with software interfaces in mind.
If we go with your format, we will have these choices:
Remove my approval
Remove your approval
Remove approval
Undo my approval
Undo your approval
Undo approval
I actually think the "Remove" versions make more sense, since "Undo" often is used in the context of correcting a silly error or backing out of a rash decision, usually within a few seconds or minutes. In this use case, after a long code review discussion, somebody may want to remove their approval. So that could be two days later.
Hehe. Fair point @victorwu. Maybe we just drop the 'my' from the original comps to keep it simpler and more consistent (and avoid the whole my/you conversation). It should be quite clear that you can only remove your approval, and it is a command that is super easy to recover from (by just approving again)
So, the command is Remove approval, and the system note and email is unapproved.
@hazelyang: could you update the comps to say Remove approval instead of Remove my approval. Thanks!
@awhildy I guess that would be easier for people seeing this the first time :)
@victorwu I don't really feel undoing a decision made 2 days ago would be weird, but since I am not native English speaker nor am I really good at English, I would never feel strong in this regard. I think this is also the top reason why I prefer consistency over semantics. Any decision would be good to me :)
While correct language usage is important, it is not the primary purpose when we create GitLab. Language is a crucial component to UX, and that's why at least I enjoy the detailed discussions here and believe it's very important we get it as close to a good experience as we can. Language is indeed extremely messy and difficult in UX. Good language helps users read and flow through the app experience seamlessly. Text is often not in content form (paragraphs), but in buttons, headings, labels, etc. So at least IMHO, there's certain situations where we should sacrifice grammatical correctness if it serves the greater good. Language itself is always evolving, with digital interfaces being a large component of how humans interact day to day. So I see correct grammar and spelling as a guidepost that we should start with as a default, and see how we can evolve from there. Correctness itself is a moving target, and new modern words and phrases are being added to "official" dictionaries every year.
All this to say, @godfat , that I appreciate your feedback, and native-English speaking is just one aspect of the discussion, and your comments are just as valuable. We are obviously creating software for all people to use, and we need a diverse set of feedback to make the best product possible.
That being said, we have to make a decision at some point, so we don't succumb to analysis paralysis. The good thing about software and GitLab is that we ship quickly and often. So getting it right is important. But just getting it done is our short term goal, we then we iterate afterward.
2
Victor WuChanged title: Unapprove merge request → Remove approval in merge request
Throwing my hat in for "unapprove". It may not technically be a dictionary word, but it's made up of simple enough blocks ("un", "approve") that it's relatively easy to understand, and has the advantage of carrying the connotations that we want here - especially as we may add "disapprove" (or "block") later.
My preference for verbiage is "Remove Approval" (or even "Withdraw Approval") - i think it stands a much better chance of simple translations. No pronouns, fewer English-to-LanguageX idiosyncrasies...
Email template could then look like "Victor removed approval for merge request !0000" or "Victor withdrew approval for merge request !0000"
All the "un-" words keep reminding me of debates i have with my team about if/then structures that lead with a negation: if (not-something) { true because it's NOT something } else { false because it IS something }
Thanks @jneen and @cautionbug. Totally get the different opinions and concerns. I think it is a very subjective thing. I'm cautious about using something that isn't a word as it may be harder to translate, etc. I'd like to stick with Remove approval, but will definitely pay attention to feedback, and consider if there is anything that tips the scale. Thanks much!