diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index ee5ce9d..90b14a4 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -4,28 +4,26 @@ on:
   release:
     types: [created]
 
+permissions:
+  contents: read
+
 jobs:
   test:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: [3.6, 3.7, 3.8, 3.9]
+        python-version: ["3.8", "3.9", "3.10", "3.11"]
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@v2
+      uses: actions/setup-python@v4
       with:
         python-version: ${{ matrix.python-version }}
-    - uses: actions/cache@v2
-      name: Configure pip caching
-      with:
-        path: ~/.cache/pip
-        key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
-        restore-keys: |
-          ${{ runner.os }}-pip-
+        cache: pip
+        cache-dependency-path: setup.py
     - name: Install dependencies
       run: |
-        pip install -e '.[test]'
+        pip install '.[test]'
     - name: Run tests
       run: |
         pytest
@@ -33,26 +31,21 @@ jobs:
     runs-on: ubuntu-latest
     needs: [test]
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
     - name: Set up Python
-      uses: actions/setup-python@v2
-      with:
-        python-version: '3.9'
-    - uses: actions/cache@v2
-      name: Configure pip caching
+      uses: actions/setup-python@v4
       with:
-        path: ~/.cache/pip
-        key: ${{ runner.os }}-publish-pip-${{ hashFiles('**/setup.py') }}
-        restore-keys: |
-          ${{ runner.os }}-publish-pip-
+        python-version: "3.11"
+        cache: pip
+        cache-dependency-path: setup.py
     - name: Install dependencies
       run: |
-        pip install setuptools wheel twine
+        pip install setuptools wheel twine build
     - name: Publish
       env:
         TWINE_USERNAME: __token__
         TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
       run: |
-        python setup.py sdist bdist_wheel
+        python -m build
         twine upload dist/*
 
diff --git a/datasette_mask_columns/__init__.py b/datasette_mask_columns/__init__.py
index f0af289..dcbd121 100644
--- a/datasette_mask_columns/__init__.py
+++ b/datasette_mask_columns/__init__.py
@@ -1,5 +1,5 @@
 from datasette import hookimpl
-import jinja2
+from markupsafe import Markup
 import sqlite3
 
 
@@ -31,6 +31,6 @@ def render_cell(column, table, database, datasette):
     masks = datasette.plugin_config("datasette-mask-columns", database=database) or {}
     columns_to_mask = masks.get(table) or set()
     if column in columns_to_mask:
-        return jinja2.Markup(
+        return Markup(
             '<span style="font-size: 0.8em; color: red; opacity: 0.8">REDACTED</span>'
         )

diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index cd7e525..e22143a 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -1,30 +1,27 @@
 name: Test
 
-on: [push]
+on: [push, pull_request]
+
+permissions:
+  contents: read
 
 jobs:
   test:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: [3.6, 3.7, 3.8, 3.9]
+        python-version: ["3.8", "3.9", "3.10", "3.11"]
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@v2
+      uses: actions/setup-python@v4
       with:
         python-version: ${{ matrix.python-version }}
-    - uses: actions/cache@v2
-      name: Configure pip caching
-      with:
-        path: ~/.cache/pip
-        key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
-        restore-keys: |
-          ${{ runner.os }}-pip-
+        cache: pip
+        cache-dependency-path: setup.py
     - name: Install dependencies
       run: |
         pip install -e '.[test]'
     - name: Run tests
       run: |
         pytest
-

Err 500 module 'jinja2' has no attribute 'Markup'
At first attempt of masking columns, I get `module 'jinja2' has no attribute 'Markup'`


![Screenshot 2023-01-24 at 18 33 44](https://user-images.githubusercontent.com/116795/214352088-7015036d-828a-4fa6-9b5e-10f01d9443b6.png)

![Screenshot 2023-01-24 at 18 33 30](https://user-images.githubusercontent.com/116795/214352069-5d922a28-76d7-4765-a278-d2cf757d5f27.png)

tests/test_mask_columns.py::test_datasette_mask_columns