diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9f7aed46..836381ef 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,7 +18,7 @@ jobs:
       - uses: actions/setup-go@v5
         with:
           go-version-file: ./go.mod
-      - run: ./ci/fmt.sh
+      - run: make fmt
 
   lint:
     runs-on: ubuntu-latest
@@ -28,7 +28,7 @@ jobs:
       - uses: actions/setup-go@v5
         with:
           go-version-file: ./go.mod
-      - run: ./ci/lint.sh
+      - run: make lint
 
   test:
     runs-on: ubuntu-latest
@@ -43,7 +43,7 @@ jobs:
       - uses: actions/setup-go@v5
         with:
           go-version-file: ./go.mod
-      - run: ./ci/test.sh
+      - run: make test
       - uses: actions/upload-artifact@v4
         with:
           name: coverage.html
@@ -56,4 +56,4 @@ jobs:
       - uses: actions/setup-go@v5
         with:
           go-version-file: ./go.mod
-      - run: ./ci/bench.sh
+      - run: make bench
diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml
index 0eac94cc..62e3d337 100644
--- a/.github/workflows/daily.yml
+++ b/.github/workflows/daily.yml
@@ -15,7 +15,7 @@ jobs:
       - uses: actions/setup-go@v5
         with:
           go-version-file: ./go.mod
-      - run: AUTOBAHN=1 ./ci/bench.sh
+      - run: AUTOBAHN=1 make bench
   test:
     runs-on: ubuntu-latest
     steps:
@@ -29,7 +29,7 @@ jobs:
       - uses: actions/setup-go@v5
         with:
           go-version-file: ./go.mod
-      - run: AUTOBAHN=1 ./ci/test.sh
+      - run: AUTOBAHN=1 make test
       - uses: actions/upload-artifact@v4
         with:
           name: coverage.html
@@ -43,7 +43,7 @@ jobs:
       - uses: actions/setup-go@v5
         with:
           go-version-file: ./go.mod
-      - run: AUTOBAHN=1 ./ci/bench.sh
+      - run: AUTOBAHN=1 make bench
   test-dev:
     runs-on: ubuntu-latest
     steps:
@@ -59,7 +59,7 @@ jobs:
       - uses: actions/setup-go@v5
         with:
           go-version-file: ./go.mod
-      - run: AUTOBAHN=1 ./ci/test.sh
+      - run: AUTOBAHN=1 make test
       - uses: actions/upload-artifact@v4
         with:
           name: coverage-dev.html
diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml
index 6ea76ab6..a78ce1b9 100644
--- a/.github/workflows/static.yml
+++ b/.github/workflows/static.yml
@@ -38,7 +38,7 @@ jobs:
           go-version-file: ./go.mod
       - name: Generate coverage and badge
         run: |
-          ./ci/test.sh
+          make test
           mkdir -p ./ci/out/static
           cp ./ci/out/coverage.html ./ci/out/static/coverage.html
           percent=$(go tool cover -func ./ci/out/coverage.prof | tail -n1 | awk '{print $3}' | tr -d '%')
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..a3e4a20d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,18 @@
+.PHONY: all
+all: fmt lint test
+
+.PHONY: fmt
+fmt:
+	./ci/fmt.sh
+
+.PHONY: lint
+lint:
+	./ci/lint.sh
+
+.PHONY: test
+test:
+	./ci/test.sh
+
+.PHONY: bench
+bench:
+	./ci/bench.sh
\ No newline at end of file
diff --git a/ci/lint.sh b/ci/lint.sh
index 20daff92..316b035d 100755
--- a/ci/lint.sh
+++ b/ci/lint.sh
@@ -1,5 +1,4 @@
 #!/bin/sh
-set -x
 set -eu
 cd -- "$(dirname "$0")/.."
 
diff --git a/make.sh b/make.sh
deleted file mode 100755
index 170d00a8..00000000
--- a/make.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-set -eu
-cd -- "$(dirname "$0")"
-
-echo "=== fmt.sh"
-./ci/fmt.sh
-echo "=== lint.sh"
-./ci/lint.sh
-echo "=== test.sh"
-./ci/test.sh "$@"
-echo "=== bench.sh"
-./ci/bench.sh