diff --git a/.build/icon-black.png b/.build/icon-black.png new file mode 100644 index 000000000..d1854ba3c Binary files /dev/null and b/.build/icon-black.png differ diff --git a/.build/icon.png b/.build/icon.png new file mode 100644 index 000000000..f9d6f7ded Binary files /dev/null and b/.build/icon.png differ diff --git a/.build/nuitka.cmd b/.build/nuitka.cmd new file mode 100755 index 000000000..bb2f88721 --- /dev/null +++ b/.build/nuitka.cmd @@ -0,0 +1 @@ +nuitka --standalone --onefile --output-dir=./dist --output-filename=ddns --remove-output --include-module=dns.dnspod --include-module=dns.alidns --include-module=dns.dnspod_com --include-module=dns.dnscom --include-module=dns.cloudflare --include-module=dns.he --include-module=dns.huaweidns --include-module=dns.callback --macos-app-name="DDNS" --product-name=DDNS --file-description="DDNS Client 自动更新域名解析到本机IP" --company-name="New Future" --copyright="https://ddns.newfuture.cc" --windows-icon-from-ico="favicon.ico" --linux-icon=".build/icon.png" --macos-app-icon=".build/icon.png" --assume-yes-for-downloads run.py \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0ed2af1dc..78c64846f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -92,7 +92,55 @@ jobs: # Upload build result - uses: actions/upload-artifact@v4 with: - name: ${{ matrix.os }}-py${{ matrix.python-version }} + name: PyInstaller-${{ matrix.os }}-py${{ matrix.python-version }} + path: dist/ + retention-days: 7 + + nuitka: + strategy: + # fail-fast: false + matrix: + os: [windows-latest, windows-11-arm, ubuntu-latest, ubuntu-24.04-arm, macos-13, macos-latest] + runs-on: ${{ matrix.os }} + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.x + uses: actions/setup-python@v5 + with: + python-version: 3.x + - name: Install dependencies + run: pip install nuitka + + # Prepare build version and cert + - name: Replace build version + run: sed -i.tmp -e "s#\${BUILD_VERSION}#${{ github.ref_name }}#" -e "s/\${BUILD_DATE}/$(date --iso-8601=seconds)/" run.py && rm run.py.tmp + shell: bash + + - name: setup on Linux + if: runner.os == 'Linux' + run: | + sudo apt-get update && sudo apt install -y patchelf ccache + cp /etc/ssl/certs/ca-certificates.crt cert.pem && export SSL_CERT_FILE=${PWD}/cert.pem + + - name: setup on macOS + if: runner.os == 'macOS' + run: | + python3 -m pip install imageio + + + - run: python ./run.py -h + + - name: Package binary + run: ./.build/nuitka.cmd + + - run: ./dist/ddns || test -e config.json + - run: ./dist/ddns -h + + # Upload build result + - uses: actions/upload-artifact@v4 + with: + name: ddns-${{ runner.os }}-${{ runner.arch }} path: dist/ retention-days: 7 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 64b2f90a0..98bda1ad9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -77,31 +77,44 @@ jobs: build-binary: strategy: + # fail-fast: false matrix: - os: [macos, ubuntu, windows] - runs-on: ${{ matrix.os }}-latest - timeout-minutes: 8 + os: [windows-latest, windows-11-arm, ubuntu-latest, ubuntu-24.04-arm, macos-13, macos-latest] + runs-on: ${{ matrix.os }} + timeout-minutes: 10 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.x" - name: Install dependencies - run: pip install pyinstaller + run: pip install nuitka - name: Replace build version run: sed -i.tmp -e "s#\${BUILD_VERSION}#${{ github.ref_name }}#" -e "s/\${BUILD_DATE}/$(date --iso-8601=seconds)/" run.py && rm run.py.tmp shell: bash - - name: Copy cert on ubuntu + + - name: setup on Linux if: runner.os == 'Linux' - run: cp /etc/ssl/certs/ca-certificates.crt cert.pem && export SSL_CERT_FILE=${PWD}/cert.pem + run: | + apt-get update && apt install -y patchelf ccache + cp /etc/ssl/certs/ca-certificates.crt cert.pem && export SSL_CERT_FILE=${PWD}/cert.pem + + - name: setup on macOS + if: runner.os == 'macOS' + run: | + python3 -m pip install imageio + + - name: Package binary + run: ./.build/nuitka.cmd - - run: python -O -m PyInstaller --noconfirm --clean .build/ddns.spec - run: ./dist/ddns || test -e config.json - run: ./dist/ddns -h - - run: mv ./dist/ddns ./dist/ddns-osx - if: runner.os == 'macOS' + - name: Move and rename binary with lowercase OS and arch + run: mv ./dist/ddns "./dist/ddns-$(echo ${{ runner.os }}-${{ runner.arch }} | tr '[:upper:]' '[:lower:]')" + shell: bash + - uses: actions/upload-artifact@v4 with: name: ${{ runner.os }} diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 000000000..973a4dfaa Binary files /dev/null and b/favicon.ico differ diff --git a/run.py b/run.py index a87e2fec8..d792ecb49 100755 --- a/run.py +++ b/run.py @@ -5,6 +5,13 @@ @author: New Future @modified: rufengsuixing """ +# nuitka-project-if: {OS} == "Linux": +# nuitka-project: --static-libpython=yes +# nuitka-project-if: os.getenv("BUILD_VERSION") is not None: +# nuitka-project: --product-version=${BUILD_VERSION} +# nuitka-project-else: +# nuitka-project: --product-version=0.0.0 + from __future__ import print_function from time import ctime, asctime from os import path, environ, name as os_name @@ -46,7 +53,7 @@ def get_ip(ip_type, index="default"): debug(f"get_ip({ip_type}, {index})") if index is False: # disabled return False - elif type(index) is list: # 如果获取到的规则是列表,则依次判断列表中每一个规则,直到找到一个可以正确获取到的IP + elif isinstance(index, list): # 如果获取到的规则是列表,则依次判断列表中每一个规则,直到找到一个可以正确获取到的IP for i in index: value = get_ip(ip_type, i) if value: @@ -66,8 +73,7 @@ def get_ip(ip_type, index="default"): value = getattr(ip, index + "_v" + ip_type)() except Exception as e: error(e) - finally: - return value + return value def change_dns_record(dns, proxy_list, **kw):