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

Latest tag is not used for versioning when multiple tags exist #13

Closed
rpanderson opened this issue May 17, 2020 · 3 comments
Closed

Latest tag is not used for versioning when multiple tags exist #13

rpanderson opened this issue May 17, 2020 · 3 comments
Labels
bug Something isn't working

Comments

@rpanderson
Copy link
Owner

rpanderson commented May 17, 2020

The problem

  1. Tag release candidate e.g. v0.3.1rc2 and push this tag.
  2. Candidate is satisfactory, tag same commit for release v0.3.1 and push.
  3. During workflow, version is incorrectly deemed to be 0.3.1rc2.

Example: https://github.com/rpanderson/workflow-sandbox/runs/682565320 (on: create tag v0.3.1).

What's happening here?

  • actions/checkout@v2 does a shallow fetch (at the time of writing).
  • So that (untagged) development versions can be labelled, we do an unshallow operation immediately after.
  • On a tag creation event, actions/checkout@v2 targets a specific tag, for example:
git -c protocol.version=2 fetch --no-tags --prune --progress --no-recurse-submodules --depth=1 origin +59651b5cf3dcdef9095398c93dfe0be8343d06b5:refs/tags/v0.3.1
git checkout --progress --force refs/tags/v0.3.1
  • If setuptools_scm ran on this shallow checkout, everything would be fine of course (there's only one tag).
  • But the unshallow step does this:
git fetch --prune --unshallow
From https://github.com/rpanderson/workflow-sandbox
 * [new branch]      requirements_files -> origin/requirements_files
 * [new tag]         v0.1.4             -> v0.1.4
 * [new tag]         v0.2.0             -> v0.2.0
 * [new tag]         v0.3.1rc2          -> v0.3.1rc2
 * [new tag]         v0.1.0             -> v0.1.0
 * [new tag]         v0.1.0rc1          -> v0.1.0rc1
 * [new tag]         v0.1.0rc2          -> v0.1.0rc2
 * [new tag]         v0.1.0rc3          -> v0.1.0rc3
 * [new tag]         v0.1.0rc4          -> v0.1.0rc4
 * [new tag]         v0.1.0rc5          -> v0.1.0rc5
 * [new tag]         v0.1.0rc6          -> v0.1.0rc6
 * [new tag]         v0.1.0rc7          -> v0.1.0rc7
 * [new tag]         v0.1.0rc8          -> v0.1.0rc8
 * [new tag]         v0.1.0rc9          -> v0.1.0rc9
 * [new tag]         v0.1.2             -> v0.1.2
 * [new tag]         v0.1.3             -> v0.1.3
 * [new tag]         v0.2.0rc1          -> v0.2.0rc1
 * [new tag]         v0.3.0             -> v0.3.0
 * [new tag]         v0.3.0rc1          -> v0.3.0rc1
 * [new tag]         v0.3.1rc1          -> v0.3.1rc1
v0.3.1rc2
commit 59651b5cf3dcdef9095398c93dfe0be8343d06b5

Same commit, different tag. Reproducing this locally, one can inspect two types of tag ordering native to git, creatordate and committerdate.

git tag --sort=-creatordate
v0.3.1rc2
v0.3.1
v0.3.1rc1
v0.3.0
v0.3.0rc1
v0.2.0
v0.2.0rc1
...

The earlier tag (v0.3.1rc2) takes precedence. Presumably because it got 'created' in the local checkout more recently, i.e. (simple) tag creation is a local concept. But from some cursory testing, it's how setuptools_scm appears to be getting the most recent tag.

The committerdate ordering, on the other hand, returns the correct ordering:

git tag --sort=-committerdate
v0.3.1
v0.3.1rc2
v0.3.1rc1
v0.3.0rc1
v0.3.0
...

Q: Is this the same for annotated tags?

@SvenRtbg commented on Mar 27, 2017
Tagging with annotated tags not only adds the timestamp and committer account to this tag (and a message that probably nobody cares about), but also allows Git to pick the more recent tag, i.e. the one added later in time, when running git describe.

Solutions

  1. Use a dummy commit to avoid multiple tags.
  2. Don't unshallow for tag creation events.
  3. (?) Use annotated tags.
  4. Propose/implement that setuptools_scm sort tags by committerdate.

Option 2 seems the best here, as the unshallow is unnecessary when the workflow is triggered off tag creation events.

The state of actions/checkout

Tagging seems to be a hot topic there, right now!

The solution/conclusions here may change if any of these are resolved.

How does versioneer deal with this scenario?

Since 2011, warner/python-versioneer has dealt with multiple tags. See, e.g. python-versioneer/python-versioneer@0a78af3. This apparently just uses sorted() on the refs which seems to suffice, although I have no experience with it on Github Actions.

This doesn't work however for the example atop python-versioneer/python-versioneer#79, i.e. 1.0.0 is chosen over 1.0.1 (although surely this would be a case of erroneous tagging and one of these could/should be deleted).

Curiously, @warner points out in a reply to this PR:

Hm, one other (perhaps more common) way this might happen is if a release candidate gets promoted to the final release without additional changes, so you'd have "v1.0rc1" and "v1.0" tags on the same commit. (This is probably the ideal outcome in any process that involves "release candidates": making no changes between your last candidate and the final release).

Yet in this example, v1.0 would be used, by the very code they committed 4 years prior (above). Maybe I'm missing something. This is the same code kicking around a lot of projects using versioneer, including those who've vendored it. And it seems to work for the case of release candidate not being promoted over release.

@rpanderson rpanderson added the bug Something isn't working label May 17, 2020
@rpanderson rpanderson changed the title Created tag is not used for versioning when multiple tags exist Latest tag is not used for versioning when multiple tags exist May 17, 2020
@rpanderson rpanderson reopened this May 17, 2020
@rpanderson
Copy link
Owner Author

rpanderson commented May 17, 2020

Resolved by 9f6bbd6 (tagged as v0.3.3rc1 and v0.3.3).

@rpanderson
Copy link
Owner Author

See actions/checkout#258.

@chrisjbillington
Copy link
Collaborator

chrisjbillington commented May 24, 2020

I guess that will let us change to something like:

      - name: Checkout
        uses: actions/checkout@v<next-version>
        with:
          fetch-depth: 0

      - name: Ignore HEAD tags
        if: github.event.ref_type != 'tag'
        run: git tag -d $(git tag --points-at HEAD)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants