Matrix of 32 and 64 bit targets in the same artifact

trevor.sandy's Avatar

trevor.sandy

03 Oct, 2017 08:14 PM

My AppVeyor.ymI supports a matrix build of 32 and 64 bit targets.

I would like to have both targets available in last build's artifact. To achieve this, I've set the target artifact to be my build folder which is also cached.

The idea is to cache the folder between builds so the second build will be added to the build folder which will then be archived as the artifact of the second build and contain both the first and second build output.

However, my artifacts are not combined on the second Matrix build, instead each build's artifact (the build folder) only contains the content for that build - i.e. 32bit and 64bit target package respectively.

Is what I'm trying to do possible on AppVeyor ?

Many thanks!

  1. 1 Posted by Ilya Finkelshte... on 03 Oct, 2017 09:09 PM

    Ilya Finkelshteyn's Avatar

    Right now it is separate cache for each build job. Please watch this GitHub issue to see what it become more flexible.

    I believe that now you can try do download build artifact from job 1 suing script called from job 2. Here is a script example. Sure this assumes that you have single concurrent job and Job 2 is always after Job 1.

    You can do even more elaborate hack by creating separate project which does not do actual build, but only download both artifacts and package them as one. This project can be started with API as final step of main build -- Sample. But probably this is overkill :)

  2. 2 Posted by trevor.sandy on 04 Oct, 2017 07:22 PM

    trevor.sandy's Avatar

    Excellent. This is good information. Many thanks.

  3. 3 Posted by trevor.sandy on 05 Oct, 2017 03:57 PM

    trevor.sandy's Avatar

    Here my cleaned script block for reference to anyone interested in this use case.
    The base script was taken from Downloading AppVeyor build artifacts.

    # The purpose of this script is to package the output of 2 jobs - 32 and 64bit targets - into a single artifact
    # The scenario is there are 2 jobs (build 32 and 64bit targets) each producing 1 artifact - the target root folder
    # At the end of job 1, the target root will contain the 32bit target which is stored as an artifact
    # At the beginning of job 2, this script downloads and extracts job 1's artifact to the target root
    # At the end of job 2, the target root will contain both the 32 and 64bit targets and subsequently stored as an artifact
    #
    # The example uses the following yml vars:
    # environment:
    #   target_root: [ your target path root folder - e.g. builds\windows\$(configuration) ]
    #   matrix:
    #   - target_arch: [ your target architecture - e.g. x86, x86_64 ]
    #
    before_build:  
     # Check target architecture condition - job 2 builds the 64bit target.
     - ps: |
          if ($env:target_arch -eq "x86_64")
          {
            Write-Output "Restoring $env:target_root target root from artifact..."
    
            $apiUrl = 'https://ci.appveyor.com/api'
            $token = '<your token>'
            $headers = @{
              "Authorization" = "Bearer $token"
              "Content-type" = "application/json"
            }
            $accountName = '<your account name>'
            $projectSlug = '<your project slug>'
    
            # using clone folder...
            $downloadLocation = 'c:\projects\<your desired location>'
    
            # get last job (job 1) details
            $project = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$accountName/$projectSlug" -Headers $headers
    
            # get this job id
            $jobId = $project.build.jobs[0].jobId
    
            # get job artifacts - an array of jobs
            $artifacts = Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts" -Headers $headers
    
            # select the first [0] artifact, or  use the artifact name - e.g. $artifactFileName = 'MyPath/MyArtifact.zip'
            $artifactFileName = $artifacts[0].fileName
    
            # artifact will be downloaded as
            $localArtifactArchive = "$downloadLocation\$artifactFileName"
    
            # download artifact
            Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifactFileName" `
            -OutFile $localArtifactArchive -Headers @{ "Authorization" = "Bearer $token" }
    
            # set artifact output path - if it is dfferent from the stored artifact name
            $CheckArtifactDir = (Get-Item $artifactFileName ).DirectoryName+"\"+$env:Configuration
    
            # extract artifact
            if (-not (Test-Path $CheckArtifactDir)) {
              if (-not (Test-Path $localArtifactArchive)) {
                Write-Output "Error artifact $localArtifactArchive not found"
              } else {
                Write-Output "Extracting artifact $localArtifactArchive ..."
                & 7z.exe x $localArtifactArchive "-o$CheckArtifactDir" | Select-String -Pattern "^Extracting " -CaseSensitive -NotMatch
                if (-not (Test-Path $CheckArtifactDir)) {
                  Write-Output "Error extracting $localArtifactArchive, $CheckArtifactDir not found"
                } else {
                  Write-Output "Target root $env:target_root restored from artifact $artifactFileName"
                }
              }
            }
          }
    
  4. 4 Posted by Ilya Finkelshte... on 05 Oct, 2017 05:04 PM

    Ilya Finkelshteyn's Avatar

    Thank you for sharing!

  5. Ilya Finkelshteyn closed this discussion on 25 Aug, 2018 02:20 AM.

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