diff --git a/.github/build_openwrt_apk.sh b/.github/build_openwrt_apk.sh new file mode 100755 index 000000000..49e1c1316 --- /dev/null +++ b/.github/build_openwrt_apk.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +set -e -o pipefail + +ARCHITECTURE="$1" +VERSION="$2" +BINARY_PATH="$3" +OUTPUT_PATH="$4" + +if [ -z "$ARCHITECTURE" ] || [ -z "$VERSION" ] || [ -z "$BINARY_PATH" ] || [ -z "$OUTPUT_PATH" ]; then + echo "Usage: $0 " + exit 1 +fi + +PROJECT=$(cd "$(dirname "$0")/.."; pwd) + +# Convert version to APK format: +# 1.13.0-beta.8 -> 1.13.0_beta8-r0 +# 1.13.0-rc.3 -> 1.13.0_rc3-r0 +# 1.13.0 -> 1.13.0-r0 +APK_VERSION=$(echo "$VERSION" | sed -E 's/-([a-z]+)\.([0-9]+)/_\1\2/') +APK_VERSION="${APK_VERSION}-r0" + +ROOT_DIR=$(mktemp -d) +trap 'rm -rf "$ROOT_DIR"' EXIT + +# Binary +install -Dm755 "$BINARY_PATH" "$ROOT_DIR/usr/bin/sing-box" + +# Config files +install -Dm644 "$PROJECT/release/config/config.json" "$ROOT_DIR/etc/sing-box/config.json" +install -Dm644 "$PROJECT/release/config/openwrt.conf" "$ROOT_DIR/etc/config/sing-box" +install -Dm755 "$PROJECT/release/config/openwrt.init" "$ROOT_DIR/etc/init.d/sing-box" +install -Dm644 "$PROJECT/release/config/openwrt.keep" "$ROOT_DIR/lib/upgrade/keep.d/sing-box" + +# Completions +install -Dm644 "$PROJECT/release/completions/sing-box.bash" "$ROOT_DIR/usr/share/bash-completion/completions/sing-box.bash" +install -Dm644 "$PROJECT/release/completions/sing-box.fish" "$ROOT_DIR/usr/share/fish/vendor_completions.d/sing-box.fish" +install -Dm644 "$PROJECT/release/completions/sing-box.zsh" "$ROOT_DIR/usr/share/zsh/site-functions/_sing-box" + +# License +install -Dm644 "$PROJECT/LICENSE" "$ROOT_DIR/usr/share/licenses/sing-box/LICENSE" + +# APK metadata +PACKAGES_DIR="$ROOT_DIR/lib/apk/packages" +mkdir -p "$PACKAGES_DIR" + +# .conffiles +cat > "$PACKAGES_DIR/.conffiles" <<'EOF' +/etc/config/sing-box +/etc/sing-box/config.json +EOF + +# .conffiles_static (sha256 checksums) +while IFS= read -r conffile; do + sha256=$(sha256sum "$ROOT_DIR$conffile" | cut -d' ' -f1) + echo "$conffile $sha256" +done < "$PACKAGES_DIR/.conffiles" > "$PACKAGES_DIR/.conffiles_static" + +# .list (all files, excluding lib/apk/packages/ metadata) +(cd "$ROOT_DIR" && find . -type f -o -type l) \ + | sed 's|^\./|/|' \ + | grep -v '^/lib/apk/packages/' \ + | sort > "$PACKAGES_DIR/.list" + +# Build APK +apk mkpkg \ + --info "name:sing-box" \ + --info "version:${APK_VERSION}" \ + --info "description:The universal proxy platform." \ + --info "arch:${ARCHITECTURE}" \ + --info "license:GPL-3.0-or-later" \ + --info "origin:sing-box" \ + --info "url:https://sing-box.sagernet.org/" \ + --info "maintainer:nekohasekai " \ + --info "depends:ca-bundle kmod-inet-diag kmod-tun firewall4 kmod-nft-queue" \ + --info "provider-priority:100" \ + --script "pre-deinstall:${PROJECT}/release/config/openwrt.prerm" \ + --files "$ROOT_DIR" \ + --output "$OUTPUT_PATH" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2b3f702a8..6ce9a98a7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -396,6 +396,21 @@ jobs: .github/deb2ipk.sh "$architecture" "dist/openwrt.deb" "dist/sing-box_${{ needs.calculate_version.outputs.version }}_openwrt_${architecture}.ipk" done rm "dist/openwrt.deb" + - name: Install apk-tools + if: matrix.openwrt != '' + run: |- + docker run --rm -v /usr/local/bin:/mnt alpine:edge sh -c "apk add --no-cache apk-tools-static && cp /sbin/apk.static /mnt/apk && chmod +x /mnt/apk" + - name: Package OpenWrt APK + if: matrix.openwrt != '' + run: |- + set -xeuo pipefail + for architecture in ${{ matrix.openwrt }}; do + .github/build_openwrt_apk.sh \ + "$architecture" \ + "${{ needs.calculate_version.outputs.version }}" \ + "dist/sing-box" \ + "dist/sing-box_${{ needs.calculate_version.outputs.version }}_openwrt_${architecture}.apk" + done - name: Archive run: | set -xeuo pipefail diff --git a/docs/installation/tools/install.sh b/docs/installation/tools/install.sh index 74166f022..fc5147679 100755 --- a/docs/installation/tools/install.sh +++ b/docs/installation/tools/install.sh @@ -47,6 +47,12 @@ elif command -v rpm >/dev/null 2>&1; then arch=$(uname -m) package_suffix=".rpm" package_install="rpm -i" +elif command -v apk >/dev/null 2>&1 && [ -f /etc/os-release ] && grep -q OPENWRT_ARCH /etc/os-release; then + os="openwrt" + . /etc/os-release + arch="$OPENWRT_ARCH" + package_suffix=".apk" + package_install="apk add --allow-untrusted" elif command -v opkg >/dev/null 2>&1; then os="openwrt" . /etc/os-release