From f203c32d5b049e692a0364e8fe5a44c1f088d0c4 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Tue, 2 Jun 2026 18:16:22 +0300 Subject: [PATCH 1/3] ci: consolidate release workflows into a matrix; add arm64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two release workflows (release-arm32.yml and release-mips32.yml) were near-identical 140-line files that differed only in toolchain URL, cross-compile binary names, and asset suffix. Roll them into a single release.yml that builds across a {arm32, mips32, arm64} matrix. Adds arm64 as a new target. No OpenIPC-hosted aarch64 musl toolchain exists yet, so the matrix entry fetches the well-known precompiled aarch64-linux-musl-cross from musl.cc; swap this for an OpenIPC tarball once one is published. S3 dev-build publishing stays gated to arm32 (the historical canonical binary on the legacy URL). Telegram success/failure notifications fire for all three targets so the channel sees per-target build state. Side fixes layered on top of the consolidation: - The release / upload / telegram-success steps are now gated on `steps.build.outcome == 'success'`. The old workflow ran the release/upload steps after a `continue-on-error` build failure, uploading whatever stale artifacts might be lying around and posting a "success" telegram doc with a missing file. - Drop the vestigial widgetii/ct-ng-builds release-fetch step — its output was assigned to REL and only ever echoed. pr-build-check.yml gets the same matrix treatment and now also tests the arm64 target on every PR. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pr-build-check.yml | 48 ++++----- .github/workflows/release-arm32.yml | 140 ------------------------ .github/workflows/release-mips32.yml | 140 ------------------------ .github/workflows/release.yml | 155 +++++++++++++++++++++++++++ 4 files changed, 176 insertions(+), 307 deletions(-) delete mode 100644 .github/workflows/release-arm32.yml delete mode 100644 .github/workflows/release-mips32.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/pr-build-check.yml b/.github/workflows/pr-build-check.yml index 99fd848..5c18718 100644 --- a/.github/workflows/pr-build-check.yml +++ b/.github/workflows/pr-build-check.yml @@ -5,38 +5,32 @@ on: branches: [master] jobs: - build-arm: - name: Build ARM (musl static) + build: + name: Build ${{ matrix.target }} (musl static) runs-on: ubuntu-latest - env: - ARCHIVE: toolchain.hisilicon-hi3516cv100 - PLATFORM: arm-openipc-linux-musleabi_sdk-buildroot - TOOLCHAIN: arm-openipc-linux-musleabi + strategy: + fail-fast: false + matrix: + include: + - target: arm32 + toolchain_url: https://github.com/OpenIPC/firmware/releases/download/toolchain/toolchain.hisilicon-hi3516cv100.tgz + toolchain_dir: arm-openipc-linux-musleabi_sdk-buildroot + cc: arm-openipc-linux-musleabi-gcc + - target: mips32 + toolchain_url: https://github.com/OpenIPC/firmware/releases/download/toolchain/toolchain.ingenic-t31.tgz + toolchain_dir: mipsel-openipc-linux-musl_sdk-buildroot + cc: mipsel-openipc-linux-musl-gcc + - target: arm64 + toolchain_url: https://musl.cc/aarch64-linux-musl-cross.tgz + toolchain_dir: aarch64-linux-musl-cross + cc: aarch64-linux-musl-gcc steps: - uses: actions/checkout@v4 - name: Download toolchain and build run: | - wget -qO- https://github.com/OpenIPC/firmware/releases/download/toolchain/$ARCHIVE.tgz | \ - tar xfz - -C /opt - export PATH=/opt/$PLATFORM/bin:$PATH - cmake -H. -Bbuild -DCMAKE_C_COMPILER=${TOOLCHAIN}-gcc -DCMAKE_BUILD_TYPE=Release - cmake --build build - - build-mips: - name: Build MIPS (musl static) - runs-on: ubuntu-latest - env: - ARCHIVE: toolchain.ingenic-t31 - PLATFORM: mipsel-openipc-linux-musl_sdk-buildroot - TOOLCHAIN: mipsel-openipc-linux-musl - steps: - - uses: actions/checkout@v4 - - name: Download toolchain and build - run: | - wget -qO- https://github.com/OpenIPC/firmware/releases/download/toolchain/$ARCHIVE.tgz | \ - tar xfz - -C /opt - export PATH=/opt/$PLATFORM/bin:$PATH - cmake -H. -Bbuild -DCMAKE_C_COMPILER=${TOOLCHAIN}-gcc -DCMAKE_BUILD_TYPE=Release + wget -qO- ${{ matrix.toolchain_url }} | tar xfz - -C /opt + export PATH=/opt/${{ matrix.toolchain_dir }}/bin:$PATH + cmake -H. -Bbuild -DCMAKE_C_COMPILER=${{ matrix.cc }} -DCMAKE_BUILD_TYPE=Release cmake --build build test-extraction-pipeline: diff --git a/.github/workflows/release-arm32.yml b/.github/workflows/release-arm32.yml deleted file mode 100644 index 36ef533..0000000 --- a/.github/workflows/release-arm32.yml +++ /dev/null @@ -1,140 +0,0 @@ -name: ipctool-arm32 - -on: - push: - branches: - - master - tags: - - 'v*' - workflow_dispatch: - - -jobs: - build-musl-static: - runs-on: ubuntu-latest - - env: - ARCHIVE: toolchain.hisilicon-hi3516cv100 - PLATFORM: arm-openipc-linux-musleabi_sdk-buildroot - TOOLCHAIN: arm-openipc-linux-musleabi - VERSION: 4.2.3 - - steps: - - uses: pozetroninc/github-action-get-latest-release@master - id: ct-ng-release - with: - owner: widgetii - repo: ct-ng-builds - - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Build sources - id: build - run: | - HEAD_TAG=$(git tag --points-at HEAD) - GIT_HASH=$(git rev-parse --short $GITHUB_SHA) - BRANCH_NAME=$(echo $GITHUB_REF | cut -d'/' -f 3) - if [ -z "$HEAD_TAG" ]; then - TAG_NAME="latest" - RELEASE_NAME="Development Build" - PRERELEASE=true - else - TAG_NAME=${{ github.ref }} - RELEASE_NAME="Release ${{ github.ref }}" - PRERELEASE=false - fi - echo "GIT_HASH=$GIT_HASH" >> $GITHUB_ENV - echo "TAG_NAME=$TAG_NAME" >> $GITHUB_ENV - echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV - echo "PRERELEASE=$PRERELEASE" >> $GITHUB_ENV - echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV - - wget -q https://github.com/upx/upx/releases/download/v$VERSION/upx-$VERSION-amd64_linux.tar.xz - tar -xf upx-$VERSION-amd64_linux.tar.xz --strip-components 1 - - REL="${{ steps.ct-ng-release.outputs.release }}" - echo "Got release $REL" - wget -qO- https://github.com/OpenIPC/firmware/releases/download/toolchain/$ARCHIVE.tgz | \ - tar xfz - -C /opt - export PATH=/opt/$PLATFORM/bin:$PATH - sudo apt-get install -y cmake - cmake -H. -Bbuild -DCMAKE_C_COMPILER=${TOOLCHAIN}-gcc -DCMAKE_BUILD_TYPE=Release - cmake --build build - ./upx build/ipcinfo - ./upx build/ipctool - cp build/ipctool ipctool-$GIT_HASH - continue-on-error: true - - - name: Send warning message to telegram channel - env: - TG_TOKEN: ${{ secrets.TELEGRAM_TOKEN_BOT_OPENIPC }} - TG_CHANNEL: ${{ secrets.TELEGRAM_CHANNEL_OPENIPC_DEV }} - if: steps.ct-ng-release.outcome != 'success' || steps.build.outcome != 'success' - run: | - TG_OPTIONS="-s --connect-timeout 5 --max-time 15" - TG_NOTIFY="Warning, ipctool build error..." - TG_HEADER=$(echo -e "\r\n$TG_NOTIFY \r\n\r\nCommit: $GIT_HASH \r\nBranch: $BRANCH_NAME \r\nTag: $TAG_NAME \r\n\r\n\xE2\x9A\xA0 GitHub Actions") - curl $TG_OPTIONS -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot$TG_TOKEN/sendMessage \ - -F chat_id=$TG_CHANNEL -F text="$TG_HEADER" - - - name: Create release - uses: actions/create-release@v1 - continue-on-error: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ env.TAG_NAME }} - release_name: ${{ env.RELEASE_NAME }} - draft: false - prerelease: ${{ env.PRERELEASE }} - - - name: Upload binaries to release - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: "build/ipctool" - asset_name: "ipctool" - tag: ${{ env.TAG_NAME }} - overwrite: true - - - name: Upload ipcinfo to release - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: "build/ipcinfo" - asset_name: "ipcinfo" - tag: ${{ env.TAG_NAME }} - overwrite: true - - - name: Publish file on S3 for HTTP access (to test dev versions) - if: env.HEAD_TAG == '' - uses: tpaschalis/s3-sync-action@master - with: - args: --acl public-read - env: - FILE: ./ipctool-${{ env.GIT_HASH }} - AWS_REGION: 'eu-north-1' - AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - -# - name: Trigger CI tests -# if: env.HEAD_TAG == '' -# uses: peter-evans/repository-dispatch@v1 -# with: -# token: ${{ secrets.REPO_ACCESS_TOKEN }} -# repository: OpenIPC/ipctool -# event-type: ci-tests -# client-payload: '{"sha": "${{ env.GIT_HASH }}"}' - - - name: Send binary file to telegram channel - env: - TG_TOKEN: ${{ secrets.TELEGRAM_TOKEN_BOT_OPENIPC }} - TG_CHANNEL: ${{ secrets.TELEGRAM_CHANNEL_OPENIPC_DEV }} - run: | - TG_OPTIONS="-s --connect-timeout 5 --max-time 15" - TG_HEADER=$(echo -e "\r\nCommit: $GIT_HASH \r\nBranch: $BRANCH_NAME \r\nTag: $TAG_NAME \r\n\r\n\xE2\x9C\x85 GitHub Actions") - curl $TG_OPTIONS -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot$TG_TOKEN/sendDocument \ - -F chat_id=$TG_CHANNEL -F document="@build/ipctool" -F caption="$TG_HEADER" diff --git a/.github/workflows/release-mips32.yml b/.github/workflows/release-mips32.yml deleted file mode 100644 index 81f125f..0000000 --- a/.github/workflows/release-mips32.yml +++ /dev/null @@ -1,140 +0,0 @@ -name: ipctool-mips32 - -on: - push: - branches: - - master - tags: - - 'v*' - workflow_dispatch: - - -jobs: - build-musl-static: - runs-on: ubuntu-latest - - env: - ARCHIVE: toolchain.ingenic-t31 - PLATFORM: mipsel-openipc-linux-musl_sdk-buildroot - TOOLCHAIN: mipsel-openipc-linux-musl - VERSION: 4.2.3 - - steps: - - uses: pozetroninc/github-action-get-latest-release@master - id: ct-ng-release - with: - owner: widgetii - repo: ct-ng-builds - - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Build sources - id: build - run: | - HEAD_TAG=$(git tag --points-at HEAD) - GIT_HASH=$(git rev-parse --short $GITHUB_SHA) - BRANCH_NAME=$(echo $GITHUB_REF | cut -d'/' -f 3) - if [ -z "$HEAD_TAG" ]; then - TAG_NAME="latest" - RELEASE_NAME="Development Build" - PRERELEASE=true - else - TAG_NAME=${{ github.ref }} - RELEASE_NAME="Release ${{ github.ref }}" - PRERELEASE=false - fi - echo "GIT_HASH=$GIT_HASH" >> $GITHUB_ENV - echo "TAG_NAME=$TAG_NAME" >> $GITHUB_ENV - echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV - echo "PRERELEASE=$PRERELEASE" >> $GITHUB_ENV - echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV - - wget -q https://github.com/upx/upx/releases/download/v$VERSION/upx-$VERSION-amd64_linux.tar.xz - tar -xf upx-$VERSION-amd64_linux.tar.xz --strip-components 1 - - REL="${{ steps.ct-ng-release.outputs.release }}" - echo "Got release $REL" - wget -qO- https://github.com/OpenIPC/firmware/releases/download/toolchain/$ARCHIVE.tgz | \ - tar xfz - -C /opt - export PATH=/opt/$PLATFORM/bin:$PATH - sudo apt-get install -y cmake - cmake -H. -Bbuild -DCMAKE_C_COMPILER=${TOOLCHAIN}-gcc -DCMAKE_BUILD_TYPE=Release - cmake --build build - ./upx build/ipcinfo - ./upx build/ipctool - cp build/ipctool ipctool-$GIT_HASH - continue-on-error: true - - - name: Send warning message to telegram channel - env: - TG_TOKEN: ${{ secrets.TELEGRAM_TOKEN_BOT_OPENIPC }} - TG_CHANNEL: ${{ secrets.TELEGRAM_CHANNEL_OPENIPC_DEV }} - if: steps.ct-ng-release.outcome != 'success' || steps.build.outcome != 'success' - run: | - TG_OPTIONS="-s --connect-timeout 5 --max-time 15" - TG_NOTIFY="Warning, ipctool-mips32 build error..." - TG_HEADER=$(echo -e "\r\n$TG_NOTIFY \r\n\r\nCommit: $GIT_HASH \r\nBranch: $BRANCH_NAME \r\nTag: $TAG_NAME \r\n\r\n\xE2\x9A\xA0 GitHub Actions") - curl $TG_OPTIONS -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot$TG_TOKEN/sendMessage \ - -F chat_id=$TG_CHANNEL -F text="$TG_HEADER" - - - name: Create release - uses: actions/create-release@v1 - continue-on-error: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ env.TAG_NAME }} - release_name: ${{ env.RELEASE_NAME }} - draft: false - prerelease: ${{ env.PRERELEASE }} - - - name: Upload binaries to release - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: "build/ipctool" - asset_name: "ipctool-mips32" - tag: ${{ env.TAG_NAME }} - overwrite: true - - - name: Upload ipcinfo to release - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: "build/ipcinfo" - asset_name: "ipcinfo-mips32" - tag: ${{ env.TAG_NAME }} - overwrite: true - -# - name: Publish file on S3 for HTTP access (to test dev versions) -# if: env.HEAD_TAG == '' -# uses: tpaschalis/s3-sync-action@master -# with: -# args: --acl public-read -# env: -# FILE: ./ipctool-${{ env.GIT_HASH }} -# AWS_REGION: 'eu-north-1' -# AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} -# AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} -# AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - -# - name: Trigger CI tests -# if: env.HEAD_TAG == '' -# uses: peter-evans/repository-dispatch@v1 -# with: -# token: ${{ secrets.REPO_ACCESS_TOKEN }} -# repository: OpenIPC/ipctool -# event-type: ci-tests -# client-payload: '{"sha": "${{ env.GIT_HASH }}"}' - -# - name: Send binary file to telegram channel -# env: -# TG_TOKEN: ${{ secrets.TELEGRAM_TOKEN_BOT_OPENIPC }} -# TG_CHANNEL: ${{ secrets.TELEGRAM_CHANNEL_OPENIPC_DEV }} -# run: | -# TG_OPTIONS="-s --connect-timeout 5 --max-time 15" -# TG_HEADER=$(echo -e "\r\nCommit: $GIT_HASH \r\nBranch: $BRANCH_NAME \r\nTag: $TAG_NAME \r\n\r\n\xE2\x9C\x85 GitHub Actions") -# curl $TG_OPTIONS -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot$TG_TOKEN/sendDocument \ -# -F chat_id=$TG_CHANNEL -F document="@build/ipctool" -F caption="$TG_HEADER" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..184e801 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,155 @@ +name: ipctool-release + +on: + push: + branches: + - master + tags: + - 'v*' + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + include: + - target: arm32 + # OpenIPC's Hi3516CV100 toolchain — the canonical 32-bit ARM + # musleabi static build used for all V1..V5 HiSilicon and the + # rest of the 32-bit-ARM camera world. + toolchain_url: https://github.com/OpenIPC/firmware/releases/download/toolchain/toolchain.hisilicon-hi3516cv100.tgz + toolchain_dir: arm-openipc-linux-musleabi_sdk-buildroot + cc: arm-openipc-linux-musleabi-gcc + asset_suffix: "" + publish_s3: true + - target: mips32 + toolchain_url: https://github.com/OpenIPC/firmware/releases/download/toolchain/toolchain.ingenic-t31.tgz + toolchain_dir: mipsel-openipc-linux-musl_sdk-buildroot + cc: mipsel-openipc-linux-musl-gcc + asset_suffix: "-mips32" + publish_s3: false + - target: arm64 + # No OpenIPC aarch64 musl toolchain published yet, so use + # musl.cc's well-known precompiled aarch64-linux-musl-cross. + # Switch to an OpenIPC-hosted tarball once one is available. + toolchain_url: https://musl.cc/aarch64-linux-musl-cross.tgz + toolchain_dir: aarch64-linux-musl-cross + cc: aarch64-linux-musl-gcc + asset_suffix: "-arm64" + publish_s3: false + + env: + UPX_VERSION: 4.2.3 + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Compute release vars + run: | + HEAD_TAG=$(git tag --points-at HEAD) + GIT_HASH=$(git rev-parse --short $GITHUB_SHA) + BRANCH_NAME=$(echo $GITHUB_REF | cut -d'/' -f 3) + if [ -z "$HEAD_TAG" ]; then + TAG_NAME="latest" + RELEASE_NAME="Development Build" + PRERELEASE=true + else + TAG_NAME=${GITHUB_REF} + RELEASE_NAME="Release ${GITHUB_REF}" + PRERELEASE=false + fi + echo "HEAD_TAG=$HEAD_TAG" >> $GITHUB_ENV + echo "GIT_HASH=$GIT_HASH" >> $GITHUB_ENV + echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV + echo "TAG_NAME=$TAG_NAME" >> $GITHUB_ENV + echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV + echo "PRERELEASE=$PRERELEASE" >> $GITHUB_ENV + + - name: Build sources + id: build + run: | + wget -q https://github.com/upx/upx/releases/download/v$UPX_VERSION/upx-$UPX_VERSION-amd64_linux.tar.xz + tar -xf upx-$UPX_VERSION-amd64_linux.tar.xz --strip-components 1 + + wget -qO- ${{ matrix.toolchain_url }} | tar xfz - -C /opt + export PATH=/opt/${{ matrix.toolchain_dir }}/bin:$PATH + sudo apt-get install -y cmake + + cmake -H. -Bbuild -DCMAKE_C_COMPILER=${{ matrix.cc }} -DCMAKE_BUILD_TYPE=Release + cmake --build build + ./upx build/ipcinfo + ./upx build/ipctool + cp build/ipctool ipctool-$GIT_HASH + continue-on-error: true + + - name: Send warning to Telegram on build failure + env: + TG_TOKEN: ${{ secrets.TELEGRAM_TOKEN_BOT_OPENIPC }} + TG_CHANNEL: ${{ secrets.TELEGRAM_CHANNEL_OPENIPC_DEV }} + if: steps.build.outcome != 'success' + run: | + TG_OPTIONS="-s --connect-timeout 5 --max-time 15" + TG_NOTIFY="Warning, ipctool-${{ matrix.target }} build error..." + TG_HEADER=$(echo -e "\r\n$TG_NOTIFY \r\n\r\nCommit: $GIT_HASH \r\nBranch: $BRANCH_NAME \r\nTag: $TAG_NAME \r\n\r\n\xE2\x9A\xA0 GitHub Actions") + curl $TG_OPTIONS -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot$TG_TOKEN/sendMessage \ + -F chat_id=$TG_CHANNEL -F text="$TG_HEADER" + + - name: Create release + if: steps.build.outcome == 'success' + uses: actions/create-release@v1 + continue-on-error: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ env.TAG_NAME }} + release_name: ${{ env.RELEASE_NAME }} + draft: false + prerelease: ${{ env.PRERELEASE }} + + - name: Upload ipctool to release + if: steps.build.outcome == 'success' + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: build/ipctool + asset_name: ipctool${{ matrix.asset_suffix }} + tag: ${{ env.TAG_NAME }} + overwrite: true + + - name: Upload ipcinfo to release + if: steps.build.outcome == 'success' + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: build/ipcinfo + asset_name: ipcinfo${{ matrix.asset_suffix }} + tag: ${{ env.TAG_NAME }} + overwrite: true + + - name: Publish dev build on S3 + if: matrix.publish_s3 && steps.build.outcome == 'success' && env.HEAD_TAG == '' + uses: tpaschalis/s3-sync-action@master + with: + args: --acl public-read + env: + FILE: ./ipctool-${{ env.GIT_HASH }} + AWS_REGION: 'eu-north-1' + AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + - name: Send binary to Telegram + if: steps.build.outcome == 'success' + env: + TG_TOKEN: ${{ secrets.TELEGRAM_TOKEN_BOT_OPENIPC }} + TG_CHANNEL: ${{ secrets.TELEGRAM_CHANNEL_OPENIPC_DEV }} + run: | + TG_OPTIONS="-s --connect-timeout 5 --max-time 15" + TG_HEADER=$(echo -e "\r\nTarget: ${{ matrix.target }} \r\nCommit: $GIT_HASH \r\nBranch: $BRANCH_NAME \r\nTag: $TAG_NAME \r\n\r\n\xE2\x9C\x85 GitHub Actions") + curl $TG_OPTIONS -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot$TG_TOKEN/sendDocument \ + -F chat_id=$TG_CHANNEL -F document="@build/ipctool" -F caption="$TG_HEADER" From 6ce3e1462bd22ec22fd250d01dca227902cfd978 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Tue, 2 Jun 2026 18:20:57 +0300 Subject: [PATCH 2/3] ci: retry + fallback URL for the arm64 musl.cc toolchain fetch The first PR run of the matrix workflow hit a truncated download from musl.cc: gzip: stdin: unexpected end of file tar: Child returned status 1 The 100 MB aarch64-linux-musl-cross tarball is large enough that any CDN-edge hiccup truncates the wget|tar pipe. Two fixes: 1. Download to a file first (with --tries=3 --timeout=60) instead of piping straight into tar. wget's retry only resumes discrete-file downloads, not in-flight pipes. 2. Add a fallback URL on the more.musl.cc mirror so a stuck musl.cc edge node doesn't fail the whole release. Applied to both release.yml and pr-build-check.yml so PR runs exercise the same fetch path the release uses. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pr-build-check.yml | 26 ++++++++++++++++++++++++-- .github/workflows/release.yml | 24 +++++++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr-build-check.yml b/.github/workflows/pr-build-check.yml index 5c18718..8323598 100644 --- a/.github/workflows/pr-build-check.yml +++ b/.github/workflows/pr-build-check.yml @@ -21,14 +21,36 @@ jobs: toolchain_dir: mipsel-openipc-linux-musl_sdk-buildroot cc: mipsel-openipc-linux-musl-gcc - target: arm64 + # musl.cc occasionally truncates large downloads; the + # more.musl.cc mirror serves the same 100 MB tarball + # from a different CDN edge. toolchain_url: https://musl.cc/aarch64-linux-musl-cross.tgz + toolchain_url_fallback: https://more.musl.cc/x86_64-linux-musl/aarch64-linux-musl-cross.tgz toolchain_dir: aarch64-linux-musl-cross cc: aarch64-linux-musl-gcc steps: - uses: actions/checkout@v4 - - name: Download toolchain and build + - name: Fetch toolchain + run: | + # Download to file (with retries) before extracting — piping + # wget -> tar makes transient stream truncations look like + # corrupt archives; the wget retry only helps with discrete + # files. + for url in ${{ matrix.toolchain_url }} ${{ matrix.toolchain_url_fallback }}; do + [ -z "$url" ] && continue + echo "::group::Downloading $url" + if wget --tries=3 --timeout=60 -O /tmp/toolchain.tgz "$url"; then + echo "::endgroup::" + break + fi + echo "::endgroup::" + rm -f /tmp/toolchain.tgz + done + test -s /tmp/toolchain.tgz + tar xfz /tmp/toolchain.tgz -C /opt + rm /tmp/toolchain.tgz + - name: Build run: | - wget -qO- ${{ matrix.toolchain_url }} | tar xfz - -C /opt export PATH=/opt/${{ matrix.toolchain_dir }}/bin:$PATH cmake -H. -Bbuild -DCMAKE_C_COMPILER=${{ matrix.cc }} -DCMAKE_BUILD_TYPE=Release cmake --build build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 184e801..cf73c94 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -35,7 +35,10 @@ jobs: # No OpenIPC aarch64 musl toolchain published yet, so use # musl.cc's well-known precompiled aarch64-linux-musl-cross. # Switch to an OpenIPC-hosted tarball once one is available. + # The more.musl.cc mirror serves the same tarball from a + # different CDN edge in case musl.cc truncates the download. toolchain_url: https://musl.cc/aarch64-linux-musl-cross.tgz + toolchain_url_fallback: https://more.musl.cc/x86_64-linux-musl/aarch64-linux-musl-cross.tgz toolchain_dir: aarch64-linux-musl-cross cc: aarch64-linux-musl-gcc asset_suffix: "-arm64" @@ -70,13 +73,32 @@ jobs: echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV echo "PRERELEASE=$PRERELEASE" >> $GITHUB_ENV + - name: Fetch toolchain + run: | + # Download to file (with retries) before extracting — piping + # wget -> tar makes transient stream truncations look like + # corrupt archives; the wget retry only helps with discrete + # files. + for url in ${{ matrix.toolchain_url }} ${{ matrix.toolchain_url_fallback }}; do + [ -z "$url" ] && continue + echo "::group::Downloading $url" + if wget --tries=3 --timeout=60 -O /tmp/toolchain.tgz "$url"; then + echo "::endgroup::" + break + fi + echo "::endgroup::" + rm -f /tmp/toolchain.tgz + done + test -s /tmp/toolchain.tgz + tar xfz /tmp/toolchain.tgz -C /opt + rm /tmp/toolchain.tgz + - name: Build sources id: build run: | wget -q https://github.com/upx/upx/releases/download/v$UPX_VERSION/upx-$UPX_VERSION-amd64_linux.tar.xz tar -xf upx-$UPX_VERSION-amd64_linux.tar.xz --strip-components 1 - wget -qO- ${{ matrix.toolchain_url }} | tar xfz - -C /opt export PATH=/opt/${{ matrix.toolchain_dir }}/bin:$PATH sudo apt-get install -y cmake From 60969a31fc6003047ce57271dc57935fa8dce015 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Tue, 2 Jun 2026 18:25:16 +0300 Subject: [PATCH 3/3] ci: switch arm64 toolchain to Bootlin's prebuilt aarch64-musl GitHub Actions runners (Azure) can't reach musl.cc at all ("Connection timed out" against 216.82.192.11 from us-east). The more.musl.cc fallback resolves to the same backend so it's no help. Move the arm64 entry to Bootlin's well-maintained aarch64 musl cross toolchain (https://toolchains.bootlin.com), which is reachable from Azure and ships a 73 MB tarball (vs 100 MB on musl.cc). The binary prefix changes to `aarch64-buildroot-linux-musl-gcc`. Side cleanup: collapse the dual-URL fallback loop in the fetch step to a single wget; `tar xf` (no compression flag) autodetects xz/bz2/gz so different targets can ship different archive formats without matrix-specific tar flags. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pr-build-check.yml | 30 +++++++++----------------- .github/workflows/release.yml | 32 +++++++++------------------- 2 files changed, 20 insertions(+), 42 deletions(-) diff --git a/.github/workflows/pr-build-check.yml b/.github/workflows/pr-build-check.yml index 8323598..795e5f9 100644 --- a/.github/workflows/pr-build-check.yml +++ b/.github/workflows/pr-build-check.yml @@ -21,13 +21,11 @@ jobs: toolchain_dir: mipsel-openipc-linux-musl_sdk-buildroot cc: mipsel-openipc-linux-musl-gcc - target: arm64 - # musl.cc occasionally truncates large downloads; the - # more.musl.cc mirror serves the same 100 MB tarball - # from a different CDN edge. - toolchain_url: https://musl.cc/aarch64-linux-musl-cross.tgz - toolchain_url_fallback: https://more.musl.cc/x86_64-linux-musl/aarch64-linux-musl-cross.tgz - toolchain_dir: aarch64-linux-musl-cross - cc: aarch64-linux-musl-gcc + # Bootlin's prebuilt aarch64 musl cross toolchain. Switch + # to an OpenIPC-hosted tarball once one is published. + toolchain_url: https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--musl--stable-2025.08-1.tar.xz + toolchain_dir: aarch64--musl--stable-2025.08-1 + cc: aarch64-buildroot-linux-musl-gcc steps: - uses: actions/checkout@v4 - name: Fetch toolchain @@ -36,19 +34,11 @@ jobs: # wget -> tar makes transient stream truncations look like # corrupt archives; the wget retry only helps with discrete # files. - for url in ${{ matrix.toolchain_url }} ${{ matrix.toolchain_url_fallback }}; do - [ -z "$url" ] && continue - echo "::group::Downloading $url" - if wget --tries=3 --timeout=60 -O /tmp/toolchain.tgz "$url"; then - echo "::endgroup::" - break - fi - echo "::endgroup::" - rm -f /tmp/toolchain.tgz - done - test -s /tmp/toolchain.tgz - tar xfz /tmp/toolchain.tgz -C /opt - rm /tmp/toolchain.tgz + wget --tries=3 --timeout=60 -O /tmp/toolchain.tar "${{ matrix.toolchain_url }}" + # `tar xf` autodetects gzip/bzip2/xz so the matrix entries + # can mix archive formats freely. + tar xf /tmp/toolchain.tar -C /opt + rm /tmp/toolchain.tar - name: Build run: | export PATH=/opt/${{ matrix.toolchain_dir }}/bin:$PATH diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cf73c94..679e294 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,15 +32,11 @@ jobs: asset_suffix: "-mips32" publish_s3: false - target: arm64 - # No OpenIPC aarch64 musl toolchain published yet, so use - # musl.cc's well-known precompiled aarch64-linux-musl-cross. - # Switch to an OpenIPC-hosted tarball once one is available. - # The more.musl.cc mirror serves the same tarball from a - # different CDN edge in case musl.cc truncates the download. - toolchain_url: https://musl.cc/aarch64-linux-musl-cross.tgz - toolchain_url_fallback: https://more.musl.cc/x86_64-linux-musl/aarch64-linux-musl-cross.tgz - toolchain_dir: aarch64-linux-musl-cross - cc: aarch64-linux-musl-gcc + # Bootlin's prebuilt aarch64 musl cross toolchain. Switch + # to an OpenIPC-hosted tarball once one is published. + toolchain_url: https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--musl--stable-2025.08-1.tar.xz + toolchain_dir: aarch64--musl--stable-2025.08-1 + cc: aarch64-buildroot-linux-musl-gcc asset_suffix: "-arm64" publish_s3: false @@ -79,19 +75,11 @@ jobs: # wget -> tar makes transient stream truncations look like # corrupt archives; the wget retry only helps with discrete # files. - for url in ${{ matrix.toolchain_url }} ${{ matrix.toolchain_url_fallback }}; do - [ -z "$url" ] && continue - echo "::group::Downloading $url" - if wget --tries=3 --timeout=60 -O /tmp/toolchain.tgz "$url"; then - echo "::endgroup::" - break - fi - echo "::endgroup::" - rm -f /tmp/toolchain.tgz - done - test -s /tmp/toolchain.tgz - tar xfz /tmp/toolchain.tgz -C /opt - rm /tmp/toolchain.tgz + wget --tries=3 --timeout=60 -O /tmp/toolchain.tar "${{ matrix.toolchain_url }}" + # `tar xf` autodetects gzip/bzip2/xz so the matrix entries + # can mix archive formats freely. + tar xf /tmp/toolchain.tar -C /opt + rm /tmp/toolchain.tar - name: Build sources id: build