GitHub.psm1

<#
    .SYNOPSIS
    Copies a GitHub repository to a local path, similar to what "git pull" would do,
    and returns the path to the repository.
#>

function Copy-GitHubRepository 
{ 
    param( 
       [Parameter(Mandatory=$True)]
       [ValidateNotNullOrEmpty()]
       [string]
       $Name, 
        
       [Parameter(Mandatory=$True)]
       [ValidateNotNullOrEmpty()]
       [string]
       $Author, 

       [Parameter(Mandatory=$True)]
       [ValidateNotNullOrEmpty()]
       [string]
       $DownloadPath, 
        
       [Parameter(ParameterSetName='SpecifyConnectionFields', Mandatory=$True)]
       [ValidateNotNullOrEmpty()]
       [string]
       $AccessToken,

       [Parameter(ParameterSetName='UseConnectionObject', Mandatory=$True)] 
       [ValidateNotNullOrEmpty()]
       [Hashtable]
       $Connection,

       [Parameter(Mandatory=$False)] 
       [string]
       $Branch = "master"
    )
     
    $ZipFile = "$DownloadPath\$Name.zip" 
    $OutputFolder = "$DownloadPath\$Name\$Branch" 
 
    $RepositoryZipUrl = "https://api.github.com/repos/$Author/$Name/zipball/$Branch" 

    $Connection = CreateGithHubCredential -AccessToken $AccessToken -Connection $Connection
 
    # download the zip
    Invoke-RestMethod -Uri $RepositoryZipUrl -Headers @{"Authorization" = "token $($Connection.AccessToken)"} -OutFile $ZipFile 
     
    # extract the zip
    New-Item -Path $OutputFolder -ItemType Directory -Force | Out-Null 
         
    [System.Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') | Out-Null 
    [System.IO.Compression.ZipFile]::ExtractToDirectory($ZipFile, $OutputFolder) 
 
    # remove zip
    Remove-Item -Path $ZipFile -Force 
     
    #output the path to the downloaded repository
    (ls $OutputFolder)[0].FullName 
}

<#
    .SYNOPSIS
    Retrieves a commit from the specified repository. If no commit ID (sha) is specified, gets the latest commit from the specified branch (defaults to master branch)
#>

function Get-GithubCommit {
    param( 
        
       [Parameter(Mandatory=$True)]
       [ValidateNotNullOrEmpty()]
       [string]
       $Author, 

       [Parameter(Mandatory=$True)]
       [ValidateNotNullOrEmpty()]
       [string]
       $Repository, 
        
       [Parameter(ParameterSetName='SpecifyConnectionFields', Mandatory=$True)]
       [ValidateNotNullOrEmpty()]
       [string]
       $AccessToken,

       [Parameter(ParameterSetName='UseConnectionObject', Mandatory=$True)] 
       [ValidateNotNullOrEmpty()]
       [Hashtable]
       $Connection,

       [Parameter(Mandatory=$False)] 
       [string]
       $Sha,

       [Parameter(Mandatory=$False)] 
       [string]
       $Branch="master"
    )
    
    $Connection = CreateGithHubCredential -AccessToken $AccessToken -Connection $Connection
    $Headers  = @{"Authorization" = "token $($Connection.AccessToken)"}

    if($Sha) {
        $UrlPart = $Sha
    }
    else {
        $UrlPart = $Branch
    }
    
    $Response = Invoke-WebRequest -Method GET -Uri "https://api.github.com/repos/$Author/$Repository/commits/$UrlPart" -Headers $Headers -UseBasicParsing
    if ($Response -eq $null) {
        Write-Error "No response content returned. Ensure you are checking the correct repository that has at least one commit."
    }
   
    $ResponseContent = $Response.Content | ConvertFrom-Json 

    return $ResponseContent
}

<#
    .SYNOPSIS
    Retrieves a list of commits for the specified repository. If StartTime is specified, only commits since that time (UTC) will be returned
#>

function List-GithubCommits {
    param( 
        
       [Parameter(Mandatory=$True)]
       [ValidateNotNullOrEmpty()]
       [string]
       $Author, 

       [Parameter(Mandatory=$True)]
       [ValidateNotNullOrEmpty()]
       [string]
       $Repository,
        
       [Parameter(ParameterSetName='SpecifyConnectionFields', Mandatory=$True)]
       [ValidateNotNullOrEmpty()]
       [string]
       $AccessToken,

       [Parameter(ParameterSetName='UseConnectionObject', Mandatory=$True)] 
       [ValidateNotNullOrEmpty()]
       [Hashtable]
       $Connection,

       [Parameter(Mandatory=$False)]
       [ValidateNotNullOrEmpty()]
       [DateTime]
       $StartTime
   )
    
    $Connection = CreateGithHubCredential -AccessToken $AccessToken -Connection $Connection
    $Headers  = @{"Authorization" = "token $($Connection.AccessToken)"}
    
    $Url = "https://api.github.com/repos/$Author/$Repository/commits"
    $Uri = "https://api.github.com/repos/$Author/AzureAutomationRunbooks/git/blobs/fbc3b79f76e7ee579884f154f925012dbc6bef84"
    if($StartTime) {
        $Url += "?since=" + (Get-Date $StartTime -format "s") + "+00:00"
    }

    $Response = Invoke-WebRequest -Method GET -Uri $Url -Headers $Headers -UseBasicParsing
    if ($Response -eq $null) {
        Write-Error "No response content returned. Ensure you are checking the correct repository that has at least one commit."
    }
   
    $ResponseContent = $Response.Content | ConvertFrom-Json 

    return $ResponseContent
}

function Get-BlobContent {
    $GithubUriGetBlob = "https://api.github.com/repos/{0}/{1}/git/blobs/{2}"
    $Owner = "epc2101"
    $Repo = "AzureAutomationRunbooks"
    $ItemSha = "fbc3b79f76e7ee579884f154f925012dbc6bef84"
    $AccessToken = "31eb14971445ca570e7c0abb1e6a10fdd8a1df1a"

    $Connection = CreateGithHubCredential -AccessToken $AccessToken -Connection $Connection
    $Headers  = @{"Authorization" = "token $($Connection.AccessToken)"}
    $Uri = [string]::Format($GithubUriGetBlob, $Owner, $Repo, $ItemSha)
    $Uri = "https://api.github.com/repos/epc2101/AzureAutomationRunbooks/git/blobs/" #fbc3b79f76e7ee579884f154f925012dbc6bef84"
       $Url = "https://api.github.com/repos/epc2101/AzureAutomationRunbooks/commits"
    $BlobData = Invoke-RestMethod -Method Get -Uri $Uri -Headers $Headers -UseBasicParsing


}


function CreateGithHubCredential {
    Param(
        [string] $AccessToken,
        [Hashtable] $Connection
    )

    if(!$Connection -and (!$AccessToken)) {
        throw("No connection data specified. You must use either the Connection parameter, or the AccessToken parameters.")
    }

    if(!$Connection) {
        $Con = @{}
    }
    elseif(!$Connection.AccessToken) {
        throw("Connection object must contain AccessToken property.")
    }
    else {
        $Con = @{
            AccessToken = $Connection.AccessToken;
        }
    }

    if($AccessToken) {
        $Con.AccessToken = $AccessToken
    }

    return $Con
}

Export-ModuleMember Get-GithubCommit, Copy-GitHubRepository, List-GithubCommits