From ff4bf24e29f18d6c155b998d6190eb4be424f2cb Mon Sep 17 00:00:00 2001
From: Josh VanDeraa <josh@josh-v.com>
Date: Sat, 27 Apr 2024 09:16:31 -0500
Subject: [PATCH 1/8] Adjusts local_context_data

---
 pynautobot/core/response.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pynautobot/core/response.py b/pynautobot/core/response.py
index f532a26c..cae5f4a0 100644
--- a/pynautobot/core/response.py
+++ b/pynautobot/core/response.py
@@ -251,7 +251,7 @@ def list_parser(list_item):
         for k, v in values.items():
             if isinstance(v, dict):
                 lookup = getattr(self.__class__, k, None)
-                if k in ["custom_fields", "local_context_data"] or hasattr(lookup, "_json_field"):
+                if k in ["custom_fields", "local_config_context_data"] or hasattr(lookup, "_json_field"):
                     self._add_cache((k, v.copy()))
                     setattr(self, k, v)
                     continue

From aba4bf32f639e8aa44a901d3ef9e07737009ee67 Mon Sep 17 00:00:00 2001
From: Josh VanDeraa <jv@networktocode.com>
Date: Tue, 14 Jan 2025 15:55:02 -0600
Subject: [PATCH 2/8] Updates CI.

---
 .github/workflows/ci.yml | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e2a73142..519ed6e4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -6,11 +6,11 @@ on: # yamllint disable
 
 jobs:
   tests:
-    runs-on: "ubuntu-20.04"
+    runs-on: "ubuntu-24.04"
     strategy:
       fail-fast: true
       matrix:
-        python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
+        python-version: ["3.9", "3.10", "3.11", "3.12"]
         nautobot-version: ["2.0", "2.1", "2.2", "2.3", "stable"]
     env:
       PYTHON_VER: "${{ matrix.python-version }}"
@@ -20,6 +20,9 @@ jobs:
         uses: "actions/checkout@v4"
       - name: "Setup environment"
         uses: "networktocode/gh-action-setup-poetry-environment@v6"
+        with:
+          poetry-version: "1.8.5"
+          python-version: "3.12"
       - name: "Set up Docker Buildx"
         id: "buildx"
         uses: "docker/setup-buildx-action@v3"
@@ -27,7 +30,7 @@ jobs:
         run: "poetry run invoke tests"
   publish_pypi:
     name: "Push Package to PyPI"
-    runs-on: "ubuntu-20.04"
+    runs-on: "ubuntu-24.04"
     if: "startsWith(github.ref, 'refs/tags/v')"
     steps:
       - name: "Check out repository code"
@@ -37,7 +40,7 @@ jobs:
         with:
           python-version: "3.9"
       - name: "Install Python Packages"
-        run: "pip install poetry"
+        run: "pip install poetry==1.8.5"
       - name: "Set env"
         run: "echo RELEASE_VERSION=${GITHUB_REF:10} >> $GITHUB_ENV"
       - name: "Run Poetry Version"

From 5b9555a553f76dc607c9e41b03a3e61e0e8baf96 Mon Sep 17 00:00:00 2001
From: Josh VanDeraa <jv@networktocode.com>
Date: Tue, 14 Jan 2025 16:12:43 -0600
Subject: [PATCH 3/8] Updates is_truthy.

---
 tasks.py | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/tasks.py b/tasks.py
index 29830200..236e3038 100644
--- a/tasks.py
+++ b/tasks.py
@@ -2,7 +2,6 @@
 
 import os
 import sys
-from distutils.util import strtobool
 from invoke import task
 
 try:
@@ -18,6 +17,28 @@
 # Can be set to a separate Python version to be used for launching or building image
 PYTHON_VER = os.getenv("INVOKE_PYNAUTOBOT_PYTHON_VER", os.getenv("PYTHON_VER", "3.8"))
 
+def is_truthy(arg):
+    """Convert "truthy" strings into Booleans.
+
+    Examples
+    --------
+        >>> is_truthy('yes')
+        True
+    Args:
+        arg (str): Truthy string (True values are y, yes, t, true, on and 1; false values are n, no,
+        f, false, off and 0. Raises ValueError if val is anything else.
+    """
+    if isinstance(arg, bool):
+        return arg
+
+    val = str(arg).lower()
+    if val in ("y", "yes", "t", "true", "on", "1"):
+        return True
+    elif val in ("n", "no", "f", "false", "off", "0"):
+        return False
+    else:
+        raise ValueError(f"Invalid truthy value: `{arg}`")
+
 
 def _get_image_name_and_tag():
     """Return image name and tag. Necessary to avoid double build in upstream testing"""
@@ -37,7 +58,7 @@ def _get_image_name_and_tag():
 # Gather current working directory for Docker commands
 PWD = os.getcwd()
 # Local or Docker execution provide "local" to run locally without docker execution
-INVOKE_LOCAL = strtobool(os.getenv("INVOKE_LOCAL", "False"))
+INVOKE_LOCAL = is_truthy(os.getenv("INVOKE_LOCAL", "False"))
 
 _DEFAULT_SERVICE = "pynautobot-dev"
 _DOCKER_COMPOSE_ENV = {

From f6a9b86cf128d24d98ca3b92dfb3fc8efb84e19f Mon Sep 17 00:00:00 2001
From: Josh VanDeraa <jv@networktocode.com>
Date: Tue, 14 Jan 2025 16:32:26 -0600
Subject: [PATCH 4/8] Removing griffe complaint.

---
 pynautobot/models/ipam.py | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/pynautobot/models/ipam.py b/pynautobot/models/ipam.py
index f467e409..f01673ed 100644
--- a/pynautobot/models/ipam.py
+++ b/pynautobot/models/ipam.py
@@ -37,9 +37,6 @@ def available_ips(self):
         Returns a DetailEndpoint object that is the interface for
         viewing and creating IP addresses inside a prefix.
 
-        Returns:
-            DetailEndpoint: The detail endpoint interface for available IPs.
-
         Examples:
             List available IPs:
 
@@ -80,9 +77,6 @@ def available_prefixes(self):
         except that the dict (or list of dicts) passed to ``.create()``
         needs to have a ``prefix_length`` key/value specified.
 
-        Returns:
-            DetailEndpoint: The detail endpoint interface for available prefixes.
-
         Examples:
             List available prefixes:
 

From 0c92880cce72bce689899ff03c95eb6f8aefdb4b Mon Sep 17 00:00:00 2001
From: Josh VanDeraa <jv@networktocode.com>
Date: Tue, 14 Jan 2025 16:33:43 -0600
Subject: [PATCH 5/8] Updates a type hint.

---
 pynautobot/models/ipam.py | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/pynautobot/models/ipam.py b/pynautobot/models/ipam.py
index f01673ed..09583e2d 100644
--- a/pynautobot/models/ipam.py
+++ b/pynautobot/models/ipam.py
@@ -30,13 +30,16 @@ def __str__(self):
         return parent_record_string or str(self.prefix)
 
     @property
-    def available_ips(self):
+    def available_ips(self) -> DetailEndpoint:
         """
         Represents the ``available-ips`` detail endpoint.
 
         Returns a DetailEndpoint object that is the interface for
         viewing and creating IP addresses inside a prefix.
 
+        Returns:
+            DetailEndpoint: The detail endpoint interface for available IPs.
+
         Examples:
             List available IPs:
 
@@ -66,7 +69,7 @@ def available_ips(self):
         return DetailEndpoint(self, "available-ips", custom_return=IpAddresses)
 
     @property
-    def available_prefixes(self):
+    def available_prefixes(self) -> DetailEndpoint:
         """
         Represents the ``available-prefixes`` detail endpoint.
 
@@ -77,6 +80,9 @@ def available_prefixes(self):
         except that the dict (or list of dicts) passed to ``.create()``
         needs to have a ``prefix_length`` key/value specified.
 
+        Returns:
+            DetailEndpoint: The detail endpoint interface for available prefixes.
+
         Examples:
             List available prefixes:
 

From 3ed2d4b4926073ce8adf625a07005a9d04effa06 Mon Sep 17 00:00:00 2001
From: Josh VanDeraa <jv@networktocode.com>
Date: Tue, 14 Jan 2025 17:18:13 -0600
Subject: [PATCH 6/8] Appease CI testing.

---
 development/Dockerfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/development/Dockerfile b/development/Dockerfile
index 1b5a873b..115e99ba 100644
--- a/development/Dockerfile
+++ b/development/Dockerfile
@@ -11,7 +11,7 @@ RUN curl -sSL https://install.python-poetry.org | python3 - && \
     /root/.local/bin/poetry config virtualenvs.create false
 
 WORKDIR /source
-COPY pyproject.toml poetry.lock /source/
+COPY pyproject.toml poetry.lock README.md /source/
 
 RUN git config --global --add safe.directory /source
 

From 6f03a595a6006a42ccbbafc07881618cd46baae9 Mon Sep 17 00:00:00 2001
From: Josh VanDeraa <jv@networktocode.com>
Date: Tue, 14 Jan 2025 18:12:47 -0600
Subject: [PATCH 7/8] Fix docker.

---
 development/Dockerfile              | 3 ++-
 development/Dockerfile.dockerignore | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/development/Dockerfile b/development/Dockerfile
index 115e99ba..083b08d4 100644
--- a/development/Dockerfile
+++ b/development/Dockerfile
@@ -7,7 +7,8 @@ RUN apt-get -y update && apt-get -y install --no-install-recommends \
     git \
     && rm -rf /var/lib/apt/lists/*
 
-RUN curl -sSL https://install.python-poetry.org | python3 - && \
+# Install specific version of Poetry (1.8.5)
+RUN curl -sSL https://install.python-poetry.org | POETRY_VERSION=1.8.5 python3 - && \
     /root/.local/bin/poetry config virtualenvs.create false
 
 WORKDIR /source
diff --git a/development/Dockerfile.dockerignore b/development/Dockerfile.dockerignore
index 73c48dbc..e4501c20 100644
--- a/development/Dockerfile.dockerignore
+++ b/development/Dockerfile.dockerignore
@@ -2,3 +2,4 @@
 
 !/pyproject.toml
 !/poetry.lock
+!/README.md
\ No newline at end of file

From 13b4bcc92ddec59e801f87e283863865f6370d13 Mon Sep 17 00:00:00 2001
From: Josh VanDeraa <jv@networktocode.com>
Date: Tue, 14 Jan 2025 18:15:47 -0600
Subject: [PATCH 8/8] blacken files.

---
 tasks.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tasks.py b/tasks.py
index 236e3038..6242d57c 100644
--- a/tasks.py
+++ b/tasks.py
@@ -17,6 +17,7 @@
 # Can be set to a separate Python version to be used for launching or building image
 PYTHON_VER = os.getenv("INVOKE_PYNAUTOBOT_PYTHON_VER", os.getenv("PYTHON_VER", "3.8"))
 
+
 def is_truthy(arg):
     """Convert "truthy" strings into Booleans.