appveyor / ci

AppVeyor community support repository
https://www.appveyor.com
344 stars 66 forks source link

Artifact download 500 internal server error #1884

Open RobertBColton opened 7 years ago

RobertBColton commented 7 years ago
Start-FileDownloadInternal : Error downloading remote file: One or more errors occurred.
Inner Exception: Remote server returned 500: Internal Server Error
At C:\Program Files\AppVeyor\BuildAgent\Modules\build-worker-api\build-worker-api.psm1:242 char:2
+     Start-FileDownloadInternal -Url $Url -FileName $FileName -Timeout ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Start-FileDownloadInternal], Exception
    + FullyQualifiedErrorId : System.Exception,Appveyor.BuildAgent.Api.Utils.StartFileDownloadInternalCmdlet

I download artifacts published by my CI build's first job, and whenever a new build is queued (even if rolling builds are enabled/disabled), I get the above error message when downloading an artifact, otherwise, downloading the artifact is fine. I will get this error message even though I can successfully visit the URL in FireFox myself and still download the artifact.

This the code to download the artifact:

$artifactsURL = "https://ci.appveyor.com/api/buildjobs/$env:ARCHIVE_JOB/artifacts/"
appveyor DownloadFile ($artifactsURL + "blobs.zip") -FileName blobs.zip

If I use the other methods for downloading files, like the web client or curl, I get messages like this too:

Invoke-WebRequest : {"message":"artifactStorageId is not specified"}
At line:24 char:3
+   Invoke-WebRequest ($artifactsURL + "blobs.zip") -OutFile blobs.zip
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
IlyaFinkelshteyn commented 7 years ago

Where $env:ARCHIVE_JOB comes from? For URL to work this should be unique build job ID and I am not aware of the easy way to pass it from on job of the same build to another. It can be easily passed from one build to another as an environment variable though (if one build starts build of another project).

RobertBColton commented 7 years ago

Like so, also using the API:

init:
  - echo "%APPVEYOR_JOB_ID%"
  # store the name of the archive job in an environment variable
  # this designates the first job of every build as the archive job
  - ps: |
      $apiURL = "https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG"
      $env:ARCHIVE_JOB = (Invoke-RestMethod -Method Get -Uri $apiURL).build.jobs[0].jobId
  - echo "%ARCHIVE_JOB%"
  - cd %APPVEYOR_BUILD_FOLDER%
IlyaFinkelshteyn commented 6 years ago

@RobertBColton just came around this issue and realized we did not resolve it. Sorry. Please check this sample, should help.

RobertBColton commented 6 years ago

@IlyaFinkelshteyn I have figured out the problem, and it seems to be AppVeyor's fault. When you queue up another build while in the middle of one build, the JSON returned will have all the jobs from the newly queued build but none of the ones of the current build. So when the new build queues, the REST API is returning the wrong ID of the current builds first job:

    "build":  {
                  "buildId":  13211986,
                  "jobs":  [
                               "@{jobId=9opu8wg5ofs0qjb6; name=Environment: COMPILER=gcc, PLATFORM=Win32, MODE=Run, GRAPHICS=Direct3D9, AUDIO=None, COLLISION=None, NETWORK=None, WIDGETS=None, EXTENSIONS=None; osType=Windows; allowFailure=False; messagesCount=0; compilationMessagesCount=0; compilationErrorsCount=0; compilationWarningsCount=0; testsCount=0; passedTestsCount=0; failedTestsCount=0; artifactsCount=0; status=running; started=2018-01-13T18:01:33.6311394+00:00; created=2018-01-13T18:00:27.41834+00:00; updated=2018-01-13T18:01:33.6311394+00:00}"

Is there another way I can go about getting the archive job's id other than using the name like you do in your example script? My build matrix names are really long and I don't like having to enter that in my yaml.

$env:ARCHIVE_JOB = (Invoke-RestMethod -Method Get -Uri $apiURL).build.jobs[0].jobId