diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 339f69a..9bebbe9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,10 +1,12 @@ stages: - build + - release build: stage: build tags: - saas-windows-medium-amd64 + rules: - if: '$CI_PIPELINE_SOURCE == "schedule"' - if: '$CI_PIPELINE_SOURCE == "web"' @@ -20,6 +22,7 @@ build: - crypto-utils.js - update-client.js - .gitlab-ci.yml + variables: GITLAB_TOKEN: $VYLA_GITLAB_TOKEN PLAYER_TMDB_KEY: $TMDB_KEY @@ -38,26 +41,35 @@ build: AUTH_PROXY_VITE_API_KEY: $AUTH_PROXY_API_KEY AUTH_PROXY_DEV_BYPASS_AUTH: $DEV_BYPASS_AUTH AUTH_PROXY_PROXY_VITE_API_KEY: $PROXY_VITE_API_KEY + GIT_TERMINAL_PROMPT: "0" + + CARGO_HOME: "$CI_PROJECT_DIR/.cargo" + cache: key: files: - package-lock.json - src-tauri/Cargo.lock paths: - - node_modules/ + - .cargo/ - src-tauri/target/ + policy: pull-push + script: - npm ci - + - | $repos = @("frontend", "player", "stream-api", "auth-proxy") $last = @{} - + if (Test-Path "last-shas.json") { $rawJson = Get-Content "last-shas.json" -Raw | ConvertFrom-Json + if ($rawJson) { - $rawJson.psobject.properties | ForEach-Object { $last[$_.Name] = $_.Value } + $rawJson.psobject.properties | ForEach-Object { + $last[$_.Name] = $_.Value + } } } @@ -68,9 +80,9 @@ build: $headers = @{ "PRIVATE-TOKEN" = "$env:GITLAB_TOKEN" } - + $uri = "https://gitlab.com/api/v4/projects/vyla-entertainment%2F$repo/repository/commits/main" - + try { $resp = Invoke-RestMethod -Uri $uri -Headers $headers $sha = $resp.id @@ -79,10 +91,12 @@ build: if (-not $last.ContainsKey($repo) -or $last[$repo] -ne $sha) { Write-Host "Change detected in $repo (main): $sha" $changed = $true - } else { + } + else { Write-Host "No change in $repo (main)" } - } catch { + } + catch { Write-Warning "Failed to fetch commit info for $repo." } } @@ -104,17 +118,24 @@ build: - | if (Test-Path "update-payload.zip") { Write-Host "Build artifact verified: update-payload.zip exists" + $size = (Get-Item update-payload.zip).Length + Write-Host " Size: $size bytes" - } else { + } + else { Write-Error "Build artifact missing: update-payload.zip" exit 1 } if (Test-Path "manifest.json") { Write-Host "Manifest file verified" - Get-Content manifest.json | ConvertFrom-Json | ConvertTo-Json -Depth 10 - } else { + + Get-Content manifest.json | + ConvertFrom-Json | + ConvertTo-Json -Depth 10 + } + else { Write-Error "Manifest file missing" exit 1 } @@ -126,48 +147,170 @@ build: - Write-Host "Setting up Rust toolchain..." - | if (-not (Get-Command rustup -ErrorAction SilentlyContinue)) { - Invoke-WebRequest -Uri "https://win.rustup.rs/x86_64" -OutFile "rustup-init.exe" + Invoke-WebRequest ` + -Uri "https://win.rustup.rs/x86_64" ` + -OutFile "rustup-init.exe" + .\rustup-init.exe -y --default-toolchain stable + Remove-Item "rustup-init.exe" } + $env:Path = "$env:USERPROFILE\.cargo\bin;" + $env:Path + rustup default stable + rustc --version + cargo --version + - Write-Host "Packaging Tauri application..." - npm run build + - | + Write-Host "Verifying Windows installers..." + + $nsisDir = "src-tauri/target/release/bundle/nsis" + $msiDir = "src-tauri/target/release/bundle/msi" + + $nsisFiles = @(Get-ChildItem "$nsisDir/*.exe" -ErrorAction SilentlyContinue) + $msiFiles = @(Get-ChildItem "$msiDir/*.msi" -ErrorAction SilentlyContinue) + + if ($nsisFiles.Count -eq 0) { + Write-Error "No NSIS installer was found." + exit 1 + } + + if ($msiFiles.Count -eq 0) { + Write-Error "No MSI installer was found." + exit 1 + } + + Write-Host "NSIS installer:" + $nsisFiles | ForEach-Object { + Write-Host " $($_.FullName)" + Write-Host " Size: $($_.Length) bytes" + } + + Write-Host "MSI installer:" + $msiFiles | ForEach-Object { + Write-Host " $($_.FullName)" + Write-Host " Size: $($_.Length) bytes" + } + + - | + Write-Host "Saving build job information..." + + @" + BUILD_JOB_ID=$env:CI_JOB_ID + BUILD_PIPELINE_ID=$env:CI_PIPELINE_ID + BUILD_PIPELINE_IID=$env:CI_PIPELINE_IID + BUILD_COMMIT_SHA=$env:CI_COMMIT_SHA + "@ | Set-Content build-info.env + + Write-Host "Build job ID: $env:CI_JOB_ID" + Write-Host "Pipeline IID: $env:CI_PIPELINE_IID" + + artifacts: + paths: + - update-payload.zip + - manifest.json + - validation-report.json + - build-info.env + - src-tauri/target/release/bundle/nsis/*.exe + - src-tauri/target/release/bundle/msi/*.msi + reports: + dotenv: build-info.env + expire_in: 30 days + + +release: + stage: release + tags: + - saas-windows-medium-amd64 + + needs: + - job: build + artifacts: true + + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule"' + - if: '$CI_PIPELINE_SOURCE == "web"' + - if: '$CI_COMMIT_BRANCH == "main"' + + script: - | Write-Host "Publishing Release to GitLab..." + + if (-not $env:BUILD_JOB_ID) { + Write-Error "BUILD_JOB_ID is missing." + exit 1 + } + + Write-Host "Build job ID: $env:BUILD_JOB_ID" + $versionTag = "v$env:CI_PIPELINE_IID" - $exeItem = Get-ChildItem src-tauri/target/release/bundle/nsis/*.exe, src-tauri/target/release/bundle/msi/*.msi | Select-Object -First 1 + + $exeItem = Get-ChildItem ` + "src-tauri/target/release/bundle/nsis/*.exe" ` + -ErrorAction SilentlyContinue | + Select-Object -First 1 + + if (-not $exeItem) { + Write-Error "No Windows NSIS installer was found in downloaded build artifacts." + exit 1 + } + $exeName = $exeItem.Name $exeEncoded = [System.Uri]::EscapeDataString($exeName) - $bundleDir = $exeItem.Directory.Name - + + Write-Host "Installer: $exeName" + + $artifactBaseUrl = "$env:CI_PROJECT_URL/-/jobs/$env:BUILD_JOB_ID/artifacts/raw" + + $exeUrl = "$artifactBaseUrl/src-tauri/target/release/bundle/nsis/$exeEncoded" + $payloadUrl = "$artifactBaseUrl/update-payload.zip" + $manifestUrl = "$artifactBaseUrl/manifest.json" + + Write-Host "Installer URL: $exeUrl" + Write-Host "Payload URL: $payloadUrl" + Write-Host "Manifest URL: $manifestUrl" + $releaseBody = @{ name = "Vyla Home Release $versionTag" + tag_name = "$versionTag" - description = "Automated release for build $versionTag. Download the Windows installer below." + + description = @" + Automated release for build $versionTag. + + Windows installer: + $exeName + + Build job: + $env:BUILD_JOB_ID + "@ + ref = "$env:CI_COMMIT_SHA" + assets = @{ links = @( @{ name = "$exeName" - url = "$env:CI_PROJECT_URL/-/jobs/$env:CI_JOB_ID/artifacts/raw/src-tauri/target/release/bundle/$bundleDir/$exeEncoded" + url = "$exeUrl" link_type = "package" }, @{ name = "update-payload.zip" - url = "$env:CI_PROJECT_URL/-/jobs/$env:CI_JOB_ID/artifacts/raw/update-payload.zip" + url = "$payloadUrl" link_type = "other" }, @{ name = "manifest.json" - url = "$env:CI_PROJECT_URL/-/jobs/$env:CI_JOB_ID/artifacts/raw/manifest.json" + url = "$manifestUrl" link_type = "other" } ) } - } | ConvertTo-Json -Depth 5 + } | ConvertTo-Json -Depth 10 $releaseHeaders = @{ "JOB-TOKEN" = "$env:CI_JOB_TOKEN" @@ -175,18 +318,21 @@ build: } try { - $createdRelease = Invoke-RestMethod -Uri "https://gitlab.com/api/v4/projects/$env:CI_PROJECT_ID/releases" -Method Post -Headers $releaseHeaders -Body $releaseBody - Write-Host "Release successfully published: $($createdRelease.tag_name)" - } catch { - Write-Warning "Release creation failed: $($_.Exception.Message)" - exit 1 - } + $createdRelease = Invoke-RestMethod ` + -Uri "https://gitlab.com/api/v4/projects/$env:CI_PROJECT_ID/releases" ` + -Method Post ` + -Headers $releaseHeaders ` + -Body $releaseBody - artifacts: - paths: - - update-payload.zip - - manifest.json - - validation-report.json - - src-tauri/target/release/bundle/nsis/*.exe - - src-tauri/target/release/bundle/msi/*.msi - expire_in: 30 days \ No newline at end of file + Write-Host "Release successfully published: $($createdRelease.tag_name)" + Write-Host "Release URL: $($createdRelease._links.self)" + } + catch { + Write-Error "Release creation failed: $($_.Exception.Message)" + + if ($_.ErrorDetails.Message) { + Write-Error $_.ErrorDetails.Message + } + + exit 1 + } \ No newline at end of file