Distribute zbox using apt #3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; } | |