UMN-Github.psm1

###
# Copyright 2017 University of Minnesota, Office of Information Technology

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with Foobar. If not, see <http://www.gnu.org/licenses/>.

###########################
#
# Module for interacting with on premise gitHub service.
# Module is designed to work with both public and private(Enterprise) github APIv3 over https ONLY
# https://developer.github.com/enterprise/2.8/v3/
#
###########################

#region Get-GitHubCommit
function Get-GitHubCommit {
    <#
        .SYNOPSIS
            Get a specific commit for a specific repo

        .DESCRIPTION
            Get a specific commit for a specific repo

        .PARAMETER psCreds
            PScredential composed of your username/password to Git Server

        .PARAMETER authToken
            Use instead of user/pass, personal auth token

        .PARAMETER sha
            sha for the commit, use Get-GitHubRepoRef to get it

        .PARAMETER Repo
            Repository name string which is used to identify which repository under the organization to go into.

        .PARAMETER Org
            Organization name string which is used to identify which organization in the GitHub instance to go into.


        .NOTES
            Name: Get-GitHubCommit
            Author: Travis Sobeck
            LASTEDIT: 6/20/2017

        .EXAMPLE
            Get-GitHubCommit -Username "Test" -Password "pass" -Repo "MyFakeReop" -Org "MyFakeOrg" -server "onPremiseServer" -sha $sha

    #>

    [CmdletBinding()]
    param(
        
        [System.Management.Automation.PSCredential]$psCreds,

        [string]$authToken,

        [Parameter(Mandatory)]
        [string]$Repo,

        [Parameter(Mandatory)]
        [string]$Org,

        [Parameter(Mandatory)]
        [string]$sha,

        ## The Default is public github but you can se this if you are running your own Enterprise Github server
        [string]$server = 'github.com'
    )

    if ($authToken){$Headers = @{"Authorization" = "token $authToken"}}
    elseif($psCreds){
        $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($psCreds.UserName+':'+$psCreds.GetNetworkCredential().Password))    
        $Headers = @{"Authorization" = "Basic $auth"}
    }
    if ($server -eq 'github.com'){$conn = "https://api.github.com"}
    else{$conn = "https://$server/api/v3"}
    $URI = "$conn/repos/$org/$Repo/git/commits/$sha"
    Invoke-RestMethod -Method Get -Uri $URI -Headers $Headers
}
#endregion

#region Get-GitHubRepoContent
function Get-GitHubRepoContent {
    <#
        .SYNOPSIS
            Get file content from a GitHub Repo.

        .DESCRIPTION
            Get file content from a GitHub Repo.

        .PARAMETER psCreds
            PScredential composed of your username/password to Git Server

        .PARAMETER authToken
            Use instead of user/pass, personal auth token

        .PARAMETER File
            File to get content of

        .PARAMETER Repo
            Repository name string which is used to identify which repository under the organization to go into.

        .PARAMETER Org
            Organization name string which is used to identify which organization in the GitHub instance to go into.

        .NOTES
            Author: Travis Sobeck
            LASTEDIT: 4/26/2017

        .EXAMPLE
            Get-GitHubRepoContent -Username "Test" -Password "pass" -File "psscript.ps1" -Repo "MyFakeReop" -Org "MyFakeOrg" -server "ServerFQDN"

    #>

    [CmdletBinding()]
    param(
        
        [System.Management.Automation.PSCredential]$psCreds,

        [string]$authToken,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$File,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Repo,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Org,

        ## The Default is public github but you can se this if you are running your own Enterprise Github server
        [string]$server = 'github.com'
    )

    if ($authToken){$Headers = @{"Authorization" = "token $authToken"}}
    elseif($psCreds){
        $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($psCreds.UserName+':'+$psCreds.GetNetworkCredential().Password))    
        $Headers = @{"Authorization" = "Basic $auth"}
    }
    if ($server -eq 'github.com'){$conn = "https://api.github.com"}
    else{$conn = "https://$server/api/v3"}
    $URI = "$conn/repos/$org/$Repo/contents/$File"
    Invoke-RestMethod -Method Get -Uri $URI -Headers $Headers
    
}
#endregion

