Skip to content

Distribute zbox using apt #3

Distribute zbox using apt

Distribute zbox using apt #3

name: Distribute zbox using apt
on:
workflow_dispatch:
inputs:
version:
description: 'Version of zbox to release'
required: true
default: '1.0.0'
env:
APP_NAME: zbox
APP_VERSION: ${{ github.event.inputs.version }}
REMOTE_SERVER: 5.9.151.246
REMOTE_USER: root
jobs:
build:
runs-on: [ubuntu-latest]
env:
SRC_DIR: ${{ github.workspace }}/src
OUTPUT_DIR: ${{ github.workspace }}/output
PACKAGE_DIR: ${{ github.workspace }}/package
strategy:
matrix:
distro:
- name: bionic
base_image: ubuntu:18.04
- name: focal
base_image: ubuntu:20.04
- name: jammy
base_image: ubuntu:22.04
- name: noble
base_image: ubuntu:24.04
- name: bookworm
base_image: debian:12
- name: bullseye
base_image: debian:11
- name: buster
base_image: debian:10
arch:
- name: amd64
platform: linux/amd64
- name: arm64
platform: linux/arm64
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
path: ${{ env.SRC_DIR }}
- name: Setup
run: |
sudo apt-get update
sudo apt-get install -y \
apt-transport-https \
software-properties-common \
tar \
gnupg \
lsb-release \
dpkg-sig
mkdir -p ${{ env.OUTPUT_DIR }}
mkdir -p ${{ env.PACKAGE_DIR }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: ${{ matrix.arch.platform }}
- name: Build Docker image
run: |
docker buildx create --use
docker buildx build \
--platform ${{ matrix.arch.platform }} \
--build-arg VERSION=${{ env.APP_VERSION }} \
--tag ${{ env.APP_NAME }}-${{ env.APP_VERSION }}-${{ matrix.distro.name }}-${{ matrix.arch.name }} \
--load \
--output type=docker,dest=${{ env.OUTPUT_DIR }}/${{ env.APP_NAME }}-${{ env.APP_VERSION }}-${{ matrix.distro.name }}-${{ matrix.arch.name }}.tar \
-f ${{ env.SRC_DIR }}/scripts/debian/Dockerfile.build ${{ env.SRC_DIR }}
- name: Load Docker image
run: |
docker load -i ${{ env.OUTPUT_DIR }}/${{ env.APP_NAME }}-${{ env.APP_VERSION }}-${{ matrix.distro.name }}-${{ matrix.arch.name }}.tar
- name: Extract binary from container
run: |
CONTAINER_ID=$(docker create ${{ env.APP_NAME }}-${{ env.APP_VERSION }}-${{ matrix.distro.name }}-${{ matrix.arch.name }})
docker cp ${CONTAINER_ID}:/zbox ${{ env.OUTPUT_DIR }}/${{ env.APP_NAME }}_${{ env.APP_VERSION }}~${{ matrix.distro.name }}_${{ matrix.arch.name }}
docker rm ${CONTAINER_ID}
- name: Package binary
run: |
mkdir -p ${{ env.PACKAGE_DIR }}/DEBIAN
mkdir -p ${{ env.PACKAGE_DIR }}/usr/local/bin
cp ${{ env.OUTPUT_DIR }}/${{ env.APP_NAME }}_${{ env.APP_VERSION }}~${{ matrix.distro.name }}_${{ matrix.arch.name }} ${{ env.PACKAGE_DIR }}/usr/local/bin/${APP_NAME}
cat <<EOT > ${{ env.PACKAGE_DIR }}/DEBIAN/control
Package: ${{ env.APP_NAME }}
Version: ${{ env.APP_VERSION }}
Architecture: ${{ matrix.arch.name }}
Description: zbox is a command line interface (CLI) tool to understand the capabilities of Züs dStorage and prototype your app
EOT
echo "Configuring GPG for batch mode and loopback pinentry..."
mkdir -p ~/.gnupg
echo "use-agent" >> ~/.gnupg/gpg.conf
echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
echo "Importing GPG private key..."
echo "${{ secrets.GPG_PRIVATE_KEY }}" | gpg --batch --import
echo "Trusting the GPG key..."
echo -e "5\ny\n" | gpg --command-fd 0 --batch --yes --pinentry-mode loopback --edit-key ${{ secrets.GPG_KEY_ID }} trust quit
tar czf "${{ env.OUTPUT_DIR }}/data.tar.gz" -C "${{ env.PACKAGE_DIR }}" .
echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --batch --yes --passphrase-fd 0 --pinentry-mode loopback --detach-sign --armor -o "${{ env.PACKAGE_DIR }}/DEBIAN/signature.asc" "${{ env.OUTPUT_DIR }}/data.tar.gz"
dpkg-deb -Zgzip -b ${{ env.PACKAGE_DIR }} ${{ env.OUTPUT_DIR }}/${{ env.APP_NAME }}_${{ env.APP_VERSION }}~${{ matrix.distro.name }}_${{ matrix.arch.name }}.deb
- name: Upload .deb file
uses: actions/upload-artifact@v3
with:
name: ${{ env.APP_NAME }}_${{ env.APP_VERSION }}~${{ matrix.distro.name }}_${{ matrix.arch.name }}
path: ${{ env.OUTPUT_DIR }}/${{ env.APP_NAME }}_${{ env.APP_VERSION }}~${{ matrix.distro.name }}_${{ matrix.arch.name }}.deb
distribute:
runs-on: [ubuntu-latest]
needs: build
env:
DISTRIBUTIONS: bionic focal jammy noble bookworm bullseye buster
ARCHITECTURES: amd64 arm64
SRC_DIR: ${{ github.workspace }}/src
REPO_DIR: ${{ github.workspace }}/zbox
DEB_DIR: ${{ github.workspace }}/deb-files
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
path: ${{ env.SRC_DIR }}
- name: Setup
run: |
sudo apt-get update
sudo apt-get install -y apt-utils dpkg-sig gnupg openssh-client
mkdir -p ~/.ssh
echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ env.REMOTE_SERVER }} >> ~/.ssh/known_hosts
mkdir -p ${{ env.REPO_DIR }}
mkdir -p ${{ env.DEB_DIR }}
echo "Configuring GPG for batch mode and loopback pinentry..."
mkdir -p ~/.gnupg
echo "use-agent" >> ~/.gnupg/gpg.conf
echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
echo "Importing GPG private key..."
echo "${{ secrets.GPG_PRIVATE_KEY }}" | gpg --batch --import
echo "Trusting the GPG key..."
echo -e "5\ny\n" | gpg --command-fd 0 --batch --yes --pinentry-mode loopback --edit-key ${{ secrets.GPG_KEY_ID }} trust quit
- name: Download APT repo
run: |
scp -v -i ~/.ssh/id_rsa -r ${{ env.REMOTE_USER }}@${{ env.REMOTE_SERVER }}:/var/www/html/aptrepo/zbox/ ${{ github.workspace }}
- name: Download all .deb files
uses: actions/download-artifact@v3
with:
path: ${{ env.DEB_DIR }}
- name: Copy debian packages
run : |
mkdir -p ${{ env.REPO_DIR }}/pool/main/z/${{ env.APP_NAME }}/
find ${{ env.DEB_DIR }} -name "*.deb"
for deb in $(find ${{ env.DEB_DIR }} -name "*.deb"); do
cp -u $deb ${{ env.REPO_DIR }}/pool/main/z/${{ env.APP_NAME }}/
done
- name: Update APT repo
run: |
cd ${{ env.REPO_DIR }}
for dist in ${{ env.DISTRIBUTIONS }}; do
rm -rf dists/${dist}
mkdir -p dists/${dist}
for arch in ${{ env.ARCHITECTURES }}; do
mkdir -p dists/${dist}/main/binary-${arch}
find "pool/main/z/${{ env.APP_NAME }}" -type f -name "${{ env.APP_NAME }}_*~${dist}_${arch}.deb" | \
xargs -I {} apt-ftparchive -o Tree::dists/${dist}::Sections="main" \
-o Tree::dists/${dist}::Architectures="${arch}" \
-o Dir::ArchiveDir="${{ env.REPO_DIR }}" \
packages {} >> dists/${dist}/main/binary-${arch}/Packages
done
apt-ftparchive -o APT::FTPArchive::Release::Origin="${{ env.APP_NAME }}" \
-o APT::FTPArchive::Release::Label="${{ env.APP_NAME }}" \
-o APT::FTPArchive::Release::Suite="${dist}" \
-o APT::FTPArchive::Release::Codename="${dist}" \
-o APT::FTPArchive::Release::Version="${{ env.APP_VERSION }}" \
-o APT::FTPArchive::Release::Architectures="${{ env.ARCHITECTURES }}" \
-o APT::FTPArchive::Release::Components="main" \
-o Dir::ArchiveDir="${{ env.REPO_DIR }}" \
release dists/${dist} > dists/${dist}/Release
echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --default-key ${{ secrets.GPG_KEY_ID }} --batch --yes --passphrase-fd 0 -abs -o dists/${dist}/Release.gpg dists/${dist}/Release
echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --default-key ${{ secrets.GPG_KEY_ID }} --batch --yes --passphrase-fd 0 --clearsign -o dists/${dist}/InRelease dists/${dist}/Release
done
- name: Upload APT repo to remote
run: |
scp -v -i ~/.ssh/id_rsa -r ${{ github.workspace }}/zbox/ ${{ env.REMOTE_USER }}@${{ env.REMOTE_SERVER }}:/var/www/html/aptrepo/
- name: Upload GPG public key to remote server
run: |
echo "${{ secrets.GPG_PUBLIC_KEY }}" > zus.asc
scp -v -i ~/.ssh/id_rsa zus.asc ${{ env.REMOTE_USER }}@${{ env.REMOTE_SERVER }}:/var/www/html/zus.asc
- name: Upload install script to remote server
run: |
scp -v -i ~/.ssh/id_rsa ${{ env.SRC_DIR }}/scripts/debian/install.sh ${{ env.REMOTE_USER }}@${{ env.REMOTE_SERVER }}:/var/www/html/aptrepo/zbox_deb_install.sh
test:
runs-on: [ubuntu-latest]
needs: distribute
env:
SRC_DIR: ${{ github.workspace }}/src
strategy:
matrix:
distro:
- name: bionic
base_image: ubuntu:18.04
- name: focal
base_image: ubuntu:20.04
- name: jammy
base_image: ubuntu:22.04
- name: noble
base_image: ubuntu:24.04
- name: bookworm
base_image: debian:12
- name: bullseye
base_image: debian:11
- name: buster
base_image: debian:10
arch:
- name: amd64
platform: linux/amd64
- name: arm64
platform: linux/arm64
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
path: ${{ env.SRC_DIR }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: ${{ matrix.arch.platform }}
- name: Build Docker image
run: |
docker buildx create --use
docker buildx build \
--platform ${{ matrix.arch.platform }} \
--build-arg BASE_IMAGE=${{ matrix.distro.base_image }} \
--build-arg LOC="https://packages.zus.network/aptrepo/zbox_deb_install.sh" \
--tag ${{ env.APP_NAME }}-${{ env.APP_VERSION }}-${{ matrix.distro.name }}-${{ matrix.arch.name }} \
--load \
--output type=docker,dest=${{ github.workspace }}/${{ env.APP_NAME }}-${{ env.APP_VERSION }}-${{ matrix.distro.name }}-${{ matrix.arch.name }}.tar \
-f ${{ env.SRC_DIR }}/scripts/debian/Dockerfile.install_test .
- name: Test zbox
run: |
docker load -i ${{ github.workspace }}/${{ env.APP_NAME }}-${{ env.APP_VERSION }}-${{ matrix.distro.name }}-${{ matrix.arch.name }}.tar
docker run --platform=${{ matrix.arch.platform }} --rm ${{ env.APP_NAME }}-${{ env.APP_VERSION }}-${{ matrix.distro.name }}-${{ matrix.arch.name }} || { echo "Test installation failed"; exit 1; }