diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 2c84e11aa29e133b93e79d02647a801d83dbc347..33b23f737c10a339517ff493d61eb3fd9c92e77c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,3 +1,5 @@
+image: alpine:3.9
+
 stages:
  - build
  - test
@@ -91,6 +93,7 @@ test:archlinux:
   image: gitlab.fit.cvut.cz:5000/algorithms-library-toolkit/ci-docker-images/alt-builder:latest
   except:
     - tags
+    - branches #TODO
 
 .build:builder:
   <<: *distro_builder
@@ -227,7 +230,6 @@ test:ubuntu:rolling:
 # doc.yml
 
 doc:doc:
-  image: alpine:3.9
   stage: build
   before_script:
     - apk add --no-cache doxygen graphviz
@@ -290,8 +292,6 @@ static-analysis:clang-tidy:
     - tags
     - /^v.*$/
 
-# -----------------------------------------------------------------------------
-
 .template:package:
   stage: package
   dependencies: []
@@ -300,6 +300,22 @@ static-analysis:clang-tidy:
   stage: release
   dependencies: []
 
+
+.releaser:
+  extends: .template:release
+  before_script:
+    - apk add --no-cache openssh
+    - echo -ne "Host *\n  StrictHostKeyChecking no\n" >> /etc/ssh/ssh_config
+    - mkdir -p ~/.ssh && echo "$SSH_PRIV_KEY" > ~/.ssh/id_rsa && chmod 700 -R ~/.ssh && eval $(ssh-agent -s)
+    - echo "$SSH_PASSPHRASE" | ssh-add ~/.ssh/id_rsa
+    - MODE=$(echo "$CI_JOB_NAME" | cut -d":" -f2)
+    - REPO=$(echo "$CI_JOB_NAME" | cut -d":" -f3)
+  script:
+    - scp $RELEASER_WILDCARD_UPLOAD $SSH_REPOSITORY:~/tmp/
+    - ssh $SSH_REPOSITORY add-packages "$REPO" "$MODE" "$GPG_KEYID" "$GPG_PASSPHRASE" $RELEASER_WILDCARD_ADD
+
+# -----------------------------------------------------------------------------
+
 # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 # release_archlinux.yml
 
@@ -319,19 +335,6 @@ static-analysis:clang-tidy:
   variables:
     PACKAGER: "Tomáš Pecka <peckato1@fit.cvut.cz>"
 
-.release:arch:
-  extends: .template:release
-  image: alpine:3.9
-
-  before_script:
-    - apk add --no-cache openssh
-    - mkdir -p ~/.ssh && echo "$SSH_PRIV_KEY" > ~/.ssh/id_rsa && chmod 700 -R ~/.ssh
-    - eval $(ssh-agent -s)
-    - echo "$SSH_PASSPHRASE" | ssh-add ~/.ssh/id_rsa
-  script:
-    - scp -o StrictHostKeyChecking=no *.pkg.tar.xz* altrepo@pecka.me:~altrepo/tmp/
-    - ssh -o StrictHostKeyChecking=no altrepo@pecka.me add-packages arch "$GPG_KEYID" "$GPG_PASSPHRASE" *.pkg.tar.xz
-
 # -----------------------------------------------------------------------------
 
 package:nightly:arch:
@@ -349,6 +352,11 @@ package:tag:arch:
     - chown builder:builder PKGBUILD
 
 # -----------------------------------------------------------------------------
+.release:arch:
+  extends: .releaser
+  variables:
+    RELEASER_WILDCARD_UPLOAD: "*.pkg.tar.xz*"
+    RELEASER_WILDCARD_ADD: "*.pkg.tar.xz"
 
 release:nightly:arch:
   <<: *release_nightly
@@ -371,8 +379,9 @@ release:tag:arch:
 
 # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 # release_docker.yml
-.template:docker: &docker
-  image: alpine:3.9
+
+.package:docker: &docker
+  extends: .template:package
   cache: {}  # disable
   services:
     - docker:dind
