diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7f4e1e2..3cf7f908 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,9 +79,42 @@ jobs: # renovate: golang=go go-version: '1.27.2' + # Windows file versions and MSI versions only compare numbers, so every + # 0.32.0 beta and the final release would all be 0.32.0.0 and MDM tools + # would not update between them. The fourth field orders them: + # beta.N and alpha.N are N, rc.N is 100+N and the release is 1000. + # Builds between tags keep the number of the tag they follow. + - name: Compute file version + run: | + # Several tags can point at one commit, such as an rc on the last + # beta, and git describe would pick the first by name. + if [[ "$GITHUB_REF_TYPE" == "tag" ]]; then + tag="$GITHUB_REF_NAME" + else + tag="$(git describe --tags --abbrev=0)" + fi + if [[ ! "$tag" =~ ^v?([0-9]+\.[0-9]+\.[0-9]+)(-(alpha|beta|rc)\.([0-9]+))?$ ]]; then + echo "::error::Cannot derive a file version from tag $tag" + exit 1 + fi + build=1000 + number="${BASH_REMATCH[4]}" + case "${BASH_REMATCH[3]}" in + alpha|beta) build="$((10#$number))"; limit=99 ;; + rc) build="$((100 + 10#$number))"; limit=899 ;; + esac + if [[ -n "$number" ]] && (( 10#$number > limit )); then + echo "::error::Pre-release number of tag $tag does not fit the file version scheme" + exit 1 + fi + mkdir -p output + printf '%s\n' "${BASH_REMATCH[1]}.$build" | tee output/FILE_VERSION + - name: Generate Windows resources working-directory: cmd/windows_exporter - run: go run github.com/tc-hib/go-winres@v0.3.3 make --product-version=git-tag --file-version=git-tag --arch=amd64,arm64 + run: | + file_version="$(cat ../../output/FILE_VERSION)" + go run github.com/tc-hib/go-winres@v0.3.3 make --product-version="$file_version" --file-version="$file_version" --arch=amd64,arm64 - name: Build snapshot if: ${{ !startsWith(github.ref, 'refs/tags/') }} @@ -196,10 +229,11 @@ jobs: run: | $ErrorActionPreference = "Stop" $Version = Get-Content output\VERSION + $FileVersion = Get-Content output\FILE_VERSION foreach($Arch in "amd64", "arm64") { - Write-Host "Building windows_exporter $Version msi for $Arch" - .\installer\build.ps1 -PathToExecutable .\output\windows_exporter-$Version-$Arch.exe -Version $Version -Arch "$Arch" + Write-Host "Building windows_exporter $Version ($FileVersion) msi for $Arch" + .\installer\build.ps1 -PathToExecutable .\output\windows_exporter-$Version-$Arch.exe -Version $Version -MsiVersion $FileVersion -Arch "$Arch" } Move-Item installer\*.msi output\ diff --git a/AGENTS.md b/AGENTS.md index ed1962ef..2ef6b303 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,6 +37,11 @@ their runtime behavior. 0.31.x package there: its `taskkill /T` follows stale parent process IDs and can kill the runner agent, which fails the job with "The hosted runner lost communication with the server" and no logs. +- Release builds give the executable and the MSI a numeric four-part version + computed in the CI build job (`output/FILE_VERSION`): the fourth field is N + for `alpha.N`/`beta.N`, 100+N for `rc.N` and 1000 for the release, so MDM + tools that compare file versions update from one beta to the next and to the + final release. Windows Installer itself ignores the fourth field. New collectors need discussion with maintainers first. Prefer the configurable `performancecounter` collector where it can provide the requested metrics, as diff --git a/installer/build.ps1 b/installer/build.ps1 index 8576e484..0ae1a172 100644 --- a/installer/build.ps1 +++ b/installer/build.ps1 @@ -4,6 +4,10 @@ Param ( [String] $PathToExecutable, [Parameter(Mandatory = $true)] [String] $Version, + # Numeric version of the package, such as 0.32.0.5 for 0.32.0-beta.5. + # Defaults to the numeric part of Version. + [Parameter(Mandatory = $false)] + [String] $MsiVersion, [Parameter(Mandatory = $false)] [ValidateSet("amd64", "arm64")] [String] $Arch = "amd64" @@ -11,7 +15,9 @@ Param ( $ErrorActionPreference = "Stop" # The MSI version is not semver compliant, so just take the numerical parts -$MsiVersion = $Version -replace '^v?([0-9\.]+).*$','$1' +if (-not $MsiVersion) { + $MsiVersion = $Version -replace '^v?([0-9\.]+).*$','$1' +} # Get absolute path to executable before switching directories $PathToExecutable = Resolve-Path $PathToExecutable