2011-03-05 77 views
16

我想弄清楚在github上生成構建的一個命令過程。在github上發佈構建工件

我想要做的是運行某種命令發佈版本,並且make release腳本構建發佈工件,然後以某種方式將其上傳到github。

但是,我對如何在github上實際獲得發行工件感到困惑。源代碼很棒,但不是每個人都想做自己的構建。 :-)

+0

看一看GitHub的新 「版本」 功能:看我的[編輯答案如下(http://stackoverflow.com/a/5207352/6309)。 – VonC

+0

@VonC:已更新。謝謝。 –

回答

15

Update September 2013,你可以自動釋放API in preview mode

Update January 2014,有一個非官方的命令行應用程序,叫做github-release通過Nicolas Hillegeer (aktau),用於創建發佈和上傳(二進制)文物。
它使用上面提到的新的github發佈API。看項目的Makefile,看看如何更自動化它。

實施例:

# create a formal release 
$ github-release release \ 
    --user aktau \ 
    --repo gofinance \ 
    --tag v0.1.0 \ 
    --name "the wolf of source street" \ 
    --description "Not a movie, contrary to popular opinion. Still, my first release!" \ 
    --pre-release 

此API是有點不同的,由於二進制資產。請求發佈資產時,我們使用Accept標頭進行內容協商。
傳遞一個標準的API,媒體類型,以獲得API表示:

$ curl -i -H "Authorization: token TOKEN" \ 
    -H "Accept: application/vnd.github.manifold-preview" \ 
    "https://uploads.github.com/repos/hubot/singularity/releases/assets/123" 

HTTP/1.1 200 OK 

{ 
    "id": 123, 
... 
} 

通「應用程序/八位字節流」下載的二進制內容。

$ curl -i -H "Authorization: token TOKEN" \ 
    -H "Accept: application/octet-stream" \ 
    "https://uploads.github.com/repos/hubot/singularity/releases/assets/123" 

HTTP/1.1 302 Found 

上傳由單個請求到一個同伴「uploads.github.com」的服務處理。

$ curl -H "Authorization: token TOKEN" \ 
    -H "Accept: application/vnd.github.manifold-preview" \ 
    -H "Content-Type: application/zip" \ 
    --data-binary @build/mac/package.zip \ 
    "https://uploads.github.com/repos/hubot/singularity/releases/123/assets?name=1.0.0-mac.zip" 

Update 2d July 2013,你現在可以定義釋放

release

  • 發佈都伴隨着發行說明和鏈接,下載該軟件或源代碼。
  • 遵循許多Git項目的約定,發佈與Git標籤綁定。您可以使用現有標籤,也可以讓版本在發佈時創建標籤。
  • 您還可以將二進制資源(如編譯的可執行文件,縮小的腳本,文檔)附加到版本。一旦發佈,任何可以查看存儲庫的人都可以獲得發佈細節和資產。

這是什麼取代old binary upload service,這是removed in December 2012


化妝釋放腳本積聚釋放神器,然後上傳它以某種方式github上。

這將意味着增加它(「它」正在傳送由一個或多個文件,大致包括:二進制文件)到正規的本地回購,然後推動該回購其匹配GitHub庫。

這就是說,GitHub沒有在任何「發佈」任務中提及的原因是因爲Git是一個源代碼控制管理系統,並且不適合二進制文件。

它當然可以有這些文件(二進制文件),但由於一段時間後回購數據的臃腫大小,它們並沒有定期生成它們:每次克隆需要的時間越來越長。
What are the Git limits,還有「git - should source files and repository be on the same machine ?」。

+0

嗯。這是一個痛苦。我想在那裏有一個滾動的「當前構建」。 (我也希望能夠獲得構建的點數發佈)。 –

+1

@Paul:但是VCS並不是你想要發佈的版本(有點像http://stackoverflow.com/questions/3863964/tracking-deployed-applications-files/3864134#3864134)。像Nexus這樣的工件存儲庫更合適,如http://stackoverflow.com/questions/4983060/should-generated-documentation-go-into-source-control/4983530#4983530或http://stackoverflow.com/questions/4968745/many-binary-files-synchronization/4968834#4968834 – VonC

+0

我認爲GitHub有一個文件上傳機制(下載)可以與一個項目一起使用。有沒有辦法使這個腳本? –

0

我會建議使用一個附帶的開源託管站點,並將文件放在那裏。

我更喜歡這個 - http://www.cloudbees.com/foss/foss-dev.cb - 你得到一個jenkins設置來建立你的項目,測試你的項目,然後可以分發這些存檔的工件。

這樣,所有的bug報告/討論/ wiki可以保存在github上。

1

Github上有一個API來訪問他們自己的文件下載系統。 通過Repo下載,您可以爲用戶提供二進制文件 - 儘管可能會限制大小和數量。該API允許從自動代理進行訪問。 看看: http://developer.github.com/v3/repos/downloads/的使用信息。

該功能沒有多大用處,但絕對有效。你可以去任何github回購,點擊「下載」標籤來查看它們。

有關可下載文件的示例: http://github.com/dannystaple/emacs_cheat_sheets/downloads - 提供的HTML文件實際上是一個內置的製造品,而不是源代碼。我正在嘗試創建一個更好的(二進制)示例 - 但沒有理由不能提供可執行文件,zip文件/ tarball文件和其他文件類型。

這些下載與repo或其代碼的源代碼tarball不同。任何任意文件都可以通過這種方式上傳。

1

我有同樣的問題,設計了一個簡單的小蟒蛇做到這一點對我來說。我必須說這是一個痛苦,s3是一個完全怪異的表演。

https://raw.github.com/reklis/utilityscripts/master/github-upload

#!/opt/local/bin/python2.7 


import json 
import requests 
import sys 
import argparse 
import os 
import mimetypes 
import pycurl 
import cStringIO 
from xml.dom import minidom 

github_api_root = "https://api.github.com/" 

def parse_args(): 
    parser = argparse.ArgumentParser(description='post a file to github as a download') 
    parser.add_argument('--user', dest='user', help='github username', required=True) 
    parser.add_argument('--pass', dest='password', help='github password', required=True) 
    parser.add_argument('--repo', dest='repo', help='the name of the github repo', required=True) 
    parser.add_argument('--file', dest='filepath', help='path of the local file to upload', required=True) 
    parser.add_argument('--desc', dest='description', help='descriptive text about this file', required=True) 
    parser.add_argument('--owner', dest='owner', help='owner of the github repository', required=True) 
    args = parser.parse_args() 
    # print args 
    return args 

def make_dl_post_url(owner, repo): 
    url = "%srepos/%s/%s/downloads" % (str(github_api_root), str(owner), str(repo)) 
    # print url 
    return url 

def make_dl_delete_url(owner, repo, dlid): 
    url = "%srepos/%s/%s/downloads/%s" % (str(github_api_root), str(owner), str(repo), str(dlid)) 
    # print url 
    return url 

def add_github_reference(args): 
    dl_post_url = make_dl_post_url(args.owner, args.repo) 

    fp = args.filepath 
    filename = os.path.basename(fp) 
    filesize = os.path.getsize(fp) 

    mtype, mdetails = mimetypes.guess_type(fp) 

    file_description = { 
     'name': filename, 
     'size': filesize, 
     'description': args.description, 
     'content_type': mtype 
    } 
    # print json.dumps(file_description, indent=2) 

    github = requests.post(dl_post_url, auth=(args.user, args.password), data=json.dumps(file_description)) 
    resp = github.json 
    # print json.dumps(resp, indent=2) 
    return resp 

def remove_github_reference(args, dlid): 
    dl_delete_url = make_dl_delete_url(args.owner, args.repo, dlid) 

    github = requests.delete(dl_delete_url, auth=(args.user, args.password)) 
    delete_ok = (204 == github.status_code) 
    return delete_ok 

def post_file_to_s3(file_path, gh): 
    # s3 is very particular with field ordering 

    # curl \ 
    # -F "key=downloads/octocat/Hello-World/new_file.jpg" \ 
    # -F "acl=public-read" \ 
    # -F "success_action_status=201" \ 
    # -F "Filename=new_file.jpg" \ 
    # -F "AWSAccessKeyId=1ABCDEF..." \ 
    # -F "Policy=ewogIC..." \ 
    # -F "Signature=mwnF..." \ 
    # -F "Content-Type=image/jpeg" \ 
    # -F "[email protected]_file.jpg" \ 
    # https://github.s3.amazonaws.com/ 

    s3_ok = 201 
    xml_buffer = cStringIO.StringIO() 

    try: 
     post_fields = [ 
      ('key', str(gh['path'])), 
      ('acl', str(gh['acl'])), 
      ('success_action_status', str(s3_ok)), 
      ('Filename', str(gh['name'])), 
      ('AWSAccessKeyId', str(gh['accesskeyid'])), 
      ('Policy', str(gh['policy'])), 
      ('Signature', str(gh['signature'])), 
      ('Content-Type', str(gh['mime_type'])), 
      ('file', (pycurl.FORM_FILE, file_path)) 
     ] 
     # print post_fields 

     s3 = pycurl.Curl() 
     s3.setopt(pycurl.SSL_VERIFYPEER, 0) 
     s3.setopt(pycurl.SSL_VERIFYHOST, 0) 
     s3.setopt(pycurl.POST, 1) 
     s3.setopt(pycurl.URL, str(gh['s3_url'])) 
     s3.setopt(pycurl.HTTPPOST, post_fields) 
     # s3.setopt(pycurl.VERBOSE, 1) 

     # accumulate string response 
     s3.setopt(pycurl.WRITEFUNCTION, xml_buffer.write) 

     s3.perform() 

     file_upload_success = (s3_ok == s3.getinfo(pycurl.HTTP_CODE)) 
     xml_payload = minidom.parseString(xml_buffer.getvalue()) 

     if (file_upload_success): 
      location_element = xml_payload.getElementsByTagName('Location') 
      print location_element[0].firstChild.nodeValue 
     else: 
      print xml_payload.toprettyxml() 


    except Exception, e: 
     print e 
     file_upload_success = False 

    finally: 
     s3.close() 

    return file_upload_success 


def main(): 
    mimetypes.init() 
    args = parse_args() 

    # step 1: tell github about the file 
    gh = add_github_reference(args) 

    # step 2: upload file to s3 
    if ('errors' in gh): 
     print json.dumps(gh, indent=2) 
    else: 
     file_upload_success = post_file_to_s3(args.filepath, gh) 

     # cleanup if upload failed 
     if (False == file_upload_success): 
      removed_ok = remove_github_reference(args, gh['id']) 
      if (removed_ok): 
       print "removed github reference" 
      else: 
       print "failed to remove github reference" 


if __name__ == '__main__': 
    main() 
5

準備:

1)下載github-releases,並把其可執行文件路徑中。
2)創建於https://github.com/settings/applications#personal-access-tokens令牌假設ABC123

上傳一個神器:

1)假設你剛纔編譯你決定打電話給3.1版本是什麼,並希望將其上傳。
2)確保你承諾一切。
3)運行以下五個命令:

