Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BuildServer get latest build status #2471

Closed
halcwb opened this issue Feb 20, 2020 · 2 comments
Closed

BuildServer get latest build status #2471

halcwb opened this issue Feb 20, 2020 · 2 comments

Comments

@halcwb
Copy link

halcwb commented Feb 20, 2020

Description

Currently I have some code to get the build status from Travis and AppVeyor. I can then use this to automatically merge my development branch with the master branch depending upon the results of the latest builds. Is there a specific Fake api I can use as well?

Repro steps

Please provide the steps required to reproduce the problem

Code to get the latest builds:

module Travis =

    open System
    open Newtonsoft.Json

    [<CLIMutable>]
    type Build = 
        {
            commit_id: Nullable<int>
            number: string
            duration: Nullable<int>
            finished_at: Nullable<DateTime>
            started_at: Nullable<DateTime>
            state: string
        }

    type Commit = 
        {
            id: Nullable<int> 
            sha: string
            branch: string
            message: string
            committed_at: string
        }

    [<CLIMutable>]
    type Builds =
        {
            builds: Build[]
            commits: Commit[]
        }

    let getLatestBuild project =
        try
            let url = sprintf "http://api.travis-ci.org/repos/halcwb/%s/builds" project
            let wr = System.Net.HttpWebRequest.Create(url) :?> System.Net.HttpWebRequest
            wr.Host <- "api.travis-ci.org"
            wr.UserAgent <- project
            wr.Accept <- "application/vnd.travis-ci.2+json"
            let resp = wr.GetResponse()
            use reader = new IO.StreamReader(resp.GetResponseStream())
            let json = reader.ReadToEnd()
            //    printfn "%A" json
            let builds = JsonConvert.DeserializeObject<Builds>(json)
            (builds.commits.[0].sha, builds.builds.[0].started_at, builds.commits.[0].branch, builds.builds.[0].state) |> Some
        with 
        | e -> printfn "Failed with %A" e; None


module AppVeyor =

    open Newtonsoft.Json

    type Project = 
        {
            repositoryName: string
            repositoryBranch : string
            updated: System.DateTime
        }


    type Build = 
        {
            buildNumber: int
            branch: string
            commitId : string
            status : string
            started: System.DateTime
        }

    type Result = 
        {
            project: Project
            build: Build
        }


    let getLatestBuild project =
        try
            let url = sprintf "https://ci.appveyor.com/api/projects/%s/%s" "halcwb" project
            let wr = System.Net.HttpWebRequest.Create(url) :?> System.Net.HttpWebRequest
            wr.Accept <- "application/json"
            let resp = wr.GetResponse()
            use reader = new System.IO.StreamReader(resp.GetResponseStream())
            let json = reader.ReadToEnd()
            let build = JsonConvert.DeserializeObject<Result>(json)
            (build.build.commitId, build.build.started, build.build.branch, build.build.status) |> Some
        with
        | e -> printfn "%A" e; None

Code to have an "integrate" target:

// --------------------------------------------------------------------------------------
// Integrate current branch with master

Target.create "Integrate" <| fun _ ->
    let master   = "master"
    let remote   = "origin"
    let develop  = currentBranch
    let currDir  = __SOURCE_DIRECTORY__
    let traVsucc = "passed"
    let appVsucc = "success"
    let currId   = Git.Information.getCurrentSHA1 currDir   

    printfn "Starting to integrate"
    if Git.Information.isCleanWorkingCopy currDir |> not then 
        failwith "Working copy is not clean, cannot integrate"
    else
        // Get the latest mono build
        let lastTravisBuild   = Travis.getLatestBuild gitName
        // Get the latest .Net build
        let lastAppVeyorBuild = AppVeyor.getLatestBuild gitName

        // Check whether the builds passed
        match lastTravisBuild, lastAppVeyorBuild with
        | Some (id, dt, br, st), Some (id', dt', br', st') -> 
            if id = currId && id = id' && st = traVsucc && st' = appVsucc then
                printfn "Last build was at %A and %s" dt st
                // Update the master branch with the latest remote master
                Git.Branches.checkoutBranch currDir master
                Git.Branches.pull "" remote master
                // Merge the master with the current development branch
                Git.Merge.merge currDir Git.Merge.FastForwardFlag develop
                // Update the remote master branch
                Git.Branches.pushBranch currDir remote master
                // Checkout the current development branch
                Git.Branches.checkoutBranch currDir develop
            else 
                printfn "curr: %s, travis: %s, appveyor; %s" currId id id'
                sprintf "Last build did not pass on %s" (if st = traVsucc then "AppVeyor" else "Travis")
                |> failwith
        | e   -> 
            failwith <| sprintf "Cannot get last build, cannot integrate: %A" e

Expected behavior

NA

Actual behavior

NA

Known workarounds

With the above code I have a target I can run that only merges the current branch with the master branch if the integration builds have succeeded.

Related information

FAKE 5 - F# Make (5.19.1) (this line is written to standard error, see #2066)
Paket.Core: 5.241.2

@matthid
Copy link
Member

matthid commented Feb 21, 2020

I'm not sure I get the question, so you are asking if there is another API for the code you have written?
Currently I don't think there is but feel free to send a PR, I guess?

@halcwb
Copy link
Author

halcwb commented Feb 22, 2020

Thanks, I wanted indeed to know whether there is an existing api in FAKE. I am currently looking at the MiniScaffold template, maybe it is more appropriate to have this functionality in the template.

@halcwb halcwb closed this as completed Feb 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants