diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9b0feeb1e0199b145246971fd77e6fdb99199cb3
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,73 @@
+---
+
+variables:
+  GOCACHE: $CI_PROJECT_DIR/.gocache
+  GOPATH: $CI_PROJECT_DIR/.go
+  PACKAGE_REGISTRY_URL: >-
+    $CI_API_V4_URL/projects/$CI_PROJECT_ID/packages/generic/wsshit
+
+cache:
+  paths:
+    - .gocache
+    - .go
+
+build:
+  image: golang:1-buster
+  stage: build
+  before_script:
+    - go version
+  script:
+    - go build -o $CI_PROJECT_NAME-$GOOS-$GOARCH$EXEEXT
+  artifacts:
+    paths:
+      - $CI_PROJECT_NAME-$GOOS-$GOARCH$EXEEXT
+  parallel:
+    matrix:
+      - GOOS:
+          - linux
+        GOARCH:
+          - amd64
+          - arm
+          - arm64
+        EXEEXT:
+          - ""
+      - GOOS:
+          - windows
+        GOARCH:
+          - amd64
+        EXEEXT:
+          - .exe
+
+lint:
+  image: golangci/golangci-lint:v1.46-alpine
+  stage: test
+  needs: []
+  script:
+    - >-
+      golangci-lint
+      run
+      -v
+      --max-issues-per-linter=0
+      --max-same-issues=0
+      --out-format=code-climate
+      --timeout=10m
+      > golangci-output.json
+  artifacts:
+    paths:
+      - golangci-output.json
+    reports:
+      codequality: golangci-output.json
+    expire_in: 7 days
+
+upload:
+  stage: deploy
+  image: curlimages/curl:latest
+  needs:
+    - build
+  rules:
+    - if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
+  script:
+    - >-
+      for file in ${CI_PROJECT_NAME}-* ; do
+      curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file ${file} ${PACKAGE_REGISTRY_URL}/${CI_COMMIT_SHA}/${file} || exit $? ;
+      done