diff --git a/src/app/FakeLib/HockeyAppHelper.fs b/src/app/FakeLib/HockeyAppHelper.fs index dfb7befcbfd..3033c8480a2 100644 --- a/src/app/FakeLib/HockeyAppHelper.fs +++ b/src/app/FakeLib/HockeyAppHelper.fs @@ -67,65 +67,129 @@ type HockeyResponse = { [] PublicUrl : string + + AppSize : int64 } +/// HockeyAppVersion's success response +/// https://support.hockeyapp.net/kb/api/api-versions#create-version +type HockeyVersionResponse = { + Title: string + + Timestamp : int64 + + Id : string + + Version : string + + ShortVersion : string + + Status : int + + [] + ConfigUrl : string + + [] + PublicUrl : string +} + +type BaseHockeyAppParams = + /// (Required) API token + abstract ApiToken: string + + /// Set to your App Id (required for UWP apps targeting windows phone) + abstract AppId: string + + /// Set maximum upload delay + abstract UploadTimeout: TimeSpan + +/// The HockeyAppVersion parameter type +/// Based on https://support.hockeyapp.net/kb/api/api-versions#create-version +[] +type HockeyAppVersionParams = + { + /// (Required) API token + ApiToken: string + + /// Set to your App Id (required for UWP apps targeting windows phone) + AppId: string + + /// Human readable version + Version: string + + /// Set maximum upload delay + UploadTimeout: TimeSpan + } + interface BaseHockeyAppParams with + member this.ApiToken = this.ApiToken + member this.AppId = this.AppId + member this.UploadTimeout = this.UploadTimeout + /// The HockeyApp parameter type /// Based on http://support.hockeyapp.net/kb/api/api-apps#upload-app [] -type HockeyAppUploadParams = { - /// (Required) API token - ApiToken: string +type HockeyAppUploadParams = + { + /// (Required) API token + ApiToken: string - /// (Required) file data for the build (.ipa or .apk) - File: string + /// (Required) file data for the build (.ipa or .apk) + File: string - /// file data for dsym (IOS: *.dysm.zip or Android: mapping.txt) - Dsym: string + /// file data for dsym (IOS: *.dysm.zip or Android: mapping.txt) + Dsym: string - /// Release notes for the build - Notes: string + /// Release notes for the build + Notes: string - /// Release notes type for the build - NotesType: NoteType + /// Release notes type for the build + NotesType: NoteType - /// Set the release type of the app - ReleaseType: ReleaseType + /// Set the release type of the app + ReleaseType: ReleaseType - /// Set the owner of the app - OwnerId: string + /// Set the owner of the app + OwnerId: string - /// Set the notify option - Notify: NotifyOption + /// Set the notify option + Notify: NotifyOption - /// Set version as mandatory - Mandatory: MandatoryOption + /// Set version as mandatory + Mandatory: MandatoryOption - /// Set to true to enable the private download page (default is false) - Private: bool + /// Set to true to enable the private download page (default is false) + Private: bool - /// Set to the git commit sha for this build - CommitSHA: string + /// Set to the git commit sha for this build + CommitSHA: string - /// Set to the URL of the build job on your build server - BuildServerUrl: string + /// Set to the URL of the build job on your build server + BuildServerUrl: string - /// Set to your source repository - RepositoryUrl: string + /// Set to your source repository + RepositoryUrl: string - /// Release download status (can only be set with full-access tokens) - DownloadStatus: DownloadStatusOption + /// Release download status (can only be set with full-access tokens) + DownloadStatus: DownloadStatusOption - /// Restrict download to specific teams - Teams: string[] + /// Restrict download to specific teams + Teams: string[] - /// Set maximum upload delay - UploadTimeout: TimeSpan + /// Set maximum upload delay + UploadTimeout: TimeSpan - /// Set to your App Id (required for UWP apps targeting windows phone) - AppId: string -} + /// Set to your App Id (required for UWP apps targeting windows phone) + AppId: string + + /// When uploading a build, specify to which version (hockeyapp version id) + VersionId: string + } + interface BaseHockeyAppParams with + member this.ApiToken: string = this.ApiToken + member this.AppId: string = this.AppId + member this.UploadTimeout = this.UploadTimeout -/// The default HockeyApp parameters +/// The default HockeyApp parameters to upload a build let HockeyAppUploadDefaults = { ApiToken = String.Empty File = String.Empty @@ -144,13 +208,22 @@ let HockeyAppUploadDefaults = { Teams = Array.empty UploadTimeout = TimeSpan.FromMinutes 2. AppId = String.Empty + VersionId = String.Empty +} + +/// The default HockeyAppVersion parameters to create a version +let HockeyAppVersionDefaults = { + ApiToken = String.Empty + AppId = String.Empty + Version = String.Empty + UploadTimeout = TimeSpan.FromMinutes 2. } /// [omit] let private nl = Environment.NewLine /// [omit] -let private validateParams param = +let private validateParams param:HockeyAppUploadParams = if param.ApiToken = "" then failwith "You must provide your API token" if param.File = "" then failwith "You must provide an app file to upload" if not <| File.Exists param.File then @@ -172,8 +245,16 @@ let private validateParams param = param /// [omit] -let private toCurlArgs param = seq { +let private validateVersionParams (param:HockeyAppVersionParams) = + if param.ApiToken = "" then failwith "You must provide your API token" + if param.Version = "" then failwith "You must provide a version" + if param.AppId = "" then failwith "You must provide an app id" + param + +/// [omit] +let private toCurlArgs (param:HockeyAppUploadParams) = seq { yield (String.Format("-sL -w \"{0}%{{http_code}}{0}\"", Regex.Escape(nl))) + if not (String.IsNullOrEmpty param.VersionId) then yield "-X PUT" yield sprintf "-H \"X-HockeyAppToken:%s\"" param.ApiToken yield sprintf "-F \"ipa=@%s\"" param.File if not (String.IsNullOrEmpty param.Dsym) then yield sprintf "-F \"dsym=@%s\"" param.Dsym @@ -189,20 +270,33 @@ let private toCurlArgs param = seq { if not (String.IsNullOrEmpty param.CommitSHA) then yield sprintf "-F \"commit_sha=%s\"" param.CommitSHA if not (String.IsNullOrEmpty param.BuildServerUrl) then yield sprintf "-F \"build_server_url=%s\"" param.BuildServerUrl if not (String.IsNullOrEmpty param.RepositoryUrl) then yield sprintf "-F \"repository_url=%s\"" param.RepositoryUrl - if not (String.IsNullOrEmpty param.AppId) - then + + if not (String.IsNullOrEmpty param.AppId) && (String.IsNullOrEmpty param.VersionId) then yield sprintf "https://rink.hockeyapp.net/api/2/apps/%s/app_versions/upload" param.AppId + else if not (String.IsNullOrEmpty param.AppId) && not (String.IsNullOrEmpty param.VersionId) then + yield sprintf "https://rink.hockeyapp.net/api/2/apps/%s/app_versions/%s" param.AppId param.VersionId else yield "https://rink.hockeyapp.net/api/2/apps/upload" } -/// Uploads an app to HockeyApp -/// ## Parameters -/// - `setParams` - Function used to override the default parameters -let HockeyApp (setParams: HockeyAppUploadParams -> HockeyAppUploadParams) = - let p = HockeyAppUploadDefaults +/// [omit] +let private toVersionCurlArgs (param:HockeyAppVersionParams) = seq { + yield (String.Format("-sL -w \"{0}%{{http_code}}{0}\"", Regex.Escape(nl))) + yield "-X POST" + yield "-H \"Content-Type: application/json\"" + yield sprintf "-d '{\"bundle_version\":\"%s\"}'" param.Version + yield sprintf "-H \"X-HockeyAppToken:%s\"" param.ApiToken + yield sprintf "https://rink.hockeyapp.net/api/2/apps/%s/app_versions/new" param.AppId +} + +/// [omit] +let private processHockeyAppCmd<'TParam, 'TResponse when 'TParam :> BaseHockeyAppParams> defaults + (setParams: 'TParam -> 'TParam) + (validateParam: 'TParam -> 'TParam) + (toCurlArgs: 'TParam -> seq) = + let p = defaults |> setParams - |> validateParams + |> validateParam p |> toCurlArgs @@ -219,6 +313,38 @@ let HockeyApp (setParams: HockeyAppUploadParams -> HockeyAppUploadParams) = | (false, _) -> failwith error | (true, responseCode) -> match responseCode with - | 201 -> JsonConvert.DeserializeObject(response.Messages.[0]) + | 201 -> JsonConvert.DeserializeObject<'TResponse>(response.Messages.[0]) | _ -> failwith error - | _ -> failwith error \ No newline at end of file + | _ -> failwith error + + +/// Uploads an app to HockeyApp +/// ## Parameters +/// - `setParams` - Function used to override the default parameters +/// +/// ## Sample +/// +/// HockeyApp (fun defaults -> +/// {defaults with +/// AppId = ... +/// ApiToken = ... +/// ... +/// }) + +let HockeyApp setParams = processHockeyAppCmd HockeyAppUploadDefaults setParams validateParams toCurlArgs + +/// Create a new version of an app on HockeyApp +/// ## Parameters +/// - `setParams` - Function used to override the default parameters +/// +/// ## Sample +/// +/// HockeyAppVersions (fun defaults -> +/// {defaults with +/// AppId = ... +/// ApiToken = ... +/// Version = ... +/// ... +/// }) + +let HockeyAppVersion setParams = processHockeyAppCmd HockeyAppVersionDefaults setParams validateVersionParams toVersionCurlArgs