mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-29 01:55:42 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa33a359b9 |
@@ -15,10 +15,10 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
githubToken string
|
||||
githubRepo string
|
||||
mapsRepoPath string
|
||||
githubPRReady bool
|
||||
githubToken string
|
||||
githubRepo string
|
||||
mapsRepoPath string
|
||||
githubPRReady bool
|
||||
)
|
||||
|
||||
func initGitHubPR(repo, repoPath string) {
|
||||
@@ -71,106 +71,9 @@ func githubAPIRequest(method, path string, body interface{}) (int, []byte, error
|
||||
return resp.StatusCode, respBody, nil
|
||||
}
|
||||
|
||||
// githubGraphQL makes an authenticated request to the GitHub GraphQL API.
|
||||
// The REST /git/refs endpoint doesn't work with fine-grained PATs, so we use
|
||||
// GraphQL for branch creation (createRef) which handles the same permissions correctly.
|
||||
func githubGraphQL(query string, variables map[string]interface{}) (json.RawMessage, error) {
|
||||
payload := map[string]interface{}{
|
||||
"query": query,
|
||||
"variables": variables,
|
||||
}
|
||||
data, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshal graphql request: %w", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", "https://api.github.com/graphql", bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create request: %w", err)
|
||||
}
|
||||
req.Header.Set("Authorization", "Bearer "+githubToken)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("graphql request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read response: %w", err)
|
||||
}
|
||||
|
||||
var result struct {
|
||||
Data json.RawMessage `json:"data"`
|
||||
Errors []struct {
|
||||
Message string `json:"message"`
|
||||
} `json:"errors"`
|
||||
}
|
||||
if err := json.Unmarshal(respBody, &result); err != nil {
|
||||
return nil, fmt.Errorf("parse graphql response: %w", err)
|
||||
}
|
||||
if len(result.Errors) > 0 {
|
||||
return nil, fmt.Errorf("graphql error: %s", result.Errors[0].Message)
|
||||
}
|
||||
return result.Data, nil
|
||||
}
|
||||
|
||||
// githubCreateBranch creates a branch using GraphQL and returns the main branch SHA.
|
||||
func githubCreateBranch(owner, repo, branchName string) (string, error) {
|
||||
// Step 1: Get repo node ID and main branch SHA
|
||||
queryData, err := githubGraphQL(`
|
||||
query($owner: String!, $repo: String!) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
id
|
||||
defaultBranchRef {
|
||||
target { oid }
|
||||
}
|
||||
}
|
||||
}
|
||||
`, map[string]interface{}{"owner": owner, "repo": repo})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("get repo info: %w", err)
|
||||
}
|
||||
|
||||
var repoInfo struct {
|
||||
Repository struct {
|
||||
ID string `json:"id"`
|
||||
DefaultBranchRef struct {
|
||||
Target struct {
|
||||
OID string `json:"oid"`
|
||||
} `json:"target"`
|
||||
} `json:"defaultBranchRef"`
|
||||
} `json:"repository"`
|
||||
}
|
||||
if err := json.Unmarshal(queryData, &repoInfo); err != nil {
|
||||
return "", fmt.Errorf("parse repo info: %w", err)
|
||||
}
|
||||
|
||||
repoID := repoInfo.Repository.ID
|
||||
mainSHA := repoInfo.Repository.DefaultBranchRef.Target.OID
|
||||
|
||||
// Step 2: Create branch via createRef mutation
|
||||
_, err = githubGraphQL(`
|
||||
mutation($repoId: ID!, $name: String!, $oid: GitObjectID!) {
|
||||
createRef(input: { repositoryId: $repoId, name: $name, oid: $oid }) {
|
||||
ref { name }
|
||||
}
|
||||
}
|
||||
`, map[string]interface{}{
|
||||
"repoId": repoID,
|
||||
"name": "refs/heads/" + branchName,
|
||||
"oid": mainSHA,
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("create branch: %w", err)
|
||||
}
|
||||
|
||||
return mainSHA, nil
|
||||
}
|
||||
|
||||
// handleCreateMapPR creates a GitHub PR with the current map file contents.
|
||||
// Uses only the Contents API and Pulls API — no Git Data API or GraphQL needed.
|
||||
// The Contents API creates a branch implicitly when committing to a non-existent branch.
|
||||
func handleCreateMapPR(w http.ResponseWriter, r *http.Request, mapName string) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
@@ -197,21 +100,7 @@ func handleCreateMapPR(w http.ResponseWriter, r *http.Request, mapName string) {
|
||||
branchSuffix := strings.ReplaceAll(mapName, " ", "-")
|
||||
branchName := fmt.Sprintf("map-editor/%s-%d", branchSuffix, time.Now().Unix())
|
||||
|
||||
// Split "owner/repo" for GraphQL
|
||||
repoParts := strings.SplitN(githubRepo, "/", 2)
|
||||
if len(repoParts) != 2 {
|
||||
http.Error(w, "Invalid github-repo format, expected owner/repo", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 2-3. Get main SHA and create branch (via GraphQL — REST /git/refs doesn't work with fine-grained PATs)
|
||||
_, err = githubCreateBranch(repoParts[0], repoParts[1], branchName)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to create branch: "+err.Error(), http.StatusBadGateway)
|
||||
return
|
||||
}
|
||||
|
||||
// 4. Get existing file's blob SHA (may 404 for new files)
|
||||
// 2. Get existing file's blob SHA from main (may 404 for new files)
|
||||
var existingSHA string
|
||||
status, body, err := githubAPIRequest("GET", fmt.Sprintf("/repos/%s/contents/%s?ref=main", githubRepo, repoFilePath), nil)
|
||||
if err != nil {
|
||||
@@ -229,7 +118,7 @@ func handleCreateMapPR(w http.ResponseWriter, r *http.Request, mapName string) {
|
||||
existingSHA = contentsResp.SHA
|
||||
}
|
||||
|
||||
// 5. Commit file to branch
|
||||
// 3. Commit file to new branch (Contents API creates the branch implicitly)
|
||||
commitBody := map[string]interface{}{
|
||||
"message": fmt.Sprintf("Update map: %s", mapName),
|
||||
"content": base64.StdEncoding.EncodeToString(fileData),
|
||||
@@ -248,7 +137,7 @@ func handleCreateMapPR(w http.ResponseWriter, r *http.Request, mapName string) {
|
||||
return
|
||||
}
|
||||
|
||||
// 6. Create pull request
|
||||
// 4. Create pull request
|
||||
prBody := map[string]string{
|
||||
"title": fmt.Sprintf("Map editor: update %s", mapName),
|
||||
"head": branchName,
|
||||
|
||||
Reference in New Issue
Block a user