pullermann 1.0.6 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/pullermann/pullermann.rb +47 -46
- metadata +7 -6
| @@ -7,23 +7,25 @@ class Pullermann | |
| 7 7 | 
             
                            :rerun_on_source_change,
         | 
| 8 8 | 
             
                            :rerun_on_target_change,
         | 
| 9 9 | 
             
                            :prepare_block,
         | 
| 10 | 
            -
                            : | 
| 11 | 
            -
                            : | 
| 10 | 
            +
                            :exec_block,
         | 
| 11 | 
            +
                            :logger,
         | 
| 12 | 
            +
                            :success
         | 
| 12 13 |  | 
| 13 14 | 
             
              # Allow configuration blocks being passed to Pullermann.
         | 
| 15 | 
            +
              # See the README.md for examples on how to call this method.
         | 
| 14 16 | 
             
              def self.setup
         | 
| 15 17 | 
             
                yield main_instance
         | 
| 16 18 | 
             
              end
         | 
| 17 19 |  | 
| 18 | 
            -
              def  | 
| 20 | 
            +
              def preparation(&block)
         | 
| 19 21 | 
             
                self.prepare_block = block
         | 
| 20 22 | 
             
              end
         | 
| 21 23 |  | 
| 22 | 
            -
              def  | 
| 23 | 
            -
                self. | 
| 24 | 
            +
              def execution(&block)
         | 
| 25 | 
            +
                self.exec_block = block
         | 
| 24 26 | 
             
              end
         | 
| 25 27 |  | 
| 26 | 
            -
              # The main Pullermann task. Call this to  | 
| 28 | 
            +
              # The main Pullermann task. Call this to run your code.
         | 
| 27 29 | 
             
              def self.run
         | 
| 28 30 | 
             
                main_instance.run
         | 
| 29 31 | 
             
              end
         | 
| @@ -31,24 +33,20 @@ class Pullermann | |
| 31 33 | 
             
              def run
         | 
| 32 34 | 
             
                # Populate variables and setup environment.
         | 
| 33 35 | 
             
                configure
         | 
| 36 | 
            +
                self.prepare_block.call
         | 
| 34 37 | 
             
                # Loop through all 'open' pull requests.
         | 
| 35 38 | 
             
                pull_requests.each do |request|
         | 
| 36 39 | 
             
                  @request_id = request['number']
         | 
| 37 40 | 
             
                  # Jump to next iteration if source and/or target haven't change since last run.
         | 
| 38 | 
            -
                  next unless  | 
| 41 | 
            +
                  next unless run_necessary?
         | 
| 39 42 | 
             
                  # GitHub always creates a merge commit for its 'Merge Button'.
         | 
| 43 | 
            +
                  # Pullermann reuses that commit to run the code on it.
         | 
| 40 44 | 
             
                  switch_branch_to_merged_state
         | 
| 41 | 
            -
                  #  | 
| 42 | 
            -
                  self. | 
| 43 | 
            -
                  #  | 
| 44 | 
            -
                  #  | 
| 45 | 
            -
                   | 
| 46 | 
            -
                  self.test_block.call
         | 
| 47 | 
            -
                  # Unless already set, the success/failure is determined by the last
         | 
| 48 | 
            -
                  # command's return code.
         | 
| 49 | 
            -
                  @test_success ||= $? == 0
         | 
| 50 | 
            -
                  # We need to switch back to the original branch in case we need to test
         | 
| 51 | 
            -
                  # more pull requests.
         | 
| 45 | 
            +
                  # Run specified code (i.e. tests) for the project.
         | 
| 46 | 
            +
                  self.exec_block.call
         | 
| 47 | 
            +
                  # Unless self.success has already been set manually,
         | 
| 48 | 
            +
                  # the success/failure is determined by the last command's return code.
         | 
| 49 | 
            +
                  self.success ||= $? == 0
         | 
| 52 50 | 
             
                  switch_branch_back
         | 
| 53 51 | 
             
                  comment_on_github
         | 
| 54 52 | 
             
                end
         | 
| @@ -63,8 +61,13 @@ class Pullermann | |
| 63 61 | 
             
              end
         | 
| 64 62 |  | 
| 65 63 | 
             
              def configure
         | 
| 66 | 
            -
                 | 
| 67 | 
            -
                 | 
| 64 | 
            +
                # Use existing logger or fall back to a new one with standard log level.
         | 
| 65 | 
            +
                if self.logger
         | 
| 66 | 
            +
                  @log = self.logger
         | 
| 67 | 
            +
                else
         | 
| 68 | 
            +
                  @log = Logger.new(STDOUT)
         | 
| 69 | 
            +
                  @log.level = Logger::INFO
         | 
| 70 | 
            +
                end
         | 
| 68 71 | 
             
                # Set default fall back values for options that aren't set.
         | 
| 69 72 | 
             
                self.username ||= git_config['github.login']
         | 
| 70 73 | 
             
                self.password ||= git_config['github.password']
         | 
