2011-03-05 22 views
16

Estoy tratando de descubrir un proceso de un solo comando para generar una construcción en github.Liberando un artefacto de construcción en github

Lo que anticipo hacer es ejecutar algún tipo de comando - make release, por ejemplo, y make make crea el artefacto de lanzamiento y luego lo carga a github de alguna manera.

Sin embargo, estoy bastante confundido acerca de cómo obtener un artefacto de lanzamiento en github. El código fuente es increíble, pero no todos quieren hacer sus propias versiones. :-)

+0

Tenga una mirada en GitHub nueva característica "Release": ver a mi [respuesta editado por debajo] (http://stackoverflow.com/a/5207352/6309). – VonC

+0

@VonC: actualizado. Gracias. –

Respuesta

15

Update September 2013, puede automatizar un comunicado de (API in preview mode)

Update January 2014, hay una aplicación de línea de comandos no oficial, llamado github-release por Nicolas Hillegeer (aktau), para la creación de versiones y artefactos subirlas (binarios).
Utiliza la nueva API de versiones de github mencionada anteriormente. Mira el Makefile del proyecto para ver cómo automatizarlo aún más.

Ejemplo:

# 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 

Esta API es un poco diferente debido a los activos binarios. Utilizamos el encabezado Aceptar para la negociación de contenido al solicitar un activo de lanzamiento.
pasa un tipo de soporte API estándar para obtener la representación de la 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, 
... 
} 

Pass “application/octet-stream” para descargar el contenido binario.

$ 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 

subidos son manejados por una sola solicitud a un compañero de servicio “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, ahora se puede definir un comunicado de .

release

  • lanzamientos se acompañan de notas de la versión y enlaces para descargar el código de software o fuente.
  • Siguiendo las convenciones de muchos proyectos de Git, los lanzamientos están ligados a las etiquetas de Git. Puede usar una etiqueta existente o permitir que las versiones creen la etiqueta cuando se publique.
  • También puede adjuntar recursos binarios (como ejecutables compilados, scripts minificados, documentación) a un lanzamiento. Una vez publicados, los detalles y los activos están disponibles para cualquiera que pueda ver el repositorio.

Esto es lo que reemplaza al old binary upload service, que era removed in December 2012!


el guión make release se acumula el artefacto liberación y luego lo carga a github de alguna manera.

Eso significaría que la adición ("él" se hizo la entrega de uno o varios archivos, incluyendo generalmente binarios) para un acuerdo de recompra locales regulares, y luego empujar esa cesión temporal a su juego de recompra GitHub.

Dicho esto, la razón por la cual GitHub no se menciona en ninguna tarea de "liberación" es porque Git es un sistema de administración de control fuente, y no es adecuado para binarios.

Puede tener esos archivos (binarios) por supuesto, pero no está hecho para tenerlos regularmente, debido al tamaño inflado del repositorio después de un tiempo: cada clonación tomaría más y más tiempo.
Ver What are the Git limits, y también "git - should source files and repository be on the same machine ?".

+0

Hmm. Eso es un dolor. Me gustaría tener un 'build actual' rodando por ahí. (También me gustaría poder tener lanzamientos puntuales de las compilaciones). –

+1

@Paul: pero un VCS no es exactamente lo que desea para el lanzamiento (un poco como http://stackoverflow.com/questions/3863964/tracking-deployed-applications-files/3864134#3864134). Un repositorio de artefactos como Nexus es más apropiado, como en http://stackoverflow.com/questions/4983060/should-generated-documentation-go-into-source-control/4983530#4983530 o http://stackoverflow.com/questions/4968745/many-binary-files-synchronization/4968834 # 4968834 – VonC

+0

Pensé que GitHub tiene un mecanismo de carga de archivos (descargas) que puede ir con un proyecto. ¿No hay forma de hacer esa secuencia de comandos? –

0

Sugeriría utilizar un sitio de alojamiento de código abierto y poner allí los archivos.

Me gusta mucho esto - http://www.cloudbees.com/foss/foss-dev.cb - obtienes una configuración de jenkins para construir tu proyecto, probar tu proyecto y luego esos artefactos archivados pueden distribuirse.

De esta manera, todos los errores de informe/discusión/wiki se pueden mantener en github.

1

Github tiene una API para acceder a su propio sistema de descarga de archivos. Las descargas de Repo le permiten proporcionar archivos binarios a los usuarios, aunque puede haber un límite para el tamaño y el número. La API permite el acceso de agentes automatizados. Eche un vistazo a: http://developer.github.com/v3/repos/downloads/ para la información de uso.

La característica no está en uso, pero definitivamente funciona. Puede ir a cualquier repositorio de Github, haga clic en la pestaña "Descargas" para verlos.

Para obtener un ejemplo de archivos descargables: http://github.com/dannystaple/emacs_cheat_sheets/downloads - el archivo HTML ofrecido allí es en realidad un artefacto construido, y no en la fuente. Estoy intentando armar un mejor ejemplo (binario), pero no hay ninguna razón por la que no se puedan ofrecer ejecutables, cremalleras/tarballs y otros tipos de archivos.

Estas descargas NO son lo mismo que los tarballs de origen para un repositorio o sus etiquetas. Cualquier archivo arbitrario se puede cargar de esta manera.

1

que tenían el mismo problema, cortado un poco pitón que lo haga por mí. Debo decir que fue un dolor, s3 es un espectáculo total.

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

Preparación:

1) Descargar github-releases y poner su ejecutable en su PATH.
2) Crear una ficha en https://github.com/settings/applications#personal-access-tokens digamos abc123

Carga de un artefacto:

1) Digamos que acaba compilado lo que decide llamar a la versión 3.1, y quieren subirlo.
2) Asegúrate de haber comprometido todo.
3) ejecutar estos cinco comandos:

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> 

Puede cargar varios archivos, por ejemplo, para diferentes sistemas operativos.

(Basado en la respuesta de VonC, que por desgracia no detalla cómo cargar un artefacto)

+0

Agradable además de mi respuesta. +1 – VonC

0

Para aquellos que utilizan Gradle, el plugin gradle-github-plugin también permite crear los comunicados y adjuntar archivos a ellos.

  1. Añadir el plugin para el gradle.build:
plugins { 
    id "co.riiid.gradle" version "X.Y.Z" 
} 
  1. Configurar la carga. Ejemplo:
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', 
      ... 
    ] 
} 
Cuestiones relacionadas