Publish coverage to coveralls.io
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c64b077..844f9a7 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -5,6 +5,9 @@
     branches: [ main ]
   pull_request:
 
+permissions:
+  contents: read
+
 jobs:
 
   build_on_linux:
@@ -106,6 +109,14 @@
     services:
       foundationdb:
         image: foundationdb/foundationdb:6.3.18
+    env:
+      # We could create a different profile that looks for fdb.cluster in the
+      # default /etc/foundationdb/ location, but for now we can just specify the
+      # custom location here
+      FDB_CLUSTER_FILE: /usr/local/etc/foundationdb/fdb.cluster
+      # This profile just ensures we use the FDB server in the service container
+      REBAR_PROFILE: devcontainer
+      DIAGNOSTIC: 1
     steps:
       - name: Create FDB cluster file
         env:
@@ -122,15 +133,42 @@
           persist-credentials: false
       - name: Compile erlfdb
         run: rebar3 compile
+      - name: Execute unit tests
+        run: rebar3 eunit
       - name: Execute binding test
         env:
           TEST_NAME: ${{ matrix.test-name }}
           API_VERSION: ${{ matrix.api-version }}
-          ERL_LIBS: _build/default/lib/erlfdb/
+          COVER_ENABLED: true
+          ERL_LIBS: _build/devcontainer+test/lib/erlfdb/
         run: |
           mkdir -p /usr/src/erlfdb/test/
           ln -s $GITHUB_WORKSPACE/test/tester.es /usr/src/erlfdb/test/tester.es
           /usr/src/foundationdb/bindings/bindingtester/bindingtester.py erlang \
               --test-name $TEST_NAME \
               --api-version $API_VERSION \
+              --instruction-prefix $TEST_NAME \
               --num-ops 10000
+      - name: Upload results to Coveralls
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          COVERALLS_FLAG_NAME: bindingtest-${{ matrix.test-name }}-${{ matrix.api-version }}
+        run: rebar3 as test coveralls send
+
+
+  finish:
+    needs: [build_on_linux, build_on_windows, binding_tester]
+    runs-on: ubuntu-latest
+    steps:
+      - name: Finalize Coveralls report
+        run: |
+          curl https://coveralls.io/webhook \
+           --header 'Content-Type: application/json' \
+            --data '{
+                "repo_name": "${{ github.repository }}",
+                "repo_token": "${{ secrets.GITHUB_TOKEN }}",
+                "payload": {
+                  "build_num": ${{ github.run_number }},
+                  "status": "done"
+                }
+              }'
diff --git a/README.md b/README.md
index 30e34e2..2d95224 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 An Erlang Binding to FoundationDB
 ===
 
-[![CI](https://github.com/apache/couchdb-erlfdb/actions/workflows/ci.yml/badge.svg)](https://github.com/apache/couchdb-erlfdb/actions/workflows/ci.yml)
+[![CI](https://github.com/apache/couchdb-erlfdb/actions/workflows/ci.yml/badge.svg)](https://github.com/apache/couchdb-erlfdb/actions/workflows/ci.yml)[![Coverage](https://coveralls.io/repos/github/apache/couchdb-erlfdb/badge.svg?branch=main)](https://coveralls.io/github/apache/couchdb-erlfdb?branch=main)
 
 This project is a NIF wrapper for the FoundationDB C API. Documentation on
 the main API can be found [here][fdb_docs].
diff --git a/rebar.config b/rebar.config
index 2b00cba..34d277d 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,4 +1,5 @@
 {plugins, [
+    coveralls,
     pc
 ]}.
 
@@ -38,3 +39,7 @@
 ]}.
 
 {cover_enabled, true}.
+{cover_export_enabled, true}.
+{coveralls_coverdata, "_build/devcontainer+test/cover/*.coverdata"}.
+{coveralls_service_name, "github"}.
+{coveralls_parallel, true}.
diff --git a/rebar.config.script b/rebar.config.script
index 7a8dbb6..4a07085 100644
--- a/rebar.config.script
+++ b/rebar.config.script
@@ -9,6 +9,26 @@
         integer_to_list(APIVersionBytes, 16)
     end.
 
+% https://github.com/markusn/coveralls-erl#example-usage-rebar3-and-github-actions
+CoverallConfig =
+    case {os:getenv("GITHUB_ACTIONS"), os:getenv("GITHUB_TOKEN")} of
+        {"true", Token} when is_list(Token) ->
+        CONFIG1 = [{coveralls_repo_token, Token},
+                    {coveralls_service_job_id, os:getenv("GITHUB_RUN_ID")},
+                    {coveralls_service_number, os:getenv("GITHUB_RUN_NUMBER")},
+                    {coveralls_commit_sha, os:getenv("GITHUB_SHA")},
+                    {coveralls_flag_name, os:getenv("COVERALLS_FLAG_NAME")} | CONFIG],
+        case os:getenv("GITHUB_EVENT_NAME") =:= "pull_request"
+            andalso string:tokens(os:getenv("GITHUB_REF"), "/") of
+            [_, "pull", PRNO, _] ->
+                [{coveralls_service_pull_request, PRNO} | CONFIG1];
+            _ ->
+                CONFIG1
+        end;
+        _ ->
+        CONFIG
+    end.
+
 [{port_env, [
     {
         "(linux|solaris|freebsd|netbsd|openbsd|dragonfly|darwin|gnu)",
@@ -31,4 +51,4 @@
         "LDFLAGS",
         "$LDFLAGS /LIBPATH:\"c:/Program Files/foundationdb/lib/foundationdb\" fdb_c.lib"
     }
-]}] ++ CONFIG.
+]}] ++ CoverallConfig.