prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  [BUG] Regression in docker build
  ### Description
  
  I cannot locally build the docker image. 
  The error message is
  ```
  FROM ghcr.io/${REPO}/builder/jbig2enc:${JBIG2ENC_VERSION} as jbig2enc-builder
  invalid reference format
  ```
  
  I did a git bisect and this came out:
  ```
  6c70db31bd78d166f06ace734761824239aeb3e4 is the first bad commit
  commit 6c70db31bd78d166f06ace734761824239aeb3e4
  Author: Trenton Holmes <holmes.trenton@gmail.com>
  Date:   Mon Apr 18 08:18:20 2022 -0700
  
      Incorporates the base image building back into the main repo with multi stage building
  
   .github/workflows/ci.yml                        | 313 +++++++++++++++---------
   .github/workflows/reusable-ci-backend.yml       | 108 ++++++++
   .github/workflows/reusable-ci-frontend.yml      |  42 ++++
   .github/workflows/reusable-workflow-builder.yml |  68 +++++
   .pre-commit-config.yaml                         |  13 +-
   Dockerfile                                      | 147 +++++++++--
   docker-builders/Dockerfile.frontend             |  13 +
   docker-builders/Dockerfile.jbig2enc             |  39 +++
   docker-builders/Dockerfile.pikepdf              |  65 +++++
   docker-builders/Dockerfile.psycopg2             |  44 ++++
   docker-builders/Dockerfile.qpdf                 |  51 ++++
   docker-builders/get-build-json.py               | 112 +++++++++
   docker/docker-prepare.sh                        |   2 +
   docker/install_management_commands.sh           |   2 +
   14 files changed, 877 insertions(+), 142 deletions(-)
   create mode 100644 .github/workflows/reusable-ci-backend.yml
   create mode 100644 .github/workflows/reusable-ci-frontend.yml
   create mode 100644 .github/workflows/reusable-workflow-builder.yml
   create mode 100644 docker-builders/Dockerfile.frontend
   create mode 100644 docker-builders/Dockerfile.jbig2enc
   create mode 100644 docker-builders/Dockerfile.pikepdf
   create mode 100644 docker-builders/Dockerfile.psycopg2
   create mode 100644 docker-builders/Dockerfile.qpdf
   create mode 100755 docker-builders/get-build-json.py
  ```
  So 6c70db31bd78d166f06ace734761824239aeb3e4 is the first bad commit. @stumpylog can you have a look? It seems you do a ton of magic in the CI pipeline and I am unsure how to reproduce this locally..
  
  ### Steps to reproduce
  
  1. git checkout dev
  2. docker build .
  
  ### Webserver logs
  
  _No response_
  
  ### Screenshots
  
  _No response_
  
  ### Paperless-ngx version
  
  dev
  
  ### Host OS
  
  NixOS
  
  ### Installation method
  
  Docker
  
  ### Browser
  
  Brave
  
  ### Configuration changes
  
  _No response_
  
  ### Other
  
  _No response_
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `.github/scripts/get-build-json.py`
  Content:
  ```
  1 #!/usr/bin/env python3
  2 """
  3 This is a helper script for the mutli-stage Docker image builder.
  4 It provides a single point of configuration for package version control.
  5 The output JSON object is used by the CI workflow to determine what versions
  6 to build and pull into the final Docker image.
  7 
  8 Python package information is obtained from the Pipfile.lock.  As this is
  9 kept updated by dependabot, it usually will need no further configuration.
  10 The sole exception currently is pikepdf, which has a dependency on qpdf,
  11 and is configured here to use the latest version of qpdf built by the workflow.
  12 
  13 Other package version information is configured directly below, generally by
  14 setting the version and Git information, if any.
  15 
  16 """
  17 import argparse
  18 import json
  19 import os
  20 from pathlib import Path
  21 from typing import Final
  22 
  23 from common import get_cache_image_tag
  24 from common import get_image_tag
  25 
  26 
  27 def _main():
  28     parser = argparse.ArgumentParser(
  29         description="Generate a JSON object of information required to build the given package, based on the Pipfile.lock",
  30     )
  31     parser.add_argument(
  32         "package",
  33         help="The name of the package to generate JSON for",
  34     )
  35 
  36     PIPFILE_LOCK_PATH: Final[Path] = Path("Pipfile.lock")
  37     BUILD_CONFIG_PATH: Final[Path] = Path(".build-config.json")
  38 
  39     # Read the main config file
  40     build_json: Final = json.loads(BUILD_CONFIG_PATH.read_text())
  41 
  42     # Read Pipfile.lock file
  43     pipfile_data: Final = json.loads(PIPFILE_LOCK_PATH.read_text())
  44 
  45     args: Final = parser.parse_args()
  46 
  47     # Read from environment variables set by GitHub Actions
  48     repo_name: Final[str] = os.environ["GITHUB_REPOSITORY"]
  49     branch_name: Final[str] = os.environ["GITHUB_REF_NAME"]
  50 
  51     # Default output values
  52     version = None
  53     git_tag = None
  54     extra_config = {}
  55 
  56     if args.package == "frontend":
  57         # Version is just the branch or tag name
  58         version = branch_name
  59     elif args.package in pipfile_data["default"]:
  60         # Read the version from Pipfile.lock
  61         pkg_data = pipfile_data["default"][args.package]
  62         pkg_version = pkg_data["version"].split("==")[-1]
  63         version = pkg_version
  64 
  65         # Based on the package, generate the expected Git tag name
  66         if args.package == "pikepdf":
  67             git_tag = f"v{pkg_version}"
  68         elif args.package == "psycopg2":
  69             git_tag = pkg_version.replace(".", "_")
  70 
  71         # Any extra/special values needed
  72         if args.package == "pikepdf":
  73             extra_config["qpdf_version"] = build_json["qpdf"]["version"]
  74 
  75     elif args.package in build_json:
  76         version = build_json[args.package]["version"]
  77 
  78         if "git_tag" in build_json[args.package]:
  79             git_tag = build_json[args.package]["git_tag"]
  80     else:
  81         raise NotImplementedError(args.package)
  82 
  83     # The JSON object we'll output
  84     output = {
  85         "name": args.package,
  86         "version": version,
  87         "git_tag": git_tag,
  88         "image_tag": get_image_tag(repo_name, args.package, version),
  89         "cache_tag": get_cache_image_tag(
  90             repo_name,
  91             args.package,
  92             version,
  93             branch_name,
  94         ),
  95     }
  96 
  97     # Add anything special a package may need
  98     output.update(extra_config)
  99 
  100     # Output the JSON info to stdout
  101     print(json.dumps(output))
  102 
  103 
  104 if __name__ == "__main__":
  105     _main()
  106
  ```
  --- 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/.github/scripts/get-build-json.py b/.github/scripts/get-build-json.py
  --- a/.github/scripts/get-build-json.py
  +++ b/.github/scripts/get-build-json.py
  @@ -53,10 +53,7 @@
       git_tag = None
       extra_config = {}
   
  -    if args.package == "frontend":
  -        # Version is just the branch or tag name
  -        version = branch_name
  -    elif args.package in pipfile_data["default"]:
  +    if args.package in pipfile_data["default"]:
           # Read the version from Pipfile.lock
           pkg_data = pipfile_data["default"][args.package]
           pkg_version = pkg_data["version"].split("==")[-1]
  
