プロジェクト

全般

プロフィール

Proposal #1311

Redmine Hudson plugin should support projects with multiple repositories.

Ivan Samygin4年以上前に追加. 4年以上前に更新.

ステータス:
新規(New)
優先度:
通常(Normal)
担当者:
-
対象バージョン:
開始日:
2014/02/19
期日:
進捗率:

0%

予定工数:

説明

Redmine Hudson plugin ver. 2.1.2 supports changesets from only project's default repository.

Particulary, plugin binds revision number from build details with project's default repository changeset that has the same revision number. On the one hand, changesets from nondefault repositories are lost, and on the other hand, it could cause misbinding - when changeset's revision from nondefault repository mathes some changeset revision from default repository.

I worked this feature awhile and I have working solution for svn repository.

diff -r -C 10 -w /tmp/redmine_hudson/app/helpers/hudson_api.rb /usr/share/redmine/plugins/redmine_hudson/app/helpers/hudson_api.rb
*** /tmp/redmine_hudson/app/helpers/hudson_api.rb    2013-09-23 14:50:56.000000000 +0400
--- /usr/share/redmine/plugins/redmine_hudson/app/helpers/hudson_api.rb    2014-02-19 08:30:11.060001723 +0400
***************
*** 56,76 ****
      ).get
    end

    def self.get_build_results(api_url, auth_user, auth_password)
      url = "#{api_url}/xml/?depth=1" 
      url << "&exclude=//build/changeSet/item/path" 
      url << "&exclude=//build/changeSet/item/addedPath" 
      url << "&exclude=//build/changeSet/item/modifiedPath" 
      url << "&exclude=//build/changeSet/item/deletedPath" 
      url << "&exclude=//build/culprit" 
!     url << "&exclude=//module" 
      url << "&exclude=//firstBuild&exclude=//lastBuild" 
      url << "&exclude=//lastCompletedBuild" 
      url << "&exclude=//lastFailedBuild" 
      url << "&exclude=//lastStableBuild" 
      url << "&exclude=//lastSuccessfulBuild" 
      url << "&exclude=//downstreamProject" 
      url << "&exclude=//upstreamProject" 

      HudsonApi.new(
        :url           => url, 
--- 56,76 ----
      ).get
    end

    def self.get_build_results(api_url, auth_user, auth_password)
      url = "#{api_url}/xml/?depth=1" 
      url << "&exclude=//build/changeSet/item/path" 
      url << "&exclude=//build/changeSet/item/addedPath" 
      url << "&exclude=//build/changeSet/item/modifiedPath" 
      url << "&exclude=//build/changeSet/item/deletedPath" 
      url << "&exclude=//build/culprit" 