| @@ -73,8 +76,8 @@ class Pullermann | |
| 73 76 | 
             
                self.rerun_on_source_change = true unless self.rerun_on_source_change == false
         | 
| 74 77 | 
             
                self.rerun_on_target_change = true unless self.rerun_on_target_change == false
         | 
| 75 78 | 
             
                # Find environment (tasks, project, ...).
         | 
| 76 | 
            -
                 | 
| 77 | 
            -
                 | 
| 79 | 
            +
                self.prepare_block ||= lambda {}
         | 
| 80 | 
            +
                self.exec_block ||= lambda { `rake` }
         | 
| 78 81 | 
             
                @github = connect_to_github
         | 
| 79 82 | 
             
                @github_fail = if self.username == self.username_fail
         | 
| 80 83 | 
             
                  @github
         | 
| @@ -109,11 +112,11 @@ class Pullermann | |
| 109 112 | 
             
                pulls
         | 
| 110 113 | 
             
              end
         | 
| 111 114 |  | 
| 112 | 
            -
              #  | 
| 113 | 
            -
              # - the pull request hasn't been  | 
| 115 | 
            +
              # (Re-)runs are necessary if:
         | 
| 116 | 
            +
              # - the pull request hasn't been used for a run before.
         | 
| 114 117 | 
             
              # - the pull request has been updated since the last run.
         | 
| 115 118 | 
             
              # - the target (i.e. master) has been updated since the last run.
         | 
| 116 | 
            -
              def  | 
| 119 | 
            +
              def run_necessary?
         | 
| 117 120 | 
             
                pull_request = @github.pull_request @project, @request_id
         | 
| 118 121 | 
             
                @log.info "Checking pull request ##{@request_id}: #{pull_request.title}"
         | 
| 119 122 | 
             
                # Compare current sha ids of target and source branch with those from the last test run.
         | 
| @@ -134,7 +137,7 @@ class Pullermann | |
| 134 137 | 
             
                end
         | 
| 135 138 | 
             
                # If it's not mergeable, we need to delete all comments of former test runs.
         | 
| 136 139 | 
             
                unless pull_request.mergeable
         | 
| 137 | 
            -
                  @log.info 'Pull request not auto-mergeable. Not running | 
| 140 | 
            +
                  @log.info 'Pull request not auto-mergeable. Not running.'
         | 
| 138 141 | 
             
                  if @comment
         | 
| 139 142 | 
             
                    @log.info 'Deleting existing comment.'
         | 
| 140 143 | 
             
                    call_github(old_comment_success?).delete_comment(@project, @comment.id)
         | 
| @@ -145,18 +148,18 @@ class Pullermann | |
| 145 148 | 
             
                  @log.info "Current target sha: '#{@target_head_sha}', pull sha: '#{@pull_head_sha}'."
         | 
| 146 149 | 
             
                  @log.info "Last test run target sha: '#{shas[1]}', pull sha: '#{shas[2]}'."
         | 
| 147 150 | 
             
                  if self.rerun_on_source_change && (shas[2] != @pull_head_sha)
         | 
| 148 | 
            -
                    @log.info 'Re-running  | 
| 151 | 
            +
                    @log.info 'Re-running due to new commit in pull request.'
         | 
| 149 152 | 
             
                    return true
         | 
| 150 153 | 
             
                  elsif self.rerun_on_target_change && (shas[1] != @target_head_sha)
         | 
| 151 | 
            -
                    @log.info 'Re-running  | 
| 154 | 
            +
                    @log.info 'Re-running due to new commit in target branch.'
         | 
| 152 155 | 
             
                    return true
         | 
| 153 156 | 
             
                  end
         | 
| 154 157 | 
             
                else
         | 
| 155 158 | 
             
                  # If there are no comments yet, it has to be a new request.
         | 
| 156 | 
            -
                  @log.info 'New pull request detected,  | 
| 159 | 
            +
                  @log.info 'New pull request detected, run needed.'
         | 
| 157 160 | 
             
                  return true
         | 
| 158 161 | 
             
                end
         | 
| 159 | 
            -
                @log.info "Not running  | 
| 162 | 
            +
                @log.info "Not running for request ##{@request_id}."
         | 
| 160 163 | 
             
                false
         | 
| 161 164 | 
             
              end
         | 
| 162 165 |  | 
| @@ -179,35 +182,34 @@ class Pullermann | |
| 179 182 | 
             
                `git checkout master &> /dev/null`
         | 
| 180 183 | 
             
              end
         | 
| 181 184 |  | 
| 182 | 
            -
              # Analyze old comment to see whether it was a successful or a failing one.
         | 
| 183 185 | 
             
              def old_comment_success?
         | 
| 184 186 | 
             
                return unless @comment
         | 
| 185 | 
            -
                #  | 
| 187 | 
            +
                # Analyze old comment to see whether it was a successful or a failing one.
         | 
| 186 188 | 
             
                @comment.body.include? 'Well done!'
         | 
