[openstack-dev] [release][reno][infra] merging tags between branches is confusing our release notes

Doug Hellmann doug at doughellmann.com
Wed Jun 8 19:35:23 UTC 2016

Excerpts from John Dickinson's message of 2016-06-08 11:30:03 -0700:
> On 8 Jun 2016, at 11:13, Doug Hellmann wrote:
> > tl;dr: The switch from pre-versioning to post-versioning means that
> > sometimes master appears to be older than stable/$previous, so we
> > merge "final" tags from stable/$previous into master to make up for
> > it. This introduces versions into the history of master that aren't
> > *really* there, but git sees them and so does reno. That, in turn,
> > means that the release notes generated from master may place some
> > notes in the wrong version, suggesting that something happened
> > sooner than it did. I propose that we stop merging tags, and instead
> > introduce a new tag on master after we create a branch to ensure
> > that the version number there is always higher than stable/$previous.
> >
> >
> > Background
> > ----------
> >
> > Over the last year or so we've switched from pre-versioning (declaring
> > versions in setup.cfg) to post-versioning (relying solely on git
> > tags for versions). This made the release process simpler, because
> > we didn't need to worry about synchronizing the change of version
> > strings within setup.cfg as we created our branches. A side-effect,
> > though, is that the version from which we tag appears on both
> > branches. That means that stable/$previous and master both have the
> > same version for some period of time, and then stable/$previous
> > receives a final tag and has a version newer than master. To
> > compensate, we merge that final tag from stable/$previous into
> > master (taking only the tag, without any of the code changes), so
> > that master again has the same version.
> >
> >
> > The Problem
> > -----------
> >
> > The tag may be merged into master after other changes have landed
> > in master but not stable/$previous, and if those changes include
> > release notes then reno will associate them with the newly merged
> > tag, rather than the correct version number.
> >
> > Here's an example I have been using to test reno. In it, 3 separate
> > reno notes are created on two branches. Note 1 is on master when
> > it is tagged 1.0.0. Then master is branched and note 2 is added to
> > the branch and tagged 1.1.0. Then the tag is merged into master and
> > note 3 is added.
> >
> >   * af93946 (HEAD -> master, tag: 2.0.0) add slug-0000000000000003.yaml
> >   * f78d1a2 add ignore-2.txt
> >   *   4502dbd merge 1.1.0 tag into master
> >   |\
> >   | * bf50a97 (tag: 1.1.0, test_merge_tags) add slug-0000000000000002.yaml
> >   * | 1e4d846 add ignore-1.txt
> >   |/
> >   * 9f481a9 (tag: 1.0.0) add slug-0000000000000001.yaml
> >
> > Before the tag is applied to note 3, it appears to be part of 1.1.0,
> > even though it is not from the branch where that version was created
> > and the version 1.1.0 is included in the release notes for master,
> > even though that version should not really be a part of that series.
> >
> > Technically reno is doing the right thing, because even "git describe"
> > honors the merged tag and treats commit f78d1a2 as 1.1.0-4-gaf93946.
> > So because we've merged the version number into a different series
> > branch, that version becomes part of that series.
> >
> >
> > The Proposal
> > ------------
> >
> > We should stop merging tags between branches, at all. Then our git
> > branches will be nice and linear, without merges, and reno will
> > associate the correct version number with each note.
> >
> > To compensate for the fact that master will have a lower version
> > number after the branch, we can introduce a new alpha tag on master
> > to raise its version. So, after creating stable/$series from version
> > X.0.0.0rc1, we would tag the next commit on master with X+
> > All subsequent commits on master would then be considered to be
> > part of the X+1.0.0 series.
> This seems to go back to the essence of pre-versioning. Instead of updating a string in a file, you've updated it as a tag. You've still got the coordination issues at release to deal with (when and what to tag) and the issue of knowing what the next release is before you've landed any patches that will be in that release.