git tag v3.1 
git push 
git push --tags 

github-release release --security-token abc123 --user <you> --repo <yourrepo> \ 
    --tag v3.1 

github-release upload --security-token abc123 --user <you> --repo <yourrepo> \ 
    --tag v3.1 --name <thefile> --file <thefile> 

您可以上傳多個文件,例如爲不同的操作系統。

(基於VonC的答案,不幸的是沒有詳細說明如何上傳一個神器)

+0

好的除了我的答案。 +1 – VonC

0

對於使用這些的gradle,該插件還gradle-github-plugin允許創建發佈和附加文件給他們。

  1. 插件添加到gradle.build
plugins { 
    id "co.riiid.gradle" version "X.Y.Z" 
} 
  • 配置的上載。例如:
  • github { 
        owner = 'riiid' 
        repo = 'gradle-github-plugin' 
        token = 'XXXXXXXXXXXXXXXXXXXXX' 
        tagName = '0.1.0' 
        targetCommitish = 'master' 
        name = 'v0.1.0' 
        body = """# Project Name 
    Write `release note` here. 
    """ 
        assets = [ 
          'app/build/outputs/apk/app-release.apk', 
          'app/build/outputs/mapping/release/mapping.txt', 
          'app/build/outputs', 
          ... 
        ] 
    }