diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000..95dc4047
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,55 @@
+name: Release
+
+on:
+  release:
+    types: [published]
+
+jobs:
+  release:
+    name: Release
+    permissions:
+      id-token: write
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        node-version: [18]
+    steps:
+      - uses: actions/checkout@v4
+        with:
+          ref: ${{ github.event.release.target_commitish }}
+
+      - uses: pnpm/action-setup@v4
+        with:
+          version: 9.4.0
+
+      - name: Install Node.js
+        uses: actions/setup-node@v4
+        with:
+          node-version: ${{ matrix.node-version }}
+          cache: 'pnpm'
+
+      - run: pnpm install --frozen-lockfile
+
+      - name: Set up git
+        run: |
+          git config --local user.email '41898282+github-actions[bot]@users.noreply.github.com'
+          git config --local user.name 'github-actions[bot]'
+
+      - name: Bump version to ${{ github.event.release.tag_name }}
+        run: |
+          pnpm -F @ensdomains/ensjs ver ${{ github.event.release.tag_name }}
+          git add .
+          git commit -m "${{ github.event.release.tag_name }}"
+
+      - name: Publish
+        env:
+          NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+          NPM_CONFIG_PROVENANCE: true
+        run: |
+          pnpm config set //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}
+          pnpm -F @ensdomains/ensjs publish
+
+      - name: Push changes
+        run: git push
+        env:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/packages/ensjs/src/functions/public/_getAbi.test.ts b/packages/ensjs/src/functions/public/_getAbi.test.ts
index 83674f73..d448fa22 100644
--- a/packages/ensjs/src/functions/public/_getAbi.test.ts
+++ b/packages/ensjs/src/functions/public/_getAbi.test.ts
@@ -17,6 +17,6 @@ it('propagates error when strict is true', async () => {
     Params: (uint256, bytes)
     Data:   0x1234 (2 bytes)
 
-    Version: viem@2.9.2]
+    Version: 2.21.12]
   `)
 })
diff --git a/packages/ensjs/src/functions/public/_getAddr.test.ts b/packages/ensjs/src/functions/public/_getAddr.test.ts
index 9f848c8a..1e511c16 100644
--- a/packages/ensjs/src/functions/public/_getAddr.test.ts
+++ b/packages/ensjs/src/functions/public/_getAddr.test.ts
@@ -17,6 +17,6 @@ it('propagates error when strict is true', async () => {
     Params: (address)
     Data:   0x1234 (2 bytes)
 
-    Version: viem@2.9.2]
+    Version: 2.21.12]
   `)
 })
diff --git a/packages/ensjs/src/functions/public/_getContentHash.test.ts b/packages/ensjs/src/functions/public/_getContentHash.test.ts
index 16d0d2ac..61d69aed 100644
--- a/packages/ensjs/src/functions/public/_getContentHash.test.ts
+++ b/packages/ensjs/src/functions/public/_getContentHash.test.ts
@@ -18,6 +18,6 @@ it('propagates error when strict is true', async () => {
     Params: (bytes)
     Data:   0x1234 (2 bytes)
 
-    Version: viem@2.9.2]
+    Version: 2.21.12]
   `)
 })
diff --git a/packages/ensjs/src/functions/public/_getText.test.ts b/packages/ensjs/src/functions/public/_getText.test.ts
index deab21e8..fbd9243d 100644
--- a/packages/ensjs/src/functions/public/_getText.test.ts
+++ b/packages/ensjs/src/functions/public/_getText.test.ts
@@ -17,6 +17,6 @@ it('propagates error when strict is true', async () => {
     Params: (string)
     Data:   0x1234 (2 bytes)
 
-    Version: viem@2.9.2]
+    Version: 2.21.12]
   `)
 })
diff --git a/packages/ensjs/src/functions/public/getAbiRecord.test.ts b/packages/ensjs/src/functions/public/getAbiRecord.test.ts
index 51383162..afb5ab26 100644
--- a/packages/ensjs/src/functions/public/getAbiRecord.test.ts
+++ b/packages/ensjs/src/functions/public/getAbiRecord.test.ts
@@ -261,7 +261,7 @@ describe('getAbiRecord()', () => {
         function:  resolve(bytes name, bytes data)
         args:             (0x, 0x)
 
-      Version: viem@2.9.2]
+      Version: 2.21.12]
     `)
   })
 })
diff --git a/packages/ensjs/src/functions/public/getAddressRecord.test.ts b/packages/ensjs/src/functions/public/getAddressRecord.test.ts
index cca089ca..0074d639 100644
--- a/packages/ensjs/src/functions/public/getAddressRecord.test.ts
+++ b/packages/ensjs/src/functions/public/getAddressRecord.test.ts
@@ -121,7 +121,7 @@ describe('getAddressRecord()', () => {
         function:  resolve(bytes name, bytes data)
         args:             (0x, 0x)
 
-      Version: viem@2.9.2]
+      Version: 2.21.12]
     `)
   })
 })
