Created
August 26, 2020 15:44
-
-
Save DanielCalvo/456347340b35d26ca16041cd8b1a944d to your computer and use it in GitHub Desktop.
Github app repository clone golang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"github.com/dgrijalva/jwt-go" | |
"io/ioutil" | |
"net/http" | |
"os/exec" | |
"time" | |
) | |
type AuthTokenClaim struct { | |
*jwt.StandardClaims | |
} | |
type InstallationAuthResponse struct { | |
Token string `json:"token"` | |
ExpiresAt time.Time `json:"expires_at"` | |
Permissions struct { | |
Checks string `json:"checks"` | |
Contents string `json:"contents"` | |
Deployments string `json:"deployments"` | |
Metadata string `json:"metadata"` | |
PullRequests string `json:"pull_requests"` | |
Statuses string `json:"statuses"` | |
} `json:"permissions"` | |
RepositorySelection string `json:"repository_selection"` | |
} | |
//This is an implementation of the workflow described here: https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/#http-based-git-access-by-an-installation | |
//Your app must have rights to read/clone repositories | |
func main(){ | |
keyFilepath := "/path/to/your/key.pem" | |
appID := "00000" //GitHub app ID | |
appInstalationID := "0000000" //Instalation ID for this app on your organization | |
keyBytes, err := ioutil.ReadFile(keyFilepath) | |
if err != nil { | |
fmt.Println(err) | |
} | |
rsaPrivateKey, err := jwt.ParseRSAPrivateKeyFromPEM(keyBytes) | |
if err != nil { | |
fmt.Println(err) | |
} | |
jwtToken := jwt.New(jwt.SigningMethodRS256) | |
jwtToken.Claims = &AuthTokenClaim{ | |
&jwt.StandardClaims{ | |
IssuedAt: time.Now().Unix(), | |
ExpiresAt: time.Now().Add(time.Minute * 1).Unix(), | |
Issuer: appID, | |
}, | |
} | |
tokenString, err := jwtToken.SignedString(rsaPrivateKey) | |
if err != nil { | |
fmt.Println(err) | |
} | |
client := &http.Client{} | |
req, _ := http.NewRequest("POST", "https://api.github.com/app/installations/" + appInstalationID + "/access_tokens", nil) | |
req.Header.Set("Accept", "application/vnd.github.machine-man-preview+json") | |
req.Header.Set("Authorization", "Bearer " + tokenString) | |
res, _ := client.Do(req) | |
decoder := json.NewDecoder(res.Body) | |
var installationAuthResponse InstallationAuthResponse | |
err = decoder.Decode(&installationAuthResponse) | |
if err != nil { | |
fmt.Println(err) | |
} | |
//go-git consumes large amounts of memory cloning large repositories, this can cause small VMs/containers to run out of memory | |
//sticking to the git executable for this example | |
cmd := exec.Command("git", "clone", "https://x-access-token:" + installationAuthResponse.Token + "@github.com/organization/repository.git", "/tmp/repository") | |
err = cmd.Run() | |
if err != nil { | |
fmt.Println(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment