Question regarding Build Matrices and Visual Studio

rionmonster's Avatar

rionmonster

13 Jan, 2017 03:28 PM

Hi all,

I've been working on refactoring a long-running open-source project of mine, which has used Appveyor for quite some time to handle building and functioning as a basic deployment mechanism. The original, and last working Appveyor configuration looked something like this :

version: 1.0.{build}
 os: Visual Studio 2015
 
 install:
 - set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH%"
 - ps: (new-object Net.WebClient).DownloadString("https://raw.github.com/madskristensen/ExtensionScripts/master/AppVeyor/vsix.ps1") | iex
 
 before_build:
   - ps: Vsix-IncrementVsixVersion | Vsix-UpdateBuildVersion
 
 build_script:
   - msbuild /p:configuration=Release /p:DeployExtension=false /p:ZipPackageCompressionLevel=normal /v:m
 
 after_test:
   - ps: Vsix-PushArtifacts | Vsix-PublishToGallery

However, this refactoring introduced another project into my solution that needs to be built as well and will need to target Visual Studio 2017, which I requested access to through this GitHub thread. Since I have two projects, I figured that I would need to use a Build Matrix to handle each of the builds independently using the same Appveyor.xml file, but I wasn't entirely sure how to structure as I need to target both the VS2015 project and VS2017 projects independently as they are in different projects and will require different build images.

