name: Build OpenWrt Packages on: push: branches: [ "main", "master" ] tags: [ "v*" ] pull_request: branches: [ "main", "master" ] workflow_dispatch: env: PACKAGE_NAME: luci-app-wechatpush SDK_DIR: /home/runner/work/openwrt-sdk permissions: contents: write jobs: build-apk: name: Build APK (v25.12) runs-on: ubuntu-latest env: OPENWRT_VERSION: 'v25.12.0-rc1' strategy: fail-fast: false matrix: target: - name: all path: x86/64 steps: - name: Checkout package repository uses: actions/checkout@v4 - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y build-essential rsync unzip zstd python3-pyelftools - name: Cache OpenWrt SDK id: cache-sdk uses: actions/cache@v4 with: path: ${{ env.SDK_DIR }} key: ${{ runner.os }}-sdk-apk-${{ matrix.target.name }}-${{ env.OPENWRT_VERSION }} - name: Download, extract OpenWrt SDK and update feeds if: steps.cache-sdk.outputs.cache-hit != 'true' run: | release_version="${OPENWRT_VERSION#v}" sdk_url_prefix="https://downloads.openwrt.org/releases/${release_version}/targets/${{ matrix.target.path }}" sdk_filename=$(curl -s "$sdk_url_prefix/" | \ grep -o '' | \ sed -e 's/.*//' | \ head -n 1) if [ -z "$sdk_filename" ]; then echo "::error::Could not find SDK file at ${sdk_url_prefix}/" echo "Available files:" curl -s "$sdk_url_prefix/" | grep -o '[^<]*' | sed -e 's/\(.*\)/\1\t\2/' exit 1 fi echo "Downloading SDK: ${sdk_url_prefix}/${sdk_filename}" wget -q "${sdk_url_prefix}/${sdk_filename}" echo "Extracting SDK..." tar -xf "$sdk_filename" mv $(find . -maxdepth 1 -type d -name 'openwrt-sdk-*') ${{ env.SDK_DIR }} echo "Updating feeds..." cd ${{ env.SDK_DIR }} echo "Original feeds configuration:" cat feeds.conf.default max_retries=5 retry_count=0 while [ $retry_count -lt $max_retries ]; do echo "Attempt $((retry_count + 1)) of $max_retries to update feeds..." echo "Replacing feeds URLs with GitHub mirrors..." sed -i 's|https://git.openwrt.org/openwrt/openwrt.git|https://github.com/openwrt/openwrt.git|g' feeds.conf.default sed -i 's|https://git.openwrt.org/feed/packages.git|https://github.com/openwrt/packages.git|g' feeds.conf.default sed -i 's|https://git.openwrt.org/project/luci.git|https://github.com/openwrt/luci.git|g' feeds.conf.default sed -i 's|https://git.openwrt.org/feed/routing.git|https://github.com/openwrt/routing.git|g' feeds.conf.default sed -i 's|https://git.openwrt.org/feed/telephony.git|https://github.com/openwrt/telephony.git|g' feeds.conf.default if [ $retry_count -eq 0 ]; then echo "Updated feeds configuration:" cat feeds.conf.default fi if ./scripts/feeds update -a; then echo "Feeds update successful" break else retry_count=$((retry_count + 1)) if [ $retry_count -lt $max_retries ]; then wait_time=$((60 * retry_count)) echo "Feeds update failed, waiting ${wait_time} seconds before retry..." sleep $wait_time else echo "::error::Feeds update failed after $max_retries attempts" exit 1 fi fi done ./scripts/feeds install -a cd .. - name: Prepare build environment working-directory: ${{ env.SDK_DIR }} run: | rm -rf package/${PACKAGE_NAME} src_dir="${{ github.workspace }}" if [ -f "$src_dir/Makefile" ]; then pkg_src="$src_dir" else pkg_src=$(find "$src_dir" -maxdepth 1 -type d -name "${PACKAGE_NAME}" -o -name "luci-app-*${PACKAGE_NAME#luci-app-}*" | head -n 1) if [ -z "$pkg_src" ]; then echo "::error::Could not locate package directory for ${PACKAGE_NAME}" exit 1 fi fi mkdir -p ./package/${PACKAGE_NAME} rsync -a --delete "$pkg_src"/ ./package/${PACKAGE_NAME}/ # 注意:wrtbwmon 在 OpenWrt 22+ (firewall4/nftables) 环境下不兼容 # 流量统计功能在新版本中不可用,但保留其他功能 translation_pkg=${PACKAGE_NAME#luci-app-} mkdir -p ./bin/packages find ./bin/packages -type f -name "${PACKAGE_NAME}*.apk" -delete find ./bin/packages -type f -name "luci-i18n-${translation_pkg}-*.apk" -delete { echo "CONFIG_PACKAGE_${PACKAGE_NAME}=m" # 注意:流量监控功能在 OpenWrt 22+ 中不可用(wrtbwmon 与 firewall4 不兼容) # echo "CONFIG_PACKAGE_${PACKAGE_NAME}_Enable_Traffic_Monitoring=y" echo "CONFIG_PACKAGE_${PACKAGE_NAME}_Enable_Local_Disk_Information_Detection=y" echo "CONFIG_PACKAGE_${PACKAGE_NAME}_Enable_Host_Information_Detection=y" # echo "CONFIG_PACKAGE_wrtbwmon=m" # 在 firewall4 环境下不兼容 echo "CONFIG_PACKAGE_lsblk=m" echo "CONFIG_PACKAGE_smartmontools=m" echo "CONFIG_PACKAGE_smartmontools-drivedb=m" echo "CONFIG_PACKAGE_openssh-client=m" echo "CONFIG_PACKAGE_openssh-keygen=m" echo "CONFIG_PACKAGE_luci-i18n-${translation_pkg}-zh-cn=m" echo "CONFIG_LUCI_LANG_zh_Hans=y" } > .config make defconfig - name: Compile the package working-directory: ${{ env.SDK_DIR }} run: | make package/${PACKAGE_NAME}/compile V=s -j$(($(nproc) + 1)) - name: Find and prepare .apk file id: find_apk working-directory: ${{ env.SDK_DIR }} run: | translation_pkg=${PACKAGE_NAME#luci-app-} rm -rf upload mkdir -p upload find ./bin/packages -type f \( -name "${PACKAGE_NAME}*.apk" -o -name "luci-i18n-${translation_pkg}-*.apk" -o -name "lsblk*.apk" -o -name "smartmontools*.apk" -o -name "openssh-client*.apk" -o -name "openssh-keygen*.apk" \) | while read -r apk; do rel_path=${apk#./} echo "Found apk: $rel_path" cp "$apk" upload/ done if ! find upload -maxdepth 1 -type f -name '*.apk' | grep -q '.'; then echo "::error::No apk files found in ./bin/packages/" echo "Directory tree of ./bin/:" ls -R ./bin/ exit 1 fi echo "path=upload" >> $GITHUB_OUTPUT - name: Upload .apk artifact uses: actions/upload-artifact@v4 with: name: ${{ env.PACKAGE_NAME }}-apk-${{ matrix.target.name }} path: ${{ env.SDK_DIR }}/${{ steps.find_apk.outputs.path }} if-no-files-found: error build-ipk: name: Build IPK (v23.05) runs-on: ubuntu-latest env: OPENWRT_VERSION: 'v23.05.3' strategy: fail-fast: false matrix: target: - name: all path: x86/64 steps: - name: Checkout package repository uses: actions/checkout@v4 - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y build-essential rsync unzip zstd - name: Cache OpenWrt SDK id: cache-sdk uses: actions/cache@v4 with: path: ${{ env.SDK_DIR }} key: ${{ runner.os }}-sdk-ipk-${{ matrix.target.name }}-${{ env.OPENWRT_VERSION }} - name: Download, extract OpenWrt SDK and update feeds if: steps.cache-sdk.outputs.cache-hit != 'true' run: | release_version="${OPENWRT_VERSION#v}" sdk_url_prefix="https://downloads.openwrt.org/releases/${release_version}/targets/${{ matrix.target.path }}" sdk_filename=$(curl -s "$sdk_url_prefix/" | \ grep -o '' | \ sed -e 's/.*//' | \ head -n 1) if [ -z "$sdk_filename" ]; then echo "::error::Could not find SDK file at ${sdk_url_prefix}/" echo "Available files:" curl -s "$sdk_url_prefix/" | grep -o '[^<]*' | sed -e 's/\(.*\)/\1\t\2/' exit 1 fi echo "Downloading SDK: ${sdk_url_prefix}/${sdk_filename}" wget -q "${sdk_url_prefix}/${sdk_filename}" echo "Extracting SDK..." tar -xf "$sdk_filename" mv $(find . -maxdepth 1 -type d -name 'openwrt-sdk-*') ${{ env.SDK_DIR }} echo "Updating feeds..." cd ${{ env.SDK_DIR }} ./scripts/feeds update -a ./scripts/feeds install -a cd .. - name: Prepare build environment working-directory: ${{ env.SDK_DIR }} run: | rm -rf package/${PACKAGE_NAME} src_dir="${{ github.workspace }}" if [ -f "$src_dir/Makefile" ]; then pkg_src="$src_dir" else pkg_src=$(find "$src_dir" -maxdepth 1 -type d -name "${PACKAGE_NAME}" -o -name "luci-app-*${PACKAGE_NAME#luci-app-}*" | head -n 1) if [ -z "$pkg_src" ]; then echo "::error::Could not locate package directory for ${PACKAGE_NAME}" exit 1 fi fi mkdir -p ./package/${PACKAGE_NAME} rsync -a --delete "$pkg_src"/ ./package/${PACKAGE_NAME}/ translation_pkg=${PACKAGE_NAME#luci-app-} mkdir -p ./bin/packages find ./bin/packages -type f -name "${PACKAGE_NAME}*.ipk" -delete find ./bin/packages -type f -name "luci-i18n-${translation_pkg}-*.ipk" -delete { echo "CONFIG_PACKAGE_${PACKAGE_NAME}=m" echo "CONFIG_PACKAGE_luci-i18n-${translation_pkg}-zh-cn=m" echo "CONFIG_LUCI_LANG_zh_Hans=y" } > .config make defconfig - name: Compile the package working-directory: ${{ env.SDK_DIR }} run: | make package/${PACKAGE_NAME}/compile V=s -j$(($(nproc) + 1)) - name: Find and prepare .ipk file id: find_ipk working-directory: ${{ env.SDK_DIR }} run: | translation_pkg=${PACKAGE_NAME#luci-app-} rm -rf upload mkdir -p upload find ./bin/packages -type f \( -name "${PACKAGE_NAME}*.ipk" -o -name "luci-i18n-${translation_pkg}-*.ipk" \) | while read -r ipk; do rel_path=${ipk#./} echo "Found IPK: $rel_path" cp "$ipk" upload/ done if ! find upload -maxdepth 1 -type f -name '*.ipk' | grep -q '.'; then echo "::error::No IPK files found in ./bin/packages/" echo "Directory tree of ./bin/:" ls -R ./bin/ exit 1 fi echo "path=upload" >> $GITHUB_OUTPUT - name: Upload .ipk artifact uses: actions/upload-artifact@v4 with: name: ${{ env.PACKAGE_NAME }}-ipk-${{ matrix.target.name }} path: ${{ env.SDK_DIR }}/${{ steps.find_ipk.outputs.path }} if-no-files-found: error release: name: Publish Release runs-on: ubuntu-latest needs: [build-apk, build-ipk] if: startsWith(github.ref, 'refs/tags/') steps: - name: Download build artifacts uses: actions/download-artifact@v4 with: path: release-assets - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: tag_name: ${{ github.ref_name }} name: ${{ github.ref_name }} generate_release_notes: true files: release-assets/**/*