| 187 189 | 
             
              end
         | 
| 188 190 |  | 
| 189 | 
            -
              # Output the result to a comment on the pull request on GitHub.
         | 
| 190 191 | 
             
              def comment_on_github
         | 
| 191 192 | 
             
                # Determine comment message.
         | 
| 192 | 
            -
                 | 
| 193 | 
            -
             | 
| 194 | 
            -
                  ' | 
| 193 | 
            +
                # TODO: Allow for custom messages.
         | 
| 194 | 
            +
                message = if self.success
         | 
| 195 | 
            +
                  @log.info 'Successful run.'
         | 
| 196 | 
            +
                  'Well done! Your code is still running successfully after merging this pull request.'
         | 
| 195 197 | 
             
                else
         | 
| 196 | 
            -
                  @log.info ' | 
| 197 | 
            -
                  'Unfortunately your  | 
| 198 | 
            +
                  @log.info 'Failing run.'
         | 
| 199 | 
            +
                  'Unfortunately your code is failing after merging this pull request.'
         | 
| 198 200 | 
             
                end
         | 
| 199 201 | 
             
                message += "\n( master sha# #{@target_head_sha} ; pull sha# #{@pull_head_sha} )"
         | 
| 200 | 
            -
                if old_comment_success? ==  | 
| 202 | 
            +
                if old_comment_success? == self.success
         | 
| 201 203 | 
             
                  # Replace existing @comment's body with the correct connection.
         | 
| 202 | 
            -
                  @log.info "Updating existing #{notion( | 
| 203 | 
            -
                  call_github( | 
| 204 | 
            +
                  @log.info "Updating existing #{notion(self.success)} comment."
         | 
| 205 | 
            +
                  call_github(self.success).update_comment(@project, @comment['id'], message)
         | 
| 204 206 | 
             
                else
         | 
| 205 | 
            -
                  @log.info "Deleting existing #{notion( | 
| 207 | 
            +
                  @log.info "Deleting existing #{notion(!self.success)} comment."
         | 
| 206 208 | 
             
                  # Delete old @comment with correct connection (if @comment exists).
         | 
| 207 | 
            -
                  call_github( | 
| 209 | 
            +
                  call_github(!self.success).delete_comment(@project, @comment['id']) if @comment
         | 
| 208 210 | 
             
                  # Create new comment with correct connection.
         | 
| 209 | 
            -
                  @log.info "Adding new #{notion( | 
| 210 | 
            -
                  call_github( | 
| 211 | 
            +
                  @log.info "Adding new #{notion(self.success)} comment."
         | 
| 212 | 
            +
                  call_github(self.success).add_comment(@project, @request_id, message)
         | 
| 211 213 | 
             
                end
         | 
| 212 214 | 
             
              end
         | 
| 213 215 |  | 
| @@ -224,7 +226,6 @@ class Pullermann | |
| 224 226 | 
             
              # Checks '~/.gitconfig' for credentials.
         | 
| 225 227 | 
             
              def git_config
         | 
| 226 228 | 
             
                unless @git_config
         | 
| 227 | 
            -
                  # Read @git_config from local git config.
         | 
| 228 229 | 
             
                  @git_config = {}
         | 
| 229 230 | 
             
                  `git config --list`.split("\n").each do |line|
         | 
| 230 231 | 
             
                    key, value = line.split('=')
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: pullermann
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.0 | 
| 4 | 
            +
              version: 1.1.0
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -45,10 +45,10 @@ dependencies: | |
| 45 45 | 
             
                - - ! '>='
         | 
| 46 46 | 
             
                  - !ruby/object:Gem::Version
         | 
| 47 47 | 
             
                    version: '0'
         | 
| 48 | 
            -
            description: Pullermann runs your project's test suite on open | 
| 49 | 
            -
              Afterwards it posts the result as a comment to the respective | 
| 50 | 
            -
               | 
| 51 | 
            -
              merge the code.
         | 
| 48 | 
            +
            description: Pullermann runs custom code (i.e. your project's test suite) on open
         | 
| 49 | 
            +
              pull requests on GitHub. Afterwards it posts the result as a comment to the respective
         | 
| 50 | 
            +
              request. This should give you an outlook on the future state of your repository
         | 
| 51 | 
            +
              in case you accept the request and merge the code.
         | 
| 52 52 | 
             
            email: bamboo@suse.com
         | 
| 53 53 | 
             
            executables: []
         | 
| 54 54 | 
             
            extensions: []
         | 
| @@ -82,5 +82,6 @@ rubyforge_project: | |
| 82 82 | 
             
            rubygems_version: 1.8.24
         | 
| 83 83 | 
             
            signing_key: 
         | 
| 84 84 | 
             
            specification_version: 3
         | 
| 85 | 
            -
            summary: An easy way to  | 
| 85 | 
            +
            summary: An easy way to loop through open pull requests and run code on the merged
         | 
| 86 | 
            +
              branch.
         | 
| 86 87 | 
             
            test_files: []
         |