Any advice at all would be extremely helpful and if you have any questions, the specific branch in question can be found here on GitHub, with the two projects being in the src/...VS2015 and src/...VS2017 folders respectively.

  1. 1 Posted by Ilya Finkelshte... on 13 Jan, 2017 05:38 PM

    Ilya Finkelshteyn's Avatar

    Hi!

    You should be able to achieve this with "tweak" environment variable APPVEYOR_BUILD_WORKER_IMAGE. Please take a look at this sample:

    environment:
      matrix:
      - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
        SOME_OTHER_VARIABLE: SomeValue
      - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
        SOME_OTHER_VARIABLE: SomeValue2
    

    SOME_OTHER_VARIABLE is not required, it is just a sample in case you need to pass something specific to specific build. For example msbuild path, though it should be already correct on both images.

    Let us know if this works for you.

    Thanks!
    Ilya.

  2. 2 Posted by rionmonster on 13 Jan, 2017 09:42 PM

    rionmonster's Avatar

    Hi Ilya,

    Sorry, I'm not terribly familiar with Appveyor. So within the sections of the matrix, would I need to define the locations of each on the individual projects? They are each located in different folders from the root of the project (where the Appveyor.yml file would be defined) in /src/VS2015 and /src/VS2017 respectively.

    Is that all that would be necessary to handle the build as everything outside of the matrix would apply to both of the individual sections / builds separately correct?

    Thanks,

    Rion

  3. 3 Posted by rionmonster on 13 Jan, 2017 09:59 PM

    rionmonster's Avatar

    Just as a follow-up Ilya, this is what I currently am thinking would be along the lines of what I need :

    # The Version of the Extension
    version: 2.0.{build}
    
    #### Define each build for the extension
    environment:
      matrix:
        # Visual Studio 2015 (Question: Do I need to point to the source folder in each of these? i.e. src/VS2015 and src/VS2017 respectively)
        - image: Visual Studio 2015
        before_build:
          - nuget restore /src/VS2015
        # Visual Studio 2017
        - image: Visual Studio 2017 RC
        before_build:
          - nuget restore /src/VS2015
    
    #### Installation Scripts to Handle VSIX Deployment, etc.
    install:
      - ps: (new-object Net.WebClient).DownloadString("https://raw.github.com/madskristensen/ExtensionScripts/master/AppVeyor/vsix.ps1") | iex
      - powershell -NoProfile -ExecutionPolicy unrestricted -Command "&{iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/dotnet-install.ps1'))}"
    
    #### Only perform this for Release builds
    configuration:
      - Release
    
    #### Actually handle building
    build_script:
     - msbuild /p:configuration=Release /p:DeployExtension=false /p:ZipPackageCompressionLevel=normal /v:m
    
    #### Handle Deployment to VSIX Gallery
    after_test:
      - ps: Vsix-PushArtifacts | Vsix-PublishToGallery
    

    My only concerns are :

    • Do I need to define the project directory for each of the items within the matrix somehow?
    • Are there any glaring syntax issues that I need to address? Can the before_build section be used in each of the individual sections of the build?

    Thanks again,

    Rion

  4. 4 Posted by Ilya Finkelshte... on 13 Jan, 2017 11:10 PM

    Ilya Finkelshteyn's Avatar

    Hi Rion,

    Please try this:

    environment:
      matrix:
        # Visual Studio 2015
        - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
          SRC_FOLDER: src/VS2015
        
        # Visual Studio 2017
        - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 RC
          SRC_FOLDER: src/VS2017
    
    before_build:
      - nuget restore %SRC_FOLDER%
    

    You define project directory as environment variable SRC_FOLDER alongside with another ("tweak") environment variable APPVEYOR_BUILD_WORKER_IMAGE which defines the image. This way you can be sure that right project directory will be used with right image. When you need this project folder (in your case with nuget restore you just call SRC_FOLDER variable. Note that before_build is outside of matrix.

    Sorry for confusion, build matrix can be expressed in a few ways, but this is most straightforward and easy to read.

    Other than that I do not see any syntax issues. Note that you can always Validate YAML in advance.

    Ilya.

  5. 5 Posted by rionmonster on 16 Jan, 2017 07:23 PM

    rionmonster's Avatar

    Hi Ilya,

    Thanks for that, as I think it's a step in the right direction, however it currently doesn't appear to resolve the issue as when attempting to build I encountered an error (see attachment for example).

    If you need another example, you can see the entire solution available on GitHub here or what the Appveyor.xml file looks like below :

    version: 2.0.{build}
    
    environment:
       matrix:
          # Visual Studio 2015
          - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
            SRC_FOLDER: src/VS2015
          # Visual Studio 2017
          - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 RC
            SRC_FOLDER: src/VS2017
    
    configuration:
       - Release
    
    install:
       - ps: (new-object Net.WebClient).DownloadString("https://raw.github.com/madskristensen/ExtensionScripts/master/AppVeyor/vsix.ps1") | iex
       - powershell -NoProfile -ExecutionPolicy unrestricted -Command "&{iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/dotnet-install.ps1'))}"
    
    before_build:
       - nuget restore %SRC_FOLDER%
    
    build_script:
       - msbuild /p:configuration=Release /p:DeployExtension=false /p:ZipPackageCompressionLevel=normal /v:m
    
    after_test:
       - ps: Vsix-PushArtifacts | Vsix-PublishToGallery
    

    Again - I feel like it's quite close and may just be one minor thing that I am missing, but any advice or ideas would be extremely helpful.

    Thanks,

    Rion

  6. 6 Posted by Ilya Finkelshte... on 17 Jan, 2017 04:05 AM

    Ilya Finkelshteyn's Avatar

    Sent you PR with proposed solution

  7. 7 Posted by rionmonster on 17 Jan, 2017 07:24 PM

    rionmonster's Avatar

    Hi Illya,

    I was looking over your PR. Is it necessary to have the separate configurations for each build? Would it be possible for each to simply use the Release configuration or is there something that I am missing?

    That is, something like this :

    
    version: 2.0.{build}
    configuration: Release
    environment:
       matrix:
          # Visual Studio 2015
          - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
          # Visual Studio 2017
          - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 RC
    install:
       - ps: (new-object Net.WebClient).DownloadString("https://raw.github.com/madskristensen/ExtensionScripts/master/AppVeyor/vsix.ps1") | iex
       - powershell -NoProfile -ExecutionPolicy unrestricted -Command "&{iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/dotnet-install.ps1'))}"
    
    before_build:   
       - nuget restore
    
    build_script:
       - msbuild /p:configuration=Release /p:DeployExtension=false /p:ZipPackageCompressionLevel=normal /v:m
    
    after_test:
       - ps: Vsix-PushArtifacts | Vsix-PublishToGallery
    

    Additionally, I notice that there isn't a specific "SRC_FOLDER" to point to the appropriate project location. Is that correct?

    Thanks,

    Rion

  8. 8 Posted by Ilya Finkelshte... on 17 Jan, 2017 07:36 PM

    Ilya Finkelshteyn's Avatar

    I just though it would be nicer because no unneeded builds and artifacts will be generated. Like VS2015 build/artifact with VS2017 build. I did something similar to what you propose and if I remember correctly (unfortunately already I deleted that builds), on 2017 image it created both 2015 and 2017 artifacts (end even published :)), and on 2015 image it created only one.
    Please feel free to shutdown the PR, it is just simple way to show an idea :)

    Yes, I don't think we need SRC_FOLDER as simple nuget restore works OK.

  9. 9 Posted by Ilya Finkelshte... on 17 Jan, 2017 08:05 PM

    Ilya Finkelshteyn's Avatar

    By the way, as I mentioned -- on 2017 image it created both 2015 and 2017 artifacts (end even published :)) -- Maybe this is not bad, and you don't need matrix at all and just use 2017 image for everything?

  10. 10 Posted by rionmonster on 17 Jan, 2017 09:13 PM

    rionmonster's Avatar

    That's actually a good point.

    I'm checking with a guy that I've been working with over at MS to see how his PushArtifacts / PublishToGallery code works to ensure that it could handle multiple different projects. If that was the case, then a single build would likely work and would simplify everything.

    Otherwise, I'll probably need to make a Debug/Release build for each of the individual projects similar to the approach your PR implements.

    I'll let you know shortly.

    Thanks,

    Rion

  11. 11 Posted by rionmonster on 17 Jan, 2017 11:00 PM

    rionmonster's Avatar

    Hi again Ilya,

    So I spoke with my contact and he informed me that the publishing process will look for any VSIX artifacts (which we should get one for 2015 and one for 2017) and will publish each of them independently to the appropriate location.

    It sounds like that's what you had mentioned was occurring when you were using the 2017 worker, is that correct? If so, what changes would we need to make to the Appveyor.yml file? I'm assuming it would get rid of the Build Matrix stuff, so would it just look like this?

    version: 2.0.{build}
    configuration: Release
    image: Visual Studio 2017 RC
    
    install:
       - ps: (new-object Net.WebClient).DownloadString("https://raw.github.com/madskristensen/ExtensionScripts/master/AppVeyor/vsix.ps1") | iex
       - powershell -NoProfile -ExecutionPolicy unrestricted -Command "&{iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/dotnet-install.ps1'))}"
    
    before_build:   
       - nuget restore
    
    build_script:
       - msbuild /p:configuration=Release /p:DeployExtension=false /p:ZipPackageCompressionLevel=normal /v:m
    
    after_test:
       - ps: Vsix-PushArtifacts | Vsix-PublishToGallery
    

    You can feel free to push another PR or just let me know if that looks correct.

    Thanks so much for all of your help,

    Rion

  12. 12 Posted by Ilya Finkelshte... on 17 Jan, 2017 11:07 PM

    Ilya Finkelshteyn's Avatar

    Yes, this looks good! I closed the PR.

    Thanks!
    Ilya.

  13. rionmonster closed this discussion on 27 Feb, 2017 03:33 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac