Many applications store data in texts, such as the Beancount, or some static blogs. This data is ideal for versioning with git. However, after you push your changes locally, you need to pull them somewhere else. This article uses Webhook to automate this process.

Previously, when building Fava, I used a timed task to pull 1; previously, the articles on this site were modified and updated manually Note1. Here's an example of how to do it with Ubuntu and ForgejoNote2.

Webhook

Webhook is a webhook utility written with Go that can be used to build a general-purpose webhook server (much like Weibo(微博), with product features as product names). It can be installed directly on Ubuntu:

apt install webhook
systemctl enable webhook
touch /etc/webhook.yaml

Don't start it yet, because the default Webhook service file points to the configuration file /etc/webhook.conf, which neither exists nor has a file extension supported by Webhook. Modify the configuration file /usr/lib/systemd/system/webhook.service:

/usr/lib/systemd/system/webhook.service[Unit]
Description=Small server for creating HTTP endpoints (hooks)
Documentation=https://github.com/adnanh/webhook/
ConditionPathExists=/etc/webhook.yaml

[Service]
ExecStart=/usr/bin/webhook -nopanic -hotreload -verbose -hooks /etc/webhook.yaml 

[Install]
WantedBy=multi-user.target

Webhook also supports configuration files in json format, which has a .json suffix. To continue with the .yaml format, edit /etc/webhook.yamlNote3:

/etc/webhook.yaml- id: hookname
  execute-command: "/path-to-script.sh"
  command-working-directory: "/path-to-working-dir"
  pass-arguments-to-command:
  - source: payload
    name: head_commit.id
  - source: payload
    name: pusher.name
  - source: payload
    name: pusher.email
  trigger-rule:
    and:
    - match:
        type: payload-hmac-sha256
        secret: 'REPLACE_WITH_YOUR_SECRET'
        parameter:
          source: header
          name: X-Gitea-Signature
    - match:
        type: value
        value: refs/heads/main
        parameter:
          source: payload
          name: ref

Note that you need to set the secret, and the name of the master branch (main/master) yourself.

touch /path-to-script.sh
systemctl daemon-reload
systemctl start webhook
systemctl status webhook

If the Webhook service can be started normally then continue.

Nginx Proxy

Webhook provides http service on port 9000 by default. For security reasons, Nginx is used as a reverse proxy to provide https service. For more information, please refer to the following:

server {
    listen          443 ssl http2;
    listen          [::]:443 ssl http2;
    server_name your-domain.com;

    # YOUR SSL CONFIG

    location ^~ / {
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass http://localhost:9000/;
    }
    access_log off;
}

Forgejo Adding Hooks

On the settings page of the corresponding repo on Forgejo, add a web hook. The URL should be https://your-domain.com/hooks/hookname and the key text should be REPLACE_WITH_YOUR_SECRET. Save it and click "Test Push" at the bottom of the page to debug it.

You should also add a deployment key, which will be the SSH public key that will be used to automate the git pull. If you also need to push code in this environment, remember to check the "Enable write access" box.

git pull script

文件 path-to-script.sh

#!/bin/sh

git pull

status_log=$(git status -sb)

# In bash, `=` in the following line should be `==`
if [ "$status_log" = "## main...origin/main" ];then
        echo "nothing"
else
        echo "commit..."
        # git config --global user.email <>
        git add .
        git commit -m "update" -a
fi

git push

It is recommended to commit this script to the root of the repo to make it easier to use. After cloning the repo at the target location, try executing the script first:

chomod +x path-to-script.sh
sh path-to-script.sh

Conclusion

At this point, the code is automatically pulled (no Actions at all!). In practice, you may want to refine the webhook's match rules and check parameters in the script as needed.


Notes

  1. Since May, this site has been built using a program based on SvelteKit's own development.

  2. Forgejo is a branch of Gitea, build tutorial: Build Forgejo on Ubuntu.

  3. The Webhook project's example and issue#280 may only work with older versions of Gitea.

References

  1. Dallas Lu. 搭建多用户、多账本 Fava 服务器(Build Multi-User, Multi-Book Fava Server).