diff --git a/packages/ensjs/src/functions/public/getContentHashRecord.test.ts b/packages/ensjs/src/functions/public/getContentHashRecord.test.ts
index 7c7255fd..c34c3b4c 100644
--- a/packages/ensjs/src/functions/public/getContentHashRecord.test.ts
+++ b/packages/ensjs/src/functions/public/getContentHashRecord.test.ts
@@ -67,7 +67,7 @@ describe('getContentHashRecord', () => {
         function:  resolve(bytes name, bytes data)
         args:             (0x, 0x)
 
-      Version: viem@2.9.2]
+      Version: 2.21.12]
     `)
   })
 })
diff --git a/packages/ensjs/src/functions/public/getName.test.ts b/packages/ensjs/src/functions/public/getName.test.ts
index c0d21cb2..3e0dcbda 100644
--- a/packages/ensjs/src/functions/public/getName.test.ts
+++ b/packages/ensjs/src/functions/public/getName.test.ts
@@ -119,7 +119,7 @@ describe('getName', () => {
         function:  reverse(bytes reverseName)
         args:             (0x)
 
-      Version: viem@2.9.2]
+      Version: 2.21.12]
     `)
   })
   it('should not return unnormalised name', async () => {
diff --git a/packages/ensjs/src/functions/public/getRecords.test.ts b/packages/ensjs/src/functions/public/getRecords.test.ts
index f91655f0..d8c9621b 100644
--- a/packages/ensjs/src/functions/public/getRecords.test.ts
+++ b/packages/ensjs/src/functions/public/getRecords.test.ts
@@ -146,7 +146,7 @@ describe('getRecords()', () => {
         args:             (0x04746573740365746800, ["0x5678"])
 
       Docs: https://viem.sh/docs/contract/decodeErrorResult
-      Version: viem@2.9.2]
+      Version: 2.21.12]
     `)
   })
 })
diff --git a/packages/ensjs/src/functions/public/getTextRecord.test.ts b/packages/ensjs/src/functions/public/getTextRecord.test.ts
index 6151ef54..fe9f527a 100644
--- a/packages/ensjs/src/functions/public/getTextRecord.test.ts
+++ b/packages/ensjs/src/functions/public/getTextRecord.test.ts
@@ -58,7 +58,7 @@ describe('getTextRecord()', () => {
         function:  resolve(bytes name, bytes data)
         args:             (0x, 0x)
 
-      Version: viem@2.9.2]
+      Version: 2.21.12]
     `)
   })
 })
diff --git a/packages/ensjs/src/functions/public/universalWrapper.test.ts b/packages/ensjs/src/functions/public/universalWrapper.test.ts
index 273aca85..04397d55 100644
--- a/packages/ensjs/src/functions/public/universalWrapper.test.ts
+++ b/packages/ensjs/src/functions/public/universalWrapper.test.ts
@@ -73,7 +73,7 @@ it('throws on result decode error when strict is true', async () => {
     Params: (bytes data, address resolver)
     Data:   0x1234 (2 bytes)
 
-    Version: viem@2.9.2]
+    Version: 2.21.12]
   `)
 })
 
@@ -116,7 +116,7 @@ it('throws on known contract error when strict is true', async () => {
     function:  resolve(bytes name, bytes data)
     args:             (0x, 0x)
 
-  Version: viem@2.9.2]
+  Version: 2.21.12]
 `)
 })
 
@@ -147,7 +147,7 @@ it('throws on unknown contract error when strict is false', async () => {
       args:             (0x, 0x)
 
     Docs: https://viem.sh/docs/contract/decodeErrorResult
-    Version: viem@2.9.2]
+    Version: 2.21.12]
   `)
 })
 
@@ -178,6 +178,6 @@ it('throws on unknown contract error when strict is true', async () => {
       args:             (0x, 0x)
 
     Docs: https://viem.sh/docs/contract/decodeErrorResult
-    Version: viem@2.9.2]
+    Version: 2.21.12]
   `)
 })
diff --git a/packages/ensjs/src/utils/checkSafeUniversalResolverData.test.ts b/packages/ensjs/src/utils/checkSafeUniversalResolverData.test.ts
index 43e101bb..ea476b3a 100644
--- a/packages/ensjs/src/utils/checkSafeUniversalResolverData.test.ts
+++ b/packages/ensjs/src/utils/checkSafeUniversalResolverData.test.ts
@@ -69,7 +69,7 @@ describe('checkSafeUniversalResolverData', () => {
         function:  resolve(bytes name, bytes data)
         args:             (0x, 0x)
 
-      Version: viem@2.9.2]
+      Version: 2.21.12]
     `)
   })
 
@@ -97,7 +97,7 @@ describe('checkSafeUniversalResolverData', () => {
         function:  resolve(bytes name, bytes data)
         args:             (ab, cd)
 
-      Version: viem@2.9.2]
+      Version: 2.21.12]
     `)
   })
 
@@ -129,7 +129,7 @@ describe('checkSafeUniversalResolverData', () => {
         args:             (0x, 0x)
 
       Docs: https://viem.sh/docs/contract/decodeErrorResult
-      Version: viem@2.9.2]
+      Version: 2.21.12]
     `)
   })
 
@@ -161,7 +161,7 @@ describe('checkSafeUniversalResolverData', () => {
         args:             (0x, 0x)
 
       Docs: https://viem.sh/docs/contract/decodeErrorResult
-      Version: viem@2.9.2]
+      Version: 2.21.12]
     `)
   })
 })