mydrive / capistrano-deploytags

Add timestamped Git tags for each environment on deployment
BSD 2-Clause "Simplified" License
122 stars 20 forks source link

Get rid of the -latest tag #2

Closed hobodave closed 12 years ago

hobodave commented 12 years ago

Hi, thanks for the great plugin!

I've found a rather significant annoyance with the implementation and use of the "-latest" tag. I think the tag should be removed altogether. Tags should almost never be reused, the only sane exception to this is if the tag is local to you and has never been shared. See: http://www.kernel.org/pub/software/scm/git/docs/v1.7.3/git-tag.html (On Re-tagging)

When your plugin does this it causes lots of headaches when working on a project with a team of any size greater than 1. Here is the headache scenario:

  1. Alex: cap production deploy - Alex deploys revision abc123 to production
    • tag production-2012.05.30-000000 created (referencing abc123) and pushed to origin
    • tag production-latest created (referencing abc123) and pushed to origin
  2. Alex: cap staging deploy -- Alex deploys revision abc123 to staging
    • tag staging-2012.05.30-000000 created (referencing abc123) and pushed to origin
    • tag staging-latest created (referencing abc123) and pushed to origin
  3. Bob: git pull -- Bob now has the following tags -- tag (revision)
    • production-2012.05.30-000000 (abc123)
    • production-latest (abc123)
    • staging-2012.05.30-000000 (abc123)
    • staging-latest (abc123)
  4. Alex: Modifies code, commits, and deploys to staging -- cap staging deploy
    • tag staging-2012.05.30-010000 created (ref. def456) and pushed to origin
    • tag staging-latest deleted, recreated (ref. def456) and force pushed to origin
  5. Bob: Modifies code, commits, and deploys hotfix to production -- cap production deploy

    • tag production-2012.05.31-000000 created (ref. ghi789) and pushed to origin
    • tag production-latest deleted, recreated (ref. ghi789) and pushed to origin
    • Capistrano deploy errors out with the following:

      To git@github.com:example/central.git
      * [new tag]         production-2012.05.31-000000 -> staging-2012.05.31-000000
      * [new tag]         production-latest -> production-latest
      ! [rejected]        staging-latest -> staging-latest (non-fast-forward)
      error: failed to push some refs to 'git@github.com:example/central.git'
      To prevent you from losing history, non-fast-forward updates were rejected
      Merge the remote changes (e.g. 'git pull') before pushing again.  See the
      'Note about fast-forwards' section of 'git push --help' for details.```

The problem is that Git will never overwrite a local tag with a changed origin tag. Thus other developers will never see the changed -latest tags unless they deploy to the environment, or manually delete the tag before deploying.

Neither one of those seem to be reasonable workarounds. I'm actually not sure I see the utility of a -latest tag at all. You can always find the "latest" tag with something as simple as: $ git tag -l staging-* | tail -n 1. You could certainly add this as a Capistrano task if you still wanted to provide some access to the "latest" tag. Juggling a tag name among several commits however is a bad practice and should not be used in a library.

Thanks for your consideration and work on this valuable plugin.

-Dave

relistan commented 12 years ago

Hi David, thanks for the bug report. The reason for the *-latest tag is that it is used by the capistrano-detect-migrations plugin. But you are right that it causes problems in a multi-member team (we have seen this as well and I just haven't written a fix for it yet). I think you are right that the solution is to remove the tag and simply sort the existing dated tags after running a fetch --tags to make sure the latest tags are present. Another advantage of this is that it allows that logic to reside in capistrano-detect-migrations which is where it is primarily used. I'll take a look at writing in fix in the next day or two.

relistan commented 12 years ago

I just went ahead and cranked this out now. Latest 0.6.0 version on rubygems now has removed *-latest tagging. capistrano-detect-migrations has been updated to handle this functionality internally.

hobodave commented 12 years ago

Thanks @relistan!