Skip to content

BananaWRT SDK Matrix Builder #27

BananaWRT SDK Matrix Builder

BananaWRT SDK Matrix Builder #27

#
# File: .github/workflows/immortalwrt-sdk-matrix-builder.yml
# Description: Build BananaWRT SDK in matrix configuration
#
# Copyright (c) 2024-2025 SuperKali <[email protected]>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
name: BananaWRT SDK Matrix Builder
on:
repository_dispatch:
workflow_dispatch:
inputs:
architecture:
description: 'Select architecture to build for'
required: true
type: choice
options:
- ALL
- X64
- ARM64
default: 'ALL'
versions:
description: 'ImmortalWRT versions (comma-separated)'
required: true
default: '24.10.0,24.10.1,24.10.2,24.10.3'
nproc:
description: 'Specify the number of threads to use it on the compiler'
required: false
default: ''
env:
REPO_URL: https://github.com/immortalwrt/immortalwrt
FEEDS_CONF: feeds.conf.default
REPO_SCRIPT: scripts/builder/custom-repository.sh
STOCK_PACKAGES: scripts/builder/remove-stock-packages.sh
CONFIG_FILE: config/stable/.config
UPLOAD_SDK: true
TZ: Europe/Rome
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Set up build matrix
id: set-matrix
run: |
VERSIONS="${{ github.event.inputs.versions }}"
VERSION_ARRAY=$(echo $VERSIONS | tr ',' '\n' | jq -R . | jq -s .)
if [ "${{ github.event.inputs.architecture }}" = "ALL" ]; then
ARCHS='["X64", "ARM64"]'
else
ARCHS='["${{ github.event.inputs.architecture }}"]'
fi
MATRIX="{\"version\":$VERSION_ARRAY,\"arch\":$ARCHS}"
echo "Generated matrix: $MATRIX"
echo "matrix=$(echo "$MATRIX" | jq -c .)" >> "$GITHUB_OUTPUT"
build-sdk:
needs: prepare
runs-on: [self-hosted, "${{ matrix.arch }}"]
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
steps:
- name: Checkout Source Code
uses: actions/checkout@v5
- name: Set Up Build Environment
env:
DEBIAN_FRONTEND: noninteractive
run: |
/bin/bash .github/scripts/setup-env.sh setup
- name: Set timezone on the host
run: sudo timedatectl set-timezone "$TZ" || echo "Failed to set timezone, proceeding anyway."
- name: Authenticate GitHub
env:
GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "[email protected]"
echo "machine github.com login ${{ secrets.PERSONAL_ACCESS_TOKEN }}" > ~/.netrc
chmod 600 ~/.netrc
- name: Clone ImmortalWRT Repository
working-directory: ${{ runner.workspace }}
run: |
git clone $REPO_URL -b v"${{ matrix.version }}" immortalwrt
echo "REPO_BRANCH=${{ matrix.version }}" >> $GITHUB_ENV
- name: Apply Custom Feeds Configuration
run: |
[ -e ${{ env.FEEDS_CONF }} ] && mv ${{ env.FEEDS_CONF }} ${{ runner.workspace }}/immortalwrt/feeds.conf.default
chmod +x ${{ env.REPO_SCRIPT }}
cd ${{ runner.workspace }}/immortalwrt
$GITHUB_WORKSPACE/${{ env.REPO_SCRIPT }}
- name: Update and Install Package Feeds
working-directory: ${{ runner.workspace }}/immortalwrt
run: |
./scripts/feeds update -a
./scripts/feeds install -a
- name: Apply Custom Configuration
run: |
[ -e files ] && mv files ${{ runner.workspace }}/immortalwrt/files
[ -e ${{ env.CONFIG_FILE }} ] && mv ${{ env.CONFIG_FILE }} ${{ runner.workspace }}/immortalwrt/.config
chmod +x ${{ env.STOCK_PACKAGES }}
cd ${{ runner.workspace }}/immortalwrt
$GITHUB_WORKSPACE/${{ env.STOCK_PACKAGES }}
./scripts/feeds install -p additional_pack -a
- name: Diffconfig with current configuration
working-directory: ${{ runner.workspace }}/immortalwrt
run: |
./scripts/diffconfig.sh > diffconfig
curl https://downloads.immortalwrt.org/releases/${{ matrix.version }}/targets/mediatek/filogic/config.buildinfo
cat diffconfig >> config.buildinfo
mv config.buildinfo .config
[ -n "$REPO_BRANCH" ] && sed -i \
-e 's|^CONFIG_VERSION_REPO=.*|CONFIG_VERSION_REPO="https://downloads.immortalwrt.org/releases/'"${{ matrix.version }}"'"|g' \
.config
- name: Download Required Packages
working-directory: ${{ runner.workspace }}/immortalwrt
run: |
make defconfig
[ -n "${{ github.event.inputs.nproc }}" ] && make download -j${{ github.event.inputs.nproc }} || make download -j$(nproc)
find dl -size -1024c -exec ls -l {} \;
find dl -size -1024c -exec rm -f {} \;
- name: Build SDK
working-directory: ${{ runner.workspace }}/immortalwrt
run: |
( [ -n "${{ github.event.inputs.nproc }}" ] && make -j${{ github.event.inputs.nproc }} || make -j$(nproc) ) || make -j1 V=s
echo "FILE_DATE=$(date +'%Y%m%d%H%M')" >> $GITHUB_ENV
- name: Prepare SDK Files for Upload
run: |
SDK_PATH=$(find ${{ runner.workspace }}/immortalwrt/bin/targets -name "*sdk*" -type f | grep -v sha256sum | head -n 1)
CONFIG_PATH=$(find ${{ runner.workspace }}/immortalwrt/bin/targets -name "config.buildinfo" | head -n 1)
if [ -z "$SDK_PATH" ]; then
echo "SDK not found"
exit 1
fi
SDK_FILENAME=$(basename "$SDK_PATH")
SDK_SHA256=$(sha256sum "$SDK_PATH" | cut -d' ' -f1)
SDK_SIZE=$(stat -c%s "$SDK_PATH")
TARGET=$(echo "$SDK_FILENAME" | sed -n 's/immortalwrt-sdk-.*-\(.*\)_gcc.*/\1/p')
mkdir -p ${{ runner.workspace }}/sdk-artifacts/bananawrt/sdk/${{ matrix.arch }}/${{ matrix.version }}
cp "$SDK_PATH" ${{ runner.workspace }}/sdk-artifacts/bananawrt/sdk/${{ matrix.arch }}/${{ matrix.version }}/
cp "$CONFIG_PATH" ${{ runner.workspace }}/sdk-artifacts/bananawrt/sdk/${{ matrix.arch }}/${{ matrix.version }}/ || true
cat > ${{ runner.workspace }}/sdk-artifacts/bananawrt/sdk/${{ matrix.arch }}/${{ matrix.version }}/sdk-info.json << EOF
{
"version": "${{ matrix.version }}",
"architecture": "${{ matrix.arch }}",
"target": "$TARGET",
"filename": "$SDK_FILENAME",
"buildDate": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
"sha256": "$SDK_SHA256",
"size": $SDK_SIZE,
"download_url": "https://repo.superkali.me/bananawrt/sdk/${{ matrix.arch }}/${{ matrix.version }}/$SDK_FILENAME"
}
EOF
- name: Upload SDK Artifacts
uses: actions/upload-artifact@v5
with:
name: sdk-${{ matrix.arch }}-${{ matrix.version }}
path: ${{ runner.workspace }}/sdk-artifacts
retention-days: 1
- name: Cleanup Workspace
if: always()
run: |
sudo rm -rf ~/.netrc
if [ -d "${{ runner.workspace }}/immortalwrt" ]; then
sudo rm -rf "${{ runner.workspace }}/immortalwrt"
fi
if [ -d "${{ runner.workspace }}/sdk-artifacts" ]; then
sudo rm -rf "${{ runner.workspace }}/sdk-artifacts"
fi
upload-to-ftp:
needs: [prepare, build-sdk]
runs-on: ubuntu-latest
steps:
- name: Install lftp
run: |
sudo apt update && sudo apt install -y lftp
- name: Download All Artifacts
uses: actions/download-artifact@v6
with:
path: all-artifacts
- name: Download Existing Master Index
run: |
mkdir -p ftp-upload/bananawrt/sdk
curl -f -o ftp-upload/bananawrt/sdk/sdk-master-index.json \
https://repo.superkali.me/bananawrt/sdk/sdk-master-index.json || \
echo '{"versions":{}}' > ftp-upload/bananawrt/sdk/sdk-master-index.json
- name: Copy New Artifacts and Update Index
run: |
for artifact_dir in all-artifacts/sdk-*; do
if [ -d "$artifact_dir" ]; then
cp -rf "$artifact_dir"/* ftp-upload/
fi
done
VERSIONS=$(echo '${{ needs.prepare.outputs.matrix }}' | jq -r '.version[]')
ARCHS=$(echo '${{ needs.prepare.outputs.matrix }}' | jq -r '.arch[]')
BASE_URL="https://repo.superkali.me/bananawrt/sdk"
MASTER_INDEX="ftp-upload/bananawrt/sdk/sdk-master-index.json"
for VERSION in $VERSIONS; do
jq --arg version "$VERSION" \
'.versions[$version] //= {"architectures": {}}' \
"$MASTER_INDEX" > temp.json && mv temp.json "$MASTER_INDEX"
for ARCH in $ARCHS; do
jq --arg version "$VERSION" \
--arg arch "$ARCH" \
--arg base_url "$BASE_URL" \
'.versions[$version].architectures[$arch] = {
"sdk_url": ($base_url + "/" + $arch + "/" + $version + "/"),
"config_url": ($base_url + "/" + $arch + "/" + $version + "/config.buildinfo"),
"info_url": ($base_url + "/" + $arch + "/" + $version + "/sdk-info.json")
}' "$MASTER_INDEX" > temp.json && mv temp.json "$MASTER_INDEX"
done
done
- name: Upload All Files to FTP
run: |
echo "================================================================"
echo "🚀 Starting FTP upload to repo.superkali.me"
echo "================================================================"
echo "📁 Files to upload:"
find ftp-upload -type f | while read file; do
size=$(stat -c%s "$file")
echo " $(basename "$file") ($(numfmt --to=iec $size))"
done
echo ""
echo "🔄 Connecting to FTP server..."
lftp -c "
set ftp:ssl-allow no;
set net:timeout 30;
set net:max-retries 3;
set net:reconnect-interval-base 5;
set cmd:fail-exit true;
open -u ${{ secrets.FTP_USERNAME }},${{ secrets.FTP_PASSWORD }} ${{ secrets.FTP_HOST }};
echo '📡 Connected successfully';
echo '🔄 Starting incremental sync...';
mirror --reverse --verbose --only-newer --parallel=2 ftp-upload/bananawrt/sdk /bananawrt/sdk;
echo '✅ Upload completed successfully';
quit
" 2>&1 | while IFS= read -r line; do
case "$line" in
*"Making directory"*) echo "📁 $line" ;;
*"Transferring file"*) echo "📤 $line" ;;
*"bytes transferred"*) echo "📊 $line" ;;
*"mirror:"*) echo "🔄 $line" ;;
*"Total:"*) echo "📈 $line" ;;
*"Connected"*) echo "✅ $line" ;;
*"Upload completed"*) echo "🎉 $line" ;;
*"Error"*|*"error"*) echo "❌ $line" ;;
*) echo "$line" ;;
esac
done
# Clear history again after execution
history -c 2>/dev/null || true
echo ""
echo "================================================================"
echo "🎉 FTP upload completed!"
echo "📍 Repository URL: https://repo.superkali.me/bananawrt/sdk/"
echo "================================================================"