Skip to content
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

WIP: maintenance workflow documentation #262

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
38f9102
Removed ambiguous `username` URI bit - replaced with a more obvious p…
Ocramius Aug 29, 2018
1922293
Documenting that maintainers can fetch all active pull requests by tw…
Ocramius Aug 29, 2018
6d936fd
Documenting primary responsibility of a maintainer to detect and cate…
Ocramius Aug 29, 2018
a0a93bf
Documenting what a critical fix is
Ocramius Aug 29, 2018
25f9130
Documenting security fixes
Ocramius Aug 29, 2018
d81baf3
Documenting stability purpose
Ocramius Aug 29, 2018
9e2eee8
Maintainers should always evaluate whether a BC break is worth it
Ocramius Aug 29, 2018
fef66f7
Clarifying that `Semantic Versioning` = `SemVer`
Ocramius Aug 29, 2018
1e2f812
Documenting the branch names and branching strategy
Ocramius Aug 29, 2018
d983267
Documenting that automating the maintainer work should be one of the …
Ocramius Aug 29, 2018
a03e176
Documenting the way in which release versions should behave
Ocramius Aug 29, 2018
85fb415
Example graph of the branching structure of a typical doctrine project
Ocramius Aug 29, 2018
272f918
Adding `2.0.x` (mandatory release branch) attached to the `2.0.0` rel…
Ocramius Aug 29, 2018
be1d6d5
Documented release process
Ocramius Aug 29, 2018
268934a
Added deprecation policy link
SenseException Oct 28, 2018
21c9761
Added security policy link
SenseException Oct 28, 2018
5607868
Corrected capitalisation of `Doctrine`
Majkl578 Oct 30, 2018
cd92778
Corrected capitalisation of `Doctrine`
Majkl578 Oct 30, 2018
221807b
Corrected capitalisation of `Doctrine`
Majkl578 Oct 30, 2018
92a6365
Replaced "assuming" with "given" to avoid iterpretation issues in the…
sstok Feb 4, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 166 additions & 7 deletions source/contribute/maintainer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ following:
- Creating release branches.
- Tagging released versions within **master** and release branches.

Automation
----------

Each of the following steps are documented for humans to perform them
manually, but maintainers and contributors are highly encouraged to try
and automate them away into tooling that is commonly available across
the organisation projects, as well as the community at large.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also talked about automating PR merges, after passed builds and approvals (and i.e. no blocking label).
Ideally we should also guard automatic merges by Roave/BackwardCompatibilityCheck that would block auto-merge (ideally as a separate CI integration, not part of the Travis build directly).

Copy link
Member Author

@Ocramius Ocramius Oct 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, Roave BC is a bit too strict, but we can add our (laxer) rules to CI. Also, I need to make it faster before it is introduced.


Setup
-----

Expand All @@ -31,7 +39,7 @@ locally:

.. code-block:: console

$ git clone [email protected]:username/doctrine2.git doctrine2-orm
$ git clone [email protected]:<username>/doctrine2.git doctrine2-orm
Copy link
Member

@morozov morozov Jan 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires an update due to doctrine/orm#7552.

$ cd doctrine2-orm

Fetch dependencies using `composer <https://getcomposer.org/>`_:
Expand Down Expand Up @@ -59,16 +67,167 @@ Optionally, add any additional contributor/maintainer forks, e.g.:

$ git remote add romanb git://github.com/romanb/doctrine2.git
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be reworded to <username> for consistency with the change in git clone ....


You can also fetch all open pull requests via `git fetch` if you
edit your ``.git/config`` as following:

... code-block:: console

