diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f9391a..64c2b39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Fixes +- Updater - Fetch pinned submodule commits outside the default branch and stop on initialization or tag-fetch failures. ([#186](https://github.com/getsentry/github-workflows/pull/186)) - Validate PR - Skip PRs opened by bots of GitHub Apps owned by Sentry (the `getsentry` organization or the `sentry` enterprise), such as `sentry-junior[bot]`. App bot users are never repo collaborators, so the write-access check couldn't recognize them. ([#179](https://github.com/getsentry/github-workflows/pull/179)) - Updater - Support prefixed release tags, such as `cli@1.2.3`, via a `version` named group in `pattern`. ([#184](https://github.com/getsentry/github-workflows/pull/184)) diff --git a/updater/scripts/update-dependency.ps1 b/updater/scripts/update-dependency.ps1 index 1ffb948..f5cef79 100644 --- a/updater/scripts/update-dependency.ps1 +++ b/updater/scripts/update-dependency.ps1 @@ -140,11 +140,17 @@ if ("$Tag" -eq '') { $OriginalTag | Should -Be '' if ($isSubmodule) { - git submodule update --init --no-fetch --single-branch $Path + git submodule update --init --single-branch $Path + if ($LASTEXITCODE -ne 0) { + throw "Failed to initialize submodule '$Path' (exit code: $LASTEXITCODE)" + } Push-Location $Path try { - $originalTag = $(git describe --tags) git fetch --tags + if ($LASTEXITCODE -ne 0) { + throw "Failed to fetch tags for submodule '$Path' (exit code: $LASTEXITCODE)" + } + $originalTag = $(git describe --tags) [string[]]$tags = $(git tag --list) $url = $(git remote get-url origin) $mainBranch = $(git remote show origin | Select-String 'HEAD branch: (.*)').Matches[0].Groups[1].Value diff --git a/updater/tests/submodule-checkout.Tests.ps1 b/updater/tests/submodule-checkout.Tests.ps1 new file mode 100644 index 0000000..ad694a9 --- /dev/null +++ b/updater/tests/submodule-checkout.Tests.ps1 @@ -0,0 +1,64 @@ +BeforeAll { + $script:updater = "$PSScriptRoot/../scripts/update-dependency.ps1" + $script:previousProtocols = $env:GIT_ALLOW_PROTOCOL + $env:GIT_ALLOW_PROTOCOL = 'file' + + function script:Invoke-FixtureGit { + git @args + if ($LASTEXITCODE -ne 0) { throw "Could not create Git fixture: 'git $args' exited with $LASTEXITCODE" } + } +} + +AfterAll { $env:GIT_ALLOW_PROTOCOL = $script:previousProtocols } + +Describe 'Submodule initialization' { + BeforeEach { + $script:pushedLocation = $false + $script:caseDir = Join-Path $TestDrive ([guid]::NewGuid()) + $script:remote = "$caseDir/remote" + Invoke-FixtureGit init --quiet --initial-branch=main $remote + Invoke-FixtureGit -C $remote config user.name 'Updater tests' + Invoke-FixtureGit -C $remote config user.email 'updater@example.invalid' + Invoke-FixtureGit -C $remote -c commit.gpgsign=false commit --quiet --allow-empty -m base + Invoke-FixtureGit -C $remote tag 1.0.0 + Invoke-FixtureGit -C $remote checkout --quiet -b release + Invoke-FixtureGit -C $remote -c commit.gpgsign=false commit --quiet --allow-empty -m release + Invoke-FixtureGit -C $remote tag 1.1.0 + $script:pin = Invoke-FixtureGit -C $remote rev-parse HEAD + Invoke-FixtureGit -C $remote checkout --quiet main + Invoke-FixtureGit -C $remote -c commit.gpgsign=false commit --quiet --allow-empty -m development + Invoke-FixtureGit init --quiet "$caseDir/caller" + Push-Location "$caseDir/caller" + $script:pushedLocation = $true + $remoteUrl = ([uri]::new((Resolve-Path $remote).ProviderPath)).AbsoluteUri + Invoke-FixtureGit config -f .gitmodules submodule.dependency.path dependency + Invoke-FixtureGit config -f .gitmodules submodule.dependency.url $remoteUrl + Invoke-FixtureGit add .gitmodules + Invoke-FixtureGit update-index --add --cacheinfo "160000,$pin,dependency" + New-Item dependency -ItemType Directory | Out-Null + } + + # Popping without a matching push would hide the setup failure behind a stack error. + AfterEach { if ($script:pushedLocation) { Pop-Location } } + + It 'recognizes an already pinned release outside the default branch' { + $output = & $updater -Path dependency + $output | Should -Contain 'originalTag=1.1.0' + $output | Should -Contain 'latestTag=1.1.0' + git -C dependency rev-parse HEAD | Should -Be $pin + git diff --exit-code -- dependency + $LASTEXITCODE | Should -Be 0 + } + + It 'stops when the pinned commit cannot be checked out' { + git update-index --cacheinfo '160000,1111111111111111111111111111111111111111,dependency' + { & $updater -Path dependency } | Should -Throw '*Failed to initialize submodule*' + } + + It 'stops when fetching tags fails' { + git submodule update --init --single-branch dependency + $LASTEXITCODE | Should -Be 0 + git -C dependency remote set-url origin "$caseDir/missing" + { & $updater -Path dependency } | Should -Throw '*Failed to fetch tags*' + } +}