Tests/Integration.Tests.ps1
|
Import-Module "$PSScriptRoot/../ChocoForge.psd1" -Force Describe 'Integration: GitHub API (read-only)' { InModuleScope 'ChocoForge' { BeforeDiscovery { $script:skipGitHub = -not $env:APIKEY_GITHUB if ($script:skipGitHub) { Write-Warning 'APIKEY_GITHUB not set. Skipping GitHub integration tests.' } } It 'Fetches real releases from GitHub' -Skip:$skipGitHub { $releases = Find-GitHubReleases -RepositoryOwner 'fdcastel' -RepositoryName 'qemu-img-windows-x64' $releases | Should -Not -BeNullOrEmpty $releases.Count | Should -BeGreaterThan 0 $releases[0].tag_name | Should -Not -BeNullOrEmpty } It 'Resolves real releases with version pattern' -Skip:$skipGitHub { $releases = Find-GitHubReleases -RepositoryOwner 'fdcastel' -RepositoryName 'qemu-img-windows-x64' $expanded = $releases | Resolve-GitHubReleases -VersionPattern 'v(\d+\.\d+\.\d+)$' -AssetPattern '\.zip$' $expanded | Should -Not -BeNullOrEmpty foreach ($r in $expanded) { $r.version | Should -Not -BeNullOrEmpty $r.assets | Should -Not -BeNullOrEmpty } } It 'Reads and resolves real qemu-img configuration' -Skip:$skipGitHub { $configPath = "$PSScriptRoot/assets/qemu-img-package/qemu-img.forge.yaml" $config = Read-ForgeConfiguration -Path $configPath | Resolve-ForgeConfiguration $config.versions | Should -Not -BeNullOrEmpty $config.versions.Count | Should -BeGreaterThan 0 $config.sources.github.publishedVersions | Should -Not -BeNullOrEmpty } } } Describe 'Integration: GitHub Packages (publish/delete cycle)' { InModuleScope 'ChocoForge' { BeforeDiscovery { $script:skipGitHub = -not $env:APIKEY_GITHUB if ($script:skipGitHub) { Write-Warning 'APIKEY_GITHUB not set. Skipping GitHub Packages integration tests.' } } It 'Builds, publishes, and cleans up a package on GitHub Packages' -Skip:$skipGitHub { $configPath = "$PSScriptRoot/assets/qemu-img-package/qemu-img.forge.yaml" $config = Read-ForgeConfiguration -Path $configPath | Resolve-ForgeConfiguration # Pick the latest version $latestVersion = $config.versions | Select-Object -First 1 $latestVersion | Should -Not -BeNullOrEmpty $nuspecPath = "$PSScriptRoot/assets/qemu-img-package/qemu-img.nuspec" $sourceUrl = $config.sources.github.url # Build the package $packagePath = $latestVersion | Build-ChocolateyPackage -NuspecPath $nuspecPath $packagePath | Should -Not -BeNullOrEmpty Test-Path $packagePath | Should -Be $true # Publish with -Force (in case it already exists) $published = Publish-ChocolateyPackage -Path $packagePath -SourceUrl $sourceUrl -ApiKey $env:APIKEY_GITHUB -Force $published | Should -Not -BeNullOrEmpty # Verify it's now published $publishedVersions = Find-ChocolateyPublishedVersions -PackageName 'qemu-img' -SourceUrl $sourceUrl -User 'fdcastel' -Password $env:APIKEY_GITHUB $publishedVersions | Should -Contain $latestVersion.version # Clean up: delete the version we just published $owner = 'fdcastel' $headers = @{ 'Authorization' = "Bearer $($env:APIKEY_GITHUB)" } $versionsUrl = "https://api.github.com/users/$owner/packages/nuget/qemu-img/versions" $response = Invoke-RestMethod -Uri $versionsUrl -Headers $headers -Verbose:$false $versionId = $response | Where-Object { $_.name -eq $latestVersion.version.ToString() } | Select-Object -ExpandProperty 'id' if ($versionId) { $null = Invoke-RestMethod -Uri "$versionsUrl/$versionId" -Headers $headers -Method Delete -Verbose:$false Write-VerboseMark "Cleaned up test package version $($latestVersion.version) from GitHub Packages." } } } } Describe 'Integration: GitLab Packages (publish/delete cycle)' { InModuleScope 'ChocoForge' { BeforeDiscovery { $script:skipGitLab = -not $env:APIKEY_GITLAB if ($script:skipGitLab) { Write-Warning 'APIKEY_GITLAB not set. Skipping GitLab Packages integration tests.' } } It 'Builds, publishes, and cleans up a package on GitLab' -Skip:$skipGitLab { $configPath = "$PSScriptRoot/assets/qemu-img-package/qemu-img.forge.yaml" $config = Read-ForgeConfiguration -Path $configPath | Resolve-ForgeConfiguration # Pick the latest version $latestVersion = $config.versions | Select-Object -First 1 $latestVersion | Should -Not -BeNullOrEmpty $nuspecPath = "$PSScriptRoot/assets/qemu-img-package/qemu-img.nuspec" $sourceUrl = $config.sources.gitlab.url $gitlabUser = $config.sources.gitlab.username # Build the package $packagePath = $latestVersion | Build-ChocolateyPackage -NuspecPath $nuspecPath $packagePath | Should -Not -BeNullOrEmpty Test-Path $packagePath | Should -Be $true # Publish to GitLab $published = Publish-ChocolateyPackage -Path $packagePath -SourceUrl $sourceUrl -ApiKey $env:APIKEY_GITLAB $published | Should -Not -BeNullOrEmpty # Verify it's now published $publishedVersions = Find-ChocolateyPublishedVersions -PackageName 'qemu-img' -SourceUrl $sourceUrl -User $gitlabUser -Password $env:APIKEY_GITLAB $publishedVersions | Should -Contain $latestVersion.version # Clean up: delete the package from GitLab # GitLab API: DELETE /api/v4/projects/:id/packages/:package_id $projectId = '70655681' $headers = @{ 'PRIVATE-TOKEN' = $env:APIKEY_GITLAB } $packagesUrl = "https://gitlab.com/api/v4/projects/$projectId/packages?package_type=nuget&package_name=qemu-img" $packages = Invoke-RestMethod -Uri $packagesUrl -Headers $headers -Verbose:$false $pkgToDelete = $packages | Where-Object { $_.version -eq $latestVersion.version.ToString() } if ($pkgToDelete) { foreach ($pkg in $pkgToDelete) { $null = Invoke-RestMethod -Uri "https://gitlab.com/api/v4/projects/$projectId/packages/$($pkg.id)" -Headers $headers -Method Delete -Verbose:$false Write-VerboseMark "Cleaned up test package version $($latestVersion.version) from GitLab." } } } } } Describe 'Integration: Full Sync-ForgePackage E2E' { InModuleScope 'ChocoForge' { BeforeDiscovery { $script:skipSync = -not ($env:APIKEY_GITHUB -and $env:APIKEY_GITLAB) if ($script:skipSync) { Write-Warning 'APIKEY_GITHUB and/or APIKEY_GITLAB not set. Skipping Sync E2E test.' } } It 'Syncs a package to GitHub and GitLab' -Skip:$skipSync { # This asset lists only GitHub and GitLab - both allow deleting a published version. # It must never reference community.chocolatey.org: pushes there are irreversible, # and relying on APIKEY_CHOCOLATEY being unset is not a safeguard. $forgePath = "$PSScriptRoot/assets/qemu-img-e2e/qemu-img.forge.yaml" $config = Read-ForgeConfiguration -Path $forgePath $config.sources.Keys | Should -Not -Contain 'community' foreach ($name in $config.sources.Keys) { $config.sources[$name].url | Should -Not -Match 'community\.chocolatey\.org' } { Sync-ForgePackage -Path $forgePath -Verbose } | Should -Not -Throw # Both sources should now hold every resolved version. $resolved = Read-ForgeConfiguration -Path $forgePath | Resolve-ForgeConfiguration foreach ($name in $resolved.sources.Keys) { $resolved.sources[$name].missingVersions | Should -BeNullOrEmpty } # Clean up so the test stays repeatable and leaves nothing behind. foreach ($version in $resolved.versions.version) { $versionText = $version.ToString() $ghHeaders = @{ 'Authorization' = "Bearer $($env:APIKEY_GITHUB)" } $ghVersionsUrl = 'https://api.github.com/users/fdcastel/packages/nuget/qemu-img/versions' # Assign before piping: piping Invoke-RestMethod directly passes the whole JSON # array as a single pipeline item, so Where-Object would match the array itself. $ghVersions = Invoke-RestMethod -Uri $ghVersionsUrl -Headers $ghHeaders -Verbose:$false $ghId = @($ghVersions | Where-Object { $_.name -eq $versionText })[0].id if ($ghId) { $null = Invoke-RestMethod -Uri "$ghVersionsUrl/$ghId" -Headers $ghHeaders -Method Delete -Verbose:$false Write-VerboseMark "Cleaned up GitHub Packages qemu-img $versionText." } $glHeaders = @{ 'PRIVATE-TOKEN' = $env:APIKEY_GITLAB } $glProjectId = '70655681' $glPackages = Invoke-RestMethod -Headers $glHeaders -Verbose:$false ` -Uri "https://gitlab.com/api/v4/projects/$glProjectId/packages?package_type=nuget&package_name=qemu-img" foreach ($pkg in @($glPackages | Where-Object { $_.version -eq $versionText })) { $null = Invoke-RestMethod -Method Delete -Headers $glHeaders -Verbose:$false ` -Uri "https://gitlab.com/api/v4/projects/$glProjectId/packages/$($pkg.id)" Write-VerboseMark "Cleaned up GitLab qemu-img $versionText." } } } } } |