prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Build automation fixes for 8th release
  When triggering the wheel build the release automation does not appropriately wait for the build to complete but instead grabs the previous build. The previous attempted fix of adding a `sleep(3)` did not work around this issue.
  
  
  </issue>
  <code>
  [start of tasks.py]
  1 # This file is dual licensed under the terms of the Apache License, Version
  2 # 2.0, and the BSD License. See the LICENSE file in the root of this repository
  3 # for complete details.
  4 
  5 from __future__ import absolute_import, division, print_function
  6 
  7 import getpass
  8 import os
  9 import time
  10 
  11 import invoke
  12 
  13 import requests
  14 
  15 
  16 JENKINS_URL = "https://jenkins.cryptography.io/job/cryptography-wheel-builder"
  17 
  18 
  19 def wait_for_build_completed(session):
  20     # Wait 3 seconds before actually checking if the build is complete, to
  21     # ensure that it had time to really start.
  22     time.sleep(3)
  23     while True:
  24         response = session.get(
  25             "{0}/lastBuild/api/json/".format(JENKINS_URL),
  26             headers={
  27                 "Accept": "application/json",
  28             }
  29         )
  30         response.raise_for_status()
  31         if not response.json()["building"]:
  32             assert response.json()["result"] == "SUCCESS"
  33             break
  34         time.sleep(0.1)
  35 
  36 
  37 def download_artifacts(session):
  38     response = session.get(
  39         "{0}/lastBuild/api/json/".format(JENKINS_URL),
  40         headers={
  41             "Accept": "application/json"
  42         }
  43     )
  44     response.raise_for_status()
  45     assert not response.json()["building"]
  46     assert response.json()["result"] == "SUCCESS"
  47 
  48     paths = []
  49 
  50     for run in response.json()["runs"]:
  51         response = session.get(
  52             run["url"] + "api/json/",
  53             headers={
  54                 "Accept": "application/json",
  55             }
  56         )
  57         response.raise_for_status()
  58         for artifact in response.json()["artifacts"]:
  59             response = session.get(
  60                 "{0}artifact/{1}".format(run["url"], artifact["relativePath"])
  61             )
  62             out_path = os.path.join(
  63                 os.path.dirname(__file__),
  64                 "dist",
  65                 artifact["fileName"],
  66             )
  67             with open(out_path, "wb") as f:
  68                 f.write(response.content)
  69             paths.append(out_path)
  70     return paths
  71 
  72 
  73 @invoke.task
  74 def release(version):
  75     """
  76     ``version`` should be a string like '0.4' or '1.0'.
  77     """
  78     invoke.run("git tag -s {0} -m '{0} release'".format(version))
  79     invoke.run("git push --tags")
  80 
  81     invoke.run("python setup.py sdist")
  82     invoke.run("cd vectors/ && python setup.py sdist bdist_wheel")
  83 
  84     invoke.run(
  85         "twine upload -s dist/cryptography-{0}* "
  86         "vectors/dist/cryptography_vectors-{0}*".format(version)
  87     )
  88 
  89     session = requests.Session()
  90 
  91     # This tells the CDN to delete the cached response for the URL. We do this
  92     # so that the Jenkins builders will see the new sdist immediately when they
  93     # go to build the wheels.
  94     response = session.request(
  95         "PURGE", "https://pypi.python.org/simple/cryptography/"
  96     )
  97     response.raise_for_status()
  98 
  99     username = getpass.getpass("Input the GitHub/Jenkins username: ")
  100     token = getpass.getpass("Input the Jenkins token: ")
  101     response = session.post(
  102         "{0}/build".format(JENKINS_URL),
  103         auth=requests.auth.HTTPBasicAuth(
  104             username, token
  105         ),
  106         params={
  107             "cause": "Building wheels for {0}".format(version)
  108         }
  109     )
  110     response.raise_for_status()
  111     wait_for_build_completed(session)
  112     paths = download_artifacts(session)
  113     invoke.run("twine upload {0}".format(" ".join(paths)))
  114
  [end of tasks.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/tasks.py b/tasks.py
  --- a/tasks.py
  +++ b/tasks.py
  @@ -17,9 +17,9 @@
   
   
   def wait_for_build_completed(session):
  -    # Wait 3 seconds before actually checking if the build is complete, to
  +    # Wait 20 seconds before actually checking if the build is complete, to
       # ensure that it had time to really start.
  -    time.sleep(3)
  +    time.sleep(20)
       while True:
           response = session.get(
               "{0}/lastBuild/api/json/".format(JENKINS_URL),
  
verification_info: {"golden_diff": "diff --git a/tasks.py b/tasks.py\n--- a/tasks.py\n+++ b/tasks.py\n@@ -17,9 +17,9 @@\n \n \n def wait_for_build_completed(session):\n-    # Wait 3 seconds before actually checking if the build is complete, to\n+    # Wait 20 seconds before actually checking if the build is complete, to\n     # ensure that it had time to really start.\n-    time.sleep(3)\n+    time.sleep(20)\n     while True:\n         response = session.get(\n             \"{0}/lastBuild/api/json/\".format(JENKINS_URL),\n", "issue": "Build automation fixes for 8th release\nWhen triggering the wheel build the release automation does not appropriately wait for the build to complete but instead grabs the previous build. The previous attempted fix of adding a `sleep(3)` did not work around this issue.\n\n", "before_files": [{"content": "# This file is dual licensed under the terms of the Apache License, Version\n# 2.0, and the BSD License. See the LICENSE file in the root of this repository\n# for complete details.\n\nfrom __future__ import absolute_import, division, print_function\n\nimport getpass\nimport os\nimport time\n\nimport invoke\n\nimport requests\n\n\nJENKINS_URL = \"https://jenkins.cryptography.io/job/cryptography-wheel-builder\"\n\n\ndef wait_for_build_completed(session):\n    # Wait 3 seconds before actually checking if the build is complete, to\n    # ensure that it had time to really start.\n    time.sleep(3)\n    while True:\n        response = session.get(\n            \"{0}/lastBuild/api/json/\".format(JENKINS_URL),\n            headers={\n                \"Accept\": \"application/json\",\n            }\n        )\n        response.raise_for_status()\n        if not response.json()[\"building\"]:\n            assert response.json()[\"result\"] == \"SUCCESS\"\n            break\n        time.sleep(0.1)\n\n\ndef download_artifacts(session):\n    response = session.get(\n        \"{0}/lastBuild/api/json/\".format(JENKINS_URL),\n        headers={\n            \"Accept\": \"application/json\"\n        }\n    )\n    response.raise_for_status()\n    assert not response.json()[\"building\"]\n    assert response.json()[\"result\"] == \"SUCCESS\"\n\n    paths = []\n\n    for run in response.json()[\"runs\"]:\n        response = session.get(\n            run[\"url\"] + \"api/json/\",\n            headers={\n                \"Accept\": \"application/json\",\n            }\n        )\n        response.raise_for_status()\n        for artifact in response.json()[\"artifacts\"]:\n            response = session.get(\n                \"{0}artifact/{1}\".format(run[\"url\"], artifact[\"relativePath\"])\n            )\n            out_path = os.path.join(\n                os.path.dirname(__file__),\n                \"dist\",\n                artifact[\"fileName\"],\n            )\n            with open(out_path, \"wb\") as f:\n                f.write(response.content)\n            paths.append(out_path)\n    return paths\n\n\n@invoke.task\ndef release(version):\n    \"\"\"\n    ``version`` should be a string like '0.4' or '1.0'.\n    \"\"\"\n    invoke.run(\"git tag -s {0} -m '{0} release'\".format(version))\n    invoke.run(\"git push --tags\")\n\n    invoke.run(\"python setup.py sdist\")\n    invoke.run(\"cd vectors/ && python setup.py sdist bdist_wheel\")\n\n    invoke.run(\n        \"twine upload -s dist/cryptography-{0}* \"\n        \"vectors/dist/cryptography_vectors-{0}*\".format(version)\n    )\n\n    session = requests.Session()\n\n    # This tells the CDN to delete the cached response for the URL. We do this\n    # so that the Jenkins builders will see the new sdist immediately when they\n    # go to build the wheels.\n    response = session.request(\n        \"PURGE\", \"https://pypi.python.org/simple/cryptography/\"\n    )\n    response.raise_for_status()\n\n    username = getpass.getpass(\"Input the GitHub/Jenkins username: \")\n    token = getpass.getpass(\"Input the Jenkins token: \")\n    response = session.post(\n        \"{0}/build\".format(JENKINS_URL),\n        auth=requests.auth.HTTPBasicAuth(\n            username, token\n        ),\n        params={\n            \"cause\": \"Building wheels for {0}\".format(version)\n        }\n    )\n    response.raise_for_status()\n    wait_for_build_completed(session)\n    paths = download_artifacts(session)\n    invoke.run(\"twine upload {0}\".format(\" \".join(paths)))\n", "path": "tasks.py"}]}