Build DDNSTO Packages (Optimized) #16
This file contains hidden or 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: 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" |