Skip to content

Build DDNSTO Packages (Optimized) #16

Build DDNSTO Packages (Optimized)

Build DDNSTO Packages (Optimized) #16

name: Build DDNSTO Packages (Optimized)
on:
workflow_dispatch:
inputs:
build_type:
description: '包格式'
required: true
default: 'all'
type: choice
options:
- all
- apk_only
- ipk_only
ddnsto_type:
description: 'DDNSTO 类型'
required: true
default: 'all'
type: choice
options:
- standard
- lite
- all
arch_aarch64:
description: 'aarch64_generic'
required: true
default: true
type: boolean
arch_arm:
description: 'arm_cortex-a9'
required: true
default: true
type: boolean
arch_x86_64:
description: 'x86_64'
required: true
default: true
type: boolean
arch_mipsel:
description: 'mipsel_24kc'
required: true
default: true
type: boolean
push:
tags:
- 'v*'
permissions:
contents: write
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
setup:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.setup.outputs.matrix }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup matrix
id: setup
run: |
# SDK配置映射 - IPK使用24.10.2, APK使用25.12.2
declare -A SDK_URLS_IPK
SDK_URLS_IPK[aarch64_generic]="https://downloads.openwrt.org/releases/24.10.2/targets/armsr/armv8/openwrt-sdk-24.10.2-armsr-armv8_gcc-13.3.0_musl.Linux-x86_64.tar.zst"
SDK_URLS_IPK[arm_cortex-a9]="https://downloads.openwrt.org/releases/24.10.2/targets/mvebu/cortexa9/openwrt-sdk-24.10.2-mvebu-cortexa9_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst"
SDK_URLS_IPK[x86_64]="https://downloads.openwrt.org/releases/24.10.2/targets/x86/64/openwrt-sdk-24.10.2-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst"
SDK_URLS_IPK[mipsel_24kc]="https://downloads.openwrt.org/releases/24.10.2/targets/ramips/mt7621/openwrt-sdk-24.10.2-ramips-mt7621_gcc-13.3.0_musl.Linux-x86_64.tar.zst"
declare -A SDK_URLS_APK
SDK_URLS_APK[aarch64_generic]="https://downloads.openwrt.org/releases/25.12.2/targets/armsr/armv8/openwrt-sdk-25.12.2-armsr-armv8_gcc-14.3.0_musl.Linux-x86_64.tar.zst"
SDK_URLS_APK[arm_cortex-a9]="https://downloads.openwrt.org/releases/25.12.2/targets/mvebu/cortexa9/openwrt-sdk-25.12.2-mvebu-cortexa9_gcc-14.3.0_musl_eabi.Linux-x86_64.tar.zst"
SDK_URLS_APK[x86_64]="https://downloads.openwrt.org/releases/25.12.2/targets/x86/64/openwrt-sdk-25.12.2-x86-64_gcc-14.3.0_musl.Linux-x86_64.tar.zst"
SDK_URLS_APK[mipsel_24kc]="https://downloads.openwrt.org/releases/25.12.2/targets/ramips/mt7621/openwrt-sdk-25.12.2-ramips-mt7621_gcc-14.3.0_musl.Linux-x86_64.tar.zst"
# 确定包类型列表
if [ "${{ github.event_name }}" == "push" ]; then
pkg_types='["ipk","apk"]'
else
build_type="${{ github.event.inputs.build_type }}"
if [ "$build_type" == "all" ]; then
pkg_types='["ipk","apk"]'
elif [ "$build_type" == "ipk_only" ]; then
pkg_types='["ipk"]'
else
pkg_types='["apk"]'
fi
fi
# 确定DDNSTO类型列表
if [ "${{ github.event_name }}" == "push" ]; then
ddnsto_types='["standard"]'
else
ddnsto_type_input="${{ github.event.inputs.ddnsto_type }}"
if [ "$ddnsto_type_input" == "all" ]; then
ddnsto_types='["standard","lite"]'
else
ddnsto_types="[\"$ddnsto_type_input\"]"
fi
fi
# 确定架构列表
if [ "${{ github.event_name }}" == "push" ]; then
arches=(aarch64_generic arm_cortex-a9 x86_64 mipsel_24kc)
else
arches=()
if [ "${{ github.event.inputs.arch_aarch64 }}" == "true" ]; then
arches+=(aarch64_generic)
fi
if [ "${{ github.event.inputs.arch_arm }}" == "true" ]; then
arches+=(arm_cortex-a9)
fi
if [ "${{ github.event.inputs.arch_x86_64 }}" == "true" ]; then
arches+=(x86_64)
fi
if [ "${{ github.event.inputs.arch_mipsel }}" == "true" ]; then
arches+=(mipsel_24kc)
fi
# 如果没有选择任何架构,默认构建全部
if [ ${#arches[@]} -eq 0 ]; then
arches=(aarch64_generic arm_cortex-a9 x86_64 mipsel_24kc)
fi
fi
# 构建矩阵JSON
matrix="["
first=true
for arch in "${arches[@]}"; do
for pkg_type in $(echo "$pkg_types" | jq -r '.[]'); do
for ddnsto_type in $(echo "$ddnsto_types" | jq -r '.[]'); do
if [ "$first" == "false" ]; then
matrix="$matrix,"
fi
if [ "$pkg_type" == "ipk" ]; then
sdk_url="${SDK_URLS_IPK[$arch]}"
sdk_version="24.10.2"
else
sdk_url="${SDK_URLS_APK[$arch]}"
sdk_version="25.12.2"
fi
matrix="$matrix{\"arch\":\"$arch\",\"pkg_type\":\"$pkg_type\",\"ddnsto_type\":\"$ddnsto_type\",\"sdk_url\":\"$sdk_url\",\"sdk_version\":\"$sdk_version\"}"
first=false
done
done
done
matrix="$matrix]"
echo "matrix=$matrix" >> $GITHUB_OUTPUT
echo "Matrix: $matrix"
build:
name: Build ${{ matrix.config.pkg_type }} ${{ matrix.config.arch }} (${{ matrix.config.ddnsto_type }})
runs-on: ubuntu-latest
needs: setup
strategy:
fail-fast: false
matrix:
config: ${{ fromJson(needs.setup.outputs.matrix) }}
env:
DDNSTO_TYPE: ${{ matrix.config.ddnsto_type }}
PKG_TYPE: ${{ matrix.config.pkg_type }}
ARCH: ${{ matrix.config.arch }}
SDK_VERSION: ${{ matrix.config.sdk_version }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup variables
run: |
sudo timedatectl set-timezone 'Asia/Shanghai'
echo build_time="$(date '+%Y-%m-%d')" >> "$GITHUB_ENV"
echo sdk_cache_key="openwrt-sdk-${SDK_VERSION}-${ARCH}-${DDNSTO_TYPE}-${{ hashFiles('ddnsto/Makefile') }}-v3" >> "$GITHUB_ENV"
- name: Cache SDK
id: cache-sdk
uses: actions/cache@v4
with:
path: ~/sdk
key: ${{ env.sdk_cache_key }}
restore-keys: |
openwrt-sdk-${SDK_VERSION}-${ARCH}-${DDNSTO_TYPE}-v3
- name: Download SDK
if: steps.cache-sdk.outputs.cache-hit != 'true'
run: |
mkdir -p ~/sdk
echo "Downloading SDK from ${{ matrix.config.sdk_url }}"
wget -q --show-progress -O ~/sdk/sdk.tar.zst "${{ matrix.config.sdk_url }}"
echo "Extracting SDK..."
cd ~/sdk && tar -xf sdk.tar.zst --strip-components=1 && rm sdk.tar.zst
- name: Setup SDK
run: |
cd ~/sdk
# 安装主机编译依赖
sudo apt-get update
sudo apt-get install -y libncurses5-dev libncursesw5-dev
./scripts/feeds update -a || true
# 删除 u-boot-mediatek 包,避免 python3-setuptools 检测失败
rm -rf feeds/base/package/boot/uboot-mediatek
./scripts/feeds install -a || true
- name: Build Package
run: |
cd ~/sdk
# 清理旧的 ddnsto 构建目录和下载文件,确保完全重新编译
echo "=== Cleaning old build directories and downloads ==="
rm -rf build_dir/target-*/ddnsto-binary*
rm -rf build_dir/target-*/.ddnsto-binary*
rm -f dl/ddnsto-binary*.tar.gz
rm -f dl/ddnsto-binary*.tar.gz.flock
rm -rf staging_dir/packages/*/ddnsto*
find bin/packages/ -name "ddnsto*.${PKG_TYPE}" -delete 2>/dev/null || true
# 直接复制包到package目录(不使用feeds机制)
rm -rf package/ddnsto
mkdir -p package/ddnsto
cp -r $GITHUB_WORKSPACE/ddnsto/* package/ddnsto/
echo "=== Package directory contents ==="
ls -la package/ddnsto/
# 配置
echo "CONFIG_PACKAGE_ddnsto=m" >> .config
make defconfig
# 构建前检查
echo "=== Pre-build check ==="
echo "DDNSTO_TYPE=$DDNSTO_TYPE"
echo "PKG_TYPE=$PKG_TYPE"
ls -la build_dir/target-*/ddnsto-binary* 2>/dev/null || echo "No existing ddnsto build dir"
# 构建 - 使用详细输出
echo "=== Starting build with DDNSTO_TYPE=$DDNSTO_TYPE ==="
make package/ddnsto/compile V=sc -j1 2>&1 | tee build.log || {
echo "=== DDNSTO BUILD FAILED ==="
tail -100 build.log
exit 1
}
# 验证下载的二进制文件
echo "=== Verifying downloaded binary ==="
ls -la dl/ddnsto-binary*.tar.gz 2>/dev/null || echo "No tar.gz in dl"
# 根据DDNSTO_TYPE验证对应的tar.gz
if [ "$DDNSTO_TYPE" == "lite" ]; then
tar_file="dl/ddnsto-binary-lite-3.1.7.tar.gz"
else
tar_file="dl/ddnsto-binary-3.1.7.tar.gz"
fi
if [ -f "$tar_file" ]; then
echo "Contents of $tar_file:"
tar -tzf "$tar_file"
echo "SHA256 of downloaded tar.gz:"
sha256sum "$tar_file"
fi
echo "Directory structure of build_dir:"
find build_dir/target-*/ddnsto-binary*/ -type d 2>/dev/null | head -20
echo "Files in build_dir:"
find build_dir/target-*/ddnsto-binary*/ -type f -ls 2>/dev/null || echo "No files found"
echo "SHA256 of ddnstod in .pkgdir:"
find build_dir/target-*/ddnsto-binary*/ -name "ddnstod" -type f -exec sha256sum {} \; 2>/dev/null || echo "No ddnstod found"
echo "=== Post-build check ==="
ls -la build_dir/target-*/ddnsto-binary*/ 2>/dev/null || echo "Build dir not found"
find bin/packages/ -name "ddnsto*.${PKG_TYPE}" 2>/dev/null || echo "No ${PKG_TYPE} found"
# 检查包文件内容
echo "=== Checking ${PKG_TYPE^^} content ==="
for pkg in $(find bin/packages/ -name "ddnsto*.${PKG_TYPE}" 2>/dev/null); do
echo "Package file: $pkg"
if [ "$PKG_TYPE" == "ipk" ]; then
file "$pkg"
rm -rf /tmp/pkg_check
mkdir -p /tmp/pkg_check
tar -xzf "$PWD/$pkg" -C /tmp/pkg_check 2>/dev/null || echo "Cannot extract outer tar"
if [ -f "/tmp/pkg_check/data.tar.gz" ]; then
tar -tzf /tmp/pkg_check/data.tar.gz | grep -E "(ddnsto|sbin)" || echo "No ddnsto in data.tar.gz"
fi
rm -rf /tmp/pkg_check
else
tar -tzf "$pkg" 2>/dev/null | grep -E "(ddnsto|sbin)" || echo "No ddnsto in tar listing"
fi
done
# 复制输出
mkdir -p $GITHUB_WORKSPACE/bin/packages/${ARCH}/packages_ci
find bin/packages/ -name "ddnsto*.${PKG_TYPE}" -exec cp {} $GITHUB_WORKSPACE/bin/packages/${ARCH}/packages_ci/ \;
echo "=== Final packages ==="
ls -la $GITHUB_WORKSPACE/bin/packages/${ARCH}/packages_ci/
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.config.arch }}-${{ matrix.config.pkg_type }}-${{ matrix.config.ddnsto_type }}
path: bin/packages/${{ matrix.config.arch }}/packages_ci/*.${{ matrix.config.pkg_type }}
- name: Create release files
run: |
mkdir -p release/${PKG_TYPE}
tar -zcvf release/${PKG_TYPE}/${ARCH}-${DDNSTO_TYPE}.tar.gz -C bin/packages/${ARCH}/ packages_ci
- name: Upload to release
if: startsWith(github.ref, 'refs/tags/')
uses: ncipollo/release-action@v1
with:
name: DDNSTO ${{ env.build_time }}
token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ github.ref_name }}
allowUpdates: true
replacesArtifacts: false
artifacts: "release/${{ matrix.config.pkg_type }}/${{ matrix.config.arch }}-${{ matrix.config.ddnsto_type }}.tar.gz"