Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Features

- Updater - Support CMake `GIT_TAG` with variable references like `${FOO_REF}`, resolving and updating the corresponding `set()` definition ([#149](https://github.com/getsentry/github-workflows/pull/149))

## 3.2.1

### Fixes
Expand Down
29 changes: 25 additions & 4 deletions updater/scripts/cmake-functions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,18 @@ function Parse-CMakeFetchContent {
throw "Could not parse GIT_REPOSITORY or GIT_TAG from FetchContent_Declare block"
}

return @{ GitRepository = $repo; GitTag = $tag; DepName = $depName }
# Resolve CMake variable references like ${FOO_REF}
$gitTagVariable = $null
if ($tag -match '^\$\{(\w+)\}$') {
$gitTagVariable = $Matches[1]
$setMatch = [regex]::Match($content, "(?m)^\s*set\s*\(\s*$gitTagVariable\s+`"?([^`"\s)]+)")
if (-not $setMatch.Success) {
throw "CMake variable '$gitTagVariable' referenced by GIT_TAG not found in $filePath"
}
$tag = $setMatch.Groups[1].Value
}

return @{ GitRepository = $repo; GitTag = $tag; DepName = $depName; GitTagVariable = $gitTagVariable }
}

function Find-TagForHash {
Expand Down Expand Up @@ -167,10 +178,20 @@ function Update-CMakeFile {
$replacement = $newValue
}

# Update GIT_TAG value, replacing entire line content after GIT_TAG
# Update the value, replacing entire line content after the value
# This removes potentially outdated version-specific comments
$pattern = "(FetchContent_Declare\s*\(\s*$depName\s+[^)]*GIT_TAG\s+)[^\r\n]+(\r?\n[^)]*\))"
$newContent = [regex]::Replace($content, $pattern, "`${1}$replacement`${2}", 'Singleline')
$gitTagVariable = $fetchContent.GitTagVariable
if ($gitTagVariable) {
# Update the set() line that defines the variable
$pattern = "(?m)(^\s*set\s*\(\s*$gitTagVariable\s+`"?)([^`"\s)]+)(`"?[^)]*\))[^\r\n]*"
$valueOnly = if ($wasHash) { $newHash } else { $newValue }
$trailingComment = if ($wasHash) { " # $newValue" } else { "" }
$newContent = [regex]::Replace($content, $pattern, "`${1}$valueOnly`${3}$trailingComment")
} else {
# Update GIT_TAG value in FetchContent_Declare block
$pattern = "(FetchContent_Declare\s*\(\s*$depName\s+[^)]*GIT_TAG\s+)[^\r\n]+(\r?\n[^)]*\))"
$newContent = [regex]::Replace($content, $pattern, "`${1}$replacement`${2}", 'Singleline')
}

if ($newContent -eq $content) {
throw "Failed to update GIT_TAG in $filePath - pattern may not have matched"
Expand Down
171 changes: 171 additions & 0 deletions updater/tests/update-dependency-cmake.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,92 @@ FetchContent_MakeAvailable(sentry-native googletest)
}
}

Context 'Variable reference GIT_TAG' {
BeforeAll {
$script:tempDir = "$TestDrive/cmake-tests"
New-Item $tempDir -ItemType Directory -Force | Out-Null

$script:varRefFile = "$tempDir/varref.cmake"
@'
include(FetchContent)

set(SENTRY_NATIVE_REF "v0.9.1" CACHE STRING "The sentry-native ref")

FetchContent_Declare(
sentry-native
GIT_REPOSITORY https://github.com/getsentry/sentry-native
GIT_TAG ${SENTRY_NATIVE_REF}
GIT_SHALLOW FALSE
)

FetchContent_MakeAvailable(sentry-native)
'@ | Out-File $varRefFile

$script:varRefHashFile = "$tempDir/varref-hash.cmake"
@'
include(FetchContent)

set(SENTRY_NATIVE_REF a64d5bd8ee130f2cda196b6fa7d9b65bfa6d32e2) # 0.9.1

FetchContent_Declare(
sentry-native
GIT_REPOSITORY https://github.com/getsentry/sentry-native
GIT_TAG ${SENTRY_NATIVE_REF}
)

FetchContent_MakeAvailable(sentry-native)
'@ | Out-File $varRefHashFile

$script:varRefDirectFile = "$tempDir/varref-direct.cmake"
@'
include(FetchContent)

FetchContent_Declare(
sentry-native
GIT_REPOSITORY https://github.com/getsentry/sentry-native
GIT_TAG v0.9.1
)
'@ | Out-File $varRefDirectFile

$script:varRefMissingFile = "$tempDir/varref-missing.cmake"
@'
include(FetchContent)

FetchContent_Declare(
sentry-native
GIT_REPOSITORY https://github.com/getsentry/sentry-native
GIT_TAG ${UNDEFINED_VAR}
)
'@ | Out-File $varRefMissingFile
}

It 'resolves quoted variable to actual value' {
$result = Parse-CMakeFetchContent $varRefFile 'sentry-native'

$result.GitRepository | Should -Be 'https://github.com/getsentry/sentry-native'
$result.GitTag | Should -Be 'v0.9.1'
$result.GitTagVariable | Should -Be 'SENTRY_NATIVE_REF'
$result.DepName | Should -Be 'sentry-native'
}

It 'resolves unquoted variable with hash value' {
$result = Parse-CMakeFetchContent $varRefHashFile 'sentry-native'

$result.GitTag | Should -Be 'a64d5bd8ee130f2cda196b6fa7d9b65bfa6d32e2'
$result.GitTagVariable | Should -Be 'SENTRY_NATIVE_REF'
}

It 'throws when variable definition is missing' {
{ Parse-CMakeFetchContent $varRefMissingFile 'sentry-native' } | Should -Throw "*CMake variable 'UNDEFINED_VAR' referenced by GIT_TAG not found*"
}

It 'returns null GitTagVariable for direct values' {
$result = Parse-CMakeFetchContent $varRefDirectFile 'sentry-native'

$result.GitTagVariable | Should -BeNullOrEmpty
}
}

Context 'Malformed files' {
BeforeAll {
$script:tempDir = "$TestDrive/cmake-tests"
Expand Down Expand Up @@ -342,6 +428,91 @@ FetchContent_MakeAvailable(sentry-native)
}
}

Context 'Variable reference tag updates' {
BeforeAll {
$script:tempDir = "$TestDrive/cmake-update-tests"
New-Item $tempDir -ItemType Directory -Force | Out-Null

$script:varRefTagTemplate = @'
include(FetchContent)

set(SENTRY_NATIVE_REF "v0.9.1" CACHE STRING "The sentry-native ref")

FetchContent_Declare(
sentry-native
GIT_REPOSITORY https://github.com/getsentry/sentry-native
GIT_TAG ${SENTRY_NATIVE_REF}
GIT_SHALLOW FALSE
)

FetchContent_MakeAvailable(sentry-native)
'@
}

BeforeEach {
$script:varRefTagTestFile = "$tempDir/varref-tag-test.cmake"
}

It 'updates set() value and leaves GIT_TAG variable reference untouched' {
$varRefTagTemplate | Out-File $varRefTagTestFile

Update-CMakeFile $varRefTagTestFile 'sentry-native' 'v0.9.2'

$content = Get-Content $varRefTagTestFile -Raw
$content | Should -Match 'set\(SENTRY_NATIVE_REF "v0.9.2"'
$content | Should -Match 'GIT_TAG \$\{SENTRY_NATIVE_REF\}'
$content | Should -Not -Match 'v0.9.1'
}

It 'preserves file structure' {
$varRefTagTemplate | Out-File $varRefTagTestFile

Update-CMakeFile $varRefTagTestFile 'sentry-native' 'v0.9.2'

$content = Get-Content $varRefTagTestFile -Raw
$content | Should -Match 'include\(FetchContent\)'
$content | Should -Match 'FetchContent_MakeAvailable'
$content | Should -Match 'GIT_SHALLOW FALSE'
}
}

Context 'Variable reference hash updates' {
BeforeAll {
$script:tempDir = "$TestDrive/cmake-update-tests"
New-Item $tempDir -ItemType Directory -Force | Out-Null

$script:varRefHashTemplate = @'
include(FetchContent)

set(SENTRY_NATIVE_REF a64d5bd8ee130f2cda196b6fa7d9b65bfa6d32e2) # 0.9.1

FetchContent_Declare(
sentry-native
GIT_REPOSITORY https://github.com/getsentry/sentry-native
GIT_TAG ${SENTRY_NATIVE_REF}
)

FetchContent_MakeAvailable(sentry-native)
'@
}

BeforeEach {
$script:varRefHashTestFile = "$tempDir/varref-hash-test.cmake"
}

It 'updates set() value with new hash and comment' {
$varRefHashTemplate | Out-File $varRefHashTestFile

Update-CMakeFile $varRefHashTestFile 'sentry-native' '0.11.0'

$content = Get-Content $varRefHashTestFile -Raw
$content | Should -Match 'set\(SENTRY_NATIVE_REF 3bd091313ae97be90be62696a2babe591a988eb8\) # 0.11.0'
$content | Should -Match 'GIT_TAG \$\{SENTRY_NATIVE_REF\}'
$content | Should -Not -Match 'a64d5bd8ee130f2cda196b6fa7d9b65bfa6d32e2'
$content | Should -Not -Match '# 0.9.1'
}
}

# Note: Hash update tests require network access for git ls-remote
# and are better suited for integration tests
}
Loading