-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.fsx
298 lines (246 loc) · 9.07 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
287
288
289
290
291
292
293
294
295
296
297
298
#r "paket: groupref Build //"
#load "./.fake/build.fsx/intellisense.fsx"
open Fake.Api
open Fake.Core
open Fake.IO
open Fake.DotNet
open Fake.IO.FileSystemOperators
open Fake.Core.TargetOperators
open Fake.DotNet.Testing
open Fake.IO.Globbing.Operators
open Fake.Tools
open System
open System.IO
let concatPath pathTokens =
let rec add accumulated = function
| [] -> accumulated
// | [a] -> System.IO.Path.Combine(accumulated, a)
| head::tail -> add (System.IO.Path.Combine(accumulated, head)) tail
add "" pathTokens
let project = "FSharp.FsxConfig"
let summary = "FSharp.FsxConfig provides a simple tool for using fsx files as configuration"
let configuration = "Release"
let solutionFile = "FSharp.FsxConfig.sln"
let libraryFile = "src/FSharp.FsxConfig/FSharp.FsxConfig.fsproj"
let srcCodeGlob =
!! (__SOURCE_DIRECTORY__ </> "src/**/*.fs")
++ (__SOURCE_DIRECTORY__ </> "src/**/*.fsx")
-- (__SOURCE_DIRECTORY__ </> "src/**/obj/**/*.fs")
let testsCodeGlob =
!! (__SOURCE_DIRECTORY__ </> "tests/**/*.fs")
++ (__SOURCE_DIRECTORY__ </> "tests/**/*.fsx")
-- (__SOURCE_DIRECTORY__ </> "tests/**/obj/**/*.fs")
let gitOwner ="mecumihaisorin"
let distDir = __SOURCE_DIRECTORY__ @@ "nuget_dist"
let distGlob = distDir @@ "*.nupkg"
let githubToken = Environment.environVarOrNone "GITHUB_TOKEN"
Option.iter(TraceSecrets.register "<GITHUB_TOKEN>" )
let nugetToken = Environment.environVarOrNone "NUGET_TOKEN"
Option.iter(TraceSecrets.register "<NUGET_TOKEN>")
let failOnBadExitAndPrint (p : ProcessResult) =
if p.ExitCode <> 0 then
p.Errors |> Seq.iter Trace.traceError
failwithf "failed with exitcode %d" p.ExitCode
module dotnet =
let watch cmdParam program args =
DotNet.exec cmdParam (sprintf "watch %s" program) args
let run cmdParam args =
DotNet.exec cmdParam "run" args
let tool optionConfig command args =
DotNet.exec optionConfig (sprintf "%s" command) args
|> failOnBadExitAndPrint
let fantomas args =
DotNet.exec id "fantomas" args
let formatCode _ =
let result =
[
srcCodeGlob
testsCodeGlob
]
|> Seq.collect id
// Ignore AssemblyInfo
|> Seq.filter(fun f -> f.EndsWith("AssemblyInfo.fs") |> not)
|> String.concat " "
|> dotnet.fantomas
if not result.OK then
printfn "Errors while formatting all files: %A" result.Messages
let checkFormatCode _ =
let result =
[
srcCodeGlob
testsCodeGlob
]
|> Seq.collect id
// Ignore AssemblyInfo
|> Seq.filter(fun f -> f.EndsWith("AssemblyInfo.fs") |> not)
|> String.concat " "
|> sprintf "%s --check"
|> dotnet.fantomas
if result.ExitCode = 0 then
Trace.log "No files need formatting"
elif result.ExitCode = 99 then
failwith "Some files need formatting, check output for more info"
else
Trace.logf "Errors while formatting: %A" result.Errors
Target.create "Clean" (fun _ ->
!! "bin"
++ "src/**/bin"
++ "tests/**/bin"
++ "src/**/obj"
++ "tests/**/obj"
|> Shell.cleanDirs
[
"paket-files/paket.restore.cached"
]
|> Seq.iter Shell.rm
)
Target.create "Build" (fun _ ->
let setParams (defaults:DotNet.BuildOptions) =
{ defaults with
NoRestore = true
Configuration = DotNet.BuildConfiguration.fromString configuration}
DotNet.build setParams solutionFile
)
Target.create "Restore" (fun _ ->
Fake.DotNet.Paket.restore (fun p -> {p with ToolType = ToolType.CreateLocalTool()} )
DotNet.restore id solutionFile
)
let runTestAssembly (testAssembly, args: string list option)=
printfn "Should execute %s" testAssembly
let exitCode =
let parameters = Expecto.Params.DefaultParams
let workingDir =
if String.isNotNullOrEmpty parameters.WorkingDirectory
then parameters.WorkingDirectory else Fake.IO.Path.getDirectory testAssembly
let extraArgs =
match args with
| Some a -> a
| None -> []
Command.RawCommand("dotnet", Arguments.OfArgs [testAssembly; yield! extraArgs; parameters |> string ])
|> CreateProcess.fromCommand
|> CreateProcess.withWorkingDirectory workingDir
|> Proc.run
|> fun pr -> pr.ExitCode
testAssembly, exitCode
let runTests testAssemblies =
let details = testAssemblies |> Seq.map fst |> String.separated ", "
use __ = Trace.traceTask "Expecto" details
let res =
testAssemblies
|> Seq.map runTestAssembly
|> Seq.filter( snd >> (<>) 0)
|> Seq.toList
match res with
| [] -> ()
| failedAssemblies ->
failedAssemblies
|> List.map (fun (testAssembly,exitCode) ->
sprintf "Expecto test of assembly '%s' failed. Process finished with exit code %d." testAssembly exitCode )
|> String.concat System.Environment.NewLine
|> Fake.Testing.Common.FailedTestsException |> raise
__.MarkSuccess()
let testProjects ()= [
["tests"; "FSharp.FsxConfig.Tests"], Some ["scriptpath>" + concatPath [".."; ".."; ".."]] //"tests"; "FSharp.FsxConfig.Tests"]]
]
let testAssemblies () = [
for (proj, extraArgs) in testProjects () do
let projName = proj |> List.last
let pattern = concatPath proj </> "bin" </> configuration </> "**" </> (projName + ".dll")
yield! (!!pattern |> Seq.map(fun x -> x, extraArgs))
]
Target.create "RunTests" (fun _ ->
testAssemblies () |> runTests
)
let release = ReleaseNotes.load "RELEASE_NOTES.md"
Target.create "AssemblyInfo" (fun _ ->
let getAssemblyInfoAttributes projectName =
[ AssemblyInfo.Title (projectName)
AssemblyInfo.Product project
AssemblyInfo.Description summary
AssemblyInfo.Version release.AssemblyVersion
AssemblyInfo.FileVersion release.AssemblyVersion
AssemblyInfo.Configuration configuration ]
let getProjectDetails (projectPath: string) =
let projectName = Path.GetFileNameWithoutExtension(projectPath)
( projectPath,
projectName,
Path.GetDirectoryName(projectPath),
(getAssemblyInfoAttributes projectName)
)
!! "src/**/*.??proj"
|> Seq.map getProjectDetails
|> Seq.iter (fun (_, _, folderName, attributes) ->
AssemblyInfoFile.createFSharp (folderName </> "AssemblyInfo.fs") attributes)
)
let releaseNotes = String.toLines release.Notes
Target.create "NuGet" (fun _ ->
[libraryFile]
|> Seq.iter (
DotNet.pack(fun p ->
{ p with
// ./bin from the solution root matching the "PublishNuget" target WorkingDir
OutputPath = Some distDir
Configuration = DotNet.BuildConfiguration.Release
MSBuildParams = {MSBuild.CliArguments.Create() with
// "/p" (property) arguments to MSBuild.exe
Properties = [("Version", release.NugetVersion)
("PackageReadmeFile", "readme.md")
("PackageProjectUrl", "https://github.com/MecuSorin/FSharp.FsxConfig")
("PackageLicenseFile", "license")
("PackageReleaseNotes", releaseNotes)]}}))
)
Target.create "FormatCode" formatCode
Target.create "CheckFormatCode" checkFormatCode
Target.create "PublishNuget" (fun _ ->
Paket.push(fun p ->
{ p with
ToolType = ToolType.CreateLocalTool()
PublishUrl = "https://www.nuget.org"
WorkingDir = distDir
ApiKey =
match nugetToken with
| Some s -> s
| _ -> p.ApiKey // assume paket-config was set properly
}
)
)
Target.create "GitRelease"(fun _ ->
let remote = "origin"
Git.Staging.stageAll ""
Git.Commit.exec "" (sprintf "Bump version to %s\n\n%s" release.NugetVersion releaseNotes)
Git.Branches.push ""
Git.Branches.tag "" release.NugetVersion
Git.Branches.pushTag "" remote release.NugetVersion
)
Target.create "GitHubRelease" (fun _ ->
let token =
match githubToken with
| Some s -> s
| _ -> failwith "please set the github_token environment variable to a github personal access token with repo access."
let files = !! distGlob
GitHub.createClientWithToken token
|> GitHub.draftNewRelease gitOwner project release.NugetVersion (release.SemVer.PreRelease <> None) (releaseNotes |> Seq.singleton)
|> GitHub.uploadFiles files
|> GitHub.publishDraft
|> Async.RunSynchronously
)
Target.create "Release" ignore
Target.create "UpdateDocs" (fun _ ->
Git.Staging.stageAll ""
Git.Commit.exec "" "update docs"
Git.Branches.push ""
)
"UpdateDocs"
// *** Define Dependencies ***
"Clean"
==> "AssemblyInfo"
==> "Restore"
==> "Build"
==> "RunTests"
==> "NuGet"
==> "PublishNuGet"
// ==> "GitRelease"
// ==> "GitHubRelease"
// ==> "Release"
// *** Start Build ***
Target.runOrDefaultWithArguments "RunTests"