#region Get-GitHubRepoRef
function Get-GitHubRepoRef {
    <#
        .SYNOPSIS
            Get a specific reference or all references for a specific repo

        .DESCRIPTION
            Get a specific reference or all references for a specific repo, use -ref for a specific reference

        .PARAMETER psCreds
            PScredential composed of your username/password to Git Server

        .PARAMETER authToken
            Use instead of user/pass, personal auth token

        .PARAMETER ref
            Specific ref, run the command without it to get a list example would be.

        .PARAMETER Repo
            Repository name string which is used to identify which repository under the organization to go into.

        .PARAMETER Org
            Organization name string which is used to identify which organization in the GitHub instance to go into.


        .NOTES
            Name: Get-GitHubRepoRefs
            Author: Travis Sobeck
            LASTEDIT: 4/26/2017

        .EXAMPLE
            Get-GitHubRepoRefs -Username "Test" -Password "pass" -Repo "MyFakeReop" -Org "MyFakeOrg" -server "onPremiseServer"

        .EXAMPLE
            Get-GitHubRepoRefs -Username "Test" -Password "pass" -Repo "MyFakeReop" -Org "MyFakeOrg" -server "onPremiseServer" -ref 'refs/heads/master'

    #>

    [CmdletBinding()]
    [Alias("Get-GitHubRepoRefs")]
    param(
        
        [System.Management.Automation.PSCredential]$psCreds,

        [string]$authToken,

        [Parameter(Mandatory)]
        [string]$Repo,

        [Parameter(Mandatory)]
        [string]$Org,

        [string]$ref,

        ## The Default is public github but you can se this if you are running your own Enterprise Github server
        [string]$server = 'github.com'
    )

    if ($authToken){$Headers = @{"Authorization" = "token $authToken"}}
    elseif($psCreds){
        $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($psCreds.UserName+':'+$psCreds.GetNetworkCredential().Password))    
        $Headers = @{"Authorization" = "Basic $auth"}
    }
    if ($server -eq 'github.com'){$conn = "https://api.github.com"}
    else{$conn = "https://$server/api/v3"}
    if (-not($ref)){$ref = 'refs'}
    $URI = "$conn/repos/$org/$Repo/git/$ref"
    try{return(Invoke-RestMethod -Method Get -Uri $URI -Headers $Headers)}
    catch{throw $Error[0]}
}
#endregion

#region Get-GitHubRepoFile
function Get-GitHubRepoFile {
    <#
        .SYNOPSIS
            Get a file from a GitHub Repo.

        .DESCRIPTION
            Takes in a username, password, filename, repository, organization and a file to output to then downloads the file
            from the repository.

        .PARAMETER psCreds
            PScredential composed of your username/password to Git Server

        .PARAMETER authToken
            Use instead of user/pass, personal auth token

        .PARAMETER File
            Filename string which needs to be downloaded from the repository.

        .PARAMETER Repo
            Repository name string which is used to identify which repository under the organization to go into.

        .PARAMETER Org
            Organization name string which is used to identify which organization in the GitHub instance to go into.

        .PARAMETER OutFile
            A string representing the local file path to download the GitHub file to.

        .NOTES
            Name: Get-GitHubRepoFile
            Author: Jeff Bolduan
            LASTEDIT: 4/26/2017

        .EXAMPLE
            Get-GitHubRepoFile -Username "Test" -Password "pass" -File "psscript.ps1" -Repo "MyFakeReop" -Org "MyFakeOrg" -OutFile "C:\temp\psscript.ps1" -server "ServerFQDN"

    #>

    [CmdletBinding()]
    param(
        
        [System.Management.Automation.PSCredential]$psCreds,

        [string]$authToken,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$File,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Repo,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Org,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$OutFile,

        ## The Default is public github but you can se this if you are running your own Enterprise Github server
        [string]$server = 'github.com'
    )

    if ($authToken){$Headers = @{"Authorization" = "token $authToken"}}
    elseif($psCreds){
        $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($psCreds.UserName+':'+$psCreds.GetNetworkCredential().Password))    
        $Headers = @{"Authorization" = "Basic $auth"}
    }
    if ($server -eq 'github.com'){$conn = "https://api.github.com"}
    else{$conn = "https://$server/api/v3"}
    $URI = "$conn/repos/$org/$Repo/contents/$File"
    $RESTRequest = Invoke-RestMethod -Method Get -Uri $URI -Headers $Headers
    if($RESTRequest.download_url -eq $null) {
        throw [System.IO.IOException]
    } else {
        $null = Invoke-WebRequest -Uri $RESTRequest.download_url -Headers $Headers -OutFile $OutFile
    }
}
#endregion

