From 2048220524b48b7198a0525ab8409cc8f9cd7441 Mon Sep 17 00:00:00 2001 From: HudsonGraeme Date: Mon, 16 Mar 2026 02:24:51 +0000 Subject: [PATCH 1/6] Build both ipk and apk packages for OpenWrt 24.10+ compatibility OpenWrt 24.10+ defaults to APK as the package manager on many targets. Users on these builds get "v2 package format error" when installing .ipk files with `apk add`. This builds both formats per architecture so both opkg and apk users are supported. --- .github/workflows/build-release.yml | 44 +++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index a74de55..5ba3ca8 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -89,37 +89,63 @@ jobs: ./scripts/feeds update -a ./scripts/feeds install -a - - name: Configure SDK + - name: Configure SDK (ipk) working-directory: ${{ matrix.sdk_name }} run: | make defconfig - - name: Build package + - name: Build ipk package working-directory: ${{ matrix.sdk_name }} run: | make package/moci/compile V=s - - name: Find package - id: find_package + - name: Find ipk package + id: find_ipk working-directory: ${{ matrix.sdk_name }} run: | IPK_FILE=$(find bin/packages -name "moci_*.ipk" | head -n 1) if [ -z "$IPK_FILE" ]; then - echo "Error: Package not found!" + echo "Error: ipk package not found!" exit 1 fi - echo "package_path=$IPK_FILE" >> $GITHUB_OUTPUT VERSION=${GITHUB_REF#refs/tags/} ARCH_SUFFIX="${{ matrix.arch }}" NEW_NAME="moci_${VERSION}-r1_${ARCH_SUFFIX}.ipk" + mv "$IPK_FILE" "/tmp/$NEW_NAME" echo "package_name=$NEW_NAME" >> $GITHUB_OUTPUT - - name: Rename package + - name: Configure SDK (apk) working-directory: ${{ matrix.sdk_name }} run: | - mv ${{ steps.find_package.outputs.package_path }} /tmp/${{ steps.find_package.outputs.package_name }} + echo "CONFIG_USE_APK=y" >> .config + make defconfig + + - name: Build apk package + working-directory: ${{ matrix.sdk_name }} + run: | + make package/moci/clean V=s + make package/moci/compile V=s + + - name: Find apk package + id: find_apk + working-directory: ${{ matrix.sdk_name }} + run: | + APK_FILE=$(find bin/packages -name "moci*.apk" | head -n 1) + if [ -z "$APK_FILE" ]; then + echo "Warning: apk package not found, skipping" + echo "found=false" >> $GITHUB_OUTPUT + exit 0 + fi + VERSION=${GITHUB_REF#refs/tags/} + ARCH_SUFFIX="${{ matrix.arch }}" + NEW_NAME="moci_${VERSION}-r1_${ARCH_SUFFIX}.apk" + mv "$APK_FILE" "/tmp/$NEW_NAME" + echo "package_name=$NEW_NAME" >> $GITHUB_OUTPUT + echo "found=true" >> $GITHUB_OUTPUT - name: Upload to release uses: softprops/action-gh-release@v2 with: - files: /tmp/${{ steps.find_package.outputs.package_name }} + files: | + /tmp/${{ steps.find_ipk.outputs.package_name }} + /tmp/${{ steps.find_apk.outputs.package_name }} From 86e4fba741efec70e7f65c7daf294ddd4880073f Mon Sep 17 00:00:00 2001 From: HudsonGraeme Date: Mon, 16 Mar 2026 02:33:04 +0000 Subject: [PATCH 2/6] Add run-build label trigger for PR build testing Allows triggering the full build matrix on PRs by adding a "run-build" label. Builds also re-trigger on push if the label is present. PR builds upload artifacts instead of attaching to a release. --- .github/workflows/build-release.yml | 31 ++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 5ba3ca8..c82bf47 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -3,6 +3,8 @@ name: Build Release Packages on: release: types: [published] + pull_request: + types: [labeled, synchronize] permissions: contents: write @@ -10,6 +12,7 @@ permissions: jobs: build: name: Build ${{ matrix.target }} + if: github.event_name == 'release' || github.event.label.name == 'run-build' || (github.event_name == 'pull_request' && github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'run-build')) runs-on: ubuntu-latest strategy: matrix: @@ -76,7 +79,11 @@ jobs: - name: Copy package files run: | - VERSION=${GITHUB_REF#refs/tags/} + if [ "${{ github.event_name }}" = "release" ]; then + VERSION=${GITHUB_REF#refs/tags/} + else + VERSION="0.0.0-pr${{ github.event.pull_request.number }}" + fi mkdir -p ${{ matrix.sdk_name }}/package/moci sed "s/PKG_VERSION:=.*/PKG_VERSION:=$VERSION/" Makefile > ${{ matrix.sdk_name }}/package/moci/Makefile cp -r dist ${{ matrix.sdk_name }}/package/moci/ @@ -108,7 +115,11 @@ jobs: echo "Error: ipk package not found!" exit 1 fi - VERSION=${GITHUB_REF#refs/tags/} + if [ "${{ github.event_name }}" = "release" ]; then + VERSION=${GITHUB_REF#refs/tags/} + else + VERSION="0.0.0-pr${{ github.event.pull_request.number }}" + fi ARCH_SUFFIX="${{ matrix.arch }}" NEW_NAME="moci_${VERSION}-r1_${ARCH_SUFFIX}.ipk" mv "$IPK_FILE" "/tmp/$NEW_NAME" @@ -136,7 +147,11 @@ jobs: echo "found=false" >> $GITHUB_OUTPUT exit 0 fi - VERSION=${GITHUB_REF#refs/tags/} + if [ "${{ github.event_name }}" = "release" ]; then + VERSION=${GITHUB_REF#refs/tags/} + else + VERSION="0.0.0-pr${{ github.event.pull_request.number }}" + fi ARCH_SUFFIX="${{ matrix.arch }}" NEW_NAME="moci_${VERSION}-r1_${ARCH_SUFFIX}.apk" mv "$APK_FILE" "/tmp/$NEW_NAME" @@ -144,8 +159,18 @@ jobs: echo "found=true" >> $GITHUB_OUTPUT - name: Upload to release + if: github.event_name == 'release' uses: softprops/action-gh-release@v2 with: files: | /tmp/${{ steps.find_ipk.outputs.package_name }} /tmp/${{ steps.find_apk.outputs.package_name }} + + - name: Upload build artifacts + if: github.event_name != 'release' + uses: actions/upload-artifact@v4 + with: + name: moci-${{ matrix.arch }} + path: | + /tmp/${{ steps.find_ipk.outputs.package_name }} + /tmp/${{ steps.find_apk.outputs.package_name }} From 1090205ba42ac7dd5117d0500e7b5c426deb841a Mon Sep 17 00:00:00 2001 From: HudsonGraeme Date: Mon, 16 Mar 2026 02:36:01 +0000 Subject: [PATCH 3/6] Split upload steps to handle missing apk gracefully When the APK build is not found, the package_name output is empty, causing the upload path to resolve to /tmp/ which fails. Split uploads into conditional steps gated on find_apk.outputs.found. --- .github/workflows/build-release.yml | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index c82bf47..63e1af6 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -158,19 +158,28 @@ jobs: echo "package_name=$NEW_NAME" >> $GITHUB_OUTPUT echo "found=true" >> $GITHUB_OUTPUT - - name: Upload to release + - name: Upload ipk to release if: github.event_name == 'release' uses: softprops/action-gh-release@v2 with: - files: | - /tmp/${{ steps.find_ipk.outputs.package_name }} - /tmp/${{ steps.find_apk.outputs.package_name }} + files: /tmp/${{ steps.find_ipk.outputs.package_name }} - - name: Upload build artifacts + - name: Upload apk to release + if: github.event_name == 'release' && steps.find_apk.outputs.found == 'true' + uses: softprops/action-gh-release@v2 + with: + files: /tmp/${{ steps.find_apk.outputs.package_name }} + + - name: Upload ipk artifact if: github.event_name != 'release' uses: actions/upload-artifact@v4 with: - name: moci-${{ matrix.arch }} - path: | - /tmp/${{ steps.find_ipk.outputs.package_name }} - /tmp/${{ steps.find_apk.outputs.package_name }} + name: moci-ipk-${{ matrix.arch }} + path: /tmp/${{ steps.find_ipk.outputs.package_name }} + + - name: Upload apk artifact + if: github.event_name != 'release' && steps.find_apk.outputs.found == 'true' + uses: actions/upload-artifact@v4 + with: + name: moci-apk-${{ matrix.arch }} + path: /tmp/${{ steps.find_apk.outputs.package_name }} From 43d26169749c3ea5adcd6f7cdf687952433133fd Mon Sep 17 00:00:00 2001 From: HudsonGraeme Date: Mon, 16 Mar 2026 02:59:04 +0000 Subject: [PATCH 4/6] Use 25.12.0 SDK for apk builds, 24.10.5 SDK for ipk builds CONFIG_USE_APK is marked BROKEN in the 24.10 SDK and the apk host binary is absent, so it cannot produce apk packages. Split into two parallel job matrices: 24.10.5 SDK produces ipk for opkg devices, 25.12.0 SDK (which ships apk as default) produces apk for devices running apk. --- .github/workflows/build-release.yml | 148 +++++++++++++++++++--------- 1 file changed, 102 insertions(+), 46 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 63e1af6..b96ef8c 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -10,8 +10,8 @@ permissions: contents: write jobs: - build: - name: Build ${{ matrix.target }} + build-ipk: + name: Build ipk ${{ matrix.arch }} if: github.event_name == 'release' || github.event.label.name == 'run-build' || (github.event_name == 'pull_request' && github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'run-build')) runs-on: ubuntu-latest strategy: @@ -62,20 +62,12 @@ jobs: - name: Build minified assets run: pnpm run build - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y zstd - - - name: Download SDK + - name: Download and extract SDK run: | SDK_URL="https://downloads.openwrt.org/releases/24.10.5/targets/${{ matrix.target }}/${{ matrix.sdk_name }}.tar.zst" - echo "Downloading SDK from: $SDK_URL" curl -L -o sdk.tar.zst "$SDK_URL" - - - name: Extract SDK - run: | tar --use-compress-program=unzstd -xf sdk.tar.zst + rm sdk.tar.zst - name: Copy package files run: | @@ -96,17 +88,13 @@ jobs: ./scripts/feeds update -a ./scripts/feeds install -a - - name: Configure SDK (ipk) - working-directory: ${{ matrix.sdk_name }} - run: | - make defconfig - - name: Build ipk package working-directory: ${{ matrix.sdk_name }} run: | + make defconfig make package/moci/compile V=s - - name: Find ipk package + - name: Find and rename ipk id: find_ipk working-directory: ${{ matrix.sdk_name }} run: | @@ -120,66 +108,134 @@ jobs: else VERSION="0.0.0-pr${{ github.event.pull_request.number }}" fi - ARCH_SUFFIX="${{ matrix.arch }}" - NEW_NAME="moci_${VERSION}-r1_${ARCH_SUFFIX}.ipk" + NEW_NAME="moci_${VERSION}-r1_${{ matrix.arch }}.ipk" mv "$IPK_FILE" "/tmp/$NEW_NAME" echo "package_name=$NEW_NAME" >> $GITHUB_OUTPUT - - name: Configure SDK (apk) + - name: Upload to release + if: github.event_name == 'release' + uses: softprops/action-gh-release@v2 + with: + files: /tmp/${{ steps.find_ipk.outputs.package_name }} + + - name: Upload artifact + if: github.event_name != 'release' + uses: actions/upload-artifact@v4 + with: + name: moci-ipk-${{ matrix.arch }} + path: /tmp/${{ steps.find_ipk.outputs.package_name }} + + build-apk: + name: Build apk ${{ matrix.arch }} + if: github.event_name == 'release' || github.event.label.name == 'run-build' || (github.event_name == 'pull_request' && github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'run-build')) + runs-on: ubuntu-latest + strategy: + matrix: + include: + - target: x86/64 + arch: x86_64 + sdk_name: openwrt-sdk-25.12.0-x86-64_gcc-14.3.0_musl.Linux-x86_64 + - target: ramips/mt7621 + arch: mipsel_24kc + sdk_name: openwrt-sdk-25.12.0-ramips-mt7621_gcc-14.3.0_musl.Linux-x86_64 + - target: ath79/generic + arch: mips_24kc + sdk_name: openwrt-sdk-25.12.0-ath79-generic_gcc-14.3.0_musl.Linux-x86_64 + - target: mediatek/filogic + arch: aarch64_cortex-a53 + sdk_name: openwrt-sdk-25.12.0-mediatek-filogic_gcc-14.3.0_musl.Linux-x86_64 + - target: bcm27xx/bcm2711 + arch: aarch64_cortex-a72 + sdk_name: openwrt-sdk-25.12.0-bcm27xx-bcm2711_gcc-14.3.0_musl.Linux-x86_64 + - target: ipq40xx/generic + arch: arm_cortex-a7_neon-vfpv4 + sdk_name: openwrt-sdk-25.12.0-ipq40xx-generic_gcc-14.3.0_musl_eabi.Linux-x86_64 + - target: mvebu/cortexa9 + arch: arm_cortex-a9_vfpv3-d16 + sdk_name: openwrt-sdk-25.12.0-mvebu-cortexa9_gcc-14.3.0_musl_eabi.Linux-x86_64 + - target: ipq806x/generic + arch: arm_cortex-a15_neon-vfpv4 + sdk_name: openwrt-sdk-25.12.0-ipq806x-generic_gcc-14.3.0_musl_eabi.Linux-x86_64 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Install Node dependencies + run: pnpm install --frozen-lockfile + + - name: Build minified assets + run: pnpm run build + + - name: Download and extract SDK + run: | + SDK_URL="https://downloads.openwrt.org/releases/25.12.0/targets/${{ matrix.target }}/${{ matrix.sdk_name }}.tar.zst" + curl -L -o sdk.tar.zst "$SDK_URL" + tar --use-compress-program=unzstd -xf sdk.tar.zst + rm sdk.tar.zst + + - name: Copy package files + run: | + if [ "${{ github.event_name }}" = "release" ]; then + VERSION=${GITHUB_REF#refs/tags/} + else + VERSION="0.0.0-pr${{ github.event.pull_request.number }}" + fi + mkdir -p ${{ matrix.sdk_name }}/package/moci + sed "s/PKG_VERSION:=.*/PKG_VERSION:=$VERSION/" Makefile > ${{ matrix.sdk_name }}/package/moci/Makefile + cp -r dist ${{ matrix.sdk_name }}/package/moci/ + cp rpcd-acl.json ${{ matrix.sdk_name }}/package/moci/ + cp -r files ${{ matrix.sdk_name }}/package/moci/ + + - name: Update feeds working-directory: ${{ matrix.sdk_name }} run: | - echo "CONFIG_USE_APK=y" >> .config - make defconfig + ./scripts/feeds update -a + ./scripts/feeds install -a - name: Build apk package working-directory: ${{ matrix.sdk_name }} run: | - make package/moci/clean V=s + make defconfig make package/moci/compile V=s - - name: Find apk package + - name: Find and rename apk id: find_apk working-directory: ${{ matrix.sdk_name }} run: | APK_FILE=$(find bin/packages -name "moci*.apk" | head -n 1) if [ -z "$APK_FILE" ]; then - echo "Warning: apk package not found, skipping" - echo "found=false" >> $GITHUB_OUTPUT - exit 0 + echo "Error: apk package not found!" + exit 1 fi if [ "${{ github.event_name }}" = "release" ]; then VERSION=${GITHUB_REF#refs/tags/} else VERSION="0.0.0-pr${{ github.event.pull_request.number }}" fi - ARCH_SUFFIX="${{ matrix.arch }}" - NEW_NAME="moci_${VERSION}-r1_${ARCH_SUFFIX}.apk" + NEW_NAME="moci_${VERSION}-r1_${{ matrix.arch }}.apk" mv "$APK_FILE" "/tmp/$NEW_NAME" echo "package_name=$NEW_NAME" >> $GITHUB_OUTPUT - echo "found=true" >> $GITHUB_OUTPUT - - name: Upload ipk to release + - name: Upload to release if: github.event_name == 'release' uses: softprops/action-gh-release@v2 - with: - files: /tmp/${{ steps.find_ipk.outputs.package_name }} - - - name: Upload apk to release - if: github.event_name == 'release' && steps.find_apk.outputs.found == 'true' - uses: softprops/action-gh-release@v2 with: files: /tmp/${{ steps.find_apk.outputs.package_name }} - - name: Upload ipk artifact + - name: Upload artifact if: github.event_name != 'release' uses: actions/upload-artifact@v4 - with: - name: moci-ipk-${{ matrix.arch }} - path: /tmp/${{ steps.find_ipk.outputs.package_name }} - - - name: Upload apk artifact - if: github.event_name != 'release' && steps.find_apk.outputs.found == 'true' - uses: actions/upload-artifact@v4 with: name: moci-apk-${{ matrix.arch }} path: /tmp/${{ steps.find_apk.outputs.package_name }} From b21294fcb95e4c17703623a590fdeb07e2007380 Mon Sep 17 00:00:00 2001 From: HudsonGraeme Date: Mon, 16 Mar 2026 03:20:26 +0000 Subject: [PATCH 5/6] Fix PR version format for APK compatibility APK mkpkg rejects versions with hyphens in the base (0.0.0-pr8). Use dot-separated format (0.0.0.8) which is valid for both ipk and apk. --- .github/workflows/build-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index d08ea92..59bfdb4 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -42,7 +42,7 @@ jobs: if [ "${{ github.event_name }}" = "release" ]; then echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT else - echo "version=0.0.0-pr${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT + echo "version=0.0.0.${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT fi - name: Upload dist From 2562954af37ce2e1c6ea34ce3a6b02d5852523c1 Mon Sep 17 00:00:00 2001 From: HudsonGraeme Date: Mon, 16 Mar 2026 03:41:46 +0000 Subject: [PATCH 6/6] Update README with apk installation instructions Add OpenWrt 25.12+ apk install commands alongside existing opkg instructions. Update architecture list to use actual package suffixes. --- README.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6868cc7..7feb437 100644 --- a/README.md +++ b/README.md @@ -73,14 +73,23 @@ scp -r moci/* root@192.168.1.1:/www/moci/ ### Option 1: Package (Recommended) -Download the ipk for your architecture from [Releases](https://github.com/HudsonGraeme/MoCI/releases/latest): +Download the package for your architecture from [Releases](https://github.com/HudsonGraeme/MoCI/releases/latest). + +**OpenWrt 24.10 and earlier (opkg):** ```bash wget https://github.com/HudsonGraeme/MoCI/releases/latest/download/moci_VERSION_ARCH.ipk opkg install moci_VERSION_ARCH.ipk ``` -Available architectures: x86_64, ramips/mt7621, ath79, mediatek/filogic, bcm27xx, ipq40xx, mvebu, ipq806x +**OpenWrt 25.12+ (apk):** + +```bash +wget https://github.com/HudsonGraeme/MoCI/releases/latest/download/moci_VERSION_ARCH.apk +apk add --allow-untrusted moci_VERSION_ARCH.apk +``` + +Available architectures: x86_64, mipsel_24kc, mips_24kc, aarch64_cortex-a53, aarch64_cortex-a72, arm_cortex-a7_neon-vfpv4, arm_cortex-a9_vfpv3-d16, arm_cortex-a15_neon-vfpv4 Replace `VERSION_ARCH` with your specific file from the releases page. @@ -123,7 +132,7 @@ git clone https://github.com/HudsonGraeme/MoCI.git package/moci make package/moci/compile ``` -The package will be in `bin/packages/*/base/moci_*.ipk` +The package will be in `bin/packages/*/base/moci_*.ipk` (24.10) or `bin/packages/*/base/moci-*.apk` (25.12+) ---