!     # url << "&exclude=//module" 
      url << "&exclude=//firstBuild&exclude=//lastBuild" 
      url << "&exclude=//lastCompletedBuild" 
      url << "&exclude=//lastFailedBuild" 
      url << "&exclude=//lastStableBuild" 
      url << "&exclude=//lastSuccessfulBuild" 
      url << "&exclude=//downstreamProject" 
      url << "&exclude=//upstreamProject" 

      HudsonApi.new(
        :url           => url, 
Only in /usr/share/redmine/plugins/redmine_hudson/app/models: _hudson_build.rb
diff -r -C 10 -w /tmp/redmine_hudson/app/models/hudson_build.rb /usr/share/redmine/plugins/redmine_hudson/app/models/hudson_build.rb
*** /tmp/redmine_hudson/app/models/hudson_build.rb    2013-09-23 14:50:56.000000000 +0400
--- /usr/share/redmine/plugins/redmine_hudson/app/models/hudson_build.rb    2014-02-19 16:45:32.364001048 +0400
***************
*** 82,110 ****
      self.finished_at = info[:published]
      self.building = info[:building]
      self.caused_by = 1
      self.error = "" 
    end

    def add_changesets_from_xml(element)
      element.children.each do |child|
        next if child.is_a?(REXML::Text)
        next if "changeSet" != child.name
!       child.children.each do |item|
!         next if item.is_a?(REXML::Text)
!         next if "item" != item.name
!         changeset = new_changeset(item)
          changeset.save
          self.changesets << changeset
        end
      end
-   end

    def add_testresult_from_xml(element)
      test_result = nil
      element.children.each do |child|
        next if child.is_a?(REXML::Text)
        next if "action" != child.name
        next if "testReport" != get_element_value(child, "urlName")
        test_result = new_test_result(child)
        test_result.save
        self.test_result = test_result
--- 82,106 ----
      self.finished_at = info[:published]
      self.building = info[:building]
      self.caused_by = 1
      self.error = "" 
    end

    def add_changesets_from_xml(element)
      element.children.each do |child|
        next if child.is_a?(REXML::Text)
        next if "changeSet" != child.name
!       changeset = new_changeset(child)
        changeset.save
        self.changesets << changeset
      end
    end

    def add_testresult_from_xml(element)
      test_result = nil
      element.children.each do |child|
        next if child.is_a?(REXML::Text)
        next if "action" != child.name
        next if "testReport" != get_element_value(child, "urlName")
        test_result = new_test_result(child)
        test_result.save
        self.test_result = test_result
***************
*** 128,168 ****
      retval.hudson_build_id = self.id
      retval.fail_count = get_element_value(elem, "failCount")
      retval.skip_count = get_element_value(elem, "skipCount")
      retval.total_count = get_element_value(elem, "totalCount")
      return retval
    end

    def new_changeset(elem)
      retval = HudsonBuildChangeset.new
      retval.hudson_build_id = self.id
!     retval.repository_id = self.project.repository.id
      retval.revision = get_revision_no(elem)
      return retval
    end

    def new_artifact(elem)
      retval = HudsonBuildArtifact.new
      retval.hudson_build_id = self.id
      retval.display_path = get_element_value(elem,"displayPath")
      retval.file_name = get_element_value(elem, "fileName")
      retval.relative_path = get_element_value(elem, "relativePath")
      return retval
    end

    def get_revision_no(elem)
!     retval = get_element_value(elem, "revision")
      return retval if retval != "" 
!     retval = get_element_value(elem, "rev") # for mercurial or hudson 1.340
      return retval
    end

  end

  def HudsonBuild.count_of(job)
    return 0 unless job
    return 0 unless job.is_a?(HudsonJob)
    return HudsonBuild.count_by_sql(["select count(*) from #{HudsonBuild.table_name} where hudson_job_id = ?", job.id])
  end

  def HudsonBuild.parse_rss(entry)
    params = get_element_value(entry, "title").scan(/(.*)#(.*)\s\((.*)\)/)[0]
--- 124,211 ----
      retval.hudson_build_id = self.id
      retval.fail_count = get_element_value(elem, "failCount")
      retval.skip_count = get_element_value(elem, "skipCount")
      retval.total_count = get_element_value(elem, "totalCount")
      return retval
    end

    def new_changeset(elem)
      retval = HudsonBuildChangeset.new
      retval.hudson_build_id = self.id
!     retval.repository_id = get_repository_id(elem)
      retval.revision = get_revision_no(elem)
      return retval
    end

    def new_artifact(elem)
      retval = HudsonBuildArtifact.new
      retval.hudson_build_id = self.id
      retval.display_path = get_element_value(elem,"displayPath")
      retval.file_name = get_element_value(elem, "fileName")
      retval.relative_path = get_element_value(elem, "relativePath")
      return retval
    end

    def get_revision_no(elem)
!     kind = get_element_value(elem, "kind")
!     retval = get_svn_revision_no(elem) if kind == "svn" 
!     return retval if retval != "" 
!     
!     # default fallback
!     elem.children.each do |item|
!       next if item.is_a?(REXML::Text)
!       next if "item" != item.name
!       retval = get_element_value(item, "revision")
!       return retval if retval != "" 
!       retval = get_element_value(item, "rev") # for mercurial or hudson 1.340
!       return retval if retval != "" 
!     end
!   end
! 
!   def get_svn_revision_no(elem)
!     # rev_no - changeSet/revision/revision
!     elem.children.each do |revision|
!       next if revision.is_a?(REXML::Text)
!       next if "revision" != revision.name
!       retval = get_element_value(revision, "revision")
        return retval if retval != "" 
!     end
!   end
!   
!   def get_repository_id(elem)
!     kind = get_element_value(elem, "kind")
!     retval = get_svn_repository_id(elem) if kind == "svn" 
!     # default fallback
!     retval = self.project.repository.id unless retval != "" 
      return retval
    end

+   def get_svn_repository_id(elem)
+     # url - changeSet/revision/module
+     elem.children.each do |child|
+       next if child.is_a?(REXML::Text)
+       next if "revision" != child.name
+       module_val = get_element_value(child, "module")
+       return nil unless module_val != "" 
+       
+       module_val.chomp!("/")
+       repos = self.project.repositories.find(:all,
+         # searching repository with the closest url
+         :conditions => ["type=? and url <= ?", "Repository::Subversion", module_val],
+         :order=>"#{Repository.table_name}.url desc")
+       repos.each do |repo|
+         next unless module_val.start_with?(repo.url.chomp!("/"))
+         return repo.id
+       end
+     end
+   end
+ 
  end

  def HudsonBuild.count_of(job)
    return 0 unless job
    return 0 unless job.is_a?(HudsonJob)
    return HudsonBuild.count_by_sql(["select count(*) from #{HudsonBuild.table_name} where hudson_job_id = ?", job.id])
  end

  def HudsonBuild.parse_rss(entry)
    params = get_element_value(entry, "title").scan(/(.*)#(.*)\s\((.*)\)/)[0]

履歴

#1 Ivan Samygin4年以上前に更新

Oo-oops!

I've made a mistake in url comparison. Since we may encounter url ending with "/" in database and the same url without "/" on the end in hudson, we should modify hudson module url to ensure it ends with "/". Then we can use expression project_repo_url <= hudson_url in database search condition and hudson_url.start_with?(project_repo_url) in code to satisfy the closest repository url containing hudson module url.

#2 Ivan Samygin4年以上前に更新

Perhaps git commit hash can be used to search across all revisions of redmine project's git repositories. Once we've find revision with equal hash, we have repository as well.

#3 Haru Iida4年以上前に更新

  • プロジェクトr-labs から Hudson に変更
  • カテゴリ を削除 (Hudson Plugin)

他の形式にエクスポート: Atom PDF