@@ -112,17 +112,31 @@ public static function generateJwt(string $appId, string $pemContents): ?string
112112 public static function getInstallationId (string $ jwt , string $ owner ): ?int
113113 {
114114 $ result = Shell::run (
115- "curl -s -H " . escapeshellarg ("Authorization: Bearer {$ jwt }" )
115+ "curl -s -w ' \\ n%{http_code}' - H " . escapeshellarg ("Authorization: Bearer {$ jwt }" )
116116 . " -H 'Accept: application/vnd.github+json' "
117117 . " https://api.github.com/app/installations 2>/dev/null "
118118 );
119119
120120 if (!$ result ) {
121+ Log::error ('github-app ' , "installations list request returned empty response " );
121122 return null ;
122123 }
123124
124- $ installations = json_decode ($ result , true );
125+ // Separate body from HTTP status code
126+ $ lines = explode ("\n" , trim ($ result ));
127+ $ httpCode = (int ) array_pop ($ lines );
128+ $ body = implode ("\n" , $ lines );
129+
130+ if ($ httpCode < 200 || $ httpCode >= 300 ) {
131+ $ parsed = json_decode ($ body , true );
132+ $ message = $ parsed ['message ' ] ?? trim ($ body );
133+ Log::error ('github-app ' , "installations list failed: HTTP {$ httpCode } — {$ message }" );
134+ return null ;
135+ }
136+
137+ $ installations = json_decode ($ body , true );
125138 if (!is_array ($ installations )) {
139+ Log::error ('github-app ' , "installations response is not an array: " . trim ($ body ));
126140 return null ;
127141 }
128142
@@ -133,6 +147,7 @@ public static function getInstallationId(string $jwt, string $owner): ?int
133147 }
134148 }
135149
150+ Log::warn ('github-app ' , "no installation found for owner ' {$ owner }' among " . count ($ installations ) . " installation(s) " );
136151 return null ;
137152 }
138153
@@ -143,18 +158,36 @@ public static function getInstallationId(string $jwt, string $owner): ?int
143158 public static function generateInstallationToken (string $ jwt , int $ installationId ): ?string
144159 {
145160 $ result = Shell::run (
146- "curl -s -X POST "
161+ "curl -s -w ' \\ n%{http_code}' - X POST "
147162 . " -H " . escapeshellarg ("Authorization: Bearer {$ jwt }" )
148163 . " -H 'Accept: application/vnd.github+json' "
149164 . " https://api.github.com/app/installations/ {$ installationId }/access_tokens 2>/dev/null "
150165 );
151166
152167 if (!$ result ) {
168+ Log::error ('github-app ' , "installation token request returned empty response for installation {$ installationId }" );
169+ return null ;
170+ }
171+
172+ // Separate body from HTTP status code
173+ $ lines = explode ("\n" , trim ($ result ));
174+ $ httpCode = (int ) array_pop ($ lines );
175+ $ body = implode ("\n" , $ lines );
176+
177+ $ data = json_decode ($ body , true );
178+
179+ if ($ httpCode < 200 || $ httpCode >= 300 ) {
180+ $ message = $ data ['message ' ] ?? trim ($ body );
181+ Log::error ('github-app ' , "installation token request failed: HTTP {$ httpCode } — {$ message }" );
182+ return null ;
183+ }
184+
185+ if (!isset ($ data ['token ' ])) {
186+ Log::error ('github-app ' , "installation token response missing 'token' field: " . trim ($ body ));
153187 return null ;
154188 }
155189
156- $ data = json_decode ($ result , true );
157- return $ data ['token ' ] ?? null ;
190+ return $ data ['token ' ];
158191 }
159192
160193 /**
0 commit comments