Skip to content

Build DDNSTO Packages (Manual) #38

Build DDNSTO Packages (Manual)

Build DDNSTO Packages (Manual) #38

name: Build DDNSTO Packages (Manual)
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 }}
ddnsto_type: ${{ steps.setup.outputs.ddnsto_type }}
ddnsto_types: ${{ steps.setup.outputs.ddnsto_types }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup matrix
id: setup
run: |
# SDK配置映射 - 使用官方镜像
declare -A SDK_URLS
SDK_URLS[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[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[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[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"
# 构建矩阵JSON
matrix="["
first=true
if [ "${{ github.event_name }}" == "push" ]; then
# push事件构建全部
for arch in aarch64_generic arm_cortex-a9 x86_64 mipsel_24kc; do
if [ "$first" == "false" ]; then matrix="$matrix,"; fi
matrix="$matrix{\"arch\":\"$arch\",\"sdk_url\":\"${SDK_URLS[$arch]}\"}"
first=false
done
echo 'ddnsto_type=standard' >> $GITHUB_OUTPUT
echo 'ddnsto_types=["standard"]' >> $GITHUB_OUTPUT
else
# 手动触发时根据选择构建
if [ "${{ github.event.inputs.arch_aarch64 }}" == "true" ]; then
if [ "$first" == "false" ]; then matrix="$matrix,"; fi
matrix="$matrix{\"arch\":\"aarch64_generic\",\"sdk_url\":\"${SDK_URLS[aarch64_generic]}\"}"
first=false
fi
if [ "${{ github.event.inputs.arch_arm }}" == "true" ]; then
if [ "$first" == "false" ]; then matrix="$matrix,"; fi
matrix="$matrix{\"arch\":\"arm_cortex-a9\",\"sdk_url\":\"${SDK_URLS[arm_cortex-a9]}\"}"
first=false
fi
if [ "${{ github.event.inputs.arch_x86_64 }}" == "true" ]; then
if [ "$first" == "false" ]; then matrix="$matrix,"; fi
matrix="$matrix{\"arch\":\"x86_64\",\"sdk_url\":\"${SDK_URLS[x86_64]}\"}"
first=false
fi
if [ "${{ github.event.inputs.arch_mipsel }}" == "true" ]; then
if [ "$first" == "false" ]; then matrix="$matrix,"; fi
matrix="$matrix{\"arch\":\"mipsel_24kc\",\"sdk_url\":\"${SDK_URLS[mipsel_24kc]}\"}"
first=false
fi
# 如果没有选择任何架构,默认构建全部
if [ "$first" == "true" ]; then
for arch in aarch64_generic arm_cortex-a9 x86_64 mipsel_24kc; do
if [ "$first" == "false" ]; then matrix="$matrix,"; fi
matrix="$matrix{\"arch\":\"$arch\",\"sdk_url\":\"${SDK_URLS[$arch]}\"}"
first=false
done
fi
# 处理 ddnsto_type,all 表示同时编译 standard 和 lite
DDNSTO_TYPE="${{ github.event.inputs.ddnsto_type }}"
if [ "$DDNSTO_TYPE" == "all" ]; then
echo 'ddnsto_type=standard' >> $GITHUB_OUTPUT
echo 'ddnsto_types=["standard","lite"]' >> $GITHUB_OUTPUT
else
echo "ddnsto_type=$DDNSTO_TYPE" >> $GITHUB_OUTPUT
echo "ddnsto_types=[\"$DDNSTO_TYPE\"]" >> $GITHUB_OUTPUT
fi
fi
matrix="$matrix]"
echo "matrix=$matrix" >> $GITHUB_OUTPUT
echo "Matrix: $matrix"
build-ipk:
name: Build IPK ${{ matrix.arch_info.arch }} (${{ matrix.ddnsto_type }})
runs-on: ubuntu-latest
needs: setup
if: github.event.inputs.build_type == 'ipk_only' || github.event.inputs.build_type == 'all' || github.event_name == 'push'
strategy:
fail-fast: false
matrix:
arch_info: ${{ fromJson(needs.setup.outputs.matrix) }}
ddnsto_type: ${{ fromJson(needs.setup.outputs.ddnsto_types) }}
env:
DDNSTO_TYPE: ${{ matrix.ddnsto_type }}
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"
- name: Cache SDK
id: cache-sdk
uses: actions/cache@v4
with:
path: ~/sdk
key: openwrt-sdk-24.10.2-${{ matrix.arch_info.arch }}-${{ matrix.ddnsto_type }}-${{ hashFiles('ddnsto/Makefile') }}
restore-keys: |
openwrt-sdk-24.10.2-${{ matrix.arch_info.arch }}-
- name: Download SDK
if: steps.cache-sdk.outputs.cache-hit != 'true'
run: |
mkdir -p ~/sdk
echo "Downloading SDK from ${{ matrix.arch_info.sdk_url }}"
wget -q --show-progress -O ~/sdk/sdk.tar.zst "${{ matrix.arch_info.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
./scripts/feeds install -a || true
- name: Build Package
run: |
cd ~/sdk
# 清理旧的 ddnsto 构建目录,确保完全重新编译
# 必须删除整个构建目录,而不仅仅是标记文件,因为目录中可能缺少下载的源码
echo "=== Cleaning old build directories ==="
rm -rf build_dir/target-*/ddnsto-binary*
rm -rf build_dir/target-*/.ddnsto-binary*
rm -rf staging_dir/packages/*/ddnsto*
find bin/packages/ -name "ddnsto*.ipk" -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"
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 "=== Post-build check ==="
ls -la build_dir/target-*/ddnsto-binary*/ 2>/dev/null || echo "Build dir not found"
find bin/packages/ -name "ddnsto*.ipk" 2>/dev/null || echo "No IPK found"
# 复制输出
mkdir -p $GITHUB_WORKSPACE/bin/packages/${{ matrix.arch_info.arch }}/packages_ci
find bin/packages/ -name "ddnsto*.ipk" -exec cp {} $GITHUB_WORKSPACE/bin/packages/${{ matrix.arch_info.arch }}/packages_ci/ \;
echo "=== Final packages ==="
ls -la $GITHUB_WORKSPACE/bin/packages/${{ matrix.arch_info.arch }}/packages_ci/
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.arch_info.arch }}-ipk-${{ matrix.ddnsto_type }}
path: bin/packages/${{ matrix.arch_info.arch }}/packages_ci/*.ipk
- name: Create release files
run: |
mkdir -p release/ipk
tar -zcvf release/ipk/${{ matrix.arch_info.arch }}-${{ matrix.ddnsto_type }}.tar.gz -C bin/packages/${{ matrix.arch_info.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/ipk/${{ matrix.arch_info.arch }}-${{ matrix.ddnsto_type }}.tar.gz"
build-apk:
name: Build APK ${{ matrix.arch_info.arch }} (${{ matrix.ddnsto_type }})
runs-on: ubuntu-latest
needs: setup
if: github.event.inputs.build_type == 'apk_only' || github.event.inputs.build_type == 'all' || github.event_name == 'push'
strategy:
fail-fast: false
matrix:
arch_info: ${{ fromJson(needs.setup.outputs.matrix) }}
ddnsto_type: ${{ fromJson(needs.setup.outputs.ddnsto_types) }}
env:
DDNSTO_TYPE: ${{ matrix.ddnsto_type }}
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"
- name: Cache SDK
id: cache-sdk
uses: actions/cache@v4
with:
path: ~/sdk
key: openwrt-sdk-25.12.2-${{ matrix.arch_info.arch }}-${{ matrix.ddnsto_type }}-${{ hashFiles('ddnsto/Makefile') }}
restore-keys: |
openwrt-sdk-25.12.2-${{ matrix.arch_info.arch }}-
- name: Download SDK
if: steps.cache-sdk.outputs.cache-hit != 'true'
run: |
mkdir -p ~/sdk
# APK 构建使用 OpenWrt 25.12.2 SDK(支持 APK 包格式)
case "${{ matrix.arch_info.arch }}" in
aarch64_generic)
SDK_URL="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"
;;
arm_cortex-a9)
SDK_URL="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"
;;
x86_64)
SDK_URL="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"
;;
mipsel_24kc)
SDK_URL="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"
;;
esac
echo "Downloading SDK from $SDK_URL"
wget -q --show-progress -O ~/sdk/sdk.tar.zst "$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
./scripts/feeds install -a || true
- name: Build Package
run: |
cd ~/sdk
# 清理旧的 ddnsto 构建目录,确保完全重新编译
# 必须删除整个构建目录,而不仅仅是标记文件,因为目录中可能缺少下载的源码
echo "=== Cleaning old build directories ==="
rm -rf build_dir/target-*/ddnsto-binary*
rm -rf build_dir/target-*/.ddnsto-binary*
rm -rf staging_dir/packages/*/ddnsto*
find bin/packages/ -name "ddnsto*.apk" -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"
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 "=== Post-build check ==="
ls -la build_dir/target-*/ddnsto-binary*/ 2>/dev/null || echo "Build dir not found"
find bin/packages/ -name "ddnsto*.apk" 2>/dev/null || echo "No APK found"
# 复制输出
mkdir -p $GITHUB_WORKSPACE/bin/packages/${{ matrix.arch_info.arch }}/packages_ci
find bin/packages/ -name "ddnsto*.apk" -exec cp {} $GITHUB_WORKSPACE/bin/packages/${{ matrix.arch_info.arch }}/packages_ci/ \;
echo "=== Final packages ==="
ls -la $GITHUB_WORKSPACE/bin/packages/${{ matrix.arch_info.arch }}/packages_ci/
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.arch_info.arch }}-apk-${{ matrix.ddnsto_type }}
path: bin/packages/${{ matrix.arch_info.arch }}/packages_ci/*.apk
- name: Create release files
run: |
mkdir -p release/apk
tar -zcvf release/apk/${{ matrix.arch_info.arch }}-${{ matrix.ddnsto_type }}.tar.gz -C bin/packages/${{ matrix.arch_info.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/apk/${{ matrix.arch_info.arch }}-${{ matrix.ddnsto_type }}.tar.gz"