# Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. version: '{build}.{branch}' skip_branch_with_pr: true clone_folder: C:\deno clone_depth: 1 environment: APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 DENO_BUILD_MODE: release DENO_BUILD_PATH: $(APPVEYOR_BUILD_FOLDER)\target\release DENO_THIRD_PARTY_PATH: $(APPVEYOR_BUILD_FOLDER)\third_party RELEASE_ARTIFACT: deno_win_x64.zip RUST_VERSION: 1.37.0 RUST_DIR: $(USERPROFILE)\rust-$(RUST_VERSION) CARGO_HOME: $(RUST_DIR)\cargo RUSTUP_HOME: $(RUST_DIR)\rustup RUST_BACKTRACE: full RUSTC_WRAPPER: sccache PYTHONPATH: third_party\python_packages SCCACHE_BUCKET: deno-sccache AWS_ACCESS_KEY_ID: AKIAIVRN52PLDBP55LBQ AWS_SECRET_ACCESS_KEY: secure: 8ybpi/y5qE2baChsCBhNHmykng3FitELAtTYOiqZd0mw38i88dzdAX8ETNtBogMV # Appveyor uses 7zip to pack cache directories. We use these options: # -t7z : Use '7z' format. # -snl : Store symlinks; doesn't work, but it prevents following symlinks. # -mtc : Use UTC timestamps. This is required for incremental builds. # -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" } } # Get-Tree lists all objects in a tree. It's different from Get-ChildItem # in that the latter recurses through symlinks, which is problematic. function Get-Tree([string[]] $Path, [switch] $Recurse, [switch] $Force) { function Get-SubDirs([string[]] $Path) { Get-ChildItem $Path -Force:$Force ` -Attributes Directory+!ReparsePoint | foreach { $_.FullName } | foreach { $_; Get-SubDirs $_ } } if ($Recurse) { $Path += Get-SubDirs $Path } Get-ChildItem $Path -Force:$Force @args } # `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 { "Deleting '$_'" | Write-Host -NoNewLine if (Test-Path $_) { Remove-Item $_ -Recurse -Force -ErrorAction Ignore $(if ($?) { " - ok" } else { " - failed" }) | Write-Host } else { " - not found" | Write-Host } } } # Get-SaveCache returns $true if the cache will be saved at the end. function Get-SaveCache { -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: # Rust stuff. - $(RUST_DIR) - $(APPVEYOR_BUILD_FOLDER)\prebuilt\win\ init: # Load utility functions - ps: Invoke-Expression $env:PS_UTILS # Upgrade git. # TODO: remove when Appveyor upgrades to version 2.19.2.windows.1 or higher. - ps: |- $git_setup_uri = "https://github.com/git-for-windows/git/releases/" + "download/v2.21.0.windows.1/Git-2.21.0-64-bit.exe" Invoke-WebRequest -Uri $git_setup_uri -OutFile "$env:TEMP\git-setup.exe" Start-Process -FilePath "$env:TEMP\git-setup.exe" ` -ArgumentList "/verysilent" ` -Wait # Make git check out symlinks (not placeholder text files). - git config --global core.symlinks true install: # Make sure the PATH includes the prebuilt files (downloaded during setup.py) - set PATH=%PATH%;%CD%\prebuilt\win\ # Clone the third_party submodule. - 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. Delete-Tree $env:DENO_THIRD_PARTY_PATH Exec -NoNewLines { & git submodule update --init --force --depth 1 } } # Configure depot_tools and add it to the search path. This is necessary # because, later in this script, we need to invoke ninja directly. - ps: |- $env:PATH = "$env:DENO_THIRD_PARTY_PATH\depot_tools;$env:PATH" $env:DEPOT_TOOLS_WIN_TOOLCHAIN = "0" # Install a recent Node.js version. # TODO(ry) Upgrade to v12 once Install-Produce supports it. - ps: Install-Product -Product node -Version 10 -Platform x64 # Make sure the right Python version is in PATH, and others are not. - ps: |- # Remove the wrong Python version(s) from PATH. $p = $env:PATH -split ";" | where { -not (Test-Path "$_\python.exe") } # Add python27-x64. $p += "C:\Python27-x64" $env:PATH = $p -join ";" # Add Rust/Cargo to PATH. - ps: $env:PATH += ";$env:CARGO_HOME\bin" # Install Rust via rustup-init. # * After install, 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 $env:CARGO_HOME)) { Invoke-WebRequest -Uri "https://win.rustup.rs" ` -OutFile "$env:TEMP\rustup-init.exe" Exec -NoNewLines { & "$env:TEMP\rustup-init.exe" -y --default-toolchain $env:RUST_VERSION } Delete-Tree @( "$env:RUSTUP_HOME\downloads", "$env:RUSTUP_HOME\tmp", "$env:RUSTUP_HOME\toolchains\stable-x86_64-pc-windows-msvc\share\doc" ) } Exec { rustup component add clippy } Exec { rustup component add rustfmt } # Log installed Node.js version + processor architecture. - node -p "`Node ${process.version} ${process.arch}`" # Log installed Python version + processor architecture. - ps: |- @("from sys import version", "print 'Python', version") -join "`n" | & python - # Log some more versions. - rustc --version - cargo --version before_build: # Download clang and gn, generate ninja files. - python tools\setup.py # Start sccache, then throw away the S3 access key. - ps: |- sccache --start-server $env:AWS_SECRET_ACCESS_KEY = $null build_script: # Build with Cargo first. Both builds produce a deno.exe in the same dir. We # want the final one (which gets tested and released) to be built by Ninja. - cargo build -vv --release --locked - cargo clippy --all-targets --release --locked -- -D clippy::all - python tools\build.py test_script: - python tools\lint.py - python tools\test_format.py - ps: Exec { & python tools\test.py --build-dir $env:DENO_BUILD_PATH } after_test: # Delete the the rollup cache, which is unreliable, so that it doesn't get # persisted in the appveyor cache. - ps: if (Get-SaveCache) { Delete-Tree "$env:DENO_BUILD_PATH\.rpt2_cache" } # Stop sccache and show stats. - ps: sccache --stop-server # Verify that the build is fully up-to-date. Running ninja should be a no-op. # This catches erroneous file cleanup, and incorrectly set up build deps. - ps: |- $out = ninja -C $env:DENO_BUILD_PATH -n -d explain if ($out -notcontains "ninja: no work to do.") { throw "Build should be up-to-date but isn't." } # Verify that javascript and typescript files which are bundled by rollup are # listed explicitly in cli\BUILD.gn. This is not an air-tight check. # TODO: make rollup or another bundler write a depfile. - ps: |- $ignore = "test_util.ts", "unit_tests.ts", "unit_test_runner.ts", "*_test.ts" Get-ChildItem "js" -File -Force -Name | where { $name = $_; -not ($ignore | where { $name -like $_ }) } | where { -not (Select-String -Pattern $_ -Path cli\BUILD.gn ` -SimpleMatch -CaseSensitive) } | foreach { throw "$_ should be listed in cli\BUILD.gn but isn't." } # Verify that generated ninja files do not use absolute path names. # If they do, it makes ccache/sccache much less effective. - ps: |- $trap = "NO_ABS_PATH_PLS" $dir = "$env:APPVEYOR_BUILD_FOLDER\out\$trap" Exec { gn gen $dir | Out-Null } $files = Get-Tree $dir -File -Force -Recurse | where Extension -ne ".dll" Select-String $trap -Path $files -SimpleMatch | where { # V8 took the liberty to produce an absolute path in their ninja # output. We can't do much about that, so we just ignore it. $_.Line -notmatch "v8/builtins-generated/bytecodes-builtins-list.h" } | tee -Variable line_matches if ($line_matches) { $ctx = $line_matches.Line | Select-String "[^\s;,]*[\s=]*[^\s;,=]*$trap[^\s;,]*" -AllMatches | foreach { $_.Matches.Value -replace '\$(.)', '$1' } | sort -Unique throw @("Absolute path(s) found in build script:") + $ctx -join "`n " } # If this build is going to be deployed, build a zip file. - ps: |- if ($env:APPVEYOR_REPO_TAG -eq "true") { Compress-Archive -CompressionLevel Optimal -Force ` -Path "$env:DENO_BUILD_PATH\deno.exe" ` -DestinationPath "$env:APPVEYOR_BUILD_FOLDER\$env:RELEASE_ARTIFACT" } artifacts: path: $(RELEASE_ARTIFACT) deploy: provider: GitHub auth_token: secure: HQIIUEOtep3yRiBacZCtX8hVmgtdNvt6Hx7u9fP4Wj2ZYp+eBFP2OLf67RKVa5VZ on: APPVEYOR_REPO_NAME: denoland/deno APPVEYOR_REPO_TAG: true