From fbb6cd4b82949252efd46401d32540a35da7451a Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Sat, 4 Aug 2018 00:02:45 +0200 Subject: [PATCH] Appveyor updates * Don't update the cache after building a PR or feature branch. * Work around 'rustup update' erroring when an update is found. * Log deleted directories and success/failure status. * Make build log less noisy. --- .appveyor.yml | 139 ++++++++++++++++++++++++++++---------------------- 1 file changed, 79 insertions(+), 60 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 7a3e712da4..f7ce54c00d 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -20,6 +20,45 @@ environment: # -mx=1 : Fast compression. APPVEYOR_CACHE_ENTRY_ZIP_ARGS: -t7z -snl -mtc -mx=1 + # Define some PowerShell helper functions which are used in the scripts below. + # They're defined in an environment variable to reduce noise in the build log. + PS_UTILS: |- + # `Exec` runs a regular executable. It looks at the process' exit code, + # rather than its stderr output, to tell if a command has failed. + function Exec([ScriptBlock] $Command, [switch] $NoNewLines) { + "$Command".TrimStart(" &") | Write-Host # Echo command. + & $Command 2>&1 | Write-Host -NoNewLine:$NoNewLines # Execute command. + if ($NoNewLines) { Write-Host } # Write newline. + if ($LastExitCode -ne 0) { throw "Failure. Exit code: $LastExitCode" } + } + + # `Delete-Tree` is a simple wrapper around Remove-Item. It doesn't set + # an error status if one of the paths to be deleted doesn't exist. + function Delete-Tree([string[]] $Path) { + $Path | Foreach-Object { + "Deleting '$_'" | Write-Host -NoNewLine + if (Test-Path -Path $_) { + Remove-Item -Path $_ -Recurse -Force -ErrorAction Ignore + $(if ($?) { " - ok" } else { " - failed" }) | Write-Host + } else { + " - not found" | Write-Host + } + } + } + + # `$will_save_cache` equals true if the cache will be saved at the end. + $will_save_cache = -not $env:APPVEYOR_PULL_REQUEST_NUMBER -and + -not $env:APPVEYOR_CACHE_SKIP_SAVE -eq "true" + +for: + # Do no save the build cache for feature branches. TODO: Once we have multiple + # permanent branches, use a build matrix so each branch has it's own cache. + - branches: + except: + - master + environment: + APPVEYOR_CACHE_SKIP_SAVE: true + cache: # Python packages installed with `pip --user` and Pip cache. - $(APPDATA)\Python @@ -35,47 +74,31 @@ cache: - $(DENO_BUILD_PATH) init: - # TODO: enable after this lands in master. - # Do no save the build cache for feature branches. Once we have multiple - # "official" branches, use a build matrix so each branch has it's own cache. - # - ps: | - # if ($env:APPVEYOR_REPO_BRANCH -ne "master") { - # $env:APPVEYOR_CACHE_SKIP_SAVE = "true" - # } + # Load utility functions + - ps: Invoke-Expression $env:PS_UTILS # Make git check out symlinks (not placeholder text files). - git config --global core.symlinks true install: - # `Exec` runs a regular executable. It looks at the process' exit code, - # rather than its stderr output, to tell if a command has failed - - ps: | - function Exec([ScriptBlock] $Command, [Switch] $NoNewLines) { - "$Command".TrimStart(" &") | Write-Host # Echo command. - & $Command 2>&1 | Write-Host -NoNewLine:$NoNewLines # Execute command. - if ($NoNewLine) { Write-Host } # Write newline. - if ($LastExitCode -ne 0) { throw "Failure. Exit code: $LastExitCode" } - } - # Clone the third_party submodule. - - ps: | + - ps: |- try { Exec { & git submodule update --init --force --depth 1 } - } catch { # Git will fail if the `third_party` directory was restored from cache, # but the `.git/modules` directory wasn't. Rebuild it from scratch. - Remove-Item -Path $env:DENO_THIRD_PARTY_PATH ` - -Recurse -Force -ErrorAction Ignore + Delete-Tree -Path $env:DENO_THIRD_PARTY_PATH Exec -NoNewLines { & git submodule update --init --force --depth 1 } } - # Prune and pack git objects. Thus when we upload `.git/modules/` to - # the Appveyor cache, it'll include only objects that were actually needed. - - ps: | - if ($env:APPVEYOR_CACHE_SKIP_SAVE -ne "true") { - Push-Location $env:DENO_THIRD_PARTY_PATH - Exec { & git repack -d -l } + # Prune and pack git objects. Thus when we upload `.git/modules/` to the + # Appveyor cache, it'll include only objects that were actually needed. + # This step is skipped if the cache is not going to be saved. + - ps: |- + if ($will_save_cache) { + Push-Location -Path $env:DENO_THIRD_PARTY_PATH + Exec { & git gc --prune=all } Pop-Location } @@ -83,7 +106,7 @@ install: - ps: Install-Product node 10 x64 # Make sure the right Python version is in PATH, and others are not. - - ps: | + - ps: |- # Remove the wrong Python version(s) from PATH. $p = $env:PATH -split ";" | Where-Object { -not (Test-Path -Path "$_\python.exe") -and @@ -105,36 +128,43 @@ install: # Add Rust/Cargo to PATH. - ps: $env:PATH += ";$env:CARGO_HOME\bin" - # Install Rust via rustup-init, unless it was restored from cache. - # TODO: Ship Rust in the third_party repo. See issue #386. - - ps: | + # Look for Rust updates. + # * If there are no updates, rustup will exit cleanly. + # * If there are updates, rustup will attempt to install them, and then blow + # up because we removed the 'rust-docs' component. + # * The actual update is done by removing and reinstalling with rustup-init. + - ps: |- + if ($will_save_cache -and (Test-Path -Path $env:CARGO_HOME)) { + try { + Exec -NoNewLines { & rustup update stable-x86_64-pc-windows-msvc } + } catch { + Delete-Tree -Path $env:CARGO_HOME, $env:RUSTUP_HOME + } + } + + # Install or reinstall Rust via rustup-init. + # * After install/update, the rustup directory is very big, with many files, + # slowing down cache save/restore a lot, so we remove unnecessary stuff. + # * TODO: Use `rustup component remove docs` instead, when this issue + # is resolved: https://github.com/rust-lang-nursery/rustup.rs/issues/998. + # * TODO: Ship Rust in the third_party repo. See issue #386. + - ps: |- if (-not (Test-Path -Path $env:CARGO_HOME)) { Invoke-WebRequest -Uri "https://win.rustup.rs" ` -OutFile "$env:TEMP\rustup-init.exe" Exec -NoNewLines { & "$env:TEMP\rustup-init.exe" -y } + Delete-Tree -Path @( + "$env:RUSTUP_HOME\downloads", + "$env:RUSTUP_HOME\tmp", + "$env:RUSTUP_HOME\toolchains\stable-x86_64-pc-windows-msvc\share\doc" + ) } - # Update Rust. - - rustup update - - # The Rustup directory is very big with many files, which makes saving and - # restoring the Appveyor cache noticably slow. Remove unnecessary stuff. - # TODO: Use `rustup component remove docs` instead, when this issue - # is resolved: https://github.com/rust-lang-nursery/rustup.rs/issues/998. - - ps: | - Remove-Item -Recurse -Force -ErrorAction Ignore -Path @( - "$env:RUSTUP_HOME\downloads", - "$env:RUSTUP_HOME\tmp", - "$env:RUSTUP_HOME\toolchains\stable-x86_64-pc-windows-msvc\share\doc" - ) - # If Remove-Item didn't find one of these dirs, don't stop the build. - $null - # Log installed Node.js version + processor architecture. - node -p "`Node ${process.version} ${process.arch}`" # Log installed Python version + processor architecture. - - ps: >- + - ps: |- @("from sys import version", "print 'Python', version") -join "`n" | & python - @@ -143,16 +173,6 @@ install: - rustc --version - cargo --version - # Log environment variables. - - ps: | - Get-ChildItem env:* | Select-Object -Property Name, @{ - Name = "Value" - Expression = { - if ($_.Name -like "*PATH") { $_.Value -replace ";", ";`n" } - else { $_.Value } - } - } | Format-Table -AutoSize -Wrap - before_build: # Download clang and gn, generate ninja files. - python tools\setup.py @@ -162,10 +182,9 @@ build_script: after_build: # The build completed successfully; make sure the cache gets saved even if - # some test fails. + # some tests fail. - ps: $env:APPVEYOR_SAVE_CACHE_ON_ERROR = "true" test_script: - python tools\lint.py - ps: Exec { & python tools\test.py $env:DENO_BUILD_PATH } -