Enhance private NuGet source setup in build_windows and publish_release jobs to support fallback authentication using NUGET_USERNAME/NUGET_PASSWORD when CI_JOB_TOKEN is unavailable. Update log messages for clarity. Add diagnostic steps in build_windows to verify NuGet feed and package visibility using configured credentials. No changes to core build or publish logic.
154 lines
8.1 KiB
YAML
154 lines
8.1 KiB
YAML
stages:
|
|
- build
|
|
- publish
|
|
|
|
# Only create pipelines automatically when a Git tag is pushed.
|
|
# Otherwise the pipeline must be started manually (pipeline "Run" / dispatch equivalent).
|
|
# workflow:
|
|
# rules:
|
|
# - if: '$CI_COMMIT_TAG'
|
|
# when: always
|
|
# - if: '$CI_PIPELINE_SOURCE == "web"'
|
|
# when: always
|
|
# - when: never
|
|
|
|
variables:
|
|
DOTNET_CLI_TELEMETRY_OPTOUT: "1"
|
|
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1"
|
|
BUILD_CONFIG: "Release"
|
|
# NOTE: This project uses repository variables for NuGet auth because secrets
|
|
# (masked/protected variables) may not be available on your GitLab plan.
|
|
# Replace the placeholders below with values in the repository, or override
|
|
# them in your project CI/CD variables when available.
|
|
# - NUGET_USERNAME : username (can be any value when using a PAT)
|
|
# - NUGET_PASSWORD : personal access token or project deploy token
|
|
NUGET_USERNAME: "REPLACE_WITH_USERNAME"
|
|
NUGET_PASSWORD: "REPLACE_WITH_TOKEN"
|
|
|
|
# Build job for Windows runner (shell executor). Remove 'image' so the runner uses the host environment.
|
|
build_windows:
|
|
stage: build
|
|
tags:
|
|
- saas-windows-medium-amd64
|
|
script:
|
|
- |
|
|
powershell -NoProfile -Command {
|
|
$needsInstall = -not (dotnet --list-sdks 2>$null | Select-String '^10\.')
|
|
if ($needsInstall) {
|
|
Write-Host 'Installing .NET 10 SDK using dotnet-install.ps1'
|
|
Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile dotnet-install.ps1 -UseBasicParsing
|
|
.\dotnet-install.ps1 -Channel 10.0 -InstallDir $env:USERPROFILE\.dotnet
|
|
$dotnetExe = Join-Path $env:USERPROFILE '.dotnet\dotnet.exe'
|
|
} else {
|
|
Write-Host '.NET 10 SDK already present on PATH'
|
|
$dotnetExe = 'dotnet'
|
|
}
|
|
|
|
# Configure private NuGet source from GitLab Packages using CI_JOB_TOKEN
|
|
# Fallback to repository variables NUGET_USERNAME/NUGET_PASSWORD for shared runners
|
|
$nugetUrl = 'https://gitlab.com/api/v4/projects/79509532/packages/nuget/index.json'
|
|
$authMode = $null
|
|
if ($env:CI_JOB_TOKEN) {
|
|
Write-Host 'Configuring private NuGet source Nuget-GitLab-AIFotoONLUS using CI_JOB_TOKEN...'
|
|
try { & $dotnetExe nuget remove source Nuget-GitLab-AIFotoONLUS } catch {}
|
|
& $dotnetExe nuget add source $nugetUrl --name Nuget-GitLab-AIFotoONLUS --username gitlab-ci-token --password $env:CI_JOB_TOKEN --store-password-in-clear-text
|
|
$authMode = 'JobToken'
|
|
} elseif ($env:NUGET_USERNAME -and $env:NUGET_PASSWORD) {
|
|
Write-Host 'Configuring private NuGet source Nuget-GitLab-AIFotoONLUS using NUGET_USERNAME/NUGET_PASSWORD...'
|
|
try { & $dotnetExe nuget remove source Nuget-GitLab-AIFotoONLUS } catch {}
|
|
& $dotnetExe nuget add source $nugetUrl --name Nuget-GitLab-AIFotoONLUS --username $env:NUGET_USERNAME --password $env:NUGET_PASSWORD --store-password-in-clear-text
|
|
$authMode = 'UserCreds'
|
|
} else {
|
|
Write-Host 'No credentials available; skipping private NuGet source configuration.'
|
|
}
|
|
|
|
& $dotnetExe --info
|
|
# Diagnostic: verify GitLab NuGet feed and package visibility using configured auth
|
|
if ($authMode) {
|
|
Write-Host 'Checking GitLab NuGet feed index and project packages for AIFotoONLUS.Core using auth mode:' $authMode
|
|
try {
|
|
if ($authMode -eq 'JobToken') {
|
|
$headers = @{ 'JOB-TOKEN' = $env:CI_JOB_TOKEN }
|
|
} else {
|
|
$pair = "$env:NUGET_USERNAME:$env:NUGET_PASSWORD"
|
|
$b64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($pair))
|
|
$headers = @{ Authorization = "Basic $b64" }
|
|
}
|
|
Invoke-RestMethod -Uri $nugetUrl -Headers $headers -Method Get | ConvertTo-Json | Write-Host
|
|
} catch { Write-Host "Failed to fetch feed index: $_" }
|
|
try {
|
|
$pkgApi = "https://gitlab.com/api/v4/projects/79509532/packages?package_name=AIFotoONLUS.Core"
|
|
Invoke-RestMethod -Uri $pkgApi -Headers $headers -Method Get | ConvertTo-Json | Write-Host
|
|
} catch { Write-Host "Failed to query project packages API: $_" }
|
|
} else {
|
|
Write-Host 'Skipping feed diagnostics because no auth configured.'
|
|
}
|
|
& $dotnetExe restore
|
|
& $dotnetExe build "imagecatalog\ImageCatalog 2.csproj" -c $env:BUILD_CONFIG -v minimal
|
|
}
|
|
artifacts:
|
|
paths:
|
|
- "**/bin/$BUILD_CONFIG/net10.0-windows/**"
|
|
expire_in: 1 hour
|
|
|
|
# Publish and create GitLab Release when building a tag. This job expects a Windows runner with PowerShell and curl available.
|
|
publish_release:
|
|
stage: publish
|
|
tags:
|
|
- saas-windows-medium-amd64
|
|
needs:
|
|
- build_windows
|
|
script:
|
|
- |
|
|
powershell -NoProfile -Command {
|
|
# Ensure .NET 10 SDK is available (install to user folder if missing) and use that dotnet for publish
|
|
$needsInstall = -not (dotnet --list-sdks 2>$null | Select-String '^10\.')
|
|
if ($needsInstall) {
|
|
Write-Host 'Installing .NET 10 SDK using dotnet-install.ps1'
|
|
Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile dotnet-install.ps1 -UseBasicParsing
|
|
.\dotnet-install.ps1 -Channel 10.0 -InstallDir $env:USERPROFILE\.dotnet
|
|
$dotnetExe = Join-Path $env:USERPROFILE '.dotnet\dotnet.exe'
|
|
} else {
|
|
$dotnetExe = 'dotnet'
|
|
}
|
|
|
|
& $dotnetExe publish "imagecatalog\ImageCatalog 2.csproj" -c $env:BUILD_CONFIG -r win-x64 --self-contained false -o publish
|
|
Write-Host "Published to $(pwd)\\publish"
|
|
|
|
# Configure private NuGet source from GitLab Packages using CI_JOB_TOKEN
|
|
# Fallback to repository variables NUGET_USERNAME/NUGET_PASSWORD for shared runners
|
|
$nugetUrl = 'https://gitlab.com/api/v4/projects/79509532/packages/nuget/index.json'
|
|
if ($env:CI_JOB_TOKEN) {
|
|
Write-Host 'Configuring private NuGet source Nuget-GitLab-AIFotoONLUS using CI_JOB_TOKEN...'
|
|
try { & $dotnetExe nuget remove source Nuget-GitLab-AIFotoONLUS } catch {}
|
|
& $dotnetExe nuget add source $nugetUrl --name Nuget-GitLab-AIFotoONLUS --username gitlab-ci-token --password $env:CI_JOB_TOKEN --store-password-in-clear-text
|
|
} elseif ($env:NUGET_USERNAME -and $env:NUGET_PASSWORD) {
|
|
Write-Host 'Configuring private NuGet source Nuget-GitLab-AIFotoONLUS using NUGET_USERNAME/NUGET_PASSWORD...'
|
|
try { & $dotnetExe nuget remove source Nuget-GitLab-AIFotoONLUS } catch {}
|
|
& $dotnetExe nuget add source $nugetUrl --name Nuget-GitLab-AIFotoONLUS --username $env:NUGET_USERNAME --password $env:NUGET_PASSWORD --store-password-in-clear-text
|
|
} else {
|
|
Write-Host 'No credentials available; skipping private NuGet source configuration.'
|
|
}
|
|
|
|
# Find first file in publish folder
|
|
$file = Get-ChildItem -Path publish -File | Select-Object -First 1; Write-Host "Uploading $($file.FullName)"
|
|
# Upload to GitLab project uploads API to get a public URL for the artifact
|
|
$uploadUrl = "$env:CI_API_V4_URL/projects/$env:CI_PROJECT_ID/uploads"
|
|
$formData = "file=@$($file.FullName)"
|
|
$uploadResp = curl --silent --show-error --header "JOB-TOKEN:$env:CI_JOB_TOKEN" --form $formData $uploadUrl
|
|
$uploadJson = $uploadResp | ConvertFrom-Json
|
|
$assetUrl = "$env:CI_SERVER_URL$($uploadJson.url)"
|
|
Write-Host "Uploaded asset url: $assetUrl"
|
|
# Create the release using uploads URL
|
|
$body = @{ name = $env:CI_COMMIT_TAG; tag_name = $env:CI_COMMIT_TAG; description = "Automated release from CI"; assets = @{ links = @(@{ name = "$($file.Name)"; url = $assetUrl }) } } | ConvertTo-Json -Depth 10
|
|
Invoke-RestMethod -Method Post -Uri "$env:CI_API_V4_URL/projects/$env:CI_PROJECT_ID/releases" -Headers @{ "JOB-TOKEN" = $env:CI_JOB_TOKEN } -Body $body -ContentType "application/json"
|
|
}
|
|
artifacts:
|
|
paths:
|
|
- publish/*
|
|
expire_in: 1 day
|
|
only:
|
|
- tags
|
|
|
|
# Notes for runner setup: Ensure a GitLab Windows runner with tag 'windows' is registered and has .NET 10 SDK installed.
|
|
# Use the shell executor on the Windows machine so the job runs in the host PowerShell environment
|