diff --git a/Earthfile b/Earthfile index d029fac3..653281a8 100644 --- a/Earthfile +++ b/Earthfile @@ -1,4 +1,8 @@ -VERSION --arg-scope-and-set --global-cache 0.8 +VERSION 0.8 + +# Custom argument: "custom_version" to manually set the version of the build (and ignore Git Tag value) +# Usage example: earthly --build-arg custom_version="1.2.3" + +ARG --global custom_version = "" ARG --global go_version = 1.22 ARG --global node_version = 18 @@ -131,27 +135,9 @@ go-base: # Copy the full repo, as Go embeds whether the state is clean. COPY . . - - LET version = "$(git tag --points-at || true)" - IF [ -z "${version}" ] - LET dev_version = "$(git describe --tags --first-parent --abbrev=0 || true)" - IF [ -n "${dev_version}" ] - SET version = "${dev_version}_dev_build" - END - END - IF [ -z "${version}" ] - SET version = "dev_build" - END - ENV VERSION="${version}" - RUN echo "Version: $VERSION" - - LET source = $( ( git remote -v | cut -f2 | cut -d" " -f1 | head -n 1 ) || echo "unknown" ) - ENV SOURCE="${source}" - RUN echo "Source: $SOURCE" - - LET build_time = $(date -u "+%Y-%m-%dT%H:%M:%SZ" || echo "unknown") - ENV BUILD_TIME = "${build_time}" - RUN echo "Build Time: $BUILD_TIME" + + # Set version information: VERSION, SOURCE, BUILD_TIME and VERSION_SemVer + DO +SET_VERSION_INFO # Explicitly cache here. SAVE IMAGE --cache-hint @@ -450,7 +436,7 @@ tauri-src: tauri-build: FROM +tauri-src - + ARG --required target ARG output=".*/release/([^\./]+|([^\./]+\.(dll|exe)))" @@ -459,6 +445,12 @@ tauri-build: DO rust+SET_CACHE_MOUNTS_ENV RUN rustup target add "${target}" + + # Init version information: VERSION, SOURCE, BUILD_TIME and VERSION_SemVer + DO +SET_VERSION_INFO + # Set version in Cargo.toml if it's a valid SemVer (required to set correct version of the output binary) + RUN if [ -n "$VERSION_SemVer" ]; then sed -i 's/^version = ".*"/version = "'"$VERSION_SemVer"'"/g' Cargo.toml; fi + # Build RUN --mount=$EARTHLY_RUST_TARGET_CACHE cargo tauri build --ci --target="${target}" --no-bundle DO rust+COPY_OUTPUT --output="${output}" @@ -603,6 +595,11 @@ installer-linux: RUN mkdir -p intel COPY (+release-prep/output/intel/*) ./intel/ + # Init version information: VERSION, SOURCE, BUILD_TIME and VERSION_SemVer + DO +SET_VERSION_INFO + # Set version in Cargo.toml if it's a valid SemVer (required for using in the installer file names) + RUN if [ -n "$VERSION_SemVer" ]; then sed -i 's/^version = ".*"/version = "'"$VERSION_SemVer"'"/g' Cargo.toml; fi + # build the installers RUN cargo tauri bundle --ci --target="${target}" @@ -705,3 +702,62 @@ BIN_EXT: SET binext=".exe" END ENV BINEXT="${goos}" + +# Function to set the version-related environment variables (variables: VERSION, SOURCE, BUILD_TIME and VERSION_SemVer) +# Call example: +# DO +SET_VERSION_INFO +SET_VERSION_INFO: + FUNCTION + ARG gitDir="/tmp/git-info" + + # Check if already initialized and skip the rest if true + IF [ -n "$BUILD_TIME" ] + #RUN echo "Version info already initialized" + ELSE + # Make sure git is installed in the image + RUN which git || apk add --no-cache git + # Create a temporary directory for git information only + RUN mkdir -p ${gitDir} + # Copy only the .git directory to the temporary location + COPY --dir .git ${gitDir}/.git + + # Check if custom version was provided via command line + IF [ -n "$custom_version" ] + ENV VERSION="${custom_version}" + RUN echo "Using custom version from command line: $VERSION" + ELSE + # Get version from git tags without changing workdir + LET version = "$(git --git-dir=${gitDir}/.git tag --points-at || true)" + IF [ -z "${version}" ] + LET dev_version = "$(git --git-dir=${gitDir}/.git describe --tags --first-parent --abbrev=0 || true)" + IF [ -n "${dev_version}" ] + SET version = "${dev_version}_dev_build" + END + END + IF [ -z "${version}" ] + SET version = "dev_build" + END + ENV VERSION="${version}" + RUN echo "Version: $VERSION" + END + + # Create cleaned version without 'v' prefix and without suffix starting with '_' + # Only set VERSION_SemVer if it matches semantic versioning format + LET version_clean = "$(echo "${VERSION}" | sed -E 's/^[vV]//' | sed -E 's/_.*$//')" + IF [ $(echo "${version_clean}" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+([.-].*)?$') ] + ENV VERSION_SemVer="${version_clean}" + RUN echo "VERSION_SemVer: $VERSION_SemVer" + ELSE + RUN echo "VERSION_SemVer: [Empty - not a valid SemVer in Git Tag] - !!! WARNING !!!" + END + + # Get source information without changing workdir + LET source = "$( (git --git-dir=${gitDir}/.git remote -v | cut -f2 | cut -d" " -f1 | head -n 1) || echo "unknown" )" + ENV SOURCE="${source}" + RUN echo "Source: $SOURCE" + + # Get build time + LET build_time = "$(date -u "+%Y-%m-%dT%H:%M:%SZ" || echo "unknown")" + ENV BUILD_TIME = "${build_time}" + RUN echo "Build Time: $BUILD_TIME" + END \ No newline at end of file diff --git a/desktop/tauri/src-tauri/tauri.conf.json5 b/desktop/tauri/src-tauri/tauri.conf.json5 index 4c8acc40..ed63d729 100644 --- a/desktop/tauri/src-tauri/tauri.conf.json5 +++ b/desktop/tauri/src-tauri/tauri.conf.json5 @@ -39,7 +39,7 @@ } }, "productName": "Portmaster", - "version": "0.1.3", // If removed the version number from Cargo.toml is used. + //"version": "0.1.3", // If removed - the version number from Cargo.toml is used. "identifier": "io.safing.portmaster", // this is added as a property to the shortcut on windows (ApplicationUserModelID). Used for notifications. "app": { "withGlobalTauri": true, @@ -140,8 +140,7 @@ "targets": [ "deb", "rpm", - "nsis", - "msi" + "nsis" //, "msi" ], "icon": [ "../../../assets/data/icons/pm_dark_512.png", diff --git a/packaging/windows/generate_windows_installers.ps1 b/packaging/windows/generate_windows_installers.ps1 index 7e3acacd..812d68fb 100644 --- a/packaging/windows/generate_windows_installers.ps1 +++ b/packaging/windows/generate_windows_installers.ps1 @@ -54,7 +54,10 @@ #------------------------------------------------------------------------------ param ( [Alias('i')] - [switch]$interactive + [switch]$interactive, + + [Alias('v')] + [string]$version ) # Save the current directory @@ -126,6 +129,38 @@ function Find-And-Copy-File { exit 1 } } + +# Function to set and restore Cargo.toml version +function Set-CargoVersion { + param ([string]$Version) + if (-not (Test-Path "Cargo.toml.bak")) { + Copy-Item "Cargo.toml" "Cargo.toml.bak" -Force + } + # Update the version in Cargo.toml. + # This will allow the Tauri CLI to set the correct filename for the installer. + # NOTE: This works only when the version is not explicitly defined in tauri.conf.json5. + (Get-Content "Cargo.toml" -Raw) -replace '(\[package\][^\[]*?)version\s*=\s*"[^"]+"', ('$1version = "' + $Version + '"') | Set-Content "Cargo.toml" +} +function Restore-CargoVersion { + if (Test-Path "Cargo.toml.bak") { + Copy-Item "Cargo.toml.bak" "Cargo.toml" -Force + Remove-Item "Cargo.toml.bak" -Force + } +} + +function Get-GitTagVersion { + # Try to get exact tag pointing to current commit + $version = $(git tag --points-at 2>$null) + # If no tag points to current commit, use most recent tag + if ([string]::IsNullOrEmpty($version)) { + $devVersion = $(git describe --tags --first-parent --abbrev=0 2>$null) + if (-not [string]::IsNullOrEmpty($devVersion)) { + $version = "${devVersion}" + } + } + $version = $version -replace '^v', '' + return $version +} # >>>>>>>>>>>>>>>>>>>>>>> End Functions >>>>>>>>>>>>>>>>>>>>>>>> # Set-Location relative to the script location "../.." (root of the project). So that the script can be run from any location. @@ -164,6 +199,38 @@ try { exit 1 } +$VERSION_GIT_TAG = Get-GitTagVersion + +# Check versions of UI and Core binaries +$VERSION_UI = (Get-Item "$targetDir/portmaster.exe").VersionInfo.FileVersion +$VERSION_CORE = (& "$binaryDir/portmaster-core.exe" version | Select-String -Pattern "Portmaster\s+(\d+\.\d+\.\d+)" | ForEach-Object { $_.Matches.Groups[1].Value }) +$VERSION_KEXT = (Get-Item "$binaryDir/portmaster-kext.sys").VersionInfo.FileVersion +Write-Output "`n[i] VERSIONS INFO:" +Write-Output " VERSION_GIT_TAG : $VERSION_GIT_TAG" +Write-Output " VERSION_CORE : $VERSION_CORE" +Write-Output " VERSION_UI : $VERSION_UI" +Write-Output " VERSION_KEXT : $VERSION_KEXT" +if ($VERSION_UI -ne $VERSION_CORE -or $VERSION_CORE -ne $VERSION_GIT_TAG) { + Write-Warning "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + Write-Warning "Version mismatch between UI($VERSION_UI), Core($VERSION_CORE) and GitTag($VERSION_GIT_TAG)!" + Write-Warning "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + if ($interactive) { + $response = Read-Host "[?] Continue anyway? (y/n)" + if ($response -ne 'y' -and $response -ne 'Y') { + Write-Error "Cancelled. Version mismatch between UI and Core binaries." + exit 1 + } + } +} +# Determine which version to use for building +if ($version) { + Write-Output "`n[i] Using explicitly provided version ($version) for installer file name`n" + $VERSION_TO_USE = $version +} else { + Write-Output "`n[i] Using Core version version ($VERSION_CORE) for installer file name`n" + $VERSION_TO_USE = $VERSION_CORE +} + Set-Location $destinationDir try { # Ensure Rust toolchain is installed @@ -189,18 +256,27 @@ try { $cargoTauriCommand = "./tauri-cli/cargo-tauri.exe" } - Write-Output "[i] VERSIONS INFO:" + Write-Output "[i] Tools versions info:" Write-Output " Tauri CLI: $((& $cargoTauriCommand -V | Out-String).Trim().Replace("`r`n", " "))" Write-Output " Rust : $((rustc -V | Out-String).Trim().Replace("`r`n", " ")); $((cargo -V | Out-String).Trim().Replace("`r`n", " "))" Write-Output "" # Building Tauri app bundle - Write-Output "[+] Building Tauri app bundle" - & $cargoTauriCommand bundle - if ($LASTEXITCODE -ne 0) { - Write-Error "Tauri bundle command failed with exit code $LASTEXITCODE" + try { + Write-Output "[+] Building Tauri app bundle with version $VERSION_TO_USE" + Set-CargoVersion -Version $VERSION_TO_USE + & $cargoTauriCommand bundle + if ($LASTEXITCODE -ne 0) { + throw "Tauri bundle command failed with exit code $LASTEXITCODE" + } + } + catch { + Write-Error "[!] Bundle failed: $_" exit 1 } + finally { + Restore-CargoVersion + } Write-Output "[+] Copying generated bundles" $installerDist = "..\..\..\dist\windows_amd64\"