#region Get-GitHubRepoUnZipped
function Get-GitHubRepoUnZipped {
<#
    .SYNOPSIS
        Get a GitHub Repo.

    .DESCRIPTION
        Takes in a username, password, repository, organization and a folder to output to then downloads the files
        from the repository.

    .PARAMETER psCreds
            PScredential composed of your username/password to Git Server

    .PARAMETER authToken
        Use instead of user/pass, personal auth token

    .PARAMETER Repo
        Repository name string which is used to identify which repository under the organization to go into.

    .PARAMETER Org
        Organization name string which is used to identify which organization in the GitHub instance to go into.

    .PARAMETER OutFolder
        A string representing the local file path to download the GitHub Reop file to.


    .EXAMPLE
        Get-GitHubRepoUnZipped -authToken $authToken -Repo $repo -Org $org -OutFolder $pathToFolder.
#>


    [CmdletBinding()]
    param(
        
        [System.Management.Automation.PSCredential]$psCreds,

        [string]$authToken,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Org,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$repo,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$outFolder,

        [Parameter(Mandatory=$true)]
        [string]$ref = "master",

        ## The Default is public github but you can se this if you are running your own Enterprise Github server
        [string]$server = 'github.com'
    )

    # validate folder exits #
    if (-not(Test-Path $outFolder)){$null = New-Item $outFolder -ItemType Directory -Force}
    # get zip
    if ($authToken){Get-GitHubRepoZip -authToken $authToken -Org $org -repo $repo -OutFile "$outFolder\$repo.zip" -ref $ref -server $server}
    elseif($psCreds){Get-GitHubRepoZip -psCreds $psCreds -Org $org -repo $repo -OutFile "$outFolder\$repo.zip" -ref $ref -server $server}
    else{Get-GitHubRepoZip -Org $org -repo $repo -OutFile "$outFolder\$repo.zip" -ref $ref -server $server}
    # unzip
    Expand-Archive -Path "$outFolder\$repo.zip" -DestinationPath $outFolder -Force
    # get the actual folder name, yeah this looks funky but OpenRead locks the file, this is need to get the folder name and still remove the zip file later
    $scriptblock = {Param( [string]$path)
        $null = [Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
        $folder = [IO.Compression.ZipFile]::OpenRead((Get-Item -Path $path).FullName).Entries[0].FullName
        $folder = $folder.TrimEnd('/') # trip the stupid trailing slash
        $folder
    }
    $job = Start-Job -Name 'temp' -ArgumentList "$outFolder\$repo.zip" -ScriptBlock $scriptblock
    do{Start-Sleep -Seconds 1}until((Get-Job -Id $job.Id).State -eq 'Completed')
    $folder = Receive-Job -Job $job
    
    # rename the folder the the repo
    Rename-Item -Path "$outFolder\$folder" -NewName "$repo"-Force
    Remove-Item -Path "$outFolder\$repo.zip" -Force
}
#endregion

#region Get-GitHubRepoZip
function Get-GitHubRepoZip {
    # https://developer.github.com/v3/repos/contents/#get-archive-link

<#
    .SYNOPSIS
        Get a GitHub Repo and download to zip file.

    .DESCRIPTION
        Takes in a PSCredention or Auth Key if needed, repository, organization and a file to output to then downloads the file
        from the repository.

    .PARAMETER psCreds
            PScredential composed of your username/password to Git Server

    .PARAMETER authToken
        Use instead of PScredential, personal auth token

    .PARAMETER Repo
        Repository name string which is used to identify which repository under the organization to go into.

    .PARAMETER Org
        Organization name string which is used to identify which organization in the GitHub instance to go into.

    .PARAMETER OutFile
        A string representing the local file path to download the GitHub Zip file to.


    .EXAMPLE
        Get-GitHubRepoZip -authToken $authToken -Repo $repo -Org $org -OutFile $outFile -server "ServerFQDN"

#>

    [CmdletBinding()]
    param(
        
        [System.Management.Automation.PSCredential]$psCreds,

        [string]$authToken,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Org,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$repo,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$OutFile,

        [Parameter(Mandatory=$true)]
        [string]$ref = "master",

        ## The Default is public github but you can se this if you are running your own Enterprise Github server
        [string]$server = 'github.com'
    )

    if ($authToken){$Headers = @{"Authorization" = "token $authToken"}}
    elseif($psCreds){
        $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($psCreds.UserName+':'+$psCreds.GetNetworkCredential().Password))    
        $Headers = @{"Authorization" = "Basic $auth"}
    }
    
    if ($server -eq 'github.com'){$conn = "https://api.github.com"}
    else{$conn = "https://$server/api/v3"}
    $URI = "$conn/repos/$Org/$repo/zipball/$ref"

    Invoke-RestMethod -Method Get -Uri $URI -Headers $Headers -OutFile $OutFile
}
#endregion