[remote "doctrine"]
url = [email protected]:doctrine/doctrine2.git
fetch = +refs/heads/*:refs/remotes/doctrine/*
# add this:
fetch = +refs/pull/*/head:refs/remotes/doctrine/pr/*

Distinguishing features, bugs and critical fixes
------------------------------------------------

The primary role of a maintainer, besides being also a contributor,
is to sort incoming proposals by their category:
SenseException marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As part of this standardization, we SHOULD sync labels across all repositories and also their colors (at least all listed below). Currently it's random.


- **new features** are additions that provide new API or new behavior
that was previously not exposed by the project
- **improvements** are additions that improve existing API by making
it more clear, by improving the usability and performance, or by
verifying existing behavior via refactoring, new tests or static
analysis.
- **bug fixes** are changes to the codebase that do correct invalid
behaviour.
- **critical fixes** are changes to the codebase that correct invalid
behavior that was erroneously introduced, and prevents installation
or usage of the library by a very large portion of the community.
- **security fixes** are changes to the codebase that correct existing
behavior in the codebase that may lead to substantial financial or
personal damage to consumers of the packages due to malicious
attack vectors. Read about our `Security Policy <https://www.doctrine-project.org/policies/security.html>`_
- **deprecations** are changes to the codebase that do mark existing
API as "to be removed in future". Read about our `Deprecation Policy <https://www.doctrine-project.org/policies/deprecation.html>`_
- **backwards-compatibility breakages** (or **BC breaks** in short)
are modifications to the existing API or implementation that would
result in downstream users having to correct their software to
adapt to the new changes. Maintainers should also prevent any
unnecessary BC breaks, and always evaluating if it is worth
introducing them.

Stability and Semantic Versioning
---------------------------------

A maintainer must also always consider that any proposal, regardless
how well tested and verified it could be, brings in some instability.
In order to reduce the amount of defects and/or regressions reaching
downstream users, a maintainer must therefore always consider
carefully where a patch may land.

Packages controlled by the Doctrine organisation are to follow
`Semantic Versioning (SemVer) <https://semver.org/spec/v2.0.0.html>`_
rules, with the famous ``MAJOR.MINOR.PATCH`` naming scheme.

This effectively means:

- **PATCH** only contains **bug fixes**, **security fixes** and
**critical fixes**
- **MINOR** can contain everything that is in **PATCH** plus
**new features**, **improvements** and **deprecations**
- **MAJOR** can contain all of the above plus **BC breaks**

Whilst it is possible to automate some of these decisions, humans
are still better at categorising these changes due to the amount of
nuances that are involved in the software development process.

Branching Model
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section needs an update after the decision at the EUFOSSA hackathon. See https://github.com/doctrine/automatic-releases#todos for the process.

---------------

Merging topic branches:
In order to maintain all the stability invariants that SemVer imposes,
it is vital that maintainers know where to merge incoming patches.

Packages in the Doctrine organisation should use the following branching
structure:

* ``develop`` - extremely unstable, points at the next planned
**MAJOR** release, may be rebased in order to speed up individual
maintainers prototyping new changes. Changes on ``develop`` can
be radical, and should not be relied upon.
* ``master`` - always to be considered as the next planned **MAJOR**
or **MINOR** release (depending on team internal agreement).
Consumers should not rely on ``master`` unless they are prepared
to adapt their codebase at every potentially breaking change.
* ``MAJOR.MINOR.x`` - always to be considered the next planned
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering that we currently mostly use MAJOR.MINOR, what is the motivation to use MAJOR.MINOR.x?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ORM, DBAL and common started using MAJOR.MINOR with 2.2, while the rest either doesn't have enough branches for it to be called a model or are using MAJOR.MINOR.x.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fwiw either branch name format works with the website.

**PATCH** release. Maintainers should keep these (multiple) branches
stable. The base of these branches MUST be the ``MAJOR.MINOR.0`` tag.
Without a pre-existing tag, these branches should not exist

Releasing packages
------------------

**MAJOR.0.0** and **MAJOR.MINOR.0** releases **MUST** be tagged from
``master``.

When tagging a new **MAJOR.0.0** or **MAJOR.MINOR.0** release, a
corresponding **MAJOR.MINOR.x** branch should be branched off the tag.

**MAJOR.MINOR.1+** releases must be tagged from the corresponding
``MAJOR.MINOR.x`` branch.

This effectively means that a typical Doctrine package should have a
git graph like following:

.. code-block:: console

----- develop
/
1.0.0 ----- 1.1.0 ----- 2.0.0 ------ master
| | \
| | ----- 2.0.x
| \
| ----- 1.1.1 ----- 1.1.2 ----- 1.1.x
\
----- 1.0.1 ----- 1.0.2 ----- 1.0.x

Preparing a release
-------------------

- Topic branches **must** merge into **master** and/or any affected
release branches.
- Merging a topic branch puts it into the *next* release, that is the
next release created from **master** and/or the next patch release
created from a specific release branch.
Given that all tasks for a planned release are completed, a
maintainer would then be in the position of preparing a git tag,
which for a Doctrine project also corresponds to a release.

To do that:

- ensure that all known introduced **BC Breaks** are documented
in ``UPGRADE.md``.
- ensure that the automated tests for the branch from which
a release has to be tagged are passing.
- prepare a release description, which should:
- list all patches
- describe the points of major relevance in the patch
maintainers may want to use a tool such
as `weierophinney/changelog_generator <https://github.com/weierophinney/changelog_generator>`_
or `jwage/changelog-generator <https://github.com/jwage/changelog-generator>`_)
in order to generate such release notes

Then it is possible to tag a release.

Please note that tags *MUST* be signed. Unsigned releases will be
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Please note that tags *MUST* be signed. Unsigned releases will be
Please note that tags **MUST** be GPG-signed by either the maintainer's or Doctrine's GPG key.
Unsigned releases will be

As discussed, as part of automating releases. we may introduce a Doctrine GPG key that will be signed by all maintainers and internally used to create tags.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the anonymity of a shared GPG key - anyone could sign a malicious tag and hide between the shared identity. I'd advocate against that and suggest we keep signing with individual keys.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't be anonymous: it would require trust from the doctrine maintainers

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at one tag, would I be able to tell which maintainer signed the tag?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it would be done by tooling, not by a person

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if it's done by tooling, as long as it's triggered by a human (./bin/doctrine release a.b.c) it should be signed by that human. Otherwise, there's no significant advantage to signing with the GitHub key, except that we're maintaining our own key for the sake of it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Key K is signed as trusted by maintainer A, B, C. Subkey K1 is deployed to a (safe) environment, where the automation takes over tagging and releasing when things are triggered. There won't be a ./bin/doctrine release a.b.c: the aim is to remove it, and completely automate releases as merges happen. Yes, that would be a lot of releases :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's feasible at all at the current time, hence my opposition to this. Let's take things one at a time. If we ever get to the point where we want to do a release on every merge, we can bring this up again. Until that point, let's leave the original suggestion in: people sign tags with their GPG key instead of relying on GitHubs default key.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of relying on GitHubs default key.

Yeah, this should never be done anyway 👍

removed and replaced.

For a new patch release,
this is the workflow (here with **MAJOR** = 5, **MINOR** = 3 and **PATCH** = 1):

.. code-block:: console

$ git checkout 5.3.x
$ git pull --ff-only
$ git tag -s 5.3.1 -F my-release-notes.txt --cleanup=verbatim
$ git push origin 5.3.1

To release a new minor or major version, the workflow starts from
``master``:

.. code-block:: console

$ git checkout master
$ git pull --ff-only
$ git tag -s 6.2.0 -F my-release-notes.txt --cleanup=verbatim
$ git checkout -b 6.2.x
$ git push origin 6.2.0 6.2.x

Configuring Remotes
-------------------
Expand Down