ci: bump actions/checkout v4 -> v5 (clear Node 20 deprecation) (#176) #9
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: ipctool-release | |
| on: | |
| push: | |
| branches: | |
| - master | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| # Create (or reuse) the GitHub release exactly once, before the build | |
| # matrix fans out. Previously every matrix target ran create-release | |
| # against the same tag, so all but the first failed with | |
| # "Validation Failed: already_exists / tag_name". Hoisting it into a | |
| # single pre-job removes that race; using a gh-CLI upsert (view-or-create) | |
| # also means an existing rolling `latest` dev release is reused silently | |
| # instead of erroring on every subsequent build. | |
| release: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| tag_name: ${{ steps.vars.outputs.tag_name }} | |
| git_hash: ${{ steps.vars.outputs.git_hash }} | |
| branch_name: ${{ steps.vars.outputs.branch_name }} | |
| head_tag: ${{ steps.vars.outputs.head_tag }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Compute release vars | |
| id: 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" | |
| echo "git_hash=$GIT_HASH" | |
| echo "branch_name=$BRANCH_NAME" | |
| echo "tag_name=$TAG_NAME" | |
| echo "release_name=$RELEASE_NAME" | |
| echo "prerelease=$PRERELEASE" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Ensure release exists | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG_NAME: ${{ steps.vars.outputs.tag_name }} | |
| RELEASE_NAME: ${{ steps.vars.outputs.release_name }} | |
| PRERELEASE: ${{ steps.vars.outputs.prerelease }} | |
| GIT_HASH: ${{ steps.vars.outputs.git_hash }} | |
| run: | | |
| if gh release view "$TAG_NAME" >/dev/null 2>&1; then | |
| echo "Release '$TAG_NAME' already exists — reusing it." | |
| else | |
| FLAGS=() | |
| [ "$PRERELEASE" = "true" ] && FLAGS+=(--prerelease) | |
| gh release create "$TAG_NAME" \ | |
| --title "$RELEASE_NAME" \ | |
| --notes "Automated build of $GIT_HASH" \ | |
| --target "$GITHUB_SHA" \ | |
| "${FLAGS[@]}" | |
| fi | |
| build: | |
| needs: release | |
| 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 | |
| # 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 | |
| env: | |
| UPX_VERSION: 4.2.3 | |
| TAG_NAME: ${{ needs.release.outputs.tag_name }} | |
| GIT_HASH: ${{ needs.release.outputs.git_hash }} | |
| BRANCH_NAME: ${{ needs.release.outputs.branch_name }} | |
| HEAD_TAG: ${{ needs.release.outputs.head_tag }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - 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. | |
| 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 | |
| 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 | |
| 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: 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' | |
| # A notification timing out (curl exit 28 against api.telegram.org) | |
| # must never fail a release whose build succeeded and whose assets | |
| # already uploaded — keep it advisory. | |
| continue-on-error: true | |
| 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" |