#region New-GitHubBlob
function New-GitHubBlob {
    <#
        .SYNOPSIS
            Create a new Blob

        .DESCRIPTION
            Create a new Blob

        .PARAMETER psCreds
            PScredential composed of your username/password to Git Server

        .PARAMETER authToken
            Use instead of user/pass, personal auth token

        .PARAMETER Repo
            Repository name string which is used to identify which repository under the organization to go into.

        .PARAMETER Org
            Organization name string which is used to identify which organization in the GitHub instance to go into.

        .PARAMETER filePath
            Path to file to be added/modified

        .NOTES
            Author: Travis Sobeck
            LASTEDIT: 6/20/2017

        .EXAMPLE
           

    #>

    [CmdletBinding()]
    param(
        
        [System.Management.Automation.PSCredential]$psCreds,

        [string]$authToken,

        [Parameter(Mandatory)]
        [string]$Repo,

        [Parameter(Mandatory)]
        [string]$Org,

        [Parameter(Mandatory)]
        [string]$filePath,

        ## The Default is public github but you can se this if you are running your own Enterprise Github server
        [string]$server = 'github.com'
    )

    if ($authToken){$Headers = @{"Authorization" = "token $authToken"}}
    elseif($psCreds){
        $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($psCreds.UserName+':'+$psCreds.GetNetworkCredential().Password))    
        $Headers = @{"Authorization" = "Basic $auth"}
    }
    if ($server -eq 'github.com'){$conn = "https://api.github.com"}
    else{$conn = "https://$server/api/v3"}
    $URI = "$conn/repos/$org/$Repo/git/blobs"
    $content = $base64 = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((Get-Content -Path $filePath -Raw)))
    $json = @{"content" = $content;"encoding" = "base64"} | ConvertTo-Json -Depth 3
    Invoke-RestMethod -Method Post -Uri $URI -Headers $Headers -Body $json
}
#endregion

#region New-GitHubCommit
function New-GitHubCommit {
    <#
        .SYNOPSIS
            Create a new commit for a specific repo

        .DESCRIPTION
            Create a new commit for a specific repo

        .PARAMETER psCreds
            PScredential composed of your username/password to Git Server

        .PARAMETER authToken
            Use instead of user/pass, personal auth token

        .PARAMETER Repo
            Repository name string which is used to identify which repository under the organization to go into.

        .PARAMETER Org
            Organization name string which is used to identify which organization in the GitHub instance to go into.

        .PARAMETER message
            The commit message
        
        .PARAMETER tree
            The SHA of the tree object this commit points to
            
        .PARAMETER parents
            The SHAs of the commits that were the parents of this commit. If omitted or empty, the commit will be written as a root commit. For a single parent, an array of one SHA should be provided; for a merge commit, an array of more than one should be provided.

        .NOTES
            Author: Travis Sobeck
            LASTEDIT: 6/20/2017

        .EXAMPLE
            

    #>

    [CmdletBinding()]
    param(
        
        [System.Management.Automation.PSCredential]$psCreds,

        [string]$authToken,

        [Parameter(Mandatory)]
        [string]$Repo,

        [Parameter(Mandatory)]
        [string]$Org,

        [Parameter(Mandatory)]
        [string]$message,

        [Parameter(Mandatory)]
        [string]$tree,

        [Parameter(Mandatory)]
        [array]$parents,

        ## The Default is public github but you can se this if you are running your own Enterprise Github server
        [string]$server = 'github.com'
    )

    if ($authToken){$Headers = @{"Authorization" = "token $authToken"}}
    elseif($psCreds){
        $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($psCreds.UserName+':'+$psCreds.GetNetworkCredential().Password))    
        $Headers = @{"Authorization" = "Basic $auth"}
    }
    if ($server -eq 'github.com'){$conn = "https://api.github.com"}
    else{$conn = "https://$server/api/v3"}
    $URI = "$conn/repos/$org/$Repo/git/commits"
    $content = Get-Content $filePath
    $json = @{"message" = $message; "parents" = $parents; "tree" = $tree} | ConvertTo-Json -Depth 3
    Invoke-RestMethod -Method Post -Uri $URI -Headers $Headers -Body $json
}
#endregion

