+++
title = "Zola deployment with Gitea Actions and Rsync"
date = 2024-01-19

[taxonomies]
categories = ["Linux"]

[extra]
author = "Emil Miler"
+++

Gitea now has a native support for Actions, which is a clone of GitHub Actions with the same syntax. Since Drone CI -- which was the topic of an older article -- seems to get slowly abandoned by upstream and Gitea Actions are now stable, it is a good idea to switch.

<!-- more -->

This article shares a lot of similarities with the [old Drone CI post](@/posts/zola-website-deployment-with-drone-ci/index.md).

The main advantage of Gitea Actions is a native integration to the Gitea UI. Al we need to do is prepare an [Act Runner](https://docs.gitea.com/usage/actions/act-runner). Compatibility with the more widely used GitHub Actions is also nice.

## Pipeline

The Act Runner reads the private key from a secret and uses it for SSH authentication. I am deliberately not using some random external modules for Rsync, since it is more trustworthy to execute your own code. The ssh-agent is necessary for a successful auth.

Zola is also installed by pulling a built release tar and extracting the binary. I have tried using the official Zola container, but it just would not work properly.

Here is an example from this very website [deployment action](https://git.0x45.cz/em/em.0x45.cz/src/branch/master/.gitea/workflows/deploy.yaml):

```yaml
name: Build

on:
  push:
    branches:
      - master

env:
  ZOLA_VERSION: ${{ vars.ZOLA_VERSION }}
  HOST: ${{ vars.HOST }}
  HOST_DIR: ${{ vars.HOST_DIR }}
  SSH_USERNAME: ${{ secrets.SSH_USERNAME }}
  SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install Zola
        run: |
          wget https://github.com/getzola/zola/releases/download/v${ZOLA_VERSION}/zola-v${ZOLA_VERSION}-x86_64-unknown-linux-gnu.tar.gz
          tar -xvzf *.tar.gz

      - name: Build
        run: ./zola build

      - name: Deploy
        run: |
          apt update -y && apt-get install -y --no-install-recommends rsync
          eval "$(ssh-agent -s)"
          ssh-add - <<< "${SSH_PRIVATE_KEY}"
          mkdir -p ~/.ssh/
          ssh-keyscan -H ${HOST} >> ~/.ssh/known_hosts
          rsync -r --delete-after public/* "${SSH_USERNAME}@${HOST}:${HOST_DIR}"
```

The example cinfiguration uses both secrets and vars from within Gitea. These have to be set trough the web UI under *Settings > Actions*.

## Webserver configuration

The server needs a new user with write access to the website root directory. I still call it drone for the sake of not having to redo my server configuration.

```sh
useradd drone
mkdir -p /srv/www/em.0x45.cz
chown drone:drone /srv/www/em.0x45.cz
```

## SSH keys

Create a keypair for SSH connection from Drone to our deployment server.

```sh
ssh-keygen -t ed25519
```

Public key has to be added to `~/.ssh/authorized_keys` of the "drone" user.

## Secrets

|                   |                        |
|-------------------|------------------------|
| `SSH_USERNAME`    | In our case "drone"    |
| `SSH_PRIVATE_KEY` | Plaintext private key  |

## Vars

|                   |                        |
|-------------------|------------------------|
| `ZOLA_VERSION`    | Version of Zola        |
| `HOST`            | Server hostname        |
| `TARGET_DIR`      | Website root directory |
