ci: upload .deb from releases to APT repository (#10587)

This PR creates the necessary CI infrastructure to copy `.deb` packages
from releases to our APT repository. Re-generation of the index is
separated out into a dedicated workflow to avoid concurrency issues and
so we can re-generate it without making a release.

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Thomas Eizinger
2025-10-17 06:39:35 +11:00
committed by GitHub
parent a27676a903
commit 7e5ec7c2d7
3 changed files with 140 additions and 0 deletions

20
.github/workflows/_apt.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: Sync APT repository metadata
run-name: Triggered by ${{ github.actor }}
on:
workflow_dispatch:
workflow_call:
concurrency:
group: "create-apt-repository" # Unique group name to force only a single job at a time.
cancel-in-progress: false
jobs:
create-apt-repository-metadata:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
- run: scripts/sync-apt.sh
env:
AZURERM_ARTIFACTS_CONNECTION_STRING: ${{ secrets.AZURERM_ARTIFACTS_CONNECTION_STRING }}

View File

@@ -180,3 +180,42 @@ jobs:
component: ${{ matrix.component }}
projects: ${{ matrix.projects }}
sentry_token: ${{ secrets.SENTRY_AUTH_TOKEN }}
upload-deb-packages:
runs-on: ubuntu-24.04
if: >-
${{
startsWith(inputs.release_name || github.event.release.name, 'gateway') ||
startsWith(inputs.release_name || github.event.release.name, 'gui-client')
}}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
- name: Download .deb packages from release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -xe
# Download all .deb assets directly to pool
gh release download "${{ inputs.release_name || github.event.release.name }}" --pattern "*.deb"
# List downloaded files for verification
ls -lh ./*.deb
- name: Upload to Azure Blob Storage
run: az storage blob upload-batch \
--destination apt \
--source . \
--pattern "*.deb" \
--destination-path pool \
--overwrite \
--no-progress \
--connection-string "${{ secrets.AZURERM_ARTIFACTS_CONNECTION_STRING }}"
regenerate-apt-index:
needs: upload-deb-packages
uses: ./.github/workflows/_apt.yml
secrets: inherit

81
scripts/sync-apt.sh Executable file
View File

@@ -0,0 +1,81 @@
#!/usr/bin/env bash
#
set -euo pipefail
DISTRIBUTION="stable"
COMPONENT="main"
WORK_DIR="$(mktemp -d)"
POOL_DIR="${WORK_DIR}/pool"
DISTS_DIR="${WORK_DIR}/dists"
if [ -z "${AZURERM_ARTIFACTS_CONNECTION_STRING:-}" ]; then
echo "Error: AZURERM_ARTIFACTS_CONNECTION_STRING not set"
exit 1
fi
cleanup() {
rm -rf "${WORK_DIR}"
}
trap cleanup EXIT
echo "Downloading packages..."
az storage blob download-batch \
--destination "${WORK_DIR}" \
--source apt \
--pattern "pool/*.deb" \
--connection-string "${AZURERM_ARTIFACTS_CONNECTION_STRING}" \
2>&1 | grep -v "WARNING" || true
echo "Detecting architectures..."
ARCHITECTURES=$(for deb in "${POOL_DIR}"/*.deb; do dpkg-deb -f "$deb" Architecture 2>/dev/null; done | sort -u | tr '\n' ' ')
if [ -z "$ARCHITECTURES" ]; then
echo "Error: Could not detect architectures"
exit 1
fi
echo "Found: ${ARCHITECTURES}"
echo "Generating metadata..."
mkdir -p "${DISTS_DIR}/${DISTRIBUTION}/${COMPONENT}"
for ARCH in $ARCHITECTURES; do
BINARY_DIR="${DISTS_DIR}/${DISTRIBUTION}/${COMPONENT}/binary-${ARCH}"
mkdir -p "${BINARY_DIR}"
apt-ftparchive packages --arch "${ARCH}" "${POOL_DIR}/" >"${BINARY_DIR}/Packages"
gzip -k -f "${BINARY_DIR}/Packages"
cat >"${BINARY_DIR}/Release" <<EOF
Archive: ${DISTRIBUTION}
Component: ${COMPONENT}
Architecture: ${ARCH}
EOF
done
cd "${DISTS_DIR}/${DISTRIBUTION}"
cat >Release <<EOF
Origin: Firezone
Label: Firezone
Suite: ${DISTRIBUTION}
Codename: ${DISTRIBUTION}
Architectures: ${ARCHITECTURES}
Components: ${COMPONENT}
Description: Firezone APT Repository
Date: $(date -R -u)
EOF
apt-ftparchive release . >>Release
echo "Uploading metadata..."
az storage blob upload-batch \
--destination apt \
--source "${DISTS_DIR}" \
--destination-path dists \
--connection-string "${AZURERM_ARTIFACTS_CONNECTION_STRING}" \
--overwrite \
--output table
echo "Done"