BananaWRT SDK Matrix Builder #25
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
| # | |
| # 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.1' | |
| 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@v4 | |
| 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@v5 | |
| 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 "================================================================" |