|
| 1 | +<# |
| 2 | +.SYNOPSIS |
| 3 | + This script generates a list of changed files in a given pull request and outputs |
| 4 | + that list to a file. |
| 5 | +.DESCRIPTION |
| 6 | + Generates a file containing a list of all modified files (added/modified) in |
| 7 | + the given pull request. The output file contains a list that is newline delimited, for |
| 8 | + example: |
| 9 | +
|
| 10 | + Assets/MixedRealityToolkit.SDK/AssemblyInfo.cs |
| 11 | + Assets/MixedRealityToolkit.Tests/PlayModeTests/ManipulationHandlerTests.cs |
| 12 | +
|
| 13 | + The file will not contain files that have been completely deleted (for example, if |
| 14 | + a change deleted Assets/MixedRealityToolkit.SDK/DeletedFile.cs), that line will not exist |
| 15 | + in the output file. |
| 16 | +
|
| 17 | + Note that this script assumes that the local git repo doesn't already contain the |
| 18 | + target branch (e.g. mrtk_development). This is what happens by default on Azure DevOps |
| 19 | + pipeline integrations with Github pull requests. |
| 20 | +
|
| 21 | + In particular, this will checkout (via this command: |
| 22 | + git fetch --force --tags --prune --progress --no-recurse-submodules origin $(System.PullRequest.TargetBranch)) |
| 23 | +.EXAMPLE |
| 24 | + .\githubchanges.ps1 -OutputFile c:\path\to\changes\file.txt -PullRequestId 1234 -RepoRoot c:\path\to\mrtk -TargetBranch mrtk_development |
| 25 | +#> |
| 26 | +param( |
| 27 | + # The ID of the pull request. (e.g. 1234) |
| 28 | + [string]$PullRequestId, |
| 29 | + |
| 30 | + # The target branch that the pull request will merge into (e.g. mrtk_development) |
| 31 | + [string]$TargetBranch, |
| 32 | + |
| 33 | + # The output filename (e.g. c:\path\to\output.txt) |
| 34 | + [Parameter(Mandatory=$true)] |
| 35 | + [string]$OutputFile, |
| 36 | + |
| 37 | + # The root folder of the repo (e.g. c:\repo) |
| 38 | + # This primarily used to filter out files that were deleted. |
| 39 | + [Parameter(Mandatory=$true)] |
| 40 | + [string]$RepoRoot |
| 41 | +) |
| 42 | + |
| 43 | +# The pull request ID might not be present (i.e. this is an adhoc build being spun up) |
| 44 | +# and the target branch might not be set in which case there's nothing to validate. |
| 45 | +if ([string]::IsNullOrEmpty($PullRequestId) -or [string]::IsNullOrEmpty($TargetBranch)) |
| 46 | +{ |
| 47 | + Write-Warning "PullRequestId or TargetBranch aren't specified, skipping." |
| 48 | + exit 0; |
| 49 | +} |
| 50 | + |
| 51 | +# If the output file already exists, blow it away. Each run should get a new set of changed files. |
| 52 | +if (Test-Path $OutputFile -PathType leaf) { |
| 53 | + Remove-Item $OutputFile |
| 54 | +} |
| 55 | +New-Item -ItemType File -Force -Path $OutputFile |
| 56 | + |
| 57 | +# The path to the .git file is necessary when invoking the git command below, as the working |
| 58 | +# directory may not actually be pointed toward the git path. |
| 59 | +$gitDir = Join-Path -Path $RepoRoot -ChildPath ".git" |
| 60 | + |
| 61 | +# Fetches the target branch so that the git diffing down below will actually be possible. git diff will list |
| 62 | +# the set of changed files between two different commit stamps (or branches, in this case), and needs |
| 63 | +# both branches to exist in order to make this happen. |
| 64 | +# Uses a shallow fetch (i.e. depth=1) because only the latest commit from the target branch is |
| 65 | +# needed to do the diff. |
| 66 | +git --git-dir=$gitDir --work-tree=$RepoRoot fetch --depth=1 --force --tags --prune --progress --no-recurse-submodules origin $TargetBranch |
| 67 | + |
| 68 | +# The set of changed files is the diff between the target branch and the pull request |
| 69 | +# branch that was checked out locally. Note that the format of the pull request branch |
| 70 | +# (i.e. "pull/$PullRequestId/merge") is based on the format that Azure DevOps does for its |
| 71 | +# local checkout of the pull request code. |
| 72 | +# WARNING: This is a loose dependency on Azure DevOps git checkout mechanism - if this errors out |
| 73 | +# we'd likely need to another fetch. Something like: |
| 74 | +# |
| 75 | +# git fetch origin pull/$PullRequestId/head:local_branch |
| 76 | +# $changedFiles=$(git --git-dir=$gitDir --work-tree=$RepoRoot diff --name-only local_branch origin/$TargetBranch 2>&1) |
| 77 | +$changedFiles=$(git --git-dir=$gitDir --work-tree=$RepoRoot diff --name-only pull/$PullRequestId/merge origin/$TargetBranch 2>&1) |
| 78 | + |
| 79 | +foreach ($changedFile in $changedFiles) { |
| 80 | + $joinedPath = Join-Path -Path $RepoRoot -ChildPath $changedFile |
| 81 | + # Only save the path if the file still exists - also, do not store the absolute path |
| 82 | + # of the file, in case this set of information is used later in the pipeline on a different |
| 83 | + # machine/context. |
| 84 | + if (Test-Path $joinedPath -PathType leaf) { |
| 85 | + Add-Content -Path $OutputFile -Value $changedFile |
| 86 | + } |
| 87 | +} |
0 commit comments