@@ -8,6 +8,8 @@ namespace Cake.Frosting.Issues.Recipe;
8
8
using Cake . Common . Diagnostics ;
9
9
using Cake . Common . IO ;
10
10
using Cake . Core . IO ;
11
+ using System . Net ;
12
+ using System . Net . Http ;
11
13
12
14
/// <summary>
13
15
/// Support for builds running on GitHub Actions.
@@ -31,6 +33,40 @@ public override string DetermineCommitId(
31
33
{
32
34
context . NotNull ( ) ;
33
35
36
+ // For pull request events, use the actual HEAD commit instead of the merge commit SHA
37
+ if ( this . DetermineIfPullRequest ( context ) )
38
+ {
39
+ var eventPath = context . EnvironmentVariable ( "GITHUB_EVENT_PATH" ) ;
40
+
41
+ if ( ! string . IsNullOrWhiteSpace ( eventPath ) && System . IO . File . Exists ( eventPath ) )
42
+ {
43
+ try
44
+ {
45
+ var eventJson = System . IO . File . ReadAllText ( eventPath ) ;
46
+ var eventData = Newtonsoft . Json . JsonConvert . DeserializeObject ( eventJson ) as Newtonsoft . Json . Linq . JObject ;
47
+ var prHeadSha = eventData ? [ "pull_request" ] ? [ "head" ] ? [ "sha" ] ;
48
+
49
+ if ( prHeadSha != null )
50
+ {
51
+ return prHeadSha . ToString ( ) ;
52
+ }
53
+ }
54
+ catch ( System . IO . IOException )
55
+ {
56
+ // Fall through to default behavior if file I/O fails
57
+ }
58
+ catch ( System . UnauthorizedAccessException )
59
+ {
60
+ // Fall through to default behavior if access is denied
61
+ }
62
+ catch ( Newtonsoft . Json . JsonException )
63
+ {
64
+ // Fall through to default behavior if JSON parsing fails
65
+ }
66
+ }
67
+ }
68
+
69
+ // Default behavior for non-PR events or when event data is not available
34
70
return context . GitHubActions ( ) . Environment . Workflow . Sha ;
35
71
}
36
72
@@ -125,7 +161,14 @@ private static void UploadSarifToCodeScanning(IIssuesContext context)
125
161
}
126
162
127
163
var repository = context . GitHubActions ( ) . Environment . Workflow . Repository ;
128
- var commitSha = context . GitHubActions ( ) . Environment . Workflow . Sha ;
164
+
165
+ // Check if code scanning is enabled before attempting upload
166
+ if ( ! IsCodeScanningEnabled ( context , repository , token ) )
167
+ {
168
+ context . Information ( "GitHub code scanning is not enabled for this repository. Skipping SARIF upload." ) ;
169
+ return ;
170
+ }
171
+
129
172
var ref_ = context . GitHubActions ( ) . Environment . Workflow . Ref ;
130
173
131
174
// Read and encode SARIF file
@@ -136,8 +179,8 @@ private static void UploadSarifToCodeScanning(IIssuesContext context)
136
179
var apiUrl = new Uri ( $ "https://api.github.com/repos/{ repository } /code-scanning/sarifs") ;
137
180
var requestBody = new
138
181
{
139
- commit_sha = commitSha ,
140
- ref_ = ref_ ,
182
+ commit_sha = context . State . CommitId ,
183
+ ref_ ,
141
184
sarif = sarifBase64 ,
142
185
tool_name = "Cake.Issues.Recipe"
143
186
} ;
@@ -163,4 +206,61 @@ private static void UploadSarifToCodeScanning(IIssuesContext context)
163
206
context . Warning ( $ "Failed to upload SARIF report to GitHub code scanning. Status: { response . StatusCode } , Error: { errorContent } ") ;
164
207
}
165
208
}
209
+
210
+ private static bool IsCodeScanningEnabled ( IIssuesContext context , string repository , string token )
211
+ {
212
+ // Check if code scanning is enabled by attempting to fetch code scanning alerts
213
+ var apiUrl = new Uri ( $ "https://api.github.com/repos/{ repository } /code-scanning/alerts?per_page=1") ;
214
+
215
+ using var httpClient = new HttpClient ( ) ;
216
+ httpClient . DefaultRequestHeaders . Add ( "Authorization" , $ "token { token } ") ;
217
+ httpClient . DefaultRequestHeaders . Add ( "Accept" , "application/vnd.github.v3+json" ) ;
218
+ httpClient . DefaultRequestHeaders . Add ( "User-Agent" , "Cake.Issues.Recipe" ) ;
219
+
220
+ try
221
+ {
222
+ var response = httpClient . GetAsync ( apiUrl ) . Result ;
223
+
224
+ // If we get a successful response (200) or even a 404 for no alerts, code scanning is enabled
225
+ if ( response . IsSuccessStatusCode || response . StatusCode == HttpStatusCode . NotFound )
226
+ {
227
+ return true ;
228
+ }
229
+
230
+ // If we get a 403 (Forbidden), check if it's because code scanning is not enabled
231
+ if ( response . StatusCode == HttpStatusCode . Forbidden )
232
+ {
233
+ var errorContent = response . Content . ReadAsStringAsync ( ) . Result ;
234
+ if ( errorContent . Contains ( "Code Security must be enabled" , StringComparison . Ordinal ) )
235
+ {
236
+ return false ;
237
+ }
238
+ }
239
+
240
+ // For any other error, assume code scanning might be enabled but there's another issue
241
+ // Log the issue but don't block the upload attempt
242
+ context . Warning ( $ "Unable to determine code scanning status. Response: { response . StatusCode } ") ;
243
+ return true ;
244
+ }
245
+ catch ( HttpRequestException ex )
246
+ {
247
+ // If there's an HTTP exception checking the status, assume code scanning might be enabled
248
+ context . Warning ( $ "HTTP error checking code scanning status: { ex . Message } ") ;
249
+ return true ;
250
+ }
251
+ catch ( TaskCanceledException ex )
252
+ {
253
+ // If there's a timeout checking the status, assume code scanning might be enabled
254
+ context . Warning ( $ "Timeout checking code scanning status: { ex . Message } ") ;
255
+ return true ;
256
+ }
257
+ #pragma warning disable CA1031 // Do not catch general exception types - intentional fail-safe behavior
258
+ catch ( Exception ex )
259
+ {
260
+ // If there's any other exception checking the status, assume code scanning might be enabled
261
+ context . Warning ( $ "Error checking code scanning status: { ex . Message } ") ;
262
+ return true ;
263
+ }
264
+ #pragma warning restore CA1031 // Do not catch general exception types
265
+ }
166
266
}
0 commit comments