Search code examples
tfsgithookspivotaltracker

Pivotal tracker story is not getting updated after code push


We had pivotal tracker integrated with GitHub and when we used to commit with story id, it used to update the story with a commit message update story status.

We recently migrated to Team Foundation Server from GitHub and that integration is not working anymore.

Looks like there is no integration App exists yet.

Is there a programmatic way of doing it?


Solution

  • Create file named pre-push (without any extension) and put it under ./.git/hooks/ folder inside your repo. This folder should already exist if it's a valid repo. Copy paste following code in the file. Don't forget to replace the API token value in the following code -

    #!/usr/bin/env ruby
    # encoding: UTF-8
    
    require 'net/https'
    require 'json'
    
    class GitLogs
      attr_accessor :raw_log, :commit_data, :commit, :author, :message, :refs
    
      def initialize
        self.commit = 'Commit: ' + `git log -1 --pretty=format:%h`.force_encoding('utf-8')
        self.author = 'Author: ' + `git log -1 --pretty=format:%aN`.force_encoding('utf-8')
        self.message = 'Message: ' + `git log -1 --pretty=format:%s`.force_encoding('utf-8')
        self.refs = 'Refs: ' + `git log -1 --pretty=format:%d`.force_encoding('utf-8')
    
        # Example git formatted log output:
        #
        # Commit: 8872e8fe03a10238d7be84d78813874d79ce0c3d
        # Author: John Doe <john.doe@unknown.com>
        # Message: [#90743834] test new v5 hook addition
        # Refs:  (HEAD, feature/hook-test)
    
        parse!
        self
      end
    
      def parse!
        self.commit_data = GitLog.new(self.commit, self.author, self.message, self.refs)
      end
    
      def pivotal_sync!
        Pivotal.new(commit_data).send! if commit_has_story_id?
      end
    
      def commit_has_story_id?
        # somewhere between square brackets there has to be a hash followed by multiple digits
        !commit_data.message.scan(/\[*+\#(\d+)\D?(.*)\]/).empty?
      end
    
    end
    
    class GitLog
      attr_accessor :hash, :author, :message, :refs
    
      def initialize hash, author, message, refs
        self.hash     = hash
        self.author   = author
        self.refs     = refs
        self.message  = message
    
        updated_message
      end
    
      def updated_message
        return message
      end
    
      def to_json
        { source_commit:
          { commit_id:  self.hash,
            author:     self.author,
            message:    self.message,
          }
        }.to_json
      end
    end
    
    class Pivotal
      attr_accessor :git_log, :tracker_token
    
      BASE_URI = URI('https://www.pivotaltracker.com/')
    
      def initialize git_log
        self.git_log        = git_log
        self.tracker_token  = get_token
      end
    
      def get_token
        'YOUR APT TOKEN GOES HERE. CAN GET IT FROM https://www.pivotaltracker.com/profile'
      end
    
      def send!
        https = Net::HTTP.start(BASE_URI.host, 443, {
          use_ssl:      true,
          verify_mode:  OpenSSL::SSL::VERIFY_NONE
        })
    
        request = Net::HTTP::Post.new('/services/v5/source_commits')
        request['X-TrackerToken'] = tracker_token
        request['Content-type']   = 'application/json'
        request.body              = git_log.to_json
    
        response                  = https.request(request)
      end
    end
    
    GitLogs.new().pivotal_sync!