prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Improve regex for semver in automation rules
  We have a very basic pattern, but on the semver faq they have a better one
  
  https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
  
  This needs to be changed and with a comment to the link from where it came from.
  
  https://github.com/readthedocs/readthedocs.org/blob/ff0ad67991e599f79e9d956a3733785ccb78c505/readthedocs/builds/constants.py#L113-L113
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `readthedocs/builds/constants.py`
  Content:
  ```
  1 """Constants for the builds app."""
  2 
  3 from django.conf import settings
  4 from django.utils.translation import ugettext_lazy as _
  5 
  6 
  7 BUILD_STATE_TRIGGERED = 'triggered'
  8 BUILD_STATE_CLONING = 'cloning'
  9 BUILD_STATE_INSTALLING = 'installing'
  10 BUILD_STATE_BUILDING = 'building'
  11 BUILD_STATE_FINISHED = 'finished'
  12 
  13 BUILD_STATE = (
  14     (BUILD_STATE_TRIGGERED, _('Triggered')),
  15     (BUILD_STATE_CLONING, _('Cloning')),
  16     (BUILD_STATE_INSTALLING, _('Installing')),
  17     (BUILD_STATE_BUILDING, _('Building')),
  18     (BUILD_STATE_FINISHED, _('Finished')),
  19 )
  20 
  21 BUILD_TYPES = (
  22     ('html', _('HTML')),
  23     ('pdf', _('PDF')),
  24     ('epub', _('Epub')),
  25     # There is currently no support for building man/dash formats, but we keep
  26     # it there since the DB might still contain those values for legacy
  27     # projects.
  28     ('man', _('Manpage')),
  29     ('dash', _('Dash')),
  30 )
  31 
  32 # Manager name for Internal Versions or Builds.
  33 # ie: Versions and Builds Excluding pull request/merge request Versions and Builds.
  34 INTERNAL = 'internal'
  35 # Manager name for External Versions or Builds.
  36 # ie: Only pull request/merge request Versions and Builds.
  37 EXTERNAL = 'external'
  38 EXTERNAL_TEXT = _('External')
  39 
  40 BRANCH = 'branch'
  41 BRANCH_TEXT = _('Branch')
  42 TAG = 'tag'
  43 TAG_TEXT = _('Tag')
  44 UNKNOWN = 'unknown'
  45 UNKNOWN_TEXT = _('Unknown')
  46 
  47 VERSION_TYPES = (
  48     (BRANCH, BRANCH_TEXT),
  49     (TAG, TAG_TEXT),
  50     (EXTERNAL, EXTERNAL_TEXT),
  51     (UNKNOWN, UNKNOWN_TEXT),
  52 )
  53 
  54 LATEST = settings.RTD_LATEST
  55 LATEST_VERBOSE_NAME = settings.RTD_LATEST_VERBOSE_NAME
  56 
  57 STABLE = settings.RTD_STABLE
  58 STABLE_VERBOSE_NAME = settings.RTD_STABLE_VERBOSE_NAME
  59 
  60 # Those names are specialcased version names. They do not correspond to
  61 # branches/tags in a project's repository.
  62 NON_REPOSITORY_VERSIONS = (
  63     LATEST,
  64     STABLE,
  65 )
  66 
  67 # General Build Statuses
  68 BUILD_STATUS_FAILURE = 'failed'
  69 BUILD_STATUS_PENDING = 'pending'
  70 BUILD_STATUS_SUCCESS = 'success'
  71 
  72 # GitHub Build Statuses
  73 GITHUB_BUILD_STATUS_FAILURE = 'failure'
  74 GITHUB_BUILD_STATUS_PENDING = 'pending'
  75 GITHUB_BUILD_STATUS_SUCCESS = 'success'
  76 
  77 # GitLab Build Statuses
  78 GITLAB_BUILD_STATUS_FAILURE = 'failed'
  79 GITLAB_BUILD_STATUS_PENDING = 'pending'
  80 GITLAB_BUILD_STATUS_SUCCESS = 'success'
  81 
  82 # Used to select correct Build status and description to be sent to each service API
  83 SELECT_BUILD_STATUS = {
  84     BUILD_STATUS_FAILURE: {
  85         'github': GITHUB_BUILD_STATUS_FAILURE,
  86         'gitlab': GITLAB_BUILD_STATUS_FAILURE,
  87         'description': 'Read the Docs build failed!',
  88     },
  89     BUILD_STATUS_PENDING: {
  90         'github': GITHUB_BUILD_STATUS_PENDING,
  91         'gitlab': GITLAB_BUILD_STATUS_PENDING,
  92         'description': 'Read the Docs build is in progress!',
  93     },
  94     BUILD_STATUS_SUCCESS: {
  95         'github': GITHUB_BUILD_STATUS_SUCCESS,
  96         'gitlab': GITLAB_BUILD_STATUS_SUCCESS,
  97         'description': 'Read the Docs build succeeded!',
  98     },
  99 }
  100 
  101 RTD_BUILD_STATUS_API_NAME = 'continuous-documentation/read-the-docs'
  102 
  103 GITHUB_EXTERNAL_VERSION_NAME = 'Pull Request'
  104 GITLAB_EXTERNAL_VERSION_NAME = 'Merge Request'
  105 GENERIC_EXTERNAL_VERSION_NAME = 'External Version'
  106 
  107 
  108 # Automation rules
  109 
  110 ALL_VERSIONS = 'all-versions'
  111 ALL_VERSIONS_REGEX = r'.*'
  112 SEMVER_VERSIONS = 'semver-versions'
  113 SEMVER_VERSIONS_REGEX = r'^v?(\d+\.)(\d+\.)(\d+)(-.+)?$'
  114 
  115 
  116 PREDEFINED_MATCH_ARGS = (
  117     (ALL_VERSIONS, _('Any version')),
  118     (SEMVER_VERSIONS, _('SemVer versions')),
  119     (None, _('Custom match')),
  120 )
  121 
  122 PREDEFINED_MATCH_ARGS_VALUES = {
  123     ALL_VERSIONS: ALL_VERSIONS_REGEX,
  124     SEMVER_VERSIONS: SEMVER_VERSIONS_REGEX,
  125 }
  126
  ```
  --- 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/readthedocs/builds/constants.py b/readthedocs/builds/constants.py
  --- a/readthedocs/builds/constants.py
  +++ b/readthedocs/builds/constants.py
  @@ -110,7 +110,10 @@
   ALL_VERSIONS = 'all-versions'
   ALL_VERSIONS_REGEX = r'.*'
   SEMVER_VERSIONS = 'semver-versions'
  -SEMVER_VERSIONS_REGEX = r'^v?(\d+\.)(\d+\.)(\d+)(-.+)?$'
  +
  +# Pattern referred from
  +# https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
  +SEMVER_VERSIONS_REGEX = r'^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'  # noqa
   
   
   PREDEFINED_MATCH_ARGS = (
  
verification_info: {"golden_diff": "diff --git a/readthedocs/builds/constants.py b/readthedocs/builds/constants.py\n--- a/readthedocs/builds/constants.py\n+++ b/readthedocs/builds/constants.py\n@@ -110,7 +110,10 @@\n ALL_VERSIONS = 'all-versions'\n ALL_VERSIONS_REGEX = r'.*'\n SEMVER_VERSIONS = 'semver-versions'\n-SEMVER_VERSIONS_REGEX = r'^v?(\\d+\\.)(\\d+\\.)(\\d+)(-.+)?$'\n+\n+# Pattern referred from\n+# https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string\n+SEMVER_VERSIONS_REGEX = r'^v?(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$'  # noqa\n \n \n PREDEFINED_MATCH_ARGS = (\n", "issue": "Improve regex for semver in automation rules\nWe have a very basic pattern, but on the semver faq they have a better one\r\n\r\nhttps://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string\r\n\r\nThis needs to be changed and with a comment to the link from where it came from.\r\n\r\nhttps://github.com/readthedocs/readthedocs.org/blob/ff0ad67991e599f79e9d956a3733785ccb78c505/readthedocs/builds/constants.py#L113-L113\n", "before_files": [{"content": "\"\"\"Constants for the builds app.\"\"\"\n\nfrom django.conf import settings\nfrom django.utils.translation import ugettext_lazy as _\n\n\nBUILD_STATE_TRIGGERED = 'triggered'\nBUILD_STATE_CLONING = 'cloning'\nBUILD_STATE_INSTALLING = 'installing'\nBUILD_STATE_BUILDING = 'building'\nBUILD_STATE_FINISHED = 'finished'\n\nBUILD_STATE = (\n    (BUILD_STATE_TRIGGERED, _('Triggered')),\n    (BUILD_STATE_CLONING, _('Cloning')),\n    (BUILD_STATE_INSTALLING, _('Installing')),\n    (BUILD_STATE_BUILDING, _('Building')),\n    (BUILD_STATE_FINISHED, _('Finished')),\n)\n\nBUILD_TYPES = (\n    ('html', _('HTML')),\n    ('pdf', _('PDF')),\n    ('epub', _('Epub')),\n    # There is currently no support for building man/dash formats, but we keep\n    # it there since the DB might still contain those values for legacy\n    # projects.\n    ('man', _('Manpage')),\n    ('dash', _('Dash')),\n)\n\n# Manager name for Internal Versions or Builds.\n# ie: Versions and Builds Excluding pull request/merge request Versions and Builds.\nINTERNAL = 'internal'\n# Manager name for External Versions or Builds.\n# ie: Only pull request/merge request Versions and Builds.\nEXTERNAL = 'external'\nEXTERNAL_TEXT = _('External')\n\nBRANCH = 'branch'\nBRANCH_TEXT = _('Branch')\nTAG = 'tag'\nTAG_TEXT = _('Tag')\nUNKNOWN = 'unknown'\nUNKNOWN_TEXT = _('Unknown')\n\nVERSION_TYPES = (\n    (BRANCH, BRANCH_TEXT),\n    (TAG, TAG_TEXT),\n    (EXTERNAL, EXTERNAL_TEXT),\n    (UNKNOWN, UNKNOWN_TEXT),\n)\n\nLATEST = settings.RTD_LATEST\nLATEST_VERBOSE_NAME = settings.RTD_LATEST_VERBOSE_NAME\n\nSTABLE = settings.RTD_STABLE\nSTABLE_VERBOSE_NAME = settings.RTD_STABLE_VERBOSE_NAME\n\n# Those names are specialcased version names. They do not correspond to\n# branches/tags in a project's repository.\nNON_REPOSITORY_VERSIONS = (\n    LATEST,\n    STABLE,\n)\n\n# General Build Statuses\nBUILD_STATUS_FAILURE = 'failed'\nBUILD_STATUS_PENDING = 'pending'\nBUILD_STATUS_SUCCESS = 'success'\n\n# GitHub Build Statuses\nGITHUB_BUILD_STATUS_FAILURE = 'failure'\nGITHUB_BUILD_STATUS_PENDING = 'pending'\nGITHUB_BUILD_STATUS_SUCCESS = 'success'\n\n# GitLab Build Statuses\nGITLAB_BUILD_STATUS_FAILURE = 'failed'\nGITLAB_BUILD_STATUS_PENDING = 'pending'\nGITLAB_BUILD_STATUS_SUCCESS = 'success'\n\n# Used to select correct Build status and description to be sent to each service API\nSELECT_BUILD_STATUS = {\n    BUILD_STATUS_FAILURE: {\n        'github': GITHUB_BUILD_STATUS_FAILURE,\n        'gitlab': GITLAB_BUILD_STATUS_FAILURE,\n        'description': 'Read the Docs build failed!',\n    },\n    BUILD_STATUS_PENDING: {\n        'github': GITHUB_BUILD_STATUS_PENDING,\n        'gitlab': GITLAB_BUILD_STATUS_PENDING,\n        'description': 'Read the Docs build is in progress!',\n    },\n    BUILD_STATUS_SUCCESS: {\n        'github': GITHUB_BUILD_STATUS_SUCCESS,\n        'gitlab': GITLAB_BUILD_STATUS_SUCCESS,\n        'description': 'Read the Docs build succeeded!',\n    },\n}\n\nRTD_BUILD_STATUS_API_NAME = 'continuous-documentation/read-the-docs'\n\nGITHUB_EXTERNAL_VERSION_NAME = 'Pull Request'\nGITLAB_EXTERNAL_VERSION_NAME = 'Merge Request'\nGENERIC_EXTERNAL_VERSION_NAME = 'External Version'\n\n\n# Automation rules\n\nALL_VERSIONS = 'all-versions'\nALL_VERSIONS_REGEX = r'.*'\nSEMVER_VERSIONS = 'semver-versions'\nSEMVER_VERSIONS_REGEX = r'^v?(\\d+\\.)(\\d+\\.)(\\d+)(-.+)?$'\n\n\nPREDEFINED_MATCH_ARGS = (\n    (ALL_VERSIONS, _('Any version')),\n    (SEMVER_VERSIONS, _('SemVer versions')),\n    (None, _('Custom match')),\n)\n\nPREDEFINED_MATCH_ARGS_VALUES = {\n    ALL_VERSIONS: ALL_VERSIONS_REGEX,\n    SEMVER_VERSIONS: SEMVER_VERSIONS_REGEX,\n}\n", "path": "readthedocs/builds/constants.py"}], "after_files": [{"content": "\"\"\"Constants for the builds app.\"\"\"\n\nfrom django.conf import settings\nfrom django.utils.translation import ugettext_lazy as _\n\n\nBUILD_STATE_TRIGGERED = 'triggered'\nBUILD_STATE_CLONING = 'cloning'\nBUILD_STATE_INSTALLING = 'installing'\nBUILD_STATE_BUILDING = 'building'\nBUILD_STATE_FINISHED = 'finished'\n\nBUILD_STATE = (\n    (BUILD_STATE_TRIGGERED, _('Triggered')),\n    (BUILD_STATE_CLONING, _('Cloning')),\n    (BUILD_STATE_INSTALLING, _('Installing')),\n    (BUILD_STATE_BUILDING, _('Building')),\n    (BUILD_STATE_FINISHED, _('Finished')),\n)\n\nBUILD_TYPES = (\n    ('html', _('HTML')),\n    ('pdf', _('PDF')),\n    ('epub', _('Epub')),\n    # There is currently no support for building man/dash formats, but we keep\n    # it there since the DB might still contain those values for legacy\n    # projects.\n    ('man', _('Manpage')),\n    ('dash', _('Dash')),\n)\n\n# Manager name for Internal Versions or Builds.\n# ie: Versions and Builds Excluding pull request/merge request Versions and Builds.\nINTERNAL = 'internal'\n# Manager name for External Versions or Builds.\n# ie: Only pull request/merge request Versions and Builds.\nEXTERNAL = 'external'\nEXTERNAL_TEXT = _('External')\n\nBRANCH = 'branch'\nBRANCH_TEXT = _('Branch')\nTAG = 'tag'\nTAG_TEXT = _('Tag')\nUNKNOWN = 'unknown'\nUNKNOWN_TEXT = _('Unknown')\n\nVERSION_TYPES = (\n    (BRANCH, BRANCH_TEXT),\n    (TAG, TAG_TEXT),\n    (EXTERNAL, EXTERNAL_TEXT),\n    (UNKNOWN, UNKNOWN_TEXT),\n)\n\nLATEST = settings.RTD_LATEST\nLATEST_VERBOSE_NAME = settings.RTD_LATEST_VERBOSE_NAME\n\nSTABLE = settings.RTD_STABLE\nSTABLE_VERBOSE_NAME = settings.RTD_STABLE_VERBOSE_NAME\n\n# Those names are specialcased version names. They do not correspond to\n# branches/tags in a project's repository.\nNON_REPOSITORY_VERSIONS = (\n    LATEST,\n    STABLE,\n)\n\n# General Build Statuses\nBUILD_STATUS_FAILURE = 'failed'\nBUILD_STATUS_PENDING = 'pending'\nBUILD_STATUS_SUCCESS = 'success'\n\n# GitHub Build Statuses\nGITHUB_BUILD_STATUS_FAILURE = 'failure'\nGITHUB_BUILD_STATUS_PENDING = 'pending'\nGITHUB_BUILD_STATUS_SUCCESS = 'success'\n\n# GitLab Build Statuses\nGITLAB_BUILD_STATUS_FAILURE = 'failed'\nGITLAB_BUILD_STATUS_PENDING = 'pending'\nGITLAB_BUILD_STATUS_SUCCESS = 'success'\n\n# Used to select correct Build status and description to be sent to each service API\nSELECT_BUILD_STATUS = {\n    BUILD_STATUS_FAILURE: {\n        'github': GITHUB_BUILD_STATUS_FAILURE,\n        'gitlab': GITLAB_BUILD_STATUS_FAILURE,\n        'description': 'Read the Docs build failed!',\n    },\n    BUILD_STATUS_PENDING: {\n        'github': GITHUB_BUILD_STATUS_PENDING,\n        'gitlab': GITLAB_BUILD_STATUS_PENDING,\n        'description': 'Read the Docs build is in progress!',\n    },\n    BUILD_STATUS_SUCCESS: {\n        'github': GITHUB_BUILD_STATUS_SUCCESS,\n        'gitlab': GITLAB_BUILD_STATUS_SUCCESS,\n        'description': 'Read the Docs build succeeded!',\n    },\n}\n\nRTD_BUILD_STATUS_API_NAME = 'continuous-documentation/read-the-docs'\n\nGITHUB_EXTERNAL_VERSION_NAME = 'Pull Request'\nGITLAB_EXTERNAL_VERSION_NAME = 'Merge Request'\nGENERIC_EXTERNAL_VERSION_NAME = 'External Version'\n\n\n# Automation rules\n\nALL_VERSIONS = 'all-versions'\nALL_VERSIONS_REGEX = r'.*'\nSEMVER_VERSIONS = 'semver-versions'\n\n# Pattern referred from\n# https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string\nSEMVER_VERSIONS_REGEX = r'^v?(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$'  # noqa\n\n\nPREDEFINED_MATCH_ARGS = (\n    (ALL_VERSIONS, _('Any version')),\n    (SEMVER_VERSIONS, _('SemVer versions')),\n    (None, _('Custom match')),\n)\n\nPREDEFINED_MATCH_ARGS_VALUES = {\n    ALL_VERSIONS: ALL_VERSIONS_REGEX,\n    SEMVER_VERSIONS: SEMVER_VERSIONS_REGEX,\n}\n", "path": "readthedocs/builds/constants.py"}]}