INFO
This documentation is for FAKE.exe before version 5 (or the non-netcore version). The documentation needs te be updated, please help!
This module helps android developers to automatically publish their APKs
Before using this module, you will need an android keystore for apk signing.
Next, you will need a Google service account described here:
https://developers.google.com/accounts/docs/OAuth2ServiceAccount#creatinganaccount
and here:
https://developers.google.com/android-publisher/getting_started
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
|
#r "packages/FAKE/tools/FakeLib.dll"
let androidBuildDir = "./build/"
let androidProdDir = "./pack/"
androidProdDir |> ensureDirectory
//Clean old apk
Target "Clean" (fun _ ->
CleanDir androidBuildDir
CleanDir androidProdDir
)
Target "Android-Package" (fun () ->
AndroidPackage(fun defaults ->
{ defaults with
ProjectPath = "Path to my project Droid.csproj"
Configuration = "Release"
OutputPath = androidBuildDir
Properties = ["MSBuild property", "MSBuild property value"]
})
|> AndroidSignAndAlign (fun defaults ->
{ defaults with
KeystorePath = @"path to my file.keystore"
KeystorePassword = "my password"
KeystoreAlias = "my key alias"
})
|> fun file -> file.CopyTo(Path.Combine(androidProdDir, file.Name)) |> ignore
)
// You can also build one APK per ABI
Target "Android-MultiPackages" (fun () ->
let versionStepper = (fun v t -> match t with
| AndroidAbiTarget.X86 c -> v + 1
| AndroidAbiTarget.X86And64 c -> v + 2
| AndroidAbiTarget.ArmEabi c -> v + 3
| AndroidAbiTarget.ArmEabiV7a c -> v + 4
| AndroidAbiTarget.Arm64V8a c -> v + 5
| _ -> v)
let abis = AndroidPackageAbiParam.SpecificAbis
([ AndroidAbiTarget.X86({ SuffixAndExtension="-x86.apk"; })
AndroidAbiTarget.ArmEabi({ SuffixAndExtension="-armeabi.apk"; })
AndroidAbiTarget.ArmEabiV7a({ SuffixAndExtension="-armeabi-v7a.apk"; })
AndroidAbiTarget.X86And64({ SuffixAndExtension="-x86_64.apk"; })
])
let files = AndroidBuildPackages(fun defaults ->
{ defaults with
ProjectPath = "Path to my project Droid.csproj"
Configuration = "Release"
OutputPath = androidBuildDir
PackageAbiTargets = abis
VersionStepper = Some(versionStepper)
})
for f in files do
printfn "- apk: %s" f.Name
files
|> Seq.iter (fun file -> file.CopyTo(Path.Combine(androidProdDir, file.Name)) |> ignore)
)
Target "Publish" (fun _ ->
// I like verbose script
trace "publishing Android App"
let apk = androidProdDir
|> directoryInfo
|> filesInDir
|> Seq.filter(fun f -> f.Name.EndsWith(".apk"))
|> Seq.exactlyOne
let apkPath = apk.FullName
tracefn "Apk found: %s" apkPath
let mail = "my service account mail@developer.gserviceaccount.com"
// Path to the certificate file probably named 'Google Play Android Developer-xxxxxxxxxxxx.p12'
let certificate = new X509Certificate2
(
@"Google Play Android Developer-xxxxxxxxxxxx.p12",
"notasecret",
X509KeyStorageFlags.Exportable
)
let packageName = "my Android package name"
// to publish an alpha version:
PublishApk
{ AlphaSettings with
Config =
{
Certificate = certificate;
PackageName = packageName;
AccountId = mail;
Apk = apkPath;
}
}
// to publish a beta version:
//
//PublishApk
// { BetaSettings with
// Config =
// {
// Certificate = certificate;
// PackageName = packageName;
// AccountId = mail;
// Apk = apkPath;
// }
// }
// to publish a production version:
//
//PublishApk
// { ProductionSettings with
// Config =
// {
// Certificate = certificate;
// PackageName = packageName;
// AccountId = mail;
// Apk = apkPath;
// }
// }
)
Target "Android-Build" (fun _ ->
!! "**/my project Droid.csproj"
|> MSBuildRelease androidBuildDir "Build"
|> Log "BuildAndroidLib-Output: "
)
Target "Default" (fun _ ->
trace "Building default target"
RestorePackages()
)
"Clean"
==> "Android-Package"
==> "Default"
RunTargetOrDefault "Default"
|
Default target will not start "Publish" target because apps do not need to be updated too frequently (as explained here: https://developers.google.com/android-publisher/api_usage)
To publish your app, you can run
val androidBuildDir : string
val androidProdDir : string
val file : obj
val ignore : value:'T -> unit
union case Option.Some: Value: 'T -> Option<'T>
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
module Seq
from Microsoft.FSharp.Collections
val iter : action:('T -> unit) -> source:seq<'T> -> unit
val filter : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>
val exactlyOne : source:seq<'T> -> 'T