Document how features in Gerrit can be deprecated

Gerrit is growing in size in terms of lines of code and features. At the
same time we try to keep the added functionality stable, so that users
can realy on it. Sometimes, features need to be deprecated to aid
further growth or keep the functionality maintainable.

This commit adds the first version of a guideline intended to serve as a
contract between developers, users and administrators.

Change-Id: I7aecbeb2ba57267d7dc4f3b82427af144d34da31
This commit is contained in:
Patrick Hiesel 2018-09-04 14:33:11 +02:00
parent 460a3f3c35
commit 14f5aec25b
3 changed files with 78 additions and 0 deletions

View File

@ -368,6 +368,36 @@ months after the branch was cut. This should happen on the master branch to ensu
that they are vetted long enough before they go into a release and we can be sure
that the update doesn't introduce a regression.
[[deprecating-features]]
=== Deprecating features
Gerrit should be as stable as possible and we aim to add only features that last.
However, sometimes we are required to deprecate and remove features to be able
to move forward with the project and keep the code-base clean. The following process
should serve as a guideline on how to deprecate functionality in Gerrit. Its purpose
is that we have a structured process for deprecation that users, administrators and
developers can agree and rely on.
General process:
* Make sure that the feature (e.g. a field on the API) is not needed anymore or blocks
further development or improvement. If in doubt, consult the mailing list.
* If you can provide a schema migration that moves users to a comparable feature, do
so and stop here.
* Mark the feature as deprecated in the documentation and release notes.
* If possible, mark the feature deprecated in any user-visible interface. For example,
if you are deprecating a Git push option, add a message to the Git response if
the user provided the option informing them about deprecation.
* Annotate the code with `@Deprecated` and `@RemoveAfter(x.xx)` if applicable.
Alternatively, use `// DEPRECATED, remove after x.xx` (where x.xx is the version
number that has to be branched off before removing the feature)
* Gate the feature behind a config that is off by default (forcing admins to turn
the deprecated feature on explicitly).
* After the next release was branched off, remove any code that backed the feature.
You can optionally consult the mailing list to ask if there are users of the feature you
wish to deprecate. If there are no major users, you can remove the feature without
following this process and without the grace period of one release.
GERRIT
------
Part of link:index.html[Gerrit Code Review]

View File

@ -365,6 +365,17 @@ link:https://gerrit.googlesource.com/bazlets/+/master/gerrit_api.bzl#8[gerrit_ap
must reference the new version. Upload a change to bazlets repository with
api version upgrade.
[[clean-up-on-master]]
=== Clean up on master
Once you are done with the release, check if there are any code changes in the
master branch that were gated on the next release. Mostly, these are
feature-deprecations that we were holding off on to have a stable release where
the feature is still contained, but marked as deprecated.
See link:dev-contributing.html#deprecating-features[Deprecating features] for
details.
GERRIT
------
Part of link:index.html[Gerrit Code Review]

View File

@ -0,0 +1,37 @@
// Copyright (C) 2018 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.extensions.annotations;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import com.google.inject.BindingAnnotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Annotation for features that are deprecated, but still present to adhere to the one-release-grace
* period we promised to users.
*/
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(SOURCE)
@BindingAnnotation
public @interface RemoveAfter {
/**
* Version after which the annotated functionality can be removed. Once the referenced version was
* branched off, the annotated code can be removed.
*/
String value();
}