#region New-GitHubTree
function New-GitHubTree {
    <#
        .SYNOPSIS
            Get a specific commit for a specific repo

        .DESCRIPTION
            Get a specific commit for a specific repo,

        .PARAMETER psCreds
            PScredential composed of your username/password to Git Server

        .PARAMETER authToken
            Use instead of user/pass, personal auth token

        .PARAMETER Repo
            Repository name string which is used to identify which repository under the organization to go into.

        .PARAMETER Org
            Organization name string which is used to identify which organization in the GitHub instance to go into.

        .PARAMETER path
            path to file in github
        
        .PARAMETER baseTree
            This is the SHA for the tree this is getting added onto, use Get-GitHubCommit and store ie $treeSha = $commit.tree.sha
            
        .PARAMETER mode
            The file mode; one of 100644 for file (blob), 100755 for executable (blob), 040000 for subdirectory (tree), 160000 for submodule (commit), or 120000 for a blob that specifies the path of a symlink

        .PARAMETER type
            Either blob, tree, or commit

        .PARAMETER blobSha
            Sha from the blob containing the content, use New-GitHubBlob and record the return sha

        .NOTES
            Author: Travis Sobeck
            LASTEDIT: 6/20/2017

        .EXAMPLE

    #>

    [CmdletBinding()]
    param(
        
        [System.Management.Automation.PSCredential]$psCreds,

        [string]$authToken,

        [Parameter(Mandatory)]
        [string]$Repo,

        [Parameter(Mandatory)]
        [string]$Org,

        [Parameter(Mandatory)]
        [string]$baseTree,

        [Parameter(Mandatory)]
        [string]$path,

        [Parameter(Mandatory)]
        [string]$mode,

        [Parameter(Mandatory)]
        [string]$type,

        [Parameter(Mandatory)]
        [string]$blobSha,

        ## The Default is public github but you can se this if you are running your own Enterprise Github server
        [string]$server = 'github.com'
    )

    if ($authToken){$Headers = @{"Authorization" = "token $authToken"}}
    elseif($psCreds){
        $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($psCreds.UserName+':'+$psCreds.GetNetworkCredential().Password))    
        $Headers = @{"Authorization" = "Basic $auth"}
    }
    if ($server -eq 'github.com'){$conn = "https://api.github.com"}
    else{$conn = "https://$server/api/v3"}
    $URI = "$conn/repos/$org/$Repo/git/trees"
    $json = @{"base_tree" = $baseTree;"tree" = @(@{"path" = $path;"mode"=$mode;"type" = $type;"sha" = $blobSha})} | ConvertTo-Json -Depth 3
    Invoke-RestMethod -Method Post -Uri $URI -Headers $Headers -Body $json
}
#endregion

