dbuenzli / topkg

The transitory OCaml software packager
http://erratique.ch/software/topkg
ISC License
69 stars 25 forks source link

The delegate protocol for distribution is too simplistic. #90

Closed edwintorok closed 5 years ago

edwintorok commented 7 years ago

I was writing my own (toy) delegate and noticed that the path in opam/url (releases/) is not customizable. Would be nice if the delegate could override it. OTOH most people would probably use github, and it makes sense to standardize on one thing, at least in the beginning, so this is rather a question if you'd accept a PR to make that customizable.

dbuenzli commented 7 years ago

That shouldn't be the case if your package homepage is not hosted on github. In any case you can override this per package, the full details are described in the uri argument of Pkg.distrib ? See the docs.

Note that your delegate can simply ignore this value if it's not relevant. For example my own delegate does so. I think you should have enough contextual information from the other arguments to reconstruct an appropriate URI for your context. If not tell me what's missing.

edwintorok commented 7 years ago

Thanks, I was looking in the wrong place for overriding the URI (in my case the URI is only known to the delegate because the server assigns it, however I can save that to a file and make it available to pkg.ml later on).

dbuenzli commented 7 years ago

however I can save that to a file and make it available to pkg.ml later on

But unless you have alt publication targets that URI should not be needed or does it ?

dbuenzli commented 7 years ago

Ah yes by topkg opam. Mmmh I guess the delegate protocol is a bit too simplistic (for example in the toy github delegate we hack the URIs but formally we should parse the response from the server aswell). Formally topkg publish distrib should be able to return the actual URI where the release was posted.

edwintorok commented 7 years ago

The relevant part of my delegate looks something like below. The URI from gitlab looks like: https://gitlab.com/edwintorok/ocaml-anycache/uploads/78722628e5af42b59da2abe17939ff89/anycache-0.6.0.tbz

I'm not particularly happy with the URI assignment by the gitlab server (on one hand it is immutable, so no hacking the release tarball after its released which is good, OTOH if it gets lost somehow I can't recreate the exact same URI breaking everything that depends on it). I'm thinking whether to just host the release tarball on github, and avoid all the trouble.

let create_release_json version msg id =
  Ezjsonm.to_string (`O [
    "tag_name", `String version;
    "description", `String (msg ^ "\n\n" ^ id ^ "\n")
  ])

let curl_create_release curl version msg id owner repo =
  let data = create_release_json version msg id in
  let uri =
    strf "https://gitlab.com/api/v3/projects/%s%%2f%s/repository/tags/%s/release"
      owner repo version in
  let auth = gitlab_auth ~owner in
  let cmd = Cmd.(curl % "-H" % "Content-Type: application/json" % "--data-raw" % data % uri) in
  run_with_auth auth cmd |> OS.Cmd.to_stdout

let curl_upload_archive curl archive owner repo =
  let uri =
    strf "https://gitlab.com/api/v3/projects/%s%%2f%s/uploads" owner repo
  in
  let parse_upload_id str =
    Logs.debug (fun m -> m "Upload reply from server: %s" str);
    let json = Ezjsonm.from_string str in
    Ok Ezjsonm.(find json ["markdown"] |> get_string)
  in
  let auth = gitlab_auth ~owner in
  let data = Cmd.(v "--form" % strf "file=@@%s" (Fpath.to_string archive)) in
  let cmd = Cmd.(curl %% data % uri) in
  OS.Cmd.(run_with_auth auth cmd |> to_string >>= parse_upload_id)

let publish_distrib uri _name version msg archive =
  let git_for_repo r = Cmd.of_list (Topkg.Cmd.to_list @@ Topkg.Vcs.cmd r) in
  Fpath.of_string archive
  >>= fun archive -> OS.Cmd.must_exist Cmd.(v "curl" % "-X" % "POST" % "-s" % "-S" % "-K" % "-")
  >>= fun curl -> Topkg.Vcs.get ()
  >>= fun repo -> Ok (git_for_repo repo)
  >>= fun git -> OS.Cmd.run Cmd.(git % "push" % "--force" % "--tags")
  >>= fun () -> repo_and_owner_of_uri uri
  >>= fun (owner, repo) -> curl_upload_archive curl archive owner repo
  >>= fun id -> curl_create_release curl version msg id owner repo
  >>= fun () -> Ok 0
dbuenzli commented 5 years ago

Topkg is in maintenance mode no new features will added.

@edwintorok thanks for the information you provided I will keep that in mind for future release tools.