This is an old revision of the document!
Creating repository from automated Debian Salsa builds
Motivation
I'm not an Debian maintainer. Nor I want to be in future. My reasons to do all this is that:
- I want some specific software to be packaged for Debian
- when I update packaging on salsa.debian.org I want to have available package for computers and phones
- I don't want to bother myself downloading packages from Salsa CI manually or compiling them again on the devices
- I want also others to be able use my packages
These reasons motivated me to look into Salsa, GitLab API and Aptly deployment.
Predispozition
- You have correctly setup Salsa CI (including debian/salsa-ci.yml and Gitlab settings)
- you didn't disabled build for the architecture you planing to distribute
You can take https://salsa.debian.org/okias-guest/ as an example.
Where to start
Aptly. First, you need to find a place, where you can host your repository. It's right, that Salsa-CI can offer you 1 repository per one pipeline, but that's not very pleasant having to switch repository everytime you build a package.
So, you need some VPS or physical machine with IPv6 (every provider should give you at least /64 range for free) or/and with IPv4 connectivity.
When you get it, just installing Debian, aptly and nginx should be enough.
Then it's a time to create user and generate your repository replated GPG key.
useradd -m repo && export USER=repo # create user repo sudo -u $USER gpg --default-new-key-algo rsa4096 --gen-key # generate new key sudo -u $USER mkdir -p /home/${USER}/.aptly/public/ sudo -u $USER GPG_TTY=$(tty) gpg --export > /home/${USER}/.aptly/public/public-key.asc # export key sudo -u $USER aptly repo create -distribution unstable ${REPO_NAME}
Now we have our user and GPG key, we can move to creating our script gitlab_to_aptly.sh which we will place into /home/$USER/
Before continuing, please prepare your Bearer token, you'll learn how to do that from https://www.youtube.com/watch?v=0LsMC3ZiXkA . Fill USER= and TOKEN= inside the script.
Script does simple things
- it does check for all your projects
- for each project it check latest successful jobs
- if there is new successful job, then it picks debian packages generated by salsa-ci and downloads and unpack them
- then export them into aptly repository
#!/bin/sh # SPDX-License-Identifier: GPL-3.0-only # version 0.1; created by David Heidelberg <david@ixit.cz> if [ `id -u` -eq 0 ]; then echo "Please DO NOT run as root!" exit fi USER= # your gitlab username TOKEN= # watch https://www.youtube.com/watch?v=0LsMC3ZiXkA ARCHS="arm64 amd64" JOBS="build build\ arm64" # jobs must match to build == amd64; ARTIF_UNPACK=debian/output echo "* Downloading projects..." PROJ_JSON=`curl -s -H 'Accept: application/json' -H "Authorization: Bearer ${TOKEN}" "https://salsa.debian.org/api/v4/users/${USER}/projects/"` PROJECTS=`echo $PROJ_JSON | jq ".[].id" | xargs` PUBLISH=0 check_new_jobs() { for id in $PROJECTS; do echo "* Checking jobs for project ${id}..." LAST_JOB_ID_FILE="proj_${id}_last_job.txt" LAST_JOB_ID=`curl -s -H 'Accept: application/json' -H "Authorization: Bearer ${TOKEN}" "https://salsa.debian.org/api/v4/projects/${id}/jobs?scope[]=success" | jq ".[0].id" | xargs` if [ -e "${LAST_JOB_ID_FILE}" ]; then JOB_ID=`cat ${LAST_JOB_ID_FILE}` else JOB_ID=0 fi if [ $LAST_JOB_ID != "null" ] && [ $JOB_ID -ne $LAST_JOB_ID ]; then echo $LAST_JOB_ID > ${LAST_JOB_ID_FILE} echo "* Written new JOB ID $LAST_JOB_ID into file ${LAST_JOB_ID_FILE}." get_artifacts PUBLISH=1 fi unset LAST_JOB_ID done } cleanup() { rm -vrf ./${ARTIF_UNPACK}/* } get_artifacts() { for job in $JOBS; do curl -o ${id}_${job}.zip -H 'Accept: application/json' -H "Authorization: Bearer ${TOKEN}" "https://salsa.debian.org/api/v4/projects/${id}/jobs/artifacts/debian/latest/download?job=${job}" && \ unzip ${id}_${job}.zip && \ rm ${id}_${job}.zip && \ echo aptly command ID: ${id} JOB: ${job} done! rm ${ARTIF_UNPACK}/output.log done } publish() { if [ $PUBLISH -eq 0 ]; then echo "* Nothing to publish. Quiting..." exit 0 fi REPO_NAME=ixit aptly repo add ${REPO_NAME} ${ARTIF_UNPACK} # add files aptly publish drop unstable # first we get rid of previously published repo aptly publish repo -batch -architectures ${ARCHS} -distribution unstable ${REPO_NAME} } cleanup check_new_jobs publish
Test script with
sudo -u $USER ./gitlab_to_aptly.sh
, if your /home/$USER/.aptly/public is populated, prepare nginx configuration. This configuration may differ a lot from your use. I'm assuming you have SSL configured (ssl.conf) and SSL certificates in place.
/etc/nginx/sites-available/repo.ixit.cz.conf
server { include ssl.conf; server_name repo.ixit.cz; ssl_certificate /etc/letsencrypt/live/ixit.cz/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ixit.cz/privkey.pem; location / { root /home/repo/.aptly/public/; autoindex on; } }
systemctl reload nginx and check URL, if you see the repository.
In that case, you can try add it to the first device. Replace ixit with your repository name:
echo "deb https://repo.ixit.cz/ unstable main" > /etc/apt/sources.list.d/ixit.list # repository curl -o /etc/apt/trusted.gpg.d/ixit.gpg https://repo.ixit.cz/public-key.asc # GPG key apt update # shouldn't write any errors
now you can install package you desire and test.
Most likely, you'll want to regenerate your repository at least every hour.
This is how can look /etc/systemd/system/gitlab_to_aptly.service
[Unit] Description=Radioalarm service [Service] User=repo WorkingDirectory=/home/repo/tmp/ ExecStart=/home/repo/gitlab_to_aptly.sh
and /etc/systemd/system/gitlab_to_aptly.timer
[Unit] Description=Update aptly repository every hour [Timer] OnBootSec=60min OnUnitActiveSec=60min Unit=gitlab_to_aptly.service [Install] WantedBy=timers.target