#region Set-GitHubCommit
function Set-GitHubCommit {
    <#
        .SYNOPSIS
            Update a reference to a new Commit

        .DESCRIPTION
            Update a reference to a new Commit

        .PARAMETER psCreds
            PScredential composed of your username/password to Git Server

        .PARAMETER authToken
            Use instead of user/pass, personal auth token

        .PARAMETER Repo
            Repository name string which is used to identify which repository under the organization to go into.

        .PARAMETER Org
            Organization name string which is used to identify which organization in the GitHub instance to go into.

        .PARAMETER ref
            ref to be updated
        
        .PARAMETER sha
            SHA to update reference to, get this from New-GitHubCommit
            
        .PARAMETER parents
            The SHAs of the commits that were the parents of this commit. If omitted or empty, the commit will be written as a root commit. For a single parent, an array of one SHA should be provided; for a merge commit, an array of more than one should be provided.

        .NOTES
            Author: Travis Sobeck
            LASTEDIT: 6/20/2017

        .EXAMPLE
            

    #>

    [CmdletBinding()]
    param(
        
        [System.Management.Automation.PSCredential]$psCreds,

        [string]$authToken,

        [Parameter(Mandatory)]
        [string]$Repo,

        [Parameter(Mandatory)]
        [string]$Org,

        [Parameter(Mandatory)]
        [string]$ref,

        [Parameter(Mandatory)]
        [string]$sha,

        ## The Default is public github but you can se this if you are running your own Enterprise Github server
        [string]$server = 'github.com'
    )

    if ($authToken){$Headers = @{"Authorization" = "token $authToken"}}
    elseif($psCreds){
        $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($psCreds.UserName+':'+$psCreds.GetNetworkCredential().Password))    
        $Headers = @{"Authorization" = "Basic $auth"}
    }
    if ($server -eq 'github.com'){$conn = "https://api.github.com"}
    else{$conn = "https://$server/api/v3"}
    $URI = "$conn/repos/$org/$Repo/git/$ref"
    $json = @{"sha" = $sha;"force"=$true} | ConvertTo-Json -Depth 3
    Invoke-RestMethod -Method Patch -Uri $URI -Headers $Headers -Body $json
}
#endregion

#region Update-GitHubRepo
function Update-GitHubRepo {
    <#
        .SYNOPSIS
            Get a specific reference or all references for a specific repo

        .DESCRIPTION
            Get a specific reference or all references for a specific repo, use -ref for a specific reference

        .PARAMETER psCreds
            PScredential composed of your username/password to Git Server

        .PARAMETER authToken
            Use instead of user/pass, personal auth token

        .PARAMETER ref
            Specific ref, run the command without it to get a list example would be.

        .PARAMETER Repo
            Repository name string which is used to identify which repository under the organization to go into.

        .PARAMETER Org
            Organization name string which is used to identify which organization in the GitHub instance to go into.

        .PARAMETER message
            The commit message

        .PARAMETER path
            path to file in github

        .PARAMETER filePath
            Path to file to be added/modified

        .NOTES
            Author: Travis Sobeck
            LASTEDIT: 4/26/2017

        .EXAMPLE
            

    #>

    [CmdletBinding()]
    param(
        
        [System.Management.Automation.PSCredential]$psCreds,

        [string]$authToken,

        [Parameter(Mandatory)]
        [string]$Repo,

        [Parameter(Mandatory)]
        [string]$Org,

        [Parameter(Mandatory)]        
        [string]$ref,

        [Parameter(Mandatory)]
        [string]$message,

        [Parameter(Mandatory)]
        [string]$path,

        [Parameter(Mandatory)]
        [string]$filePath,

        ## The Default is public github but you can se this if you are running your own Enterprise Github server
        [string]$server = 'github.com'
    )

    try{
        # Get ref to head of master and record Sha
        $reference = Get-GitHubRepoRef -authToken $authToken -Repo $Repo -Org $Org -server $server -ref $ref
        $sha = $reference.object.sha
        # get commit for that ref and store Sha and URL of Tree
        $commit = Get-GitHubCommit -authToken $authToken -Repo $Repo -Org $Org -server $server -sha $sha
        $treeSha = $commit.tree.sha
        # Creat Blob
        $blob = New-GitHubBlob -authToken $authToken -Repo $Repo -Org $Org -server $server -filePath $filePath
        # create new Tree
        $tree = New-GitHubTree -authToken $authToken -Repo $Repo -Org $Org -server $server -path $path -blobSha $blob.sha -baseTree $treeSha -mode 100644 -type 'blob'
        # create new comming
        $newCommit = New-GitHubCommit -authToken $authToken -Repo $Repo -Org $Org -server $server -message $message -tree $tree.sha -parents @($sha)
        # update head to point at new commint
        Set-GitHubCommit -authToken $authToken -Repo $Repo -Org $Org -server $server -ref $ref -sha $newCommit.sha
    }
    catch{$Error[0]}
}
#endregion

##########################################################################################################################
Export-ModuleMember -Function *