@@ -397,7 +406,7 @@ release:tag:arch:
 package:nightly:docker:
   <<: *release_nightly
   <<: *docker
-  extends: .template:package
+  extends: .package:docker
   script:
     - docker build --target=deploy-cli -f extra/docker/Dockerfile.master -t "$IMAGE_CLI:$TAG_NIGHTLY" .
     - docker build --target=deploy-all -f extra/docker/Dockerfile.master -t "$IMAGE_ALL:$TAG_NIGHTLY" .
@@ -414,7 +423,7 @@ package:nightly:docker:
 package:tag:docker:
   <<: *release_tag
   <<: *docker
-  extends: .template:package
+  extends: .package:docker
   script:
     - docker build --target=deploy-cli -f extra/docker/Dockerfile.master -t "$IMAGE_CLI:$TAG_NIGHTLY" .
     - docker build --target=deploy-all -f extra/docker/Dockerfile.master -t "$IMAGE_ALL:$TAG_NIGHTLY" .
@@ -462,6 +471,68 @@ release:tag:docker:
     - package:tag:docker
 
 
+# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+# release_sources.yml
+
+.package:sources:
+  extends: .template:package
+  before_script:
+    - apk add --no-cache git gnupg
+    - mkdir -p ~/.gnupg && echo -ne 'allow-preset-passphrase\nmax-cache-ttl 60480000\ndefault-cache-ttl 60480000\n' > ~/.gnupg/gpg-agent.conf
+    - echo "$GPG_PRIVATE_KEY" | gpg --no-tty --batch --import -
+    - KEYGRIP=$(gpg --with-keygrip -k $GPG_KEYID | grep Keygrip | cut -d= -f2 | tr -d ' ')
+    - /usr/libexec/gpg-preset-passphrase --preset --passphrase "$GPG_PASSPHRASE" "$KEYGRIP"
+
+  artifacts:
+    paths:
+      - "*.tar.gz*"
+    expire_in: 1 day
+
+package:nightly:sources:
+  <<: *release_nightly
+  extends: .package:sources
+  script:
+     - FILENAME=algorithms-library-$(git describe --long --tags --match="v*" |  sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g').tar.gz
+     - git archive --format=tar.gz --prefix="algorithms-library/" HEAD -o $FILENAME
+     - gpg --armor --detach-sig -o $FILENAME.sig $FILENAME
+     - sha256sum $FILENAME > $FILENAME.sha256sum
+     - md5sum    $FILENAME > $FILENAME.md5sum
+
+package:tag:sources:
+  <<: *release_tag
+  extends: .package:sources
+  script:
+     - FILENAME=algorithms-library-$(git describe  --tags --match="v*" --abbrev=0 | sed 's/^v//g').tar.gz
+     - git archive --format=tar.gz --prefix="algorithms-library/" HEAD -o "algorithms-library-$FILENAME.tar.gz"
+     - gpg --clearsign -o $FILENAME.sig $FILENAME
+     - sha256sum $FILENAME > $FILENAME.sha256sum
+     - md5sum    $FILENAME > $FILENAME.md5sum
+
+# -----------------------------------------------------------------------------
+
+.release:sources:
+  extends: .releaser
+  variables:
+    RELEASER_WILDCARD_UPLOAD: "*.tar.gz*"
+    RELEASER_WILDCARD_ADD: "*.tar.gz"
+
+release:nightly:sources:
+  <<: *release_nightly
+  extends: .release:sources
+  environment:
+    name: sources-nightly
+    url: https://altrepo.pecka.me/sources/nightly/
+  dependencies:
+    - package:nightly:sources
+
+release:tag:sources:
+  <<: *release_tag
+  extends: .release:sources
+  environment:
+    name: sources-release
+    url: https://altrepo.pecka.me/sources/releases/
+  dependencies:
+    - package:tag:sources
 
 
 #######################################################################################################################
@@ -471,7 +542,6 @@ release:tag:docker:
 
 .template:notify:
   stage: notify
-  image: alpine:3.9
   before_script:
     - apk add --no-cache curl
   dependencies: []