| 160 | } |
| 161 | |
| 162 | func listInstallations(jwtToken string) ([]installation, error) { |
| 163 | req, err := http.NewRequest("GET", "https://api.github.com/app/installations", nil) |
| 164 | if err != nil { |
| 165 | return nil, err |
| 166 | } |
| 167 | req.Header.Set("Authorization", "Bearer "+jwtToken) |
| 168 | req.Header.Set("Accept", "application/vnd.github+json") |
| 169 | |
| 170 | resp, err := http.DefaultClient.Do(req) |
| 171 | if err != nil { |
| 172 | return nil, err |
| 173 | } |
| 174 | defer resp.Body.Close() |
| 175 | |
| 176 | body, _ := io.ReadAll(resp.Body) |
| 177 | if resp.StatusCode != 200 { |
| 178 | return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body)) |
| 179 | } |
| 180 | |
| 181 | var result []installation |
| 182 | if err := json.Unmarshal(body, &result); err != nil { |
| 183 | return nil, fmt.Errorf("failed to parse response: %w", err) |
| 184 | } |
| 185 | return result, nil |
| 186 | } |
| 187 | |
| 188 | func getInstallationToken(jwtToken string, installationID int) (*installationToken, error) { |
| 189 | url := fmt.Sprintf("https://api.github.com/app/installations/%d/access_tokens", installationID) |