-
Notifications
You must be signed in to change notification settings - Fork 8
/
build.fsx
286 lines (238 loc) · 8.81 KB
/
build.fsx
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#r "paket:
nuget FSharp.Core 4.7.2
nuget Fake.DotNet.Cli
nuget Fake.IO.FileSystem
nuget Fake.BuildServer.TeamFoundation
nuget Fake.Core.CommandLineParsing
nuget Newtonsoft.Json
nuget Fake.Core.Xml
nuget Fake.Core.Target //"
#load ".fake/build.fsx/intellisense.fsx"
#nowarn "52"
open Fake.IO.Globbing.Operators
open Fake.Core.TargetOperators
open Fake.DotNet.NuGet
open Fake.BuildServer
open Fake.Net.Http
open Fake.Core.Xml
open Fake.DotNet
open Fake.Core
open System.IO
open Fake.IO
open System
(*
Usage:
dotnet fake run build.fsx AzureAD # Install, ForceRegeneration, Pack for AzureAD
dotnet fake run build.fsx AzureAD -t ForceRegeneration # Install and ForceRegeneration only
dotnet fake run build.fsx All -t ForceRegeneration # Install and ForceRegeneration for all providers
dotnet fake run build.fsx All -t Build # Install, ForceRegeneration and Build for all providers
*)
BuildServer.install [ TeamFoundation.Installer ]
let args =
Context.forceFakeContext().Arguments |>
Array.ofList |>
Docopt("""
usage: dotnet_fake_run_build.fsx [PROVIDER] [options]
options:
-t <target>
""").Parse
let getTarget args =
match Map.tryFind "-t" args with
| Some (Argument t) -> t
| _ -> "Default"
let getProvider args =
match Map.tryFind "PROVIDER" args |>
Option.bind (function | Argument p -> Some p | _ -> None) |>
Option.orElse (Environment.environVarOrNone "PROVIDER") |>
Option.orElse (Environment.environVarOrNone "BUILD_DEFINITIONNAME") with
| Some "All" -> "*"
| Some p -> p
| _ -> failwith "Missing provider"
let getProviders =
function
| "*" -> DirectoryInfo.ofPath "." |>
DirectoryInfo.getSubDirectories |>
Array.filter (fun d -> d.Name.StartsWith("Pulumi.FSharp.") &&
not <| d.Name.EndsWith(".Test") &&
not <| d.Name.EndsWith(".Core") &&
not <| d.Name.EndsWith(".Myriad")) |>
Array.map (fun d -> d.Name.Substring(14))
| name -> [| name |]
let getFullName provider =
sprintf "Pulumi.FSharp.%s" provider
let getProjectFiles provider =
let projectPattern =
provider |> getFullName |> sprintf "**/%s.fsproj"
!! projectPattern
let traceNested func projFile =
Trace.useWith true
(fun _ -> func projFile)
(Trace.traceTarget projFile "" "")
// traceTask, traceTag
let vaultFile =
"Pulumi.FSharp.Extensions.vault.json"
let nuGetApiKey =
"nuGetApiKey"
let confirm msg =
printf "%s [y/any]? " msg
Console.ReadKey().Key = ConsoleKey.Y
Target.create "CreateVault" (fun _ ->
if not <| File.exists vaultFile ||
confirm "Vault file exists, do you want to overwrite it" then
printfn "\nEnter the NuGet API key: "
let variable : Vault.Variable = {
Name = nuGetApiKey
Secret = false // On Azure DevOps SecureFile is already encrypted
Value = Console.ReadLine()
}
let vaultFileContent =
//let keyInfo = Some "keyFilePath" |> Vault.createKey
{|
// Only if encrypted
//keyFile = keyInfo.KeyFile
//iv = keyInfo.Iv
values = [| variable |]
|} |>
Newtonsoft.Json.JsonConvert.SerializeObject
File.WriteAllText(vaultFile, vaultFileContent)
)
Target.create "Install" (fun _ ->
DotNet.Options.Create() |>
DotNet.install DotNet.Versions.FromGlobalJson |>
ignore
)
Target.create "ForceRegeneration" (fun _ ->
let myriadFiles =
getProvider args |>
getProviders |>
Seq.map (fun provider -> provider,
(!! (provider |>
getFullName |>
sprintf "**/%s/Myriad.fs"))
|> Seq.exactlyOne) |>
Map.ofSeq
let random =
DateTime.Now.Millisecond |>
Random
let moduleDeclaration provider =
sprintf "module private %s" provider
let forceRebuild =
match BuildServer.isLocalBuild with
| true -> random.Next() |> sprintf "module Force = let private nonce = %i"
| false -> ""
myriadFiles |>
Map.iter (fun provider myriadFile ->
File.WriteAllText(myriadFile,
sprintf "%s\n\n%s" (moduleDeclaration provider) forceRebuild))
)
Target.create "Build" (fun _ ->
let buildOptions options : DotNet.BuildOptions = {
options with
Common = {
options.Common with
Verbosity = Some DotNet.Verbosity.Quiet
}
NoLogo = true
MSBuildParams = {
options.MSBuildParams with
Properties = ("NoRegenerate","true") :: options.MSBuildParams.Properties
}
}
getProvider args |>
getProviders |>
Array.map (getProjectFiles >> Seq.exactlyOne) |>
Seq.iter (traceNested (DotNet.build buildOptions))
)
Target.create "PublishGeneratedCode" (fun _ ->
!! (getProvider args |> getFullName |> sprintf "**/%s/Generated.fs") |>
Seq.iter (Trace.publish ImportData.BuildArtifact)
)
type NuGetVersions =
{
versions: string[]
}
Target.create "Pack" (fun _ ->
getProvider args |>
getProviders |>
Seq.iter (fun provider ->
let nextExtensionsVersion =
getFullName provider |>
// This does not work and returns wrong package
//NuGet.getLatestPackage (NuGet.getRepoUrl()) |>
//(fun x -> x.Version.Split('.')) |>
// So we have to do this crap...
sprintf "https://www.nuget.org/packages/%s" |>
get "" "" |>
(fun x -> x.Split('\n')) |>
Array.find (fun x -> x.Contains("packageVersion")) |>
(fun x -> x.Split('"')) |>
Array.item 1 |>
(fun x -> x.Split('.')) |>
Array.last |>
Int32.Parse |>
(+)1
let pulumiPackageName =
Map.empty |>
Map.add "AzureNativeV2" "AzureNative" |>
Map.tryFind provider |>
Option.defaultValue provider
let xPath =
sprintf "/Project/ItemGroup/PackageReference[@Include='Pulumi.%s']" pulumiPackageName
let projectFile =
getProjectFiles provider |>
Seq.exactlyOne
let pulumiNuGetVersion =
projectFile |>
loadDoc |>
selectXPathAttributeValue xPath
"Version"
[]
let packOptions options : DotNet.PackOptions = {
options with
MSBuildParams = {
options.MSBuildParams with
DisableInternalBinLog = true
Properties =
("PackageVersion", sprintf "%s.%i" pulumiNuGetVersion nextExtensionsVersion) ::
("NoRegenerate","true") ::
options.MSBuildParams.Properties
}
}
projectFile |>
traceNested (DotNet.pack packOptions)
)
)
Target.create "Push" (fun _ ->
let vaultFile =
Environment.environVarOrNone "FAKEVAULTFILE_SECUREFILEPATH" |>
Option.defaultValue vaultFile |>
FileInfo
let vault =
match Vault.fromFakeEnvironmentOrNone(), vaultFile.Exists with
| Some vault, _ -> vault
| None , true -> vaultFile.OpenText().ReadToEnd() |> Vault.fromJson
| None , false -> failwith "Unsupported source for secrets"
let pushOptions options : DotNet.NuGetPushOptions = {
options with
PushParams = {
options.PushParams with
ApiKey = Vault.tryGet nuGetApiKey vault
Source = Some "https://api.nuget.org/v3/index.json"
}
}
!! (getProvider args |> getFullName |> sprintf "**/%s.*.nupkg") |>
Seq.iter (DotNet.nugetPush pushOptions)
)
Target.create "Default" ignore
"Install" =?>
("ForceRegeneration" , BuildServer.isLocalBuild) ==>
"Build"
"Install" =?>
("ForceRegeneration" , BuildServer.isLocalBuild) ==>
"Pack" =?>
("PublishGeneratedCode", not BuildServer.isLocalBuild) =?>
("Push" , not BuildServer.isLocalBuild) ==>
"Default"
args |>
getTarget |>
Target.runOrDefaultWithArguments