mirror of
				https://github.com/actions/checkout.git
				synced 2025-10-31 15:47:36 +00:00 
			
		
		
		
	telemetry for incorrect merge commit (#253)
This commit is contained in:
		| @@ -29,7 +29,7 @@ export interface IGitCommandManager { | ||||
|   isDetached(): Promise<boolean> | ||||
|   lfsFetch(ref: string): Promise<void> | ||||
|   lfsInstall(): Promise<void> | ||||
|   log1(): Promise<void> | ||||
|   log1(): Promise<string> | ||||
|   remoteAdd(remoteName: string, remoteUrl: string): Promise<void> | ||||
|   removeEnvironmentVariable(name: string): void | ||||
|   setEnvironmentVariable(name: string, value: string): void | ||||
| @@ -225,8 +225,9 @@ class GitCommandManager { | ||||
|     await this.execGit(['lfs', 'install', '--local']) | ||||
|   } | ||||
|  | ||||
|   async log1(): Promise<void> { | ||||
|     await this.execGit(['log', '-1']) | ||||
|   async log1(): Promise<string> { | ||||
|     const output = await this.execGit(['log', '-1']) | ||||
|     return output.stdout | ||||
|   } | ||||
|  | ||||
|   async remoteAdd(remoteName: string, remoteUrl: string): Promise<void> { | ||||
|   | ||||
| @@ -170,7 +170,17 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> { | ||||
|     } | ||||
|  | ||||
|     // Dump some info about the checked out commit | ||||
|     await git.log1() | ||||
|     const commitInfo = await git.log1() | ||||
|  | ||||
|     // Check for incorrect pull request merge commit | ||||
|     await refHelper.checkCommitInfo( | ||||
|       settings.authToken, | ||||
|       commitInfo, | ||||
|       settings.repositoryOwner, | ||||
|       settings.repositoryName, | ||||
|       settings.ref, | ||||
|       settings.commit | ||||
|     ) | ||||
|   } finally { | ||||
|     // Remove auth | ||||
|     if (!settings.persistCredentials) { | ||||
|   | ||||
| @@ -1,4 +1,7 @@ | ||||
| import {URL} from 'url' | ||||
| import {IGitCommandManager} from './git-command-manager' | ||||
| import * as core from '@actions/core' | ||||
| import * as github from '@actions/github' | ||||
|  | ||||
| export interface ICheckoutInfo { | ||||
|   ref: string | ||||
| @@ -107,3 +110,108 @@ export function getRefSpec(ref: string, commit: string): string[] { | ||||
|     return [`+${ref}:${ref}`] | ||||
|   } | ||||
| } | ||||
|  | ||||
| export async function checkCommitInfo( | ||||
|   token: string, | ||||
|   commitInfo: string, | ||||
|   repositoryOwner: string, | ||||
|   repositoryName: string, | ||||
|   ref: string, | ||||
|   commit: string | ||||
| ): Promise<void> { | ||||
|   try { | ||||
|     // GHES? | ||||
|     if (isGhes()) { | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     // Auth token? | ||||
|     if (!token) { | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     // Public PR synchronize, for workflow repo? | ||||
|     if ( | ||||
|       fromPayload('repository.private') !== false || | ||||
|       github.context.eventName !== 'pull_request' || | ||||
|       fromPayload('action') !== 'synchronize' || | ||||
|       repositoryOwner !== github.context.repo.owner || | ||||
|       repositoryName !== github.context.repo.repo || | ||||
|       ref !== github.context.ref || | ||||
|       !ref.startsWith('refs/pull/') || | ||||
|       commit !== github.context.sha | ||||
|     ) { | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     // Head SHA | ||||
|     const expectedHeadSha = fromPayload('after') | ||||
|     if (!expectedHeadSha) { | ||||
|       core.debug('Unable to determine head sha') | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     // Base SHA | ||||
|     const expectedBaseSha = fromPayload('pull_request.base.sha') | ||||
|     if (!expectedBaseSha) { | ||||
|       core.debug('Unable to determine base sha') | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     // Expected message? | ||||
|     const expectedMessage = `Merge ${expectedHeadSha} into ${expectedBaseSha}` | ||||
|     if (commitInfo.indexOf(expectedMessage) >= 0) { | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     // Extract details from message | ||||
|     const match = commitInfo.match(/Merge ([0-9a-f]{40}) into ([0-9a-f]{40})/) | ||||
|     if (!match) { | ||||
|       core.debug('Unexpected message format') | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     // Post telemetry | ||||
|     const actualHeadSha = match[1] | ||||
|     if (actualHeadSha !== expectedHeadSha) { | ||||
|       core.debug( | ||||
|         `Expected head sha ${expectedHeadSha}; actual head sha ${actualHeadSha}` | ||||
|       ) | ||||
|       const octokit = new github.GitHub(token, { | ||||
|         userAgent: `actions-checkout-tracepoint/1.0 (code=STALE_MERGE;owner=${repositoryOwner};repo=${repositoryName};pr=${fromPayload( | ||||
|           'number' | ||||
|         )};run_id=${ | ||||
|           process.env['GITHUB_RUN_ID'] | ||||
|         };expected_head_sha=${expectedHeadSha};actual_head_sha=${actualHeadSha})` | ||||
|       }) | ||||
|       await octokit.repos.get({owner: repositoryOwner, repo: repositoryName}) | ||||
|     } | ||||
|   } catch (err) { | ||||
|     core.debug(`Error when validating commit info: ${err.stack}`) | ||||
|   } | ||||
| } | ||||
|  | ||||
| function fromPayload(path: string): any { | ||||
|   return select(github.context.payload, path) | ||||
| } | ||||
|  | ||||
| function select(obj: any, path: string): any { | ||||
|   if (!obj) { | ||||
|     return undefined | ||||
|   } | ||||
|  | ||||
|   const i = path.indexOf('.') | ||||
|   if (i < 0) { | ||||
|     return obj[path] | ||||
|   } | ||||
|  | ||||
|   const key = path.substr(0, i) | ||||
|   return select(obj[key], path.substr(i + 1)) | ||||
| } | ||||
|  | ||||
| function isGhes(): boolean { | ||||
|   const ghUrl = new URL( | ||||
|     process.env['GITHUB_SERVER_URL'] || 'https://github.com' | ||||
|   ) | ||||
|   return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM' | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 eric sciple
					eric sciple