This only affects milestone-based projects, and all of them are
currently raising their major version number each cycle to indicate the
cycle boundary. So it's easy to know what the next version will be.

It's not quite as burdensome as the post-versioning thing we were
doing because it's not necessary to commit something *before*
creating the branch or starting the release candidate phase.

> Isn't the reason that the branch is merged back in because otherwise per can't generate a valid version number?

I don't think it's related to versions being "valid," but to making
things feel less confusing to human consumers at the expense of
(what I think is) giving a misleading picture of the version history.

We started merging the tags between branches because the version
that ends up in the tarball generated from patches merging into
master is lower than the version in the tarball generated from the
stable branch, after the stable branch has received the "final" tag
for the release (master still has a 0rc1 tag for the same version
that is final on the branch). This is confusing to humans, but if
those humans have not set up automated systems to install or otherwise
consume artifacts for the same project from multiple branches it
should not confuse any computers.

> You've "solved" that by hiding the release version number behind the new *a1 tag. Therefore, for any commit on the master branch, the only ancestor commits that are tagged will have the *a1 tags, and the actual release tags will never be reachable by walking up parent commits (assuming there is at least one commit on a release branch, which seems normal).

The commit created when the tag is merged into master isn't accurate,
because it only includes the tag and not the code. So what we're
doing today is just inserting a version number at an arbitrary place
in the history of master (whatever happens to be HEAD when the merge
is done). That means the code changes between the branch and the
tag on master is very likely to be different from the code changes
between the branch and the tag on the branch, where the actual
release was created, because not everything from master will have
been back-ported to the branch.

So, if you're using the git DAG to find the version and what it
contains, as reno does by traversing a branch's history, you get
the wrong answer.

> >
> > Libraries and other projects that follow the cycle-with-intermediary
> > release model won't need this treatment, because we're not using
> > alpha or beta versions for them and they are tagged more often than
> > the projects following the cycle-with-milestones model.
> >
> >
> > Possible Issues
> > ---------------
> >
> > We will be moving back to a situation where we have to orchestrate
> > multiple operations when we create branches. Adding an extra tag
> > isn't a lot of work, though, and it doesn't really matter what the
> > commit is that gets the tag, so if there's nothing on master beyond
> > the point where a branch needs to be created we can add a minor
> > change somewhere just to have something to tag.
> >
> > fungi pointed out that if we backport anything by using a fast-forward
> > merge from master to stable/$previous, we will pull the newer version
> > number back into the older series. We already have that issue,
> > today, though, for anything backported after the first milestone.
> > So while we're shrinking the safe window period, this is not a new
> > problem.
> >
> > Some cycle-with-milestone projects may not merge commits into master
> > very soon after their branches are created. We can address that by
> > waiting, or by introducing a small commit just for the purpose of
> > having something to tag.
> >
> >
> > Alternatives
> > ------------
> >
> > Do nothing and live with some of our early release notes in a version
> > being "not quite right." I don't consider this acceptable.
> >
> > Switch back to pre-versioning. We dropped this for a good reason,
> > it makes synchronizing all of the actions needed to create a release
> > branch a real hassle.

I left out two options:

Do not branch from master until the final release for a project is
tagged. This is not likely to be desirable because it halts development
on master during the release candidate period.

Teach reno to ignore these special sorts of tags so that it gives the
"correct" results. I don't like this approach because it means we're
making reno ignore the correct git history to accommodate something that
we do but that I would not expect other users of reno to do.

> >
> >
> > If everyone agrees that this is a reasonable change to make, I will
> > update our release documentation and do the work to turn of the tag
> > merging job in project-config.
> >
> > Doug
> >
> > __________________________________________________________________________
> > OpenStack Development Mailing List (not for usage questions)
> > Unsubscribe: OpenStack-dev-request at lists.openstack.org?subject:unsubscribe
> > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev

More information about the OpenStack-dev mailing list