verification_info: {"golden_diff": "diff --git a/.github/scripts/get-build-json.py b/.github/scripts/get-build-json.py\n--- a/.github/scripts/get-build-json.py\n+++ b/.github/scripts/get-build-json.py\n@@ -53,10 +53,7 @@\n     git_tag = None\n     extra_config = {}\n \n-    if args.package == \"frontend\":\n-        # Version is just the branch or tag name\n-        version = branch_name\n-    elif args.package in pipfile_data[\"default\"]:\n+    if args.package in pipfile_data[\"default\"]:\n         # Read the version from Pipfile.lock\n         pkg_data = pipfile_data[\"default\"][args.package]\n         pkg_version = pkg_data[\"version\"].split(\"==\")[-1]\n", "issue": "[BUG] Regression in docker build\n### Description\n\nI cannot locally build the docker image. \r\nThe error message is\r\n```\r\nFROM ghcr.io/${REPO}/builder/jbig2enc:${JBIG2ENC_VERSION} as jbig2enc-builder\r\ninvalid reference format\r\n```\r\n\r\nI did a git bisect and this came out:\r\n```\r\n6c70db31bd78d166f06ace734761824239aeb3e4 is the first bad commit\r\ncommit 6c70db31bd78d166f06ace734761824239aeb3e4\r\nAuthor: Trenton Holmes <holmes.trenton@gmail.com>\r\nDate:   Mon Apr 18 08:18:20 2022 -0700\r\n\r\n    Incorporates the base image building back into the main repo with multi stage building\r\n\r\n .github/workflows/ci.yml                        | 313 +++++++++++++++---------\r\n .github/workflows/reusable-ci-backend.yml       | 108 ++++++++\r\n .github/workflows/reusable-ci-frontend.yml      |  42 ++++\r\n .github/workflows/reusable-workflow-builder.yml |  68 +++++\r\n .pre-commit-config.yaml                         |  13 +-\r\n Dockerfile                                      | 147 +++++++++--\r\n docker-builders/Dockerfile.frontend             |  13 +\r\n docker-builders/Dockerfile.jbig2enc             |  39 +++\r\n docker-builders/Dockerfile.pikepdf              |  65 +++++\r\n docker-builders/Dockerfile.psycopg2             |  44 ++++\r\n docker-builders/Dockerfile.qpdf                 |  51 ++++\r\n docker-builders/get-build-json.py               | 112 +++++++++\r\n docker/docker-prepare.sh                        |   2 +\r\n docker/install_management_commands.sh           |   2 +\r\n 14 files changed, 877 insertions(+), 142 deletions(-)\r\n create mode 100644 .github/workflows/reusable-ci-backend.yml\r\n create mode 100644 .github/workflows/reusable-ci-frontend.yml\r\n create mode 100644 .github/workflows/reusable-workflow-builder.yml\r\n create mode 100644 docker-builders/Dockerfile.frontend\r\n create mode 100644 docker-builders/Dockerfile.jbig2enc\r\n create mode 100644 docker-builders/Dockerfile.pikepdf\r\n create mode 100644 docker-builders/Dockerfile.psycopg2\r\n create mode 100644 docker-builders/Dockerfile.qpdf\r\n create mode 100755 docker-builders/get-build-json.py\r\n```\r\nSo 6c70db31bd78d166f06ace734761824239aeb3e4 is the first bad commit. @stumpylog can you have a look? It seems you do a ton of magic in the CI pipeline and I am unsure how to reproduce this locally..\n\n### Steps to reproduce\n\n1. git checkout dev\r\n2. docker build .\n\n### Webserver logs\n\n_No response_\n\n### Screenshots\n\n_No response_\n\n### Paperless-ngx version\n\ndev\n\n### Host OS\n\nNixOS\n\n### Installation method\n\nDocker\n\n### Browser\n\nBrave\n\n### Configuration changes\n\n_No response_\n\n### Other\n\n_No response_\n", "before_files": [{"content": "#!/usr/bin/env python3\n\"\"\"\nThis is a helper script for the mutli-stage Docker image builder.\nIt provides a single point of configuration for package version control.\nThe output JSON object is used by the CI workflow to determine what versions\nto build and pull into the final Docker image.\n\nPython package information is obtained from the Pipfile.lock.  As this is\nkept updated by dependabot, it usually will need no further configuration.\nThe sole exception currently is pikepdf, which has a dependency on qpdf,\nand is configured here to use the latest version of qpdf built by the workflow.\n\nOther package version information is configured directly below, generally by\nsetting the version and Git information, if any.\n\n\"\"\"\nimport argparse\nimport json\nimport os\nfrom pathlib import Path\nfrom typing import Final\n\nfrom common import get_cache_image_tag\nfrom common import get_image_tag\n\n\ndef _main():\n    parser = argparse.ArgumentParser(\n        description=\"Generate a JSON object of information required to build the given package, based on the Pipfile.lock\",\n    )\n    parser.add_argument(\n        \"package\",\n        help=\"The name of the package to generate JSON for\",\n    )\n\n    PIPFILE_LOCK_PATH: Final[Path] = Path(\"Pipfile.lock\")\n    BUILD_CONFIG_PATH: Final[Path] = Path(\".build-config.json\")\n\n    # Read the main config file\n    build_json: Final = json.loads(BUILD_CONFIG_PATH.read_text())\n\n    # Read Pipfile.lock file\n    pipfile_data: Final = json.loads(PIPFILE_LOCK_PATH.read_text())\n\n    args: Final = parser.parse_args()\n\n    # Read from environment variables set by GitHub Actions\n    repo_name: Final[str] = os.environ[\"GITHUB_REPOSITORY\"]\n    branch_name: Final[str] = os.environ[\"GITHUB_REF_NAME\"]\n\n    # Default output values\n    version = None\n    git_tag = None\n    extra_config = {}\n\n    if args.package == \"frontend\":\n        # Version is just the branch or tag name\n        version = branch_name\n    elif args.package in pipfile_data[\"default\"]:\n        # Read the version from Pipfile.lock\n        pkg_data = pipfile_data[\"default\"][args.package]\n        pkg_version = pkg_data[\"version\"].split(\"==\")[-1]\n        version = pkg_version\n\n        # Based on the package, generate the expected Git tag name\n        if args.package == \"pikepdf\":\n            git_tag = f\"v{pkg_version}\"\n        elif args.package == \"psycopg2\":\n            git_tag = pkg_version.replace(\".\", \"_\")\n\n        # Any extra/special values needed\n        if args.package == \"pikepdf\":\n            extra_config[\"qpdf_version\"] = build_json[\"qpdf\"][\"version\"]\n\n    elif args.package in build_json:\n        version = build_json[args.package][\"version\"]\n\n        if \"git_tag\" in build_json[args.package]:\n            git_tag = build_json[args.package][\"git_tag\"]\n    else:\n        raise NotImplementedError(args.package)\n\n    # The JSON object we'll output\n    output = {\n        \"name\": args.package,\n        \"version\": version,\n        \"git_tag\": git_tag,\n        \"image_tag\": get_image_tag(repo_name, args.package, version),\n        \"cache_tag\": get_cache_image_tag(\n            repo_name,\n            args.package,\n            version,\n            branch_name,\n        ),\n    }\n\n    # Add anything special a package may need\n    output.update(extra_config)\n\n    # Output the JSON info to stdout\n    print(json.dumps(output))\n\n\nif __name__ == \"__main__\":\n    _main()\n", "path": ".github/scripts/get-build-json.py"}], "after_files": [{"content": "#!/usr/bin/env python3\n\"\"\"\nThis is a helper script for the mutli-stage Docker image builder.\nIt provides a single point of configuration for package version control.\nThe output JSON object is used by the CI workflow to determine what versions\nto build and pull into the final Docker image.\n\nPython package information is obtained from the Pipfile.lock.  As this is\nkept updated by dependabot, it usually will need no further configuration.\nThe sole exception currently is pikepdf, which has a dependency on qpdf,\nand is configured here to use the latest version of qpdf built by the workflow.\n\nOther package version information is configured directly below, generally by\nsetting the version and Git information, if any.\n\n\"\"\"\nimport argparse\nimport json\nimport os\nfrom pathlib import Path\nfrom typing import Final\n\nfrom common import get_cache_image_tag\nfrom common import get_image_tag\n\n\ndef _main():\n    parser = argparse.ArgumentParser(\n        description=\"Generate a JSON object of information required to build the given package, based on the Pipfile.lock\",\n    )\n    parser.add_argument(\n        \"package\",\n        help=\"The name of the package to generate JSON for\",\n    )\n\n    PIPFILE_LOCK_PATH: Final[Path] = Path(\"Pipfile.lock\")\n    BUILD_CONFIG_PATH: Final[Path] = Path(\".build-config.json\")\n\n    # Read the main config file\n    build_json: Final = json.loads(BUILD_CONFIG_PATH.read_text())\n\n    # Read Pipfile.lock file\n    pipfile_data: Final = json.loads(PIPFILE_LOCK_PATH.read_text())\n\n    args: Final = parser.parse_args()\n\n    # Read from environment variables set by GitHub Actions\n    repo_name: Final[str] = os.environ[\"GITHUB_REPOSITORY\"]\n    branch_name: Final[str] = os.environ[\"GITHUB_REF_NAME\"]\n\n    # Default output values\n    version = None\n    git_tag = None\n    extra_config = {}\n\n    if args.package in pipfile_data[\"default\"]:\n        # Read the version from Pipfile.lock\n        pkg_data = pipfile_data[\"default\"][args.package]\n        pkg_version = pkg_data[\"version\"].split(\"==\")[-1]\n        version = pkg_version\n\n        # Based on the package, generate the expected Git tag name\n        if args.package == \"pikepdf\":\n            git_tag = f\"v{pkg_version}\"\n        elif args.package == \"psycopg2\":\n            git_tag = pkg_version.replace(\".\", \"_\")\n\n        # Any extra/special values needed\n        if args.package == \"pikepdf\":\n            extra_config[\"qpdf_version\"] = build_json[\"qpdf\"][\"version\"]\n\n    elif args.package in build_json:\n        version = build_json[args.package][\"version\"]\n\n        if \"git_tag\" in build_json[args.package]:\n            git_tag = build_json[args.package][\"git_tag\"]\n    else:\n        raise NotImplementedError(args.package)\n\n    # The JSON object we'll output\n    output = {\n        \"name\": args.package,\n        \"version\": version,\n        \"git_tag\": git_tag,\n        \"image_tag\": get_image_tag(repo_name, args.package, version),\n        \"cache_tag\": get_cache_image_tag(\n            repo_name,\n            args.package,\n            version,\n            branch_name,\n        ),\n    }\n\n    # Add anything special a package may need\n    output.update(extra_config)\n\n    # Output the JSON info to stdout\n    print(json.dumps(output))\n\n\nif __name__ == \"__main__\":\n    _main()\n", "path": ".github/scripts/get-build-json.py"}]}