Fix pkg_resources deprecated on Python 3.9 and later

Use `importlib.resources` instead of `pkg_resources` to locate grpc_tools protobuf files.

Also added CI test to cover this.
diff --git a/.github/workflows/trigger_on_code_change.yml b/.github/workflows/trigger_on_code_change.yml
index e8bf944..cb7dc5b 100644
--- a/.github/workflows/trigger_on_code_change.yml
+++ b/.github/workflows/trigger_on_code_change.yml
@@ -25,7 +25,11 @@
 jobs:
   smoke_test:
     name: Run test suite on Ubuntu 20.04
-    runs-on: ubuntu-20.04
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        python-version: ['3.8', '3.x']
+        os: ['ubuntu-20.04', 'ubuntu-24.04']
 
     steps:
       - name: Check out code from GitHub
@@ -33,10 +37,17 @@
         with:
           path: nanopb
 
+      - name: Setup Python
+        uses: actions/setup-python@v5
+        with:
+          python-version: ${{ matrix.python-version }}
+
       - name: Install dependencies
         run: |
           sudo apt-get update
-          sudo apt-get install python3-protobuf protobuf-compiler scons splint valgrind
+          sudo apt-get install protobuf-compiler splint valgrind
+          python3 -m pip install --user --upgrade scons protobuf grpcio-tools pyinstaller
+          python3 -c 'import google.protobuf; print(google.protobuf.__file__)'
 
       - name: Run tests
         run: |
diff --git a/generator/proto/__init__.py b/generator/proto/__init__.py
index 42c4d0c..b2b47b6 100644
--- a/generator/proto/__init__.py
+++ b/generator/proto/__init__.py
@@ -7,7 +7,6 @@
 import tempfile
 import shutil
 import traceback
-import pkg_resources
 from ._utils import has_grpcio_protoc, invoke_protoc, print_versions
 
 # Compatibility layer to make TemporaryDirectory() available on Python 2.
@@ -42,8 +41,7 @@
     if has_grpcio_protoc():
         # grpcio-tools has an extra CLI argument
         # from grpc.tools.protoc __main__ invocation.
-        _builtin_proto_include = pkg_resources.resource_filename('grpc_tools', '_proto')
-        cmd.append("-I={}".format(_builtin_proto_include))
+        cmd.append("-I={}".format(_utils.get_grpc_tools_proto_path()))
 
     try:
         invoke_protoc(argv=cmd)
diff --git a/generator/proto/_utils.py b/generator/proto/_utils.py
index c659a22..705629f 100644
--- a/generator/proto/_utils.py
+++ b/generator/proto/_utils.py
@@ -17,6 +17,15 @@
 
     return True
 
+def get_grpc_tools_proto_path():
+    if sys.hexversion > 0x03090000:
+        import importlib.resources as ir
+        with ir.as_file(ir.files('grpc_tools') / '_proto') as path:
+            return str(path)
+    else:
+        import pkg_resources
+        return pkg_resources.resource_filename('grpc_tools', '_proto')
+
 def get_proto_builtin_include_path():
     """Find include path for standard google/protobuf includes and for
     nanopb.proto.
@@ -36,8 +45,7 @@
         ]
 
         if has_grpcio_protoc():
-            import pkg_resources
-            paths.append(pkg_resources.resource_filename('grpc_tools', '_proto'))
+            paths.append(get_grpc_tools_proto_path())
 
     return paths