Repository navigation
Add approve, reject, publish and revert to the set view - #2581
Merged
Merged
Conversation
This was referenced Oct 19, 2026
pournasserian
added a commit
that referenced
this pull request
Oct 20, 2026
Closes #2624 ## What Follow-ups from the independent review of #2581 (F-DSK, #2422). - **Each review action is taken only from a state the panel offers it in,** whatever a post claims: - submit from open; - approve from awaiting review; - publish from approved; - reject from awaiting review, checks failed or approved; - revert from published. A post for any other state gets the "moved on" refusal and changes nothing, so a set can't be approved past its checks. - **Revert is idempotent.** Before opening a revert, the page looks for a revert of this set still in progress (open, checks running, checks failed, awaiting review or approved). If there is one, a second click lands on it. `ChangeSetListQuery.Reverts` filters the list by the set a revert undoes. - Two posts at the very same instant can still both open a set. A unique index belongs to the change sets lane, and #2646 asks for it. - **The diff island reads through a scope of its own.** The new PostgreSQL review tests exposed it: on PostgreSQL an async read can finish at once, so the set view sometimes renders `ChangeSetItems` before its own reads are done. The island's prerendered diff then ran on the same request `DbContext` and failed the page with a 500 or a stall. This is the #2642 rule applied to the last component that loads data beside its page. It is also the likely cause of the intermittent `SignedInPageTests` hang on v2. ## Tests - `ReviewActionTests` runs on SQLite and PostgreSQL. - The approve test asserts the stored state is approved. - Each of these posts carries the set's current `Seen` and is refused, leaving the state unchanged: - an approve for a set in checks running, checks failed, open or published; - a publish from awaiting review; - a revert from approved; - a submit from checks failed; - a reject from open. - A second revert of the same published set lands on the first, and only one revert set exists. - Every action's form is refused without the anti-forgery token, and an anonymous post of each goes to sign-in. - Without the guards, the refusal and revert tests fail. `dotnet build -warnaserror`, the unit and bUnit suite and the review, list and queue tests on SQLite and PostgreSQL pass locally. No new package and no new project reference. ## Checklist - [x] Linked to an issue a maintainer has confirmed - [x] Targets `v2` - [x] Tests or docs updated where behaviour changed - [x] No tool-generated co-author trailers or footers
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Closes #2578
What
The third slice of F-DSK (#2422): the review actions on the set view (DSK-03). A reviewer can approve, reject with a reason (CHG-08), publish an approved set and revert a published one (CHG-06). Each action is saved when it is made.
/sets/{id}, offering only what the state allows:Dialogwith a required reason. The directory refuses a blank one, and the stored reason shows on the view.TransitionAsync,RejectAsync,PublishAsyncorRevertAsynconIChangeSetDirectory, which appends the event with the signed-in person as initiator. Then the page shows the set as it is now, with a status line or the refusal.Seen, the id of the last move event of the set the page showed. If the set has moved since, the action is refused with "The set has moved on since this page was shown." Every action's form is always on the page, hidden when not offered, so a post from an older page reaches its handler and gets that message instead of a 400.Why
ICurrentInitiatorneeds no circuit-side variant.Tests
ChangeSetViewTests:Seenis the last move's id.Seenof a page shown before another reviewer approved the set is refused, and nothing is appended.dotnet build -warnaserrorand the full suite pass locally against apostgres:17container as well as SQLite. No new package and no new project reference.Checklist
v2