Add configuration to disable DRAFT workflow

Draft workflow breaks replication and some sites might want to disable it
for all projects. While it is already possible to block new draft changes
from be uploaded, it is still possible to delete existing drafts.

This change disable draft workflow completely.

Change-Id: Iabae835a26caab5ea4c10701c75c9b0b84882f86
This commit is contained in:
David Ostrovsky 2014-01-28 18:40:48 +01:00
parent 6601f2db97
commit 1b61dc74d0
6 changed files with 51 additions and 7 deletions

View File

@ -796,6 +796,13 @@ If 0 the update polling is disabled.
+
Default is 30 seconds.
[[change.allowDrafts]]change.allowDrafts::
+
Allow drafts workflow. If set to false, drafts cannot be created,
deleted or published.
+
Default is true.
[[changeMerge]]
=== Section changeMerge

View File

@ -24,12 +24,15 @@ import com.google.gerrit.reviewdb.client.Change.Status;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.change.DeleteDraftChange.Input;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.Config;
import java.io.IOException;
public class DeleteDraftChange implements
@ -39,13 +42,16 @@ public class DeleteDraftChange implements
protected final Provider<ReviewDb> dbProvider;
private final ChangeUtil changeUtil;
private final boolean allowDrafts;
@Inject
public DeleteDraftChange(Provider<ReviewDb> dbProvider,
PatchSetInfoFactory patchSetInfoFactory,
ChangeUtil changeUtil) {
ChangeUtil changeUtil,
@GerritServerConfig Config cfg) {
this.dbProvider = dbProvider;
this.changeUtil = changeUtil;
this.allowDrafts = cfg.getBoolean("change", "allowDrafts", true);
}
@Override
@ -60,6 +66,10 @@ public class DeleteDraftChange implements
throw new AuthException("Not permitted to delete this draft change");
}
if (!allowDrafts) {
throw new ResourceConflictException("Draft workflow is disabled.");
}
try {
changeUtil.deleteDraftChange(rsrc.getChange().getId());
} catch (NoSuchChangeException e) {
@ -75,7 +85,8 @@ public class DeleteDraftChange implements
return new UiAction.Description()
.setTitle(String.format("Delete draft change %d",
rsrc.getChange().getChangeId()))
.setVisible(rsrc.getChange().getStatus() == Status.DRAFT
.setVisible(allowDrafts
&& rsrc.getChange().getStatus() == Status.DRAFT
&& rsrc.getControl().canDeleteDraft(dbProvider.get()));
} catch (OrmException e) {
throw new IllegalStateException(e);

View File

@ -26,6 +26,7 @@ import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.change.DeleteDraftPatchSet.Input;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.NoSuchChangeException;
@ -34,6 +35,8 @@ import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.Config;
import java.io.IOException;
public class DeleteDraftPatchSet implements RestModifyView<RevisionResource, Input>,
@ -44,14 +47,17 @@ public class DeleteDraftPatchSet implements RestModifyView<RevisionResource, Inp
protected final Provider<ReviewDb> dbProvider;
private final PatchSetInfoFactory patchSetInfoFactory;
private final ChangeUtil changeUtil;
private final boolean allowDrafts;
@Inject
public DeleteDraftPatchSet(Provider<ReviewDb> dbProvider,
PatchSetInfoFactory patchSetInfoFactory,
ChangeUtil changeUtil) {
ChangeUtil changeUtil,
@GerritServerConfig Config cfg) {
this.dbProvider = dbProvider;
this.patchSetInfoFactory = patchSetInfoFactory;
this.changeUtil = changeUtil;
this.allowDrafts = cfg.getBoolean("change", "allowDrafts", true);
}
@Override
@ -66,6 +72,10 @@ public class DeleteDraftPatchSet implements RestModifyView<RevisionResource, Inp
throw new ResourceConflictException("Patch set is not a draft.");
}
if (!allowDrafts) {
throw new ResourceConflictException("Draft workflow is disabled.");
}
if (!rsrc.getControl().canDeleteDraft(dbProvider.get())) {
throw new AuthException("Not permitted to delete this draft patch set");
}
@ -84,7 +94,8 @@ public class DeleteDraftPatchSet implements RestModifyView<RevisionResource, Inp
return new UiAction.Description()
.setTitle(String.format("Delete draft revision %d",
rsrc.getPatchSet().getPatchSetId()))
.setVisible(rsrc.getPatchSet().isDraft()
.setVisible(allowDrafts
&& rsrc.getPatchSet().isDraft()
&& rsrc.getControl().canDeleteDraft(dbProvider.get())
&& psCount > 1);
} catch (OrmException e) {

View File

@ -27,6 +27,7 @@ import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.change.Publish.Input;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.mail.PatchSetNotificationSender;
import com.google.gerrit.server.notedb.ChangeUpdate;
@ -36,6 +37,8 @@ import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.Config;
import java.io.IOException;
public class Publish implements RestModifyView<RevisionResource, Input>,
@ -48,18 +51,21 @@ public class Publish implements RestModifyView<RevisionResource, Input>,
private final PatchSetNotificationSender sender;
private final ChangeHooks hooks;
private final ChangeIndexer indexer;
private final boolean allowDrafts;
@Inject
public Publish(Provider<ReviewDb> dbProvider,
ChangeUpdate.Factory updateFactory,
PatchSetNotificationSender sender,
ChangeHooks hooks,
ChangeIndexer indexer) {
ChangeIndexer indexer,
@GerritServerConfig Config cfg) {
this.dbProvider = dbProvider;
this.updateFactory = updateFactory;
this.sender = sender;
this.hooks = hooks;
this.indexer = indexer;
this.allowDrafts = cfg.getBoolean("change", "allowDrafts", true);
}
@Override
@ -74,6 +80,10 @@ public class Publish implements RestModifyView<RevisionResource, Input>,
throw new AuthException("Cannot publish this draft patch set");
}
if (!allowDrafts) {
throw new ResourceConflictException("Draft workflow is disabled.");
}
PatchSet updatedPatchSet = updateDraftPatchSet(rsrc);
Change updatedChange = updateDraftChange(rsrc);
ChangeUpdate update = updateFactory.create(rsrc.getControl(),

View File

@ -1180,8 +1180,9 @@ public class ReceiveCommits {
}
if (magicBranch.isDraft()
&& projectControl.controlForRef("refs/drafts/" + ref)
.isBlocked(Permission.PUSH)) {
&& (!receiveConfig.allowDrafts
|| projectControl.controlForRef("refs/drafts/" + ref)
.isBlocked(Permission.PUSH))) {
errors.put(Error.CODE_REVIEW, ref);
reject(cmd, "cannot upload drafts");
return;

View File

@ -24,6 +24,7 @@ import org.eclipse.jgit.lib.Config;
class ReceiveConfig {
final boolean checkMagicRefs;
final boolean checkReferencedObjectsAreReachable;
final boolean allowDrafts;
@Inject
ReceiveConfig(@GerritServerConfig Config config) {
@ -33,5 +34,8 @@ class ReceiveConfig {
checkReferencedObjectsAreReachable = config.getBoolean(
"receive", null, "checkReferencedObjectsAreReachable",
true);
allowDrafts = config.getBoolean(
"change", null, "allowDrafts",
true);
}
}