prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Release Automation Fixes for Seventh Release
  The release script is not properly waiting for the wheel job it starts to finish before downloading. This causes it to download previous releases and attempt to upload them.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `tasks.py`
  Content:
  ```
  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     while True:
  21         response = session.get(
  22             "{0}/lastBuild/api/json/".format(JENKINS_URL),
  23             headers={
  24                 "Accept": "application/json",
  25             }
  26         )
  27         response.raise_for_status()
  28         if not response.json()["building"]:
  29             assert response.json()["result"] == "SUCCESS"
  30             break
  31         time.sleep(0.1)
  32 
  33 
  34 def download_artifacts(session):
  35     response = session.get(
  36         "{0}/lastBuild/api/json/".format(JENKINS_URL),
  37         headers={
  38             "Accept": "application/json"
  39         }
  40     )
  41     response.raise_for_status()
  42     assert not response.json()["building"]
  43     assert response.json()["result"] == "SUCCESS"
  44 
  45     paths = []
  46 
  47     for run in response.json()["runs"]:
  48         response = session.get(
  49             run["url"] + "api/json/",
  50             headers={
  51                 "Accept": "application/json",
  52             }
  53         )
  54         response.raise_for_status()
  55         for artifact in response.json()["artifacts"]:
  56             response = session.get(
  57                 "{0}artifact/{1}".format(run["url"], artifact["relativePath"])
  58             )
  59             out_path = os.path.join(
  60                 os.path.dirname(__file__),
  61                 "dist",
  62                 artifact["fileName"],
  63             )
  64             with open(out_path, "wb") as f:
  65                 f.write(response.content)
  66             paths.append(out_path)
  67     return paths
  68 
  69 
  70 @invoke.task
  71 def release(version):
  72     """
  73     ``version`` should be a string like '0.4' or '1.0'.
  74     """
  75     invoke.run("git tag -s {0} -m '{0} release'".format(version))
  76     invoke.run("git push --tags")
  77 
  78     invoke.run("python setup.py sdist")
  79     invoke.run("cd vectors/ && python setup.py sdist bdist_wheel")
  80 
  81     invoke.run(
  82         "twine upload -s dist/cryptography-{0}* "
  83         "vectors/dist/cryptography_vectors-{0}*".format(version)
  84     )
  85 
  86     session = requests.Session()
  87 
  88     # This tells the CDN to delete the cached response for the URL. We do this
  89     # so that the Jenkins builders will see the new sdist immediately when they
  90     # go to build the wheels.
  91     response = session.request(
  92         "PURGE", "https://pypi.python.org/simple/cryptography/"
  93     )
  94     response.raise_for_status()
  95 
  96     username = getpass.getpass("Input the GitHub/Jenkins username: ")
  97     token = getpass.getpass("Input the Jenkins token: ")
  98     response = session.post(
  99         "{0}/build".format(JENKINS_URL),
  100         auth=requests.auth.HTTPBasicAuth(
  101             username, token
  102         ),
  103         params={
  104             "cause": "Building wheels for {0}".format(version)
  105         }
  106     )
  107     response.raise_for_status()
  108     wait_for_build_completed(session)
  109     paths = download_artifacts(session)
  110     invoke.run("twine upload {0}".format(" ".join(paths)))
  111
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/tasks.py b/tasks.py
  --- a/tasks.py
  +++ b/tasks.py
  @@ -17,6 +17,9 @@
   
   
   def wait_for_build_completed(session):
  +    # Wait 3 seconds before actually checking if the build is complete, to
  +    # ensure that it had time to really start.
  +    time.sleep(3)
       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,6 +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+    # 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", "issue": "Release Automation Fixes for Seventh Release\nThe release script is not properly waiting for the wheel job it starts to finish before downloading. This causes it to download previous releases and attempt to upload them.\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    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"}], "after_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"}]}