2

我有一個jenkins作業,在mercurial repo上運行一些測試,並且如果成功標記本地回購以'stable'標記,然後將其推回到主回購。我遇到的問題是,如果有人在構建運行時推送更改集,那麼我無法推送「穩定」標籤。在jenkins構建期間防止mercurial push

我想知道是否有一種方法可以在構建運行時將遠程repo設置爲只讀,然後在構建完成後將其設置爲「可推式」

感謝, Vackar

回答

1

防止壓可能不是你想要的(這幾乎幾乎是不可能的)。像Mercurial或git這樣的DVCS的承諾是沒有鎖定 - 這是一個進步。

你有沒有考慮讓Jenkins在合併之前進行拉取和更新?您仍然可以標記正確的修訂。事情是這樣的:

  1. 詹金斯檢查出來的代碼,並注意到修訂ID它的建設
  2. 詹金斯做構建,運行測試,等等,一切順利的話
  3. 詹金斯沒有一個hg pull得到從服務器最新
  4. 詹金斯做了hg tag -m "build number $BUILD_NUMBER" --revision X --force stable
  5. 詹金斯做了hg push

然後,在最終拉取,標記和推送之間幾乎沒有時間,但標記仍然在實際構建的修訂版本上 - 因爲您從第一次拉出時就保存了該修訂哈希標識。

+0

嗨Ry4an,這是一個很好的主意。然後,我還會添加第6步,然後將本地回購更新到,以便下一個版本在更改日誌中提取正確的更改集。將嘗試一下,讓你知道它是如何去。 –

+0

我想這取決於你如何建立Jenkins,但我們有我們的變化觀察,並且它在構建開始時更新到新近看到的修訂版,但是,它可能發生在或之後。 –

0

我剛剛在找類似的東西。在我們的例子中,Jenkins正在執行合併,運行一系列廣泛的測試,一旦它們全部通過,將合併的代碼推回到存儲庫。因此,如果開發人員在執行任務時推送它(大約不能進行最後一次推送),則需要大約1小時並且失敗。

我找不到現成的解決方案,因此最終編寫了一個mercurial hook,在允許推送前檢查作業是否正在構建(使用REST API)。

您需要訪問遠程mercurial存儲庫,但除此之外,它不是太複雜。


以下內容添加到your-remote-repo/.hg/hgrc

[hooks] 
pretxnchangegroup.DisablePushDuringJenkinsBuild= python:.hg/disable_push_if_building_hook.py:check_jenkins 
[jenkins] 
url=http://path-to-jenkins 
jobs=jenkins-job-name[,comma-separated, for-multiple, jobs] 

並確保這個python腳本在your-remote-repo/.hg/

import json, urllib2 
from mercurial import util 

TEN_SECONDS = 10 

def check_jenkins(ui, repo, node, **kwargs): 

    jenkins_url = ui.config('jenkins', 'url', default=None, untrusted=False) 
    jenkins_jobs = ui.config('jenkins', 'jobs', default=None, untrusted=False) 

    if not jenkins_url: 
     raise util.Abort('Jenkins hook has not been configured correctly. Cannot find Jenkins url in .hg/hgrc.') 

    if not jenkins_jobs: 
     raise util.Abort('Jenkins hook has not been configured correctly. Cannot find Jenkins jobs in .hg/hgrc.') 

    jenkins_jobs = [x.strip() for x in jenkins_jobs.split(',')] 

    for job in jenkins_jobs: 
     job_url = jenkins_url + '/job/' + job + '/lastBuild/api/json' 
     ui.write('Checking if job is running at URL: %s\n' % job_url) 

     try: 
      job_metadata = json.load(urllib2.urlopen(job_url, timeout = TEN_SECONDS)) 

      if 'building' in job_metadata and job_metadata['building']: 
       raise util.Abort('Jenkins build "%s" is in progress. Pushing is disabled until it completes.' % job_metadata['fullDisplayName']) 

     except urllib2.URLError, e: 
      raise util.Abort('Error while trying to poll Jenkins: "%s"' % e) 

    return False # Everything is OK, push can be accepted