Compare commits

..

2 Commits

Author SHA1 Message Date
Igor Pecovnik
63fe441107
fix: always publish main component even if utils/desktop are empty
This fixes the case where repositories like debs-beta only have packages
in the main/common component (e.g., sid with only kernel packages).
Previously, the merge command would skip publishing if both utils and
desktop repos were empty, resulting in an incomplete repository.

Now we always publish at minimum the main/common component, ensuring all
distributions with any packages get properly published.
2026-01-11 09:30:49 +01:00
Igor Pecovnik
72ec2b171b
feat: implement parallel repository management workflow
This commit implements a complete parallel repository management system
that allows building and publishing Debian repositories in parallel,
significantly reducing build time for multiple distributions.

- `update-main`: Builds common/main component once for all releases
- `update -R <release>`: Builds release-specific components in isolated DBs
- `merge`: Combines common + release-specific components into final repos

- Isolated databases (aptly-isolated-<release>) avoid locking during parallel builds
- Common component built once, not duplicated per release
- Release-specific components (utils, desktop) built independently
- Final merge combines all components with proper GPG signing

- Fixed GPG signing to target top-level Release files (dists/{release}/Release)
- Pool cleanup before publishing avoids "file already exists" errors
- Smart package import skips duplicates during merge
- Proper handling of empty repositories and missing components
- Improved error handling and logging throughout

1. update-main: Build common component (once)
2. update -R <release>: Parallel workers build release-specific components
3. merge: Combine all components and publish with GPG signatures

This enables GitHub Actions to run multiple release builders in parallel,
reducing total repository build time from hours to minutes.

Signed-off-by: Igor Pecovnik <igor@armbian.com>
2026-01-11 00:19:28 +01:00
2914 changed files with 673497 additions and 236057 deletions

View File

@ -17,7 +17,7 @@ trim_trailing_whitespace = false
[*.md]
indent_style = space
indent_size = 4
trim_trailing_whitespace = false
insert_final_newline = false
[*.json]
indent_style = space
@ -36,6 +36,7 @@ function_next_line = false
[*.{yaml,yml}]
indent_style = space
indent_size = 2
insert_final_newline = false
[*.py]
indent_size = 4

71
.github/CODEOWNERS vendored
View File

@ -25,10 +25,7 @@ config/boards/armsom-forge1.csc @amazingfate
config/boards/armsom-sige1.csc @amazingfate
config/boards/armsom-sige3.csc @amazingfate
config/boards/avaota-a1.csc @chainsx
config/boards/ayn-odin2.csc @FantasyGmm @Squishy123 @kasimling
config/boards/ayn-odin2mini.csc @Squishy123
config/boards/ayn-odin2portal.csc @Squishy123
config/boards/ayn-thor.csc @Squishy123
config/boards/ayn-odin2.csc @FantasyGmm
config/boards/bananapi.conf @DylanHP @janprunk
config/boards/bananapicm4io.conf @pyavitz
config/boards/bananapif3.conf @pyavitz
@ -57,9 +54,7 @@ config/boards/coolpi-cm5.csc @andyshrk
config/boards/coolpi-genbook.csc @andyshrk
config/boards/dusun-dsom-010r.csc @paolosabatino
config/boards/espressobin.conf @igorpecovnik
config/boards/fine3399.csc @Lemon1151
config/boards/firefly-itx-3588j.csc @SeeleVolleri
config/boards/forlinx-ok3506-s12.csc @vidplace7
config/boards/fxblox-rk1.csc @mahdichi
config/boards/gateway-gz80x.conf @pyavitz
config/boards/h96-tvbox-3566.tvb @hqnicolas
@ -114,7 +109,6 @@ config/boards/nanopi-r6s.conf @efectn
config/boards/nanopi-r76s.conf @SuperKali
config/boards/nanopiair.csc @1ubuntuuser
config/boards/nanopiduo.csc @sgjava
config/boards/nanopik1plus.conf @igorpecovnik
config/boards/nanopik2-s905.conf @igorpecovnik
config/boards/nanopim4v2.conf @igorpecovnik
config/boards/nanopineo.csc @spendist
@ -124,25 +118,20 @@ config/boards/nanopineoplus2.csc @teknoid
config/boards/odroidc1.conf @juanlufont
config/boards/odroidc2.conf @teknoid
config/boards/odroidc4.conf @igorpecovnik
config/boards/odroidhc4.conf @igorpecovnik
config/boards/odroidm1.conf @rpardini
config/boards/odroidm2.conf @mlegenovic
config/boards/odroidm2.csc @mlegenovic
config/boards/odroidn2.conf @NicoD-SBC
config/boards/odroidxu4.conf @joekhoobyar
config/boards/olimex-teres-a64.csc @Kreyren
config/boards/onecloud.csc @hzyitc
config/boards/oneplus-kebab.conf @amazingfate
config/boards/orangepi3-lts.conf @pyavitz
config/boards/orangepi4-lts.conf @paolosabatino
config/boards/orangepi4.csc @paolosabatino
config/boards/orangepi5-plus.conf @alexl83
config/boards/orangepi5.conf @efectn
config/boards/orangepione.conf @StephenGraf
config/boards/orangepipc.csc @lbmendes
config/boards/orangepipc2.conf @igorpecovnik
config/boards/orangepipcplus.csc @Janmcha
config/boards/orangepir2s.wip @sven-ola
config/boards/orangepirv2.wip @sven-ola
config/boards/orangepizero2.csc @AGM1968 @krachlatte
config/boards/orangepizero2w.csc @chraac
config/boards/orangepizero3.csc @alexl83 @chraac
@ -166,7 +155,6 @@ config/boards/radxa-e54c.conf @kamilsaigol @schwar3kat
config/boards/radxa-nio-12l.conf @HeyMeco
config/boards/radxa-rock-4d.conf @HeyMeco
config/boards/radxa-zero.conf @engineer-80
config/boards/radxa-zero3.conf @igorpecovnik
config/boards/recore.csc @eliasbakken
config/boards/renegade.conf @Tonymac32
config/boards/retro-lite-cm5.csc @ginkage
@ -187,7 +175,7 @@ config/boards/rockpi-e.conf @paolosabatino
config/boards/rockpi-s.conf @brentr
config/boards/rockpro64.csc @joekhoobyar
config/boards/rpi4b.conf @PanderMusubi @teknoid
config/boards/sakurapi-rk3308b.conf @TheSnowfield
config/boards/sakurapi-rk3308b.csc @TheSnowfield
config/boards/sk-am62-lp.conf @jonaswood01
config/boards/sk-am62-sip.conf @jonaswood01
config/boards/sk-am62b.conf @jonaswood01
@ -211,7 +199,6 @@ config/boards/uefi-x86.conf @rpardini
config/boards/visionfive2.csc @libiunc
config/boards/x96-mate.tvb @Ressetkk
config/boards/x96q.tvb @sicXnull
config/boards/xiaobao-nas.csc @Lemon1151
config/boards/xiaomi-elish.conf @amazingfate
config/boards/xpressreal-t3.csc @wei633
config/boards/youyeetoo-r1-v3.csc @SuperKali
@ -236,10 +223,10 @@ config/kernel/linux-qcs6490-*.config @HeyMeco
config/kernel/linux-rk35xx-*.config @150balbes @CodeChenL @ColorfulRhino @HeyMeco @JackHuang021 @JohnTheCoolingFan @SeeleVolleri @SuperKali @Tonymac32 @ZazaBR @alexl83 @amazingfate @andyshrk @catalinii @chainsx @efectn @fridtjof @ginkage @hoochiwetech @hqnicolas @igorpecovnik @kamilsaigol @krachlatte @lanefu @linhz0hz @mahdichi @mattx433 @prahal @rpardini @schwar3kat @sputnik2019 @vamzii
config/kernel/linux-rockchip-*.config @amazingfate @paolosabatino @vidplace7
config/kernel/linux-rockchip-rv1106-*.config @vidplace7
config/kernel/linux-rockchip64-*.config @150balbes @ColorfulRhino @HeyMeco @JohnTheCoolingFan @Lemon1151 @SuperKali @TheSnowfield @Tonymac32 @ZazaBR @ahoneybun @alexl83 @amazingfate @andyshrk @brentr @catalinii @chainsx @efectn @fridtjof @hqnicolas @igorpecovnik @joekhoobyar @krachlatte @lanefu @linhz0hz @mlegenovic @paolosabatino @prahal @pyavitz @rbqvq @redrathnure @retro98boy @rpardini @schwar3kat @sicXnull @tdleiyao @torte71 @utlark @vamzii
config/kernel/linux-rockchip64-*.config @150balbes @ColorfulRhino @HeyMeco @JohnTheCoolingFan @SuperKali @TheSnowfield @Tonymac32 @ZazaBR @ahoneybun @alexl83 @amazingfate @andyshrk @brentr @catalinii @chainsx @efectn @fridtjof @hqnicolas @igorpecovnik @joekhoobyar @krachlatte @lanefu @linhz0hz @mlegenovic @paolosabatino @prahal @pyavitz @rbqvq @redrathnure @retro98boy @rpardini @schwar3kat @sicXnull @tdleiyao @torte71 @utlark @vamzii
config/kernel/linux-sm8250-*.config @amazingfate
config/kernel/linux-sm8550-*.config @FantasyGmm @Squishy123 @kasimling
config/kernel/linux-spacemit-*.config @pyavitz @sven-ola
config/kernel/linux-sm8550-*.config @FantasyGmm
config/kernel/linux-spacemit-*.config @pyavitz
config/kernel/linux-starfive2-*.config @libiunc
config/kernel/linux-sun55iw3-syterkit-*.config @chainsx
config/kernel/linux-sunxi-*.config @1ubuntuuser @AaronNGray @DylanHP @Janmcha @StephenGraf @TheSnowfield @Tonymac32 @igorpecovnik @janprunk @lbmendes @leggewie @mhawkins-consultant @sgjava @spendist
@ -258,11 +245,10 @@ patch/atf/atf-k3/ @Grippy98 @glneo @jonaswood01
patch/atf/atf-mvebu64/ @igorpecovnik
patch/atf/atf-phytium-embedded/ @chainsx
patch/atf/atf-qcs6490/ @HeyMeco
patch/atf/atf-rockchip64/v2.13/ @150balbes @ColorfulRhino @HeyMeco @SuperKali @Tonymac32 @ahoneybun @alexl83 @amazingfate @andyshrk @fridtjof @joekhoobyar @linhz0hz @paolosabatino @prahal
patch/atf/atf-rockchip64/v2.14/ @HeyMeco
patch/atf/atf-rockchip64/ @150balbes @ColorfulRhino @HeyMeco @SuperKali @Tonymac32 @ahoneybun @amazingfate @andyshrk @fridtjof @joekhoobyar @linhz0hz @paolosabatino @prahal
patch/atf/atf-sm8250/ @amazingfate
patch/atf/atf-sm8550/ @FantasyGmm @Squishy123 @kasimling
patch/atf/atf-spacemit/ @pyavitz @sven-ola
patch/atf/atf-sm8550/ @FantasyGmm
patch/atf/atf-spacemit/ @pyavitz
patch/atf/atf-sun55iw3-syterkit/ @chainsx
patch/atf/atf-sunxi64/ @AGM1968 @IsMrX @JohnTheCoolingFan @Kreyren @PanderMusubi @Qvy-png @Ressetkk @The-going @Tonymac32 @alexl83 @chraac @devdotnetorg @eliasbakken @igorpecovnik @krachlatte @pyavitz @schwar3kat @sicXnull @spendist @teknoid
patch/kernel/archive/bcm2711-*/ @PanderMusubi @teknoid
@ -279,10 +265,10 @@ patch/kernel/archive/odroidxu4-*/ @joekhoobyar
patch/kernel/archive/qcs6490-*/ @HeyMeco
patch/kernel/archive/realtek-rtd1619b-*/ @wei633
patch/kernel/archive/rockchip-*/ @paolosabatino
patch/kernel/archive/rockchip64-*/ @150balbes @ColorfulRhino @HeyMeco @JohnTheCoolingFan @Lemon1151 @SuperKali @TheSnowfield @Tonymac32 @ZazaBR @ahoneybun @alexl83 @amazingfate @andyshrk @brentr @catalinii @chainsx @efectn @fridtjof @hqnicolas @igorpecovnik @joekhoobyar @krachlatte @lanefu @linhz0hz @mlegenovic @paolosabatino @prahal @pyavitz @rbqvq @redrathnure @retro98boy @rpardini @schwar3kat @sicXnull @tdleiyao @torte71 @utlark @vamzii
patch/kernel/archive/rockchip64-*/ @150balbes @ColorfulRhino @HeyMeco @JohnTheCoolingFan @SuperKali @TheSnowfield @Tonymac32 @ZazaBR @ahoneybun @alexl83 @amazingfate @andyshrk @brentr @catalinii @chainsx @efectn @fridtjof @hqnicolas @igorpecovnik @joekhoobyar @krachlatte @lanefu @linhz0hz @mlegenovic @paolosabatino @prahal @pyavitz @rbqvq @redrathnure @retro98boy @rpardini @schwar3kat @sicXnull @tdleiyao @torte71 @utlark @vamzii
patch/kernel/archive/sm8250-*/ @amazingfate
patch/kernel/archive/sm8550-*/ @FantasyGmm @Squishy123 @kasimling
patch/kernel/archive/spacemit-*/ @pyavitz @sven-ola
patch/kernel/archive/sm8550-*/ @FantasyGmm
patch/kernel/archive/spacemit-*/ @pyavitz
patch/kernel/archive/sunxi-*/ @1ubuntuuser @AGM1968 @AaronNGray @DylanHP @IsMrX @Janmcha @JohnTheCoolingFan @Kreyren @PanderMusubi @Qvy-png @Ressetkk @StephenGraf @The-going @TheSnowfield @Tonymac32 @alexl83 @chraac @devdotnetorg @eliasbakken @igorpecovnik @janprunk @krachlatte @lbmendes @leggewie @mhawkins-consultant @pyavitz @schwar3kat @sgjava @sicXnull @spendist @teknoid
patch/kernel/archive/uefi-arm64-*/ @PeterChrz @rpardini
patch/kernel/archive/uefi-loong64-*/ @amazingfate
@ -295,9 +281,10 @@ patch/kernel/sun55iw3-syterkit-*/ @chainsx
patch/kernel/thead-*/ @chainsx
patch/u-boot/legacy/ @chainsx @joekhoobyar @juanlufont @lanefu
patch/u-boot/legacy/u-boot-clearfog/ @Heisath
patch/u-boot/legacy/u-boot-radxa-rk35xx/ @CodeChenL @JackHuang021 @JohnTheCoolingFan @SeeleVolleri @SuperKali @Tonymac32 @ZazaBR @alexl83 @amazingfate @catalinii @chainsx @efectn @ginkage @hoochiwetech @hqnicolas @igorpecovnik @kamilsaigol @krachlatte @linhz0hz @mahdichi @mattx433 @prahal @rpardini @schwar3kat @sputnik2019 @tdleiyao @vamzii
patch/u-boot/legacy/u-boot-khadas-edge2-rk3588/ @efectn
patch/u-boot/legacy/u-boot-radxa-rk35xx/ @CodeChenL @HeyMeco @JackHuang021 @JohnTheCoolingFan @SeeleVolleri @SuperKali @Tonymac32 @ZazaBR @alexl83 @amazingfate @catalinii @chainsx @efectn @ginkage @hoochiwetech @hqnicolas @igorpecovnik @kamilsaigol @krachlatte @linhz0hz @mahdichi @mattx433 @prahal @rpardini @schwar3kat @sputnik2019 @tdleiyao @vamzii
patch/u-boot/legacy/u-boot-rockchip-buildroot/ @vidplace7
patch/u-boot/legacy/u-boot-spacemit-k1/ @pyavitz @sven-ola
patch/u-boot/legacy/u-boot-spacemit-k1/ @pyavitz
patch/u-boot/u-boot-genio/ @HeyMeco
patch/u-boot/u-boot-k3-beagle/ @Grippy98
patch/u-boot/u-boot-k3/ @Grippy98 @glneo @jonaswood01
@ -306,7 +293,7 @@ patch/u-boot/u-boot-qemu-arm64/ @rpardini
patch/u-boot/u-boot-qemu-x86/ @rpardini
patch/u-boot/u-boot-rk3506/ @amazingfate @vidplace7
patch/u-boot/u-boot-rockchip64-v2022.04/ @ahoneybun @igorpecovnik @paolosabatino
patch/u-boot/u-boot-rockchip64/ @Lemon1151 @Tonymac32 @andyshrk @igorpecovnik @redrathnure @sicXnull
patch/u-boot/u-boot-rockchip64/ @Tonymac32 @andyshrk @igorpecovnik @redrathnure @sicXnull
patch/u-boot/u-boot-sunxi-crust/ @AGM1968 @Kreyren @PanderMusubi @Qvy-png @Tonymac32 @devdotnetorg @igorpecovnik @schwar3kat @spendist @teknoid
patch/u-boot/u-boot-sunxi/ @1ubuntuuser @AGM1968 @DylanHP @Janmcha @JohnTheCoolingFan @Kreyren @PanderMusubi @Qvy-png @Ressetkk @StephenGraf @TheSnowfield @Tonymac32 @devdotnetorg @eliasbakken @igorpecovnik @janprunk @krachlatte @lbmendes @leggewie @mhawkins-consultant @schwar3kat @sgjava @sicXnull @spendist @teknoid
patch/u-boot/u-boot-sunxi/board_bananapim3/ @AaronNGray
@ -319,21 +306,21 @@ patch/u-boot/v2023.10/ @adeepn
patch/u-boot/v2024.01/ @Tonymac32 @igorpecovnik
patch/u-boot/v2024.04/ @Tonymac32 @utlark
patch/u-boot/v2024.07-coolpi-cm5/ @andyshrk
patch/u-boot/v2024.07/ @igorpecovnik
patch/u-boot/v2024.07/ @adeepn @igorpecovnik
patch/u-boot/v2024.07/board_station-m1/ @150balbes
patch/u-boot/v2024.10/ @brentr @pyavitz
patch/u-boot/v2024.10/board_bigtreetech-cb2/ @JohnTheCoolingFan
patch/u-boot/v2025-sunxi/ @The-going @alexl83 @chraac
patch/u-boot/v2025-sunxi/ @The-going @alexl83 @chraac @igorpecovnik
patch/u-boot/v2025.01-rc3-coolpi-cm5/ @andyshrk
patch/u-boot/v2025.01/ @joekhoobyar @torte71
patch/u-boot/v2025.01/ @jeanrhum @joekhoobyar @pyavitz @torte71
patch/u-boot/v2025.01/board_h96-tvbox-3566/ @hqnicolas
patch/u-boot/v2025.04/ @HeyMeco @IsMrX @NicoD-SBC @TheSnowfield @adeepn @andyshrk @rpardini
patch/u-boot/v2025.10/ @HeyMeco @SuperKali @ZazaBR @amazingfate @andyshrk @catalinii @efectn @fridtjof @igorpecovnik @mlegenovic @paolosabatino @vamzii
patch/u-boot/v2025.04/ @HeyMeco @IsMrX @NicoD-SBC @TheSnowfield @andyshrk @mlegenovic @retro98boy @rpardini
patch/u-boot/v2025.07/ @pyavitz
patch/u-boot/v2025.10/ @HeyMeco @SuperKali @ZazaBR @alexl83 @amazingfate @andyshrk @catalinii @efectn @fridtjof @igorpecovnik @paolosabatino @pyavitz @rpardini @vamzii
patch/u-boot/v2025.10/board_9tripod-x3568-v4/ @rbqvq
patch/u-boot/v2025.10/board_helios4/ @leggewie
patch/u-boot/v2026.01/ @150balbes @ColorfulRhino @NicoD-SBC @SuperKali @Tonymac32 @alexl83 @amazingfate @igorpecovnik @jeanrhum @linhz0hz @pyavitz @retro98boy @rpardini @schwar3kat
patch/u-boot/v2026.01/ @150balbes @ColorfulRhino @NicoD-SBC @SuperKali @Tonymac32 @amazingfate @linhz0hz @rpardini
patch/u-boot/v2026.01/board_helios64/ @prahal
patch/u-boot/v2026.04/ @HeyMeco @efectn
sources/families/bcm2711.conf @PanderMusubi @teknoid
sources/families/genio.conf @HeyMeco
sources/families/imx8m.conf @schmiedelm
@ -354,18 +341,18 @@ sources/families/odroidxu4.conf @joekhoobyar
sources/families/phytium-embedded.conf @chainsx
sources/families/qcs6490.conf @HeyMeco
sources/families/realtek-rtd1619b.conf @wei633
sources/families/rk35xx.conf @CodeChenL @HeyMeco @JohnTheCoolingFan @SuperKali @ZazaBR @amazingfate @andyshrk @catalinii @efectn @hoochiwetech @hqnicolas @igorpecovnik @krachlatte @mattx433 @pyavitz @sputnik2019 @tdleiyao @vamzii
sources/families/rk35xx.conf @CodeChenL @HeyMeco @JohnTheCoolingFan @SuperKali @ZazaBR @amazingfate @andyshrk @catalinii @efectn @hoochiwetech @hqnicolas @krachlatte @mattx433 @pyavitz @sputnik2019 @tdleiyao @vamzii
sources/families/rockchip-rk3588.conf @150balbes @ColorfulRhino @HeyMeco @JackHuang021 @JohnTheCoolingFan @SeeleVolleri @SuperKali @Tonymac32 @alexl83 @amazingfate @andyshrk @chainsx @efectn @fridtjof @ginkage @igorpecovnik @kamilsaigol @lanefu @linhz0hz @mahdichi @prahal @rpardini @schwar3kat
sources/families/rockchip-rv1106.conf @vidplace7
sources/families/rockchip.conf @amazingfate @paolosabatino @vidplace7
sources/families/rockchip64.conf @150balbes @JohnTheCoolingFan @Lemon1151 @TheSnowfield @Tonymac32 @ahoneybun @andyshrk @brentr @hqnicolas @igorpecovnik @joekhoobyar @mlegenovic @paolosabatino @prahal @rbqvq @redrathnure @retro98boy @rpardini @sicXnull @torte71 @utlark
sources/families/rockchip64.conf @150balbes @JohnTheCoolingFan @TheSnowfield @Tonymac32 @ahoneybun @andyshrk @brentr @hqnicolas @igorpecovnik @joekhoobyar @mlegenovic @paolosabatino @prahal @rbqvq @redrathnure @retro98boy @rpardini @sicXnull @torte71 @utlark
sources/families/sm8250.conf @amazingfate
sources/families/sm8550.conf @FantasyGmm @Squishy123 @kasimling
sources/families/spacemit.conf @pyavitz @sven-ola
sources/families/sm8550.conf @FantasyGmm
sources/families/spacemit.conf @pyavitz
sources/families/starfive2.conf @libiunc
sources/families/sun50iw1.conf @Kreyren @PanderMusubi @Qvy-png @devdotnetorg @eliasbakken
sources/families/sun50iw2.conf @AGM1968 @Tonymac32 @igorpecovnik @schwar3kat @spendist @teknoid
sources/families/sun50iw6.conf @igorpecovnik @pyavitz
sources/families/sun50iw2.conf @AGM1968 @Tonymac32 @schwar3kat @spendist @teknoid
sources/families/sun50iw6.conf @igorpecovnik
sources/families/sun50iw9-bpi.conf @The-going @pyavitz
sources/families/sun50iw9.conf @AGM1968 @IsMrX @JohnTheCoolingFan @Ressetkk @alexl83 @chraac @krachlatte @sicXnull
sources/families/sun55iw3-syterkit.conf @chainsx

View File

@ -0,0 +1,54 @@
name: Analyze kernel security
run-name: 'Check kernel security options - PR #${{ github.event.pull_request.number }} ("${{ github.event.pull_request.title }}")'
#
# Check the Linux kernel options against security hardening
#
# Attention! Changing security parameters may also affect system performance and functionality of userspace software!
# More info:
# https://github.com/a13xp0p0v/kernel-hardening-checker
on:
workflow_dispatch:
pull_request:
types: [ready_for_review, opened, reopened, synchronize]
permissions:
contents: read
concurrency:
group: pipeline-security-${{github.event.pull_request.number}}
cancel-in-progress: true
jobs:
Analysis:
name: Check kernel security options
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'Armbian' }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v46.0.3
- name: Checkout repository
uses: actions/checkout@v6
with:
repository: a13xp0p0v/kconfig-hardened-check
path: kconfig-hardened-check
- name: Check kernel config for security issues
# Run kernel-hardening-checker for each kernel config file excluding RISC-V configs, since they are not supported yet.
# See https://github.com/a13xp0p0v/kernel-hardening-checker/issues/56
# sed explanation: 1) Put spaces in front of every line 2) replace colored output with emojis since GitHub Actions job summaries don't support colored output
run: |
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
if [[ "${file}" = config/kernel/*.config && ! $(head -n 10 "${file}" | grep -q "riscv") ]]; then
kconfig-hardened-check/bin/kernel-hardening-checker -m show_fail -c $file | sed 's/^/ /; s/\x1b\[32m/✅ /; s/\x1b\[31m/❌ /; s/\x1b\[0m//' >> $GITHUB_STEP_SUMMARY
fi
done

22
.github/workflows/announce-merge.yml vendored Normal file
View File

@ -0,0 +1,22 @@
name: Announce merge
on:
push:
branches: [ main ]
jobs:
announcepush:
# Do not run this workflow in forks
if: ${{ github.repository == 'armbian/build' }}
runs-on: ubuntu-latest
steps:
- name: Get repo
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Send push to Discord
run: |
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X POST --data \
"{\"username\": \"Github\", \"avatar_url\": \"${{ secrets.AVATARURL }}\", \"content\": \"\
:white_check_mark: **Merged** into [$GITHUB_REPOSITORY](<$GITHUB_SERVER_URL/$GITHUB_REPOSITORY>) by [$GITHUB_ACTOR](<$GITHUB_SERVER_URL/$GITHUB_ACTOR>) - \
[Link](<$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/commit/$GITHUB_SHA>): *$(git show -s --format=%s)*\"}" ${{ secrets.WEBHOOKURL }}

25
.github/workflows/announce-pr.yml vendored Normal file
View File

@ -0,0 +1,25 @@
name: Announce PR
run-name: 'Announce PR #${{ github.event.pull_request.number }} on Discord for review'
on:
pull_request:
types: [ labeled ]
jobs:
Announce:
permissions:
pull-requests: read
runs-on: ubuntu-latest
if: ${{ github.repository == 'armbian/build' && github.event.label.id == '6210849975' }}
steps:
- name: Get repo
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Discord webhook
run: |
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X POST --data \
"{\"username\": \"Github\", \"avatar_url\": \"${{ secrets.AVATARURL }}\", \"content\": \"\
:arrow_heading_up: **Pull request** to [$GITHUB_REPOSITORY](<$GITHUB_SERVER_URL/$GITHUB_REPOSITORY>) by [$GITHUB_ACTOR](<$GITHUB_SERVER_URL/$GITHUB_ACTOR>) - **Please review!** \
:point_right: [Link](<$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/pull/${{github.event.pull_request.number}}>): *$(git show -s --format=%s)*\"}" ${{ secrets.WEBHOOKURL }}

113
.github/workflows/auto-label-pr.yml vendored Normal file
View File

@ -0,0 +1,113 @@
name: Auto-label PR
# Sets labels automatically based on:
# - PR size (job: label-size)
# - File categories using .github/labeler config (job: label-category)
# - PR creation date for quarterly tracking (job: label-by-date)
# - Removes "Ready to merge" label on PR update (job: label-remove)
run-name: 'Set labels - PR #${{ github.event.pull_request.number }} ("${{ github.event.pull_request.title }}")'
on: pull_request_target
# Grant required permissions globally
permissions:
contents: read # Required for checking changed files
pull-requests: write # Required for labeling PRs
issues: write # Required for adding/removing labels
jobs:
label-remove:
name: "Remove Ready to merge"
if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize' }}
runs-on: ubuntu-latest
steps:
- name: Checkout the pull request
uses: actions/checkout@v6
- name: Check for label using GH CLI
id: check
run: |
gh pr view ${{ github.event.pull_request.number }} --json labels -q '.labels[].name' | grep -q 'Ready to merge' && echo "has_label=true" >> $GITHUB_OUTPUT || echo "has_label=false" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Remove "Ready to merge" label
if: steps.check.outputs.has_label == 'true'
uses: PauMAVA/add-remove-label-action@v1.0.3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
add: ""
remove: "Ready to merge"
label-category:
name: "Category Labels"
runs-on: ubuntu-latest
if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize' }}
steps:
# Checks out the repository to read files for matching with labeler config
- uses: actions/checkout@v6
# Applies labels based on the .github/labeler.yml config
- uses: actions/labeler@v6
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
label-size:
name: "Size Label"
runs-on: ubuntu-latest
if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize' }}
steps:
# Automatically adds size labels based on total changed lines
- name: Label by size
uses: pascalgn/size-label-action@v0.5.5
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
with:
sizes: >
{
"0": "small",
"50": "medium",
"250": "large"
}
label-by-date:
name: "Date label (Quarters)"
runs-on: ubuntu-latest
if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize' }}
steps:
# Determines the label (02, 05, 08, 11) based on PR creation month
- name: Determine quarter label
env:
PR_CREATED_AT: ${{ github.event.pull_request.created_at }}
run: |
echo "PR created at: $PR_CREATED_AT"
# Extract the numeric month (e.g., 04 for April)
MONTH=$(date -d "$PR_CREATED_AT" +%m | sed 's/^0*//')
echo "Month extracted: $MONTH"
# Determine quarter-end label based on month
if [ "$MONTH" -le 2 ] || [ "$MONTH" -eq 12 ]; then
LABEL="02"
elif [ "$MONTH" -le 5 ]; then
LABEL="05"
elif [ "$MONTH" -le 8 ]; then
LABEL="08"
else
LABEL="11"
fi
# Set as environment variable for next step
echo "LABEL=${LABEL}" >> $GITHUB_ENV
# Adds the quarter label to the PR
- name: Add quarter label
uses: PauMAVA/add-remove-label-action@v1.0.3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
add: "${{ env.LABEL }}"

View File

@ -0,0 +1,41 @@
name: Build PR artifacts
run-name: "Generate artifacts - PR #${{ github.event.pull_request.number }} - by @${{ github.actor }}"
#
# If PR is labeled with "Build" and you are a member of "Release manager" team it will start a build train (additional security feature).
# In the run name, ${{ github.actor }} shows who's privileges are used for this run.
#
on: pull_request_target
jobs:
Check:
permissions:
pull-requests: read
name: Check label and authorization
runs-on: Linux
outputs:
member: ${{ steps.checkUserMember.outputs.isTeamMember }}
steps:
- uses: tspascoal/get-user-teams-membership@v3
if: contains(github.event.pull_request.labels.*.name, 'Build')
id: checkUserMember
with:
username: ${{ github.actor }}
organization: armbian
team: "Release manager"
GITHUB_TOKEN: ${{ secrets.ORG_MEMBERS }}
Compile:
needs: Check
name: Generate artifacts
concurrency:
group: pipeline-pr-${{github.event.pull_request.number}}
cancel-in-progress: true
if: ${{ github.repository_owner == 'Armbian' && needs.Check.outputs.member == 'true' }}
uses: armbian/os/.github/workflows/complete-artifact-matrix-all.yml@main
secrets:
ORG_MEMBERS: ${{ secrets.ORG_MEMBERS }}
with:
extraParamsAllBuilds: "UPLOAD_TO_OCI_ONLY=no"
ref: ${{ github.event.pull_request.head.sha }}

169
.github/workflows/check-pr-pictures.yml vendored Normal file
View File

@ -0,0 +1,169 @@
name: Check PR assets
on:
pull_request_target:
paths:
- "config/boards/**"
env:
WEBSITE_REPO: "armbian/armbian.github.io"
WEBSITE_REF: "main"
BOARDS_PATH: "config/boards"
BOARD_IMAGES_DIR: "board-images"
VENDOR_LOGOS_DIR: "board-vendor-logos"
jobs:
Check:
name: "Verify assets for newly added boards"
runs-on: ubuntu-24.04
permissions:
contents: read
pull-requests: write
issues: write
steps:
- name: "Checkout build repo (PR head)"
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: "Checkout armbian.github.io (images repo)"
uses: actions/checkout@v6
with:
repository: ${{ env.WEBSITE_REPO }}
ref: ${{ env.WEBSITE_REF }}
path: website
fetch-depth: 1
- name: "Find newly added board configs in PR"
id: added
shell: bash
run: |
set -euo pipefail
BASE_SHA="${{ github.event.pull_request.base.sha }}"
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
git diff --name-status "${BASE_SHA}" "${HEAD_SHA}" -- "${BOARDS_PATH}" \
| awk '$1=="A"{print $2}' \
| grep -E '\.(conf|csc|wip|tvb)$' \
> added-files.txt || true
echo "New board config files:"
cat added-files.txt || true
if [[ ! -s added-files.txt ]]; then
echo "No new board configs detected."
echo "none=true" >> "$GITHUB_OUTPUT"
else
echo "none=false" >> "$GITHUB_OUTPUT"
fi
- name: "Validate board image + vendor logo exist on website repo"
id: validate
if: ${{ steps.added.outputs.none != 'true' }}
shell: bash
run: |
set -euo pipefail
missing_any=0
comment_file="$(mktemp)"
{
echo "This PR adds new board configuration(s). Required assets must already exist in [github/${WEBSITE_REPO}](https://github.com/${WEBSITE_REPO})."
echo "They are required by [Armbian Imager](https://github.com/armbian/imager) to ensure all boards are displayed with proper images."
echo ""
echo "- Board images: \`${BOARD_IMAGES_DIR}/<board>.png\` (1920x1080 px transparent)"
echo "- Vendor logos: \`${VENDOR_LOGOS_DIR}/<vendor>-logo.png\` (512x512 px transparent)"
echo ""
echo "### Missing items"
echo ""
} > "$comment_file"
while IFS= read -r cfg; do
[[ -z "${cfg}" ]] && continue
file="$(basename "$cfg")"
board="${file%.*}"
vendor="$(
grep -E '^[[:space:]]*(export[[:space:]]+|declare[[:space:]]+-g[[:space:]]+)?BOARD_VENDOR[[:space:]]*=' -m1 -- "$cfg" 2>/dev/null \
| sed -E 's/^[[:space:]]*(export[[:space:]]+|declare[[:space:]]+-g[[:space:]]+)?BOARD_VENDOR[[:space:]]*=[[:space:]]*//; s/^"//; s/"$//' \
| tr '[:upper:]' '[:lower:]' \
| tr '_' '-' \
| awk 'NF{print; exit}' \
|| true
)"
board_img_match="$(find "website/${BOARD_IMAGES_DIR}" -maxdepth 1 -type f -iname "${board}.png" | head -n1 || true)"
if [[ -z "${board_img_match}" ]]; then
{
echo "- ❌ **Board image missing** for \`${board}\`"
echo " - Expected: \`${BOARD_IMAGES_DIR}/${board}.png\`"
echo " - Fix: add the file to **${WEBSITE_REPO}** (folder \`${BOARD_IMAGES_DIR}/\`)"
echo ""
} >> "$comment_file"
missing_any=1
fi
if [[ -z "${vendor}" ]]; then
{
echo "- ❌ **BOARD_VENDOR not found** in \`${cfg}\`"
echo " - Fix: add e.g. \`BOARD_VENDOR=\"radxa\"\` (lowercase recommended)"
echo ""
} >> "$comment_file"
missing_any=1
continue
fi
found_logo="$(find "website/${VENDOR_LOGOS_DIR}" -maxdepth 1 -type f \
\( -iname "${vendor}-logo.png" -o -iname "${vendor}-logo.jpg" -o -iname "${vendor}-logo.jpeg" -o -iname "${vendor}-logo.svg" \) \
| head -n1 || true)"
if [[ -z "${found_logo}" ]]; then
{
echo "- ❌ **Vendor logo missing** for vendor \`${vendor}\` (used by board \`${board}\`)"
echo " - Expected: \`${VENDOR_LOGOS_DIR}/${vendor}-logo.png\`"
echo " - Fix: add the file to **${WEBSITE_REPO}** (folder \`${VENDOR_LOGOS_DIR}/\`)"
echo " - Naming rules: lowercase, dashes (e.g. \`kobol-logo.png\`, not \`Kobol_logo.png\`)"
echo ""
} >> "$comment_file"
missing_any=1
fi
done < added-files.txt
if [[ "${missing_any}" -ne 0 ]]; then
echo "missing=true" >> "$GITHUB_OUTPUT"
echo 'comment<<EOF' >> "$GITHUB_OUTPUT"
cat "$comment_file" >> "$GITHUB_OUTPUT"
echo 'EOF' >> "$GITHUB_OUTPUT"
echo "::warning ::Missing required assets (see PR comment)."
else
echo "missing=false" >> "$GITHUB_OUTPUT"
fi
- name: "Comment on PR with missing asset instructions"
if: always() && github.event_name == 'pull_request_target' && steps.validate.outputs.missing == 'true'
uses: actions/github-script@v8
env:
COMMENT_BODY: ${{ steps.validate.outputs.comment }}
WEBSITE_REPO: ${{ env.WEBSITE_REPO }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const body =
`### 🚫 Missing required board assets
${process.env.COMMENT_BODY}
Once the missing files are added (or a PR is opened in **${process.env.WEBSITE_REPO}**), re-run this check.
`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body
});

View File

@ -0,0 +1,27 @@
name: Clean workflow logs
on:
schedule:
- cron: "0 0 * * 1" # Runs "At 00:00 on Monday." (see https://crontab.guru)
workflow_dispatch:
inputs:
runs_older_than:
description: "The amount of days old to delete"
default: "10"
required: false
env:
SCHEDULED_RUNS_OLDER_THAN: "10"
SCHEDULED_RUNS_TO_KEEP: "0"
jobs:
clean-logs:
runs-on: ubuntu-latest
permissions:
actions: write
steps:
- uses: igorjs/gh-actions-clean-workflow@v7
with:
runs_older_than: ${{ github.event.inputs.runs_older_than || env.SCHEDULED_RUNS_OLDER_THAN }}
runs_to_keep: ${{ github.event.inputs.runs_to_keep || env.SCHEDULED_RUNS_TO_KEEP }}

View File

@ -0,0 +1,22 @@
name: Sync Jira
run-name: 'Sync Jira - Issue #${{ github.event.issue.number }} ("${{ github.event.issue.title }}")'
on:
issues:
types: [opened]
jobs:
sync:
name: Sync Items
runs-on: ubuntu-latest
steps:
- name: Sync
uses: igorpecovnik/github-action-issue-to-jira@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
jiraHost: armbian.atlassian.net
jiraUsername: ${{ secrets.JIRA_USER }}
jiraPassword: ${{ secrets.JIRA_PASSWORD }}
project: AR
assignee: default_assignee

View File

@ -1,22 +0,0 @@
name: "Data: Create Jira ticket"
run-name: 'Sync Jira - Issue #${{ github.event.issue.number }} ("${{ github.event.issue.title }}")'
on:
issues:
types: [opened]
jobs:
sync:
name: Sync Items
runs-on: ubuntu-latest
steps:
- name: Sync
uses: igorpecovnik/github-action-issue-to-jira@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
jiraHost: armbian.atlassian.net
jiraUsername: ${{ secrets.JIRA_USER }}
jiraPassword: ${{ secrets.JIRA_PASSWORD }}
project: AR
assignee: default_assignee

View File

@ -1,24 +0,0 @@
name: "Data: Sync board list"
run-name: Update board JSON at armbian/armbian.github.io
on:
push:
paths:
- "config/boards/*.*"
branches: [main]
permissions:
contents: read
jobs:
update-board-list-dispatch:
name: Send dispatch
if: ${{ github.repository_owner == 'Armbian' }}
runs-on: ubuntu-latest
steps:
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@v4
with:
token: ${{ secrets.ACCESS_TOKEN }}
repository: armbian/armbian.github.io
event-type: "Data: Generate build engine inventory"

View File

@ -1,39 +0,0 @@
name: "Data: Sync labels"
run-name: Sync Labels from YML on ${{ github.event_name }}
on:
workflow_dispatch:
push:
branches:
- "main"
paths:
- ".github/labels.yml"
pull_request:
paths:
- ".github/labels.yml"
permissions:
contents: read
jobs:
labeler:
permissions:
contents: read # for actions/labeler to determine modified files
pull-requests: write # for actions/labeler to add labels to PRs
issues: write # for actions/labeler to add labels to issues
if: ${{ github.repository_owner == 'Armbian' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Run Labeler
uses: crazy-max/ghaction-github-labeler@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
yaml-file: .github/labels.yml
dry-run: ${{ github.event_name == 'pull_request' }}
exclude: |
Maintenance*

View File

@ -1,121 +0,0 @@
name: "Data: Sync maintainers"
# Script connects to the contacts database once per hour and updates BOARD_MAINTAINER property in the board config files.
# If there are any changes, it opens a Pull Request
#
# spdx-id: GPL-2.0-or-later
# copyright-owner: @igorpecovnik
on:
schedule:
- cron: "0 * * * *"
workflow_dispatch:
jobs:
Build:
name: "Maintainers sync"
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'armbian' }}
steps:
- name: "Checkout build repo"
uses: actions/checkout@v6
with:
repository: armbian/build
ref: main
fetch-depth: 0
clean: false
- name: "Install SSH key for storage"
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: "Download JSON file"
run: |
# download json that is prepared in https://github.com/armbian/armbian.github.io
curl -o /tmp/armbian_maintainers.json https://github.armbian.com/maintainers.json
- name: "Update maintainers"
run: |
# reset all maintainers so we generate from scratch
sed -i "s/BOARD_MAINTAINER.*/BOARD_MAINTAINER=\"\"/" config/boards/*.{conf,wip,eos,tvb}
# extract values fron JSON
declare -A MAINTAINERS
{
# By default, bash run the pipe command in subshells
# which make variable can't be assigned to.
# And yes, lastpipe can solve it
# But this is better.
while read -r i; do
NAME="$(echo "$i" | jq --raw-output '.First_Name')"
BOARD="$(echo "$i" | jq --raw-output '.Maintaining')"
MAINTAINER_GITHUB="$(echo "$i" | jq --raw-output '.Github' | cut -d"/" -f4)"
if [[ "$BOARD" != null && "$MAINTAINER_GITHUB" != null ]]; then
echo "- [$NAME](https://github.com/${MAINTAINER_GITHUB})"
while read -r i; do
echo -e " - $i"
MAINTAINERS["$i"]+="$MAINTAINER_GITHUB "
done < <( echo "$BOARD" | sed "s/,/\n/g" | sort -u )
fi
done < <(jq -c '.[]' /tmp/armbian_maintainers.json)
for cfg in config/boards/*.{conf,wip,csc,eos,tvb}; do
board_name="$(echo "${cfg##*/}" | sed -E 's/\..*//')"
declare -a maintainers
readarray -t maintainers < <(echo "${MAINTAINERS[${board_name}]}" | xargs -n1 | sort -u)
sed -i "s/BOARD_MAINTAINER=.*/BOARD_MAINTAINER=\"${maintainers[*]}\"/" "${cfg}"
done
} >> "$GITHUB_STEP_SUMMARY"
- name: "Mark csc for no maintainer"
run: |
grep BOARD_MAINTAINER=\"\" config/boards/*.{wip,conf} | cut -d":" -f1 |
while read -r line; do
if [[ "${line}" != "${line/.conf/.csc}" ]]; then
mv -v "$line" "${line/.conf/.csc}"
fi
if [[ "${line}" != "${line/.wip/.csc}" ]]; then
mv -v "$line" "${line/.wip/.csc}"
fi
done
- name: "Re-generate CODEOWNERS"
run: |
./.github/generate_CODEOWNERS.sh
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: '`Automatic` board configs status synchronise'
signoff: false
branch: update-maintainers
delete-branch: true
title: '`Automatic` board configs status synchronise'
body: |
Update maintainers and board status
- synced status from the database
- rename to .`csc` where we don't have anyone
If you want to become a board maintainer, [adjust data here](https://www.armbian.com/update-data/).
Ref:
- [Board Maintainers Procedures and Guidelines](https://docs.armbian.com/Board_Maintainers_Procedures_and_Guidelines/)
- [Contribute](https://docs.armbian.com/Process_Contribute/)
labels: |
Work in progress
#assignees: igorpecovnik
#reviewers: Must be org collaborator
draft: false

View File

@ -1,104 +0,0 @@
name: "Data: Sync tools"
run-name: Update Tools in Scripts by @${{ github.actor }}
#
# Some of our scripts download tools from a repo. These can't be bumped by dependabot, so this workflow is a self-created dependabot to bump versions of those tools to stay up-to-date.
# This workflow only creates a PR if the version was actually updated.
# To add a new tool, it just needs to be added to the matrix below by filling out all the variables.
#
permissions:
contents: write
pull-requests: write
on:
workflow_dispatch:
schedule:
- cron: "42 3 16 * *" # Run monthly on the 16th day of the month at 03:42 AM (random value as to not overload GitHub)
jobs:
update-tool-version:
name: Update ${{ matrix.tool.REPO_NAME }} version
runs-on: ubuntu-latest
# Add new tools here, no need to add anything anywhere else.
# Only works for tools hosted on GitHub for now.
strategy:
matrix:
tool:
# Shellcheck
- USER_NAME: "koalaman" # GitHub user name
REPO_NAME: "shellcheck" # GitHub repo name
PROJECT_NAME: "koalaman/shellcheck" # This is always USER_NAME/REPO_NAME (like in the GitHub URL)
VAR_FILE: "lib/tools/shellcheck.sh" # Where the version variable of the tool is saved
VERSION_VAR: "SHELLCHECK_VERSION" # Version variable how it appears in the script
# Shellcheck #2
- USER_NAME: "koalaman"
REPO_NAME: "shellcheck"
PROJECT_NAME: "koalaman/shellcheck"
VAR_FILE: "lib/functions/general/shellcheck.sh"
VERSION_VAR: "SHELLCHECK_VERSION"
# Shellfmt
- USER_NAME: "mvdan"
REPO_NAME: "sh"
PROJECT_NAME: "mvdan/sh"
VAR_FILE: "lib/tools/shellfmt.sh"
VERSION_VAR: "SHELLFMT_VERSION"
# ORAS
- USER_NAME: "oras-project"
REPO_NAME: "oras"
PROJECT_NAME: "oras-project/oras"
VAR_FILE: "lib/functions/general/oci-oras.sh"
VERSION_VAR: "ORAS_VERSION"
# Bat
- USER_NAME: "sharkdp"
REPO_NAME: "bat"
PROJECT_NAME: "sharkdp/bat"
VAR_FILE: "lib/functions/general/bat-cat.sh"
VERSION_VAR: "BATCAT_VERSION"
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Get current ${{ matrix.tool.PROJECT_NAME }} version
id: get-version-current
run: |
version_current=$(grep -Po '(?<=${{ matrix.tool.VERSION_VAR}}=\${${{ matrix.tool.VERSION_VAR}}:-)[0-9.]+(?=})' ${{ matrix.tool.VAR_FILE }})
echo "version_current=$version_current" >> $GITHUB_OUTPUT
- name: Get latest ${{ matrix.tool.PROJECT_NAME }} version
id: get-version-latest
# Multi-line string for CHANGE_LOG env, see https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
# Further exmplanation for the CHANGE_LOG env:
# The first 'sed' expression replaces "#123" with "username/repo#123" to link to the correct repo (would otherwise auto-link to own repo)
# The second 'sed' expression replaces GitHub URLs with "redirect.github.com" to prevent "This was referenced" in the external repo's PRs/issues
run: |
version_latest=$(curl --silent "https://api.github.com/repos/${{ matrix.tool.PROJECT_NAME }}/releases/latest" | jq -r .tag_name)
version_latest=${version_latest#v} # Removing the 'v' prefix since the script uses only plain numbers
echo "version_latest=$version_latest" >> $GITHUB_OUTPUT
- name: Update ${{ matrix.tool.VERSION_VAR}} in script
# @TODO Make sure that the version is actually higher, not lower (the 'latest' tag does not neccessarily mean that the version is higher!)
run: |
version_latest=${{ steps.get-version-latest.outputs.version_latest }}
sed -i "s/${{ matrix.tool.VERSION_VAR}}=\${${{ matrix.tool.VERSION_VAR}}:-[0-9.]*}/${{ matrix.tool.VERSION_VAR}}=\${${{ matrix.tool.VERSION_VAR}}:-$version_latest}/g" ${{ matrix.tool.VAR_FILE }}
- name: Create Pull Request to update ${{ matrix.tool.VERSION_VAR}} for ${{ matrix.tool.PROJECT_NAME }}
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "tools: Bump `${{ matrix.tool.VERSION_VAR}}` from ${{ steps.get-version-current.outputs.version_current }} to ${{ steps.get-version-latest.outputs.version_latest }}"
branch: update-version-${{ matrix.tool.VAR_FILE }}-${{ matrix.tool.PROJECT_NAME }}-${{ steps.get-version-latest.outputs.version_latest }}
delete-branch: true
title: "Bump ${{ matrix.tool.PROJECT_NAME}} from ${{ steps.get-version-current.outputs.version_current }} to ${{ steps.get-version-latest.outputs.version_latest }} in `${{ matrix.tool.VAR_FILE}}`"
body: |
Bump [${{ matrix.tool.PROJECT_NAME}}](https://github.com/${{ matrix.tool.PROJECT_NAME }}) from ${{ steps.get-version-current.outputs.version_current }} to ${{ steps.get-version-latest.outputs.version_latest }} by bumping `${{ matrix.tool.VERSION_VAR}}` in `${{ matrix.tool.VAR_FILE}}`.
Check <a href="https://github.com/${{ matrix.tool.PROJECT_NAME }}/releases/latest">the upstream release notes</a>.
<p><em>Please note that the above link only shows the release notes for the latest release.</em></p>
labels: Dependencies, Bash

33
.github/workflows/help-forked.yml vendored Normal file
View File

@ -0,0 +1,33 @@
name: Help forks
run-name: Forked Helper dispatch on ${{ github.event_name }}
on:
push:
release:
deployment:
pull_request:
workflow_dispatch:
jobs:
dispatch-on-forked-repo:
name: 📢 Run repository dispatch on fork
env:
DISPATCH_SECRET: ${{ secrets.ARMBIAN_SELF_DISPATCH_TOKEN }}
if: ${{ github.repository_owner != 'armbian' }} # Run only on forks
runs-on: ubuntu-latest
steps:
- name: Dispatch event on forked repository
if: ${{ env.DISPATCH_SECRET != '' }} # Check that the secret has been set, if not, exit
uses: peter-evans/repository-dispatch@v4
with:
token: ${{ env.DISPATCH_SECRET }}
repository: ${{ github.repository }}
event-type: armbian
client-payload: >
{
"event": "${{ github.event_name }}",
"ref": "${{ github.ref }}",
"base_ref": "${{ github.base_ref }}",
"sha": "${{ github.sha }}",
"event_details": ${{ toJSON(github.event) }}
}

View File

@ -1,36 +0,0 @@
name: "Infrastructure: Dispatch to fork"
run-name: Forked Helper dispatch on ${{ github.event_name }}
on:
push:
release:
deployment:
pull_request:
workflow_dispatch:
permissions:
contents: read
jobs:
dispatch-on-forked-repo:
name: 📢 Run repository dispatch on fork
env:
DISPATCH_SECRET: ${{ secrets.ARMBIAN_SELF_DISPATCH_TOKEN }}
if: ${{ github.repository_owner != 'armbian' }} # Run only on forks
runs-on: ubuntu-latest
steps:
- name: Dispatch event on forked repository
if: ${{ env.DISPATCH_SECRET != '' }} # Check that the secret has been set, if not, exit
uses: peter-evans/repository-dispatch@v4
with:
token: ${{ env.DISPATCH_SECRET }}
repository: ${{ github.repository }}
event-type: armbian
client-payload: >
{
"event": "${{ github.event_name }}",
"ref": "${{ github.ref }}",
"base_ref": "${{ github.base_ref }}",
"sha": "${{ github.sha }}",
"event_details": ${{ toJSON(github.event) }}
}

View File

@ -1,34 +0,0 @@
# Pushes the contents of the repo to the Codeberg mirror
name: "Infrastructure: Mirror to Codeberg"
permissions:
contents: read
on:
push:
branches:
- main
workflow_dispatch:
# Cancel older runs if a new one starts (per workflow + branch)
concurrency:
group: ${{ github.workflow }}-${{ github.repository }}-${{ github.ref }}
cancel-in-progress: true
jobs:
codeberg:
# Extra safety so forks don't try to run it
if: ${{ github.repository == 'armbian/build' }}
runs-on: ubuntu-latest
steps:
- name: Checkout full history
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Mirror to Codeberg
uses: pixta-dev/repository-mirroring-action@v1
with:
target_repo_url: git@codeberg.org:armbian/build.git
ssh_private_key: ${{ secrets.GHA_SSH_KEY }}

View File

@ -0,0 +1,54 @@
name: Label PR on approval
on:
workflow_run:
workflows: ["Listen PR review"]
types: [completed]
jobs:
label:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
pull-requests: write
steps:
- name: Download PR number artifact from upstream run
uses: actions/download-artifact@v7
with:
name: pr-number-${{ github.event.workflow_run.id }} # same unique name
path: .
run-id: ${{ github.event.workflow_run.id }} # ← CRITICAL: fetch from the upstream run
github-token: ${{ secrets.GITHUB_TOKEN }}
- id: pr
run: echo "number=$(cat pr.txt)" >> $GITHUB_OUTPUT
- name: Label when approved
uses: j-fulbright/label-when-approved-action@v1.2
with:
token: ${{ secrets.GITHUB_TOKEN }}
label: 'Ready to merge'
require_committers_approval: 'true'
remove_label_when_approval_missing: 'true'
comment: '✅ This PR has been reviewed and approved — all set for merge!'
pullRequestNumber: ${{ steps.pr.outputs.number }}
- name: Remove review-related labels
if: ${{ success() }}
uses: actions/github-script@v8
with:
script: |
const { owner, repo } = context.repo;
const issue_number = ${{ steps.pr.outputs.number }};
const labelsToRemove = ["Needs review", "Work in progress", "Backlog", "Can be closed?", "Help needed", "Needs Documentation"];
for (const name of labelsToRemove) {
try {
await github.rest.issues.removeLabel({ owner, repo, issue_number, name });
core.info(`Removed label "${name}"`);
} catch (e) {
core.warning(`Could not remove label "${name}": ${e.message}`);
}
}

59
.github/workflows/lint-pr-scripts.yml vendored Normal file
View File

@ -0,0 +1,59 @@
name: Lint scripts
run-name: 'Shellcheck - PR #${{ github.event.pull_request.number }} ("${{ github.event.pull_request.title }}")'
#
# Run ShellCheck on all scripts and generate report as build artifact
#
on:
workflow_dispatch:
pull_request:
types: [opened, reopened, synchronize]
permissions:
contents: read
concurrency:
group: pipeline-lint-${{github.event.pull_request.number}}
cancel-in-progress: true
jobs:
Shellcheck:
name: Shell script analysis
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'Armbian' }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v46.0.3
- name: List all changed files
run: |
# Use framework internal mechanism for checking `lib` and `extensions` code only one file is passed,
# and source's are followed, thus the whole project is "understood" by shellcheck.
# For example, when checking individual files, one variable might be thought "unused" because it
# is only used in another file, which does not happen when done properly.
bash lib/tools/shellcheck.sh
ret=0
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
if [[ ! "${file}" =~ lib/|extensions/|.py|.service|.rules|.network|.netdev ]]; then
if grep -qE "^#\!/.*bash" $file; then
shellcheck --severity=error $file || ret=$?
fi
fi
done
exit $ret

20
.github/workflows/listen-pr-review.yml vendored Normal file
View File

@ -0,0 +1,20 @@
name: Listen PR review
on:
pull_request_review:
types: [submitted]
jobs:
ping:
if: ${{ github.event.review.state == 'approved' }}
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Save PR number
run: echo "${{ github.event.pull_request.number }}" > pr.txt
- uses: actions/upload-artifact@v6.0.0
with:
# unique name: includes workflow run id
name: pr-number-${{ github.run_id }}
path: pr.txt

View File

@ -1,25 +0,0 @@
name: "Maintenance: Announce merge"
on:
push:
branches: [ main ]
permissions:
contents: read
jobs:
announcepush:
# Do not run this workflow in forks
if: ${{ github.repository == 'armbian/build' }}
runs-on: ubuntu-latest
steps:
- name: Get repo
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Send push to Discord
run: |
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X POST --data \
"{\"username\": \"Github\", \"avatar_url\": \"${{ secrets.AVATARURL }}\", \"content\": \"\
:white_check_mark: **Merged** into [$GITHUB_REPOSITORY](<$GITHUB_SERVER_URL/$GITHUB_REPOSITORY>) by [$GITHUB_ACTOR](<$GITHUB_SERVER_URL/$GITHUB_ACTOR>) - \
[Link](<$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/commit/$GITHUB_SHA>): *$(git show -s --format=%s)*\"}" ${{ secrets.WEBHOOKURL }}

View File

@ -1,28 +0,0 @@
name: "Maintenance: Announce PR"
run-name: 'Announce PR #${{ github.event.pull_request.number }} on Discord for review'
on:
pull_request:
types: [ labeled ]
permissions:
contents: read
jobs:
Announce:
permissions:
pull-requests: read
contents: read
runs-on: ubuntu-latest
if: ${{ github.repository == 'armbian/build' && github.event.label.id == '6210849975' }}
steps:
- name: Get repo
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Discord webhook
run: |
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X POST --data \
"{\"username\": \"Github\", \"avatar_url\": \"${{ secrets.AVATARURL }}\", \"content\": \"\
:arrow_heading_up: **Pull request** to [$GITHUB_REPOSITORY](<$GITHUB_SERVER_URL/$GITHUB_REPOSITORY>) by [$GITHUB_ACTOR](<$GITHUB_SERVER_URL/$GITHUB_ACTOR>) - **Please review!** \
:point_right: [Link](<$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/pull/${{github.event.pull_request.number}}>): *$(git show -s --format=%s)*\"}" ${{ secrets.WEBHOOKURL }}

View File

@ -1,113 +0,0 @@
name: "Maintenance: Auto-label PR"
# Sets labels automatically based on:
# - PR size (job: label-size)
# - File categories using .github/labeler config (job: label-category)
# - PR creation date for quarterly tracking (job: label-by-date)
# - Removes "Ready to merge" label on PR update (job: label-remove)
run-name: 'Set labels - PR #${{ github.event.pull_request.number }} ("${{ github.event.pull_request.title }}")'
on: pull_request_target
# Grant required permissions globally
permissions:
contents: read # Required for checking changed files
pull-requests: write # Required for labeling PRs
issues: write # Required for adding/removing labels
jobs:
label-remove:
name: "Remove Ready to merge"
if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize' }}
runs-on: ubuntu-latest
steps:
- name: Checkout the pull request
uses: actions/checkout@v6
- name: Check for label using GH CLI
id: check
run: |
gh pr view ${{ github.event.pull_request.number }} --json labels -q '.labels[].name' | grep -q 'Ready to merge' && echo "has_label=true" >> $GITHUB_OUTPUT || echo "has_label=false" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Remove "Ready to merge" label
if: steps.check.outputs.has_label == 'true'
uses: PauMAVA/add-remove-label-action@v1.0.3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
add: ""
remove: "Ready to merge"
label-category:
name: "Category Labels"
runs-on: ubuntu-latest
if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize' }}
steps:
# Checks out the repository to read files for matching with labeler config
- uses: actions/checkout@v6
# Applies labels based on the .github/labeler.yml config
- uses: actions/labeler@v6
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
label-size:
name: "Size Label"
runs-on: ubuntu-latest
if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize' }}
steps:
# Automatically adds size labels based on total changed lines
- name: Label by size
uses: pascalgn/size-label-action@v0.5.5
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
with:
sizes: >
{
"0": "small",
"50": "medium",
"250": "large"
}
label-by-date:
name: "Date label (Quarters)"
runs-on: ubuntu-latest
if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize' }}
steps:
# Determines the label (02, 05, 08, 11) based on PR creation month
- name: Determine quarter label
env:
PR_CREATED_AT: ${{ github.event.pull_request.created_at }}
run: |
echo "PR created at: $PR_CREATED_AT"
# Extract the numeric month (e.g., 04 for April)
MONTH=$(date -d "$PR_CREATED_AT" +%m | sed 's/^0*//')
echo "Month extracted: $MONTH"
# Determine quarter-end label based on month
if [ "$MONTH" -le 2 ] || [ "$MONTH" -eq 12 ]; then
LABEL="02"
elif [ "$MONTH" -le 5 ]; then
LABEL="05"
elif [ "$MONTH" -le 8 ]; then
LABEL="08"
else
LABEL="11"
fi
# Set as environment variable for next step
echo "LABEL=${LABEL}" >> $GITHUB_ENV
# Adds the quarter label to the PR
- name: Add quarter label
uses: PauMAVA/add-remove-label-action@v1.0.3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
add: "${{ env.LABEL }}"

View File

@ -1,41 +0,0 @@
name: "Maintenance: Build artifacts"
run-name: "Generate artifacts - PR #${{ github.event.pull_request.number }} - by @${{ github.actor }}"
#
# If PR is labeled with "Build" and you are a member of "Release manager" team it will start a build train (additional security feature).
# In the run name, ${{ github.actor }} shows who's privileges are used for this run.
#
on: pull_request_target
jobs:
Check:
permissions:
pull-requests: read
name: Check label and authorization
runs-on: Linux
outputs:
member: ${{ steps.checkUserMember.outputs.isTeamMember }}
steps:
- uses: tspascoal/get-user-teams-membership@v3
if: contains(github.event.pull_request.labels.*.name, 'Build')
id: checkUserMember
with:
username: ${{ github.actor }}
organization: armbian
team: "Release manager"
GITHUB_TOKEN: ${{ secrets.ORG_MEMBERS }}
Compile:
needs: Check
name: Generate artifacts
concurrency:
group: pipeline-pr-${{github.event.pull_request.number}}
cancel-in-progress: true
if: ${{ github.repository_owner == 'Armbian' && needs.Check.outputs.member == 'true' }}
uses: armbian/os/.github/workflows/complete-artifact-matrix-all.yml@main
secrets:
ORG_MEMBERS: ${{ secrets.ORG_MEMBERS }}
with:
extraParamsAllBuilds: "UPLOAD_TO_OCI_ONLY=no"
ref: ${{ github.event.pull_request.head.sha }}

View File

@ -1,172 +0,0 @@
name: "Maintenance: Check board assets"
on:
pull_request_target:
paths:
- "config/boards/**"
env:
WEBSITE_REPO: "armbian/armbian.github.io"
WEBSITE_REF: "main"
BOARDS_PATH: "config/boards"
BOARD_IMAGES_DIR: "board-images"
VENDOR_LOGOS_DIR: "board-vendor-logos"
permissions:
contents: read
jobs:
Check:
name: "Verify assets for newly added boards"
runs-on: ubuntu-24.04
permissions:
contents: read
pull-requests: write
issues: write
steps:
- name: "Checkout build repo (PR head)"
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: "Checkout armbian.github.io (images repo)"
uses: actions/checkout@v6
with:
repository: ${{ env.WEBSITE_REPO }}
ref: ${{ env.WEBSITE_REF }}
path: website
fetch-depth: 1
- name: "Find newly added board configs in PR"
id: added
shell: bash
run: |
set -euo pipefail
BASE_SHA="${{ github.event.pull_request.base.sha }}"
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
git diff --name-status "${BASE_SHA}" "${HEAD_SHA}" -- "${BOARDS_PATH}" \
| awk '$1=="A"{print $2}' \
| grep -E '\.(conf|csc|wip|tvb)$' \
> added-files.txt || true
echo "New board config files:"
cat added-files.txt || true
if [[ ! -s added-files.txt ]]; then
echo "No new board configs detected."
echo "none=true" >> "$GITHUB_OUTPUT"
else
echo "none=false" >> "$GITHUB_OUTPUT"
fi
- name: "Validate board image + vendor logo exist on website repo"
id: validate
if: ${{ steps.added.outputs.none != 'true' }}
shell: bash
run: |
set -euo pipefail
missing_any=0
comment_file="$(mktemp)"
{
echo "This PR adds new board configuration(s). Required assets must already exist in [github/${WEBSITE_REPO}](https://github.com/${WEBSITE_REPO})."
echo "They are required by [Armbian Imager](https://github.com/armbian/imager) to ensure all boards are displayed with proper images."
echo ""
echo "- Board images: \`${BOARD_IMAGES_DIR}/<board>.png\` (1920x1080 px transparent)"
echo "- Vendor logos: \`${VENDOR_LOGOS_DIR}/<vendor>-logo.png\` (512x512 px transparent)"
echo ""
echo "### Missing items"
echo ""
} > "$comment_file"
while IFS= read -r cfg; do
[[ -z "${cfg}" ]] && continue
file="$(basename "$cfg")"
board="${file%.*}"
vendor="$(
grep -E '^[[:space:]]*(export[[:space:]]+|declare[[:space:]]+-g[[:space:]]+)?BOARD_VENDOR[[:space:]]*=' -m1 -- "$cfg" 2>/dev/null \
| sed -E 's/^[[:space:]]*(export[[:space:]]+|declare[[:space:]]+-g[[:space:]]+)?BOARD_VENDOR[[:space:]]*=[[:space:]]*//; s/^"//; s/"$//' \
| tr '[:upper:]' '[:lower:]' \
| tr '_' '-' \
| awk 'NF{print; exit}' \
|| true
)"
board_img_match="$(find "website/${BOARD_IMAGES_DIR}" -maxdepth 1 -type f -iname "${board}.png" | head -n1 || true)"
if [[ -z "${board_img_match}" ]]; then
{
echo "- ❌ **Board image missing** for \`${board}\`"
echo " - Expected: \`${BOARD_IMAGES_DIR}/${board}.png\`"
echo " - Fix: add the file to **${WEBSITE_REPO}** (folder \`${BOARD_IMAGES_DIR}/\`)"
echo ""
} >> "$comment_file"
missing_any=1
fi
if [[ -z "${vendor}" ]]; then
{
echo "- ❌ **BOARD_VENDOR not found** in \`${cfg}\`"
echo " - Fix: add e.g. \`BOARD_VENDOR=\"radxa\"\` (lowercase recommended)"
echo ""
} >> "$comment_file"
missing_any=1
continue
fi
found_logo="$(find "website/${VENDOR_LOGOS_DIR}" -maxdepth 1 -type f \
\( -iname "${vendor}-logo.png" -o -iname "${vendor}-logo.jpg" -o -iname "${vendor}-logo.jpeg" -o -iname "${vendor}-logo.svg" \) \
| head -n1 || true)"
if [[ -z "${found_logo}" ]]; then
{
echo "- ❌ **Vendor logo missing** for vendor \`${vendor}\` (used by board \`${board}\`)"
echo " - Expected: \`${VENDOR_LOGOS_DIR}/${vendor}-logo.png\`"
echo " - Fix: add the file to **${WEBSITE_REPO}** (folder \`${VENDOR_LOGOS_DIR}/\`)"
echo " - Naming rules: lowercase, dashes (e.g. \`kobol-logo.png\`, not \`Kobol_logo.png\`)"
echo ""
} >> "$comment_file"
missing_any=1
fi
done < added-files.txt
if [[ "${missing_any}" -ne 0 ]]; then
echo "missing=true" >> "$GITHUB_OUTPUT"
echo 'comment<<EOF' >> "$GITHUB_OUTPUT"
cat "$comment_file" >> "$GITHUB_OUTPUT"
echo 'EOF' >> "$GITHUB_OUTPUT"
echo "::warning ::Missing required assets (see PR comment)."
else
echo "missing=false" >> "$GITHUB_OUTPUT"
fi
- name: "Comment on PR with missing asset instructions"
if: always() && github.event_name == 'pull_request_target' && steps.validate.outputs.missing == 'true'
uses: actions/github-script@v8
env:
COMMENT_BODY: ${{ steps.validate.outputs.comment }}
WEBSITE_REPO: ${{ env.WEBSITE_REPO }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const body =
`### 🚫 Missing required board assets
${process.env.COMMENT_BODY}
Once the missing files are added (or a PR is opened in **${process.env.WEBSITE_REPO}**), re-run this check.
`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body
});

View File

@ -1,54 +0,0 @@
name: "Maintenance: Analyze kernel security"
run-name: 'Check kernel security options - PR #${{ github.event.pull_request.number }} ("${{ github.event.pull_request.title }}")'
#
# Check the Linux kernel options against security hardening
#
# Attention! Changing security parameters may also affect system performance and functionality of userspace software!
# More info:
# https://github.com/a13xp0p0v/kernel-hardening-checker
on:
workflow_dispatch:
pull_request:
types: [ready_for_review, opened, reopened, synchronize]
permissions:
contents: read
concurrency:
group: pipeline-security-${{github.event.pull_request.number}}
cancel-in-progress: true
jobs:
Analysis:
name: Check kernel security options
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'Armbian' }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@7dee1b0c1557f278e5c7dc244927139d78c0e22a # v46.0.3
- name: Checkout repository
uses: actions/checkout@v6
with:
repository: a13xp0p0v/kconfig-hardened-check
path: kconfig-hardened-check
- name: Check kernel config for security issues
# Run kernel-hardening-checker for each kernel config file excluding RISC-V configs, since they are not supported yet.
# See https://github.com/a13xp0p0v/kernel-hardening-checker/issues/56
# sed explanation: 1) Put spaces in front of every line 2) replace colored output with emojis since GitHub Actions job summaries don't support colored output
run: |
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
if [[ "${file}" = config/kernel/*.config && ! $(head -n 10 "${file}" | grep -q "riscv") ]]; then
kconfig-hardened-check/bin/kernel-hardening-checker -m show_fail -c $file | sed 's/^/ /; s/\x1b\[32m/✅ /; s/\x1b\[31m/❌ /; s/\x1b\[0m//' >> $GITHUB_STEP_SUMMARY
fi
done

View File

@ -1,30 +0,0 @@
name: "Maintenance: Clean workflow logs"
on:
schedule:
- cron: "0 0 * * 1" # Runs "At 00:00 on Monday." (see https://crontab.guru)
workflow_dispatch:
inputs:
runs_older_than:
description: "The amount of days old to delete"
default: "10"
required: false
env:
SCHEDULED_RUNS_OLDER_THAN: "10"
SCHEDULED_RUNS_TO_KEEP: "0"
permissions:
contents: read
jobs:
clean-logs:
runs-on: ubuntu-latest
permissions:
actions: write
steps:
- uses: igorjs/gh-actions-clean-workflow@v7
with:
runs_older_than: ${{ github.event.inputs.runs_older_than || env.SCHEDULED_RUNS_OLDER_THAN }}
runs_to_keep: ${{ github.event.inputs.runs_to_keep || env.SCHEDULED_RUNS_TO_KEEP }}

View File

@ -1,58 +0,0 @@
name: "Maintenance: Label PR on approval"
on:
workflow_run:
workflows: ["Maintenance: Listen PR review"]
types: [completed]
permissions:
contents: read
jobs:
label:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
issues: write
pull-requests: write
steps:
- name: Download PR number artifact from upstream run
uses: actions/download-artifact@v8
with:
name: pr-number-${{ github.event.workflow_run.id }} # same unique name
path: .
run-id: ${{ github.event.workflow_run.id }} # ← CRITICAL: fetch from the upstream run
github-token: ${{ secrets.GITHUB_TOKEN }}
- id: pr
run: echo "number=$(cat pr.txt)" >> $GITHUB_OUTPUT
- name: Label when approved
uses: j-fulbright/label-when-approved-action@v1.2
with:
token: ${{ secrets.GITHUB_TOKEN }}
label: 'Ready to merge'
require_committers_approval: 'true'
remove_label_when_approval_missing: 'true'
comment: '✅ This PR has been reviewed and approved — all set for merge!'
pullRequestNumber: ${{ steps.pr.outputs.number }}
- name: Remove review-related labels
if: ${{ success() }}
uses: actions/github-script@v8
with:
script: |
const { owner, repo } = context.repo;
const issue_number = ${{ steps.pr.outputs.number }};
const labelsToRemove = ["Needs review", "Work in progress", "Backlog", "Can be closed?", "Help needed", "Needs Documentation"];
for (const name of labelsToRemove) {
try {
await github.rest.issues.removeLabel({ owner, repo, issue_number, name });
core.info(`Removed label "${name}"`);
} catch (e) {
core.warning(`Could not remove label "${name}": ${e.message}`);
}
}

View File

@ -1,59 +0,0 @@
name: "Maintenance: Lint scripts"
run-name: 'Shellcheck - PR #${{ github.event.pull_request.number }} ("${{ github.event.pull_request.title }}")'
#
# Run ShellCheck on all scripts and generate report as build artifact
#
on:
workflow_dispatch:
pull_request:
types: [opened, reopened, synchronize]
permissions:
contents: read
concurrency:
group: pipeline-lint-${{github.event.pull_request.number}}
cancel-in-progress: true
jobs:
Shellcheck:
name: Shell script analysis
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'Armbian' }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@7dee1b0c1557f278e5c7dc244927139d78c0e22a # v46.0.3
- name: List all changed files
run: |
# Use framework internal mechanism for checking `lib` and `extensions` code only one file is passed,
# and source's are followed, thus the whole project is "understood" by shellcheck.
# For example, when checking individual files, one variable might be thought "unused" because it
# is only used in another file, which does not happen when done properly.
bash lib/tools/shellcheck.sh
ret=0
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
if [[ ! "${file}" =~ lib/|extensions/|.py|.service|.rules|.network|.netdev ]]; then
if grep -qE "^#\!/.*bash" $file; then
shellcheck --severity=error $file || ret=$?
fi
fi
done
exit $ret

View File

@ -1,23 +0,0 @@
name: "Maintenance: Listen PR review"
on:
pull_request_review:
types: [submitted]
permissions:
contents: read
jobs:
ping:
if: ${{ github.event.review.state == 'approved' }}
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Save PR number
run: echo "${{ github.event.pull_request.number }}" > pr.txt
- uses: actions/upload-artifact@v7.0.0
with:
# unique name: includes workflow run id
name: pr-number-${{ github.run_id }}
path: pr.txt

View File

@ -1,296 +0,0 @@
name: "Maintenance: Rewrite kernel configs"
on:
schedule:
- cron: "0 0 * * MON"
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
build-matrix:
name: Build dynamic matrix
runs-on: super
outputs:
matrix: ${{ steps.gen.outputs.matrix }}
count: ${{ steps.gen.outputs.count }}
steps:
- uses: actions/checkout@v6
- name: "Produce inventory JSON"
run: |
./compile.sh inventory-boards
- name: Build matrix from inventory (simple sanitize)
id: gen
shell: bash
run: |
set -euo pipefail
JSON="output/info/image-info.json"
tmp="$(mktemp)"
jq -c '
def norm_branches:
if . == null then []
elif (type=="string") then ( gsub("[,\\s]+";" ") | split(" ") | map(select(length>0)) )
elif (type=="array") then ( map(tostring) | map(select(length>0)) )
else [] end;
# 1) Expand to rows: (board, linuxfamily, branch)
[ .[]
| {
board: (.out.HOST // .in.inventory.BOARD // ""),
linuxfamily: (.out.LINUXFAMILY // .in.inventory.BOARDFAMILY // ""),
branches: ((.in.inventory.BOARD_POSSIBLE_BRANCHES
// .in.inventory.BOARD_TOP_LEVEL_VARS.BOARD_POSSIBLE_BRANCHES)
| norm_branches)
}
| select((.board|length>0) and (.linuxfamily|length>0) and (.branches|length>0))
| . as $o
| $o.branches[]
| { board: $o.board, linuxfamily: $o.linuxfamily, branch: . }
]
# 2) Remove exact triplet duplicates
| unique_by([.linuxfamily,.branch,.board])
# 3) If same (board,branch) appears in multiple families, keep the one with smallest family (lexicographic)
| sort_by(.board, .branch, .linuxfamily)
| group_by([.board,.branch]) | map(.[0])
# 4) If multiple boards share same (family,branch), keep smallest board (lexicographic)
| sort_by(.linuxfamily, .branch, .board)
| group_by([.linuxfamily,.branch]) | map(.[0])
' "$JSON" > "$tmp"
echo "count=$(jq 'length' "$tmp")" >> "$GITHUB_OUTPUT"
echo "matrix=$(jq -c . "$tmp")" >> "$GITHUB_OUTPUT"
rewrite-configs:
name: "Rewrite ${{ matrix.board }} (${{ matrix.branch }})"
needs: build-matrix
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.build-matrix.outputs.matrix) }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Run rewrite-kernel-config
env:
BOARD: ${{ matrix.board }}
BRANCH: ${{ matrix.branch }}
DOCKER_ARMBIAN_BASE_IMAGE: "debian:trixie"
run: |
set -euo pipefail
./compile.sh rewrite-kernel-config BOARD=$BOARD BRANCH=$BRANCH DOCKER_ARMBIAN_BASE_IMAGE="$DOCKER_ARMBIAN_BASE_IMAGE"
- name: Collect changes into artifact (added/modified/renamed only) + step summary
id: collect
shell: bash
run: |
set -euo pipefail
# Get changed paths, NUL-delimited (safe for spaces)
mapfile -d '' -t CHANGED < <(git diff -z --name-only --diff-filter=ACMR || true)
if [[ ${#CHANGED[@]} -eq 0 ]]; then
echo "nothing_to_upload=true" >> "$GITHUB_OUTPUT"
{
echo "### No changes in this job"
echo ""
echo "- Family: **${{ matrix.linuxfamily }}**"
echo "- Branch: **${{ matrix.branch }}**"
echo "- Board: **${{ matrix.board }}**"
} >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
JOB_ID="${{ matrix.linuxfamily }}-${{ matrix.branch }}-${{ matrix.board }}"
ROOT="artifact/${JOB_ID}/payload"
mkdir -p "$ROOT"
# Copy files while preserving directory structure
printf '%s\0' "${CHANGED[@]}" | xargs -0 -I{} cp --parents -a -- "{}" "$ROOT/"
# --- Build GitHub Step Summary with numstat (additions/deletions) ---
# Note: numstat shows '-' for binary changes; we treat those as 0
NUMSTAT="$(mktemp)"
git diff --numstat --diff-filter=ACMR > "$NUMSTAT" || true
total_add=0
total_del=0
file_count=0
{
echo "### Changes for \`$JOB_ID\`"
echo ""
echo "| File | + | - | Δ |"
echo "|---|---:|---:|---:|"
} >> "$GITHUB_STEP_SUMMARY"
# Read tab-delimited: added<TAB>deleted<TAB>path
while IFS=$'\t' read -r add del path; do
[[ -z "${path:-}" ]] && continue
# Handle binary markers '-'
[[ "$add" =~ ^[0-9]+$ ]] || add=0
[[ "$del" =~ ^[0-9]+$ ]] || del=0
delta=$(( add - del ))
total_add=$(( total_add + add ))
total_del=$(( total_del + del ))
file_count=$(( file_count + 1 ))
# Escape pipes in path for Markdown safety
path_esc="${path//|/\\|}"
printf '| %s | %d | %d | %d |\n' "$path_esc" "$add" "$del" "$delta" >> "$GITHUB_STEP_SUMMARY"
done < "$NUMSTAT"
{
echo ""
echo "**Files changed:** $file_count"
echo ""
printf "**Total lines:** +%d / -%d (Δ %d)\n" "$total_add" "$total_del" "$(( total_add - total_del ))"
} >> "$GITHUB_STEP_SUMMARY"
- name: Upload artifact (per job; unique; overwrite safe)
if: steps.collect.outputs.nothing_to_upload != 'true'
uses: actions/upload-artifact@v7.0.0
with:
name: changes-${{ matrix.linuxfamily }}-${{ matrix.branch }}-${{ matrix.board }}-${{ github.run_attempt }}
path: artifact/${{ matrix.linuxfamily }}-${{ matrix.branch }}-${{ matrix.board }}
if-no-files-found: ignore
retention-days: 7
overwrite: true
aggregate-pr:
name: Aggregate changes & open PR
needs: [build-matrix, rewrite-configs]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Download all change artifacts (no merge)
continue-on-error: true
uses: actions/download-artifact@v8
with:
path: _artifacts
pattern: changes-*
- name: Apply all artifacts
shell: bash
run: |
set -euo pipefail
shopt -s nullglob
# Count artifacts
FOUND=0
for d in _artifacts/changes-*; do
[[ -d "$d" ]] || continue
FOUND=$((FOUND+1))
# Apply payload files (add/update)
if [[ -d "$d/payload" ]]; then
# rsync preserves paths; trailing slashes mean "copy contents"
rsync -a "$d/payload/" .
fi
# Accumulate deletions
if [[ -f "$d/deletions.txt" ]]; then
cat "$d/deletions.txt" >> /tmp/all_deletions.txt
fi
done
echo "Aggregated artifacts: $FOUND"
# Apply deletions (dedup + ignore non-existent)
if [[ -s /tmp/all_deletions.txt ]]; then
sort -u /tmp/all_deletions.txt > /tmp/all_deletions_uniq.txt
xargs -r -d '\n' git rm -f --ignore-unmatch < /tmp/all_deletions_uniq.txt || true
fi
# Did anything actually change?
if git diff --quiet; then
echo "NO_CHANGES=true" >> "$GITHUB_ENV"
fi
- name: Build PR body (summary table)
if: env.NO_CHANGES != 'true'
shell: bash
run: |
set -euo pipefail
rm -rf _artifacts || true
mkdir -p output/info
# Per-file stats
git diff --numstat > output/info/numstat.txt || true
total_add=0; total_del=0; files=0
{
echo "# Rewrite kernel configs"
echo
echo "### What this PR does"
echo "- Regenerates and **synchronizes Linux kernel config fragments** across boards/families based on the prepared inventory."
echo "- Runs \`./compile.sh rewrite-kernel-config\` for each scheduled (family, branch) and aggregates all changes into **one PR**."
echo "- No userspace changes; only **Kconfig option** updates (enable/disable/modules/values) aligned with the targeted kernel branches."
echo
echo "### How it was produced"
echo
echo "This PR is produced from [this](/armbian/build/tree/main/.github/workflows/maintenance-rewrite-kernel-configs.yml) GHA script."
echo
echo "1. Built a matrix: \`./compile.sh inventory-boards\` (deduped, sanitized)."
echo "2. Executed \`rewrite-kernel-config\` per matrix."
echo "3. Collected only changed files from each job as artifacts; aggregated and committed them here."
echo
echo "### Review tips"
echo "- Skim the table below for big deltas; open those configs to verify intent."
echo "- If a particular change is undesirable, comment on that file and we can exclude/adjust and re-run."
echo
echo "### Files changed"
echo
echo "| File | + | - | Δ |"
echo "|---|---:|---:|---:|"
while IFS=$'\t' read -r add del path; do
[[ -z "${path:-}" ]] && continue
[[ "$add" =~ ^[0-9]+$ ]] || add=0
[[ "$del" =~ ^[0-9]+$ ]] || del=0
delta=$(( add - del ))
total_add=$(( total_add + add ))
total_del=$(( total_del + del ))
files=$(( files + 1 ))
path_esc="${path//|/\\|}"
printf "| %s | %d | %d | %d |\n" "$path_esc" "$add" "$del" "$delta"
done < output/info/numstat.txt
echo
printf "**Files:** %d • **Lines:** +%d / -%d (Δ %d)\n" "$files" "$total_add" "$total_del" "$(( total_add - total_del ))"
echo
if compgen -G "output/info/annotated-configs/*.md" > /dev/null; then
echo "## Annotated configs"
for f in output/info/annotated-configs/*.md; do
echo "- ${f}"
done
echo
fi
} > PR_BODY.md
- name: Open / Update PR
if: env.NO_CHANGES != 'true'
uses: peter-evans/create-pull-request@v8
with:
add-paths: |
config/kernel/*
token: ${{ secrets.GITHUB_TOKEN }}
branch: update-kernel-configs
delete-branch: true
title: "`Automatic` kernel config rewrite"
commit-message: "Automatic: kernel config rewrite"
body-path: PR_BODY.md
labels: |
Needs review

View File

@ -1,135 +0,0 @@
name: "Maintenance: Rewrite patches"
on:
workflow_dispatch:
inputs:
board:
description: "Board name (e.g. bananapim5, khadas-vim3)"
required: true
type: string
branch:
description: "Branch to use"
required: true
type: choice
options:
- legacy
- vendor
- current
- edge
whattodo:
description: "rewrite uboot or kernel patches"
required: true
type: choice
options:
- rewrite-kernel-patches
- rewrite-uboot-patches
permissions:
contents: write
pull-requests: write
jobs:
rewrite-patches:
name: "Rewrite ${{ inputs.board }} (${{ inputs.branch }})"
runs-on: rewrite
timeout-minutes: 60
steps:
- name: Update existing repository
env:
REF_NAME: ${{ github.ref_name }}
REPO: ${{ github.repository }}
run: |
# Clone or update the repository
if [ -d .git ]; then
# Repo exists: update it
git fetch origin "$REF_NAME"
git checkout "$REF_NAME"
git reset --hard "origin/$REF_NAME"
git clean -fd
else
# No repo: clone it
git clone --depth 1 --filter=blob:none -b "$REF_NAME" "https://github.com/${REPO}" .
git checkout "$REF_NAME"
fi
- name: "Run ${{ inputs.whattodo }}"
env:
BOARD: ${{ inputs.board }}
BRANCH: ${{ inputs.branch }}
WHATTODO: ${{ inputs.whattodo }}
run: |
./compile.sh "BOARD=$BOARD" "BRANCH=$BRANCH" "$WHATTODO" KERNEL_GIT=shallow
- name: Check for changes
env:
WHATTODO: ${{ inputs.whattodo }}
id: check_changes
run: |
set -euo pipefail
if git diff --quiet; then
echo "has_changes=false" >> "$GITHUB_OUTPUT"
echo "::notice::No changes detected after ${WHATTODO}"
else
echo "has_changes=true" >> "$GITHUB_OUTPUT"
echo "::notice::Changes detected after ${WHATTODO} - PR will be created"
fi
- name: Build PR body
env:
WHATTODO: ${{ inputs.whattodo }}
id: build_pr_body
if: steps.check_changes.outputs.has_changes == 'true'
run: |
set -euo pipefail
# Per-file stats
tmp_stats=$(mktemp)
tmp_body=$(mktemp)
git diff --numstat > "$tmp_stats" || true
total_add=0; total_del=0; files=0
{
echo "| File | + | - | Δ |"
echo "|---|---:|---:|---:|"
while IFS=$'\t' read -r add del path; do
[[ -z "${path:-}" ]] && continue
[[ "$add" =~ ^[0-9]+$ ]] || add=0
[[ "$del" =~ ^[0-9]+$ ]] || del=0
delta=$(( add - del ))
total_add=$(( total_add + add ))
total_del=$(( total_del + del ))
files=$(( files + 1 ))
path_esc="${path//|/\\|}"
printf "| %s | %d | %d | %d |\n" "$path_esc" "$add" "$del" "$delta"
done < "$tmp_stats"
echo
printf "**Files:** %d • **Lines:** +%d / -%d (Δ %d)\n" "$files" "$total_add" "$total_del" "$(( total_add - total_del ))"
} > "$tmp_body"
echo "pr_body_path=$tmp_body" >> "$GITHUB_OUTPUT"
- name: Open / Update PR
id: create_pr
if: steps.check_changes.outputs.has_changes == 'true'
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: rewrite-patches/${{ inputs.board }}-${{ inputs.branch }}
delete-branch: true
base: main
title: "`[${{ inputs.branch }}]` `${{ inputs.whattodo }}` for `${{ inputs.board }}`"
commit-message: "[${{ inputs.branch }}] ${{ inputs.whattodo }} for ${{ inputs.board }}"
body-path: ${{ steps.build_pr_body.outputs.pr_body_path }}
labels: |
Needs review
- name: Cleanup temp files
if: steps.build_pr_body.outputs.pr_body_path != ''
run: |
rm -f "${{ steps.build_pr_body.outputs.pr_body_path }}" || true
- name: Reset working directory for next run
if: always()
run: |
git reset --hard HEAD
git clean -fd

View File

@ -1,66 +0,0 @@
name: "Maintenance: Security scan"
run-name: Scan scorecards security on ${{ github.event_name }}
on:
# Only the default branch is supported.
branch_protection_rule:
schedule:
# Weekly on Saturdays.
- cron: "30 1 * * 6"
push:
branches: [main]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
if: ${{ github.repository_owner == 'Armbian' }}
name: Scorecards analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Used to receive a badge. (Upcoming feature)
id-token: write
actions: read
contents: read
steps:
- name: "Checkout code"
uses: actions/checkout@v6
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@v2.4.3
with:
results_file: results.sarif
results_format: sarif
# (Optional) Read-only PAT token. Uncomment the `repo_token` line below if:
# - you want to enable the Branch-Protection check on a *public* repository, or
# - you are installing Scorecards on a *private* repository
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}
# Publish the results for public repositories to enable scorecard badges. For more details, see
# https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories, `publish_results` will automatically be set to `false`, regardless
# of the value entered here.
publish_results: true
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@v4
#5f532563584d71fdef14ee64d17bafb34f751ce5 # v1.0.26
with:
sarif_file: results.sarif

View File

@ -1,98 +0,0 @@
#
# This action recreate action for building stable images
#
name: "Maintenance: Watchdog"
on:
schedule:
- cron: '*/30 * * * *'
workflow_dispatch:
permissions:
actions: write
contents: read
env:
GH_TOKEN: ${{ github.token }}
concurrency:
group: watchdog-${{ github.ref }}
cancel-in-progress: true
jobs:
gradle:
strategy:
fail-fast: false
max-parallel: 8
matrix:
# list scripts you want to watch and execute failed jobs x-times
script: ["maintenance-rewrite-kernel-configs"]
name: R
runs-on: ubuntu-latest
steps:
- name: "Restart ${{ matrix.script }}.yml"
run: |
set -e # Exit on any error
# Configuration
OWNER_REPO="${{ github.repository }}" # Use dynamic repo reference
ATTEMPTS="6" # Maximum retry attempts
SCRIPT="${{ matrix.script }}" # Workflow name to monitor
echo "::group::Workflow Lookup"
echo "Looking for workflow: ${SCRIPT}.yml in ${OWNER_REPO}"
# Get the workflow ID by searching for the workflow file path
WORKFLOW=$(gh api "/repos/${OWNER_REPO}/actions/workflows" \
| jq ".workflows[] | select(.path==\".github/workflows/${SCRIPT}.yml\")" \
| jq -r '.id')
# Validate that we found the workflow
if [[ -z "$WORKFLOW" ]]; then
echo "::error::Workflow '${SCRIPT}.yml' not found"
exit 1
fi
echo "Found workflow ID: ${WORKFLOW}"
echo "::endgroup::"
echo "::group::Run Analysis"
# Get the most recent workflow run (latest = first in array)
RUN_DATA=$(gh api "/repos/${OWNER_REPO}/actions/workflows/${WORKFLOW}/runs" \
| jq '.workflow_runs[0]')
# Extract run details
ID=$(echo "$RUN_DATA" | jq -r '.id')
STATUS=$(echo "$RUN_DATA" | jq -r '.conclusion')
ATTEMPT=$(echo "$RUN_DATA" | jq -r '.run_attempt')
# Validate that we have run data
if [[ -z "$ID" || "$ID" == "null" ]]; then
echo "::error::No workflow runs found"
exit 1
fi
echo "Latest run: ${ID}"
echo "Status: ${STATUS}"
echo "Attempt: ${ATTEMPT} of ${ATTEMPTS}"
echo "::endgroup::"
# Only rerun if:
# - We haven't exceeded max attempts (attempt < 6)
# - The run failed (not cancelled, success, etc)
if [[ "${ATTEMPT}" -lt "${ATTEMPTS}" ]] && [[ "$STATUS" == "failure" ]]; then
echo "::notice::Rerunning failed jobs for run ${ID} (attempt ${ATTEMPT})"
gh api --method POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/${OWNER_REPO}/actions/runs/${ID}/rerun-failed-jobs"
echo "Rerun triggered successfully"
else
echo "No rerun needed:"
echo " - Attempt: ${ATTEMPT}/${ATTEMPTS}"
echo " - Status: ${STATUS}"
fi

View File

@ -1,30 +0,0 @@
name: "Maintenance: Welcome first-time issue contributor"
on:
issues:
types: opened
permissions:
contents: read
jobs:
welcome-first-time-contributor:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: plbstl/first-contribution@v4
with:
labels: "Good first issue"
issue-opened-msg: |
### Hey @{fc-author}! 👋
Thanks for opening your first issue with the Armbian project — were glad to have you here! 🧡
Your input doesnt just help us improve the project — it benefits everyone who uses Armbian.
If you'd like to stay informed about project updates or collaborate more closely with the team,
you can optionally share some personal contact preferences at [armbian.com/update-data](https://www.armbian.com/update-data/).
This helps us keep in touch without relying solely on GitHub notifications.
Also, dont forget to ⭐ star the repo to support the work — and welcome aboard! 🚀

View File

@ -1,29 +0,0 @@
name: "Maintenance: Welcome first-time PR contributor"
on:
pull_request_target:
types: opened
permissions:
contents: read
jobs:
welcome-first-time-contributor:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: plbstl/first-contribution@v4
with:
pr-opened-msg: |
### Hey @{fc-author}! 👋
Thanks for submitting your first pull request to the Armbian project — we're excited to have you contributing! 🧡
Your effort doesnt just improve Armbian — it benefits the entire community of users and developers.
If you'd like to stay informed about project updates or collaborate more closely with the team,
you can optionally share some personal contact preferences at [armbian.com/update-data](https://www.armbian.com/update-data/).
This helps us keep in touch without relying solely on GitHub notifications.
Also, dont forget to ⭐ star the repo if you havent already — and welcome aboard! 🚀

View File

@ -0,0 +1,34 @@
# Pushes the contents of the repo to the Codeberg mirror
name: Mirror to Codeberg
permissions:
contents: read
on:
push:
branches:
- main
workflow_dispatch:
# Cancel older runs if a new one starts (per workflow + branch)
concurrency:
group: ${{ github.workflow }}-${{ github.repository }}-${{ github.ref }}
cancel-in-progress: true
jobs:
codeberg:
# Extra safety so forks don't try to run it
if: ${{ github.repository == 'armbian/build' }}
runs-on: ubuntu-latest
steps:
- name: Checkout full history
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Mirror to Codeberg
uses: pixta-dev/repository-mirroring-action@v1
with:
target_repo_url: git@codeberg.org:armbian/build.git
ssh_private_key: ${{ secrets.GHA_SSH_KEY }}

View File

@ -0,0 +1,296 @@
name: Rewrite kernel configs
on:
schedule:
- cron: "0 0 * * MON"
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
build-matrix:
name: Build dynamic matrix
runs-on: super
outputs:
matrix: ${{ steps.gen.outputs.matrix }}
count: ${{ steps.gen.outputs.count }}
steps:
- uses: actions/checkout@v6
- name: "Produce inventory JSON"
run: |
./compile.sh inventory-boards
- name: Build matrix from inventory (simple sanitize)
id: gen
shell: bash
run: |
set -euo pipefail
JSON="output/info/image-info.json"
tmp="$(mktemp)"
jq -c '
def norm_branches:
if . == null then []
elif (type=="string") then ( gsub("[,\\s]+";" ") | split(" ") | map(select(length>0)) )
elif (type=="array") then ( map(tostring) | map(select(length>0)) )
else [] end;
# 1) Expand to rows: (board, linuxfamily, branch)
[ .[]
| {
board: (.out.HOST // .in.inventory.BOARD // ""),
linuxfamily: (.out.LINUXFAMILY // .in.inventory.BOARDFAMILY // ""),
branches: ((.in.inventory.BOARD_POSSIBLE_BRANCHES
// .in.inventory.BOARD_TOP_LEVEL_VARS.BOARD_POSSIBLE_BRANCHES)
| norm_branches)
}
| select((.board|length>0) and (.linuxfamily|length>0) and (.branches|length>0))
| . as $o
| $o.branches[]
| { board: $o.board, linuxfamily: $o.linuxfamily, branch: . }
]
# 2) Remove exact triplet duplicates
| unique_by([.linuxfamily,.branch,.board])
# 3) If same (board,branch) appears in multiple families, keep the one with smallest family (lexicographic)
| sort_by(.board, .branch, .linuxfamily)
| group_by([.board,.branch]) | map(.[0])
# 4) If multiple boards share same (family,branch), keep smallest board (lexicographic)
| sort_by(.linuxfamily, .branch, .board)
| group_by([.linuxfamily,.branch]) | map(.[0])
' "$JSON" > "$tmp"
echo "count=$(jq 'length' "$tmp")" >> "$GITHUB_OUTPUT"
echo "matrix=$(jq -c . "$tmp")" >> "$GITHUB_OUTPUT"
rewrite-configs:
name: "Rewrite ${{ matrix.board }} (${{ matrix.branch }})"
needs: build-matrix
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.build-matrix.outputs.matrix) }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Run rewrite-kernel-config
env:
BOARD: ${{ matrix.board }}
BRANCH: ${{ matrix.branch }}
DOCKER_ARMBIAN_BASE_IMAGE: "debian:trixie"
run: |
set -euo pipefail
./compile.sh rewrite-kernel-config BOARD=$BOARD BRANCH=$BRANCH DOCKER_ARMBIAN_BASE_IMAGE="$DOCKER_ARMBIAN_BASE_IMAGE"
- name: Collect changes into artifact (added/modified/renamed only) + step summary
id: collect
shell: bash
run: |
set -euo pipefail
# Get changed paths, NUL-delimited (safe for spaces)
mapfile -d '' -t CHANGED < <(git diff -z --name-only --diff-filter=ACMR || true)
if [[ ${#CHANGED[@]} -eq 0 ]]; then
echo "nothing_to_upload=true" >> "$GITHUB_OUTPUT"
{
echo "### No changes in this job"
echo ""
echo "- Family: **${{ matrix.linuxfamily }}**"
echo "- Branch: **${{ matrix.branch }}**"
echo "- Board: **${{ matrix.board }}**"
} >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
JOB_ID="${{ matrix.linuxfamily }}-${{ matrix.branch }}-${{ matrix.board }}"
ROOT="artifact/${JOB_ID}/payload"
mkdir -p "$ROOT"
# Copy files while preserving directory structure
printf '%s\0' "${CHANGED[@]}" | xargs -0 -I{} cp --parents -a -- "{}" "$ROOT/"
# --- Build GitHub Step Summary with numstat (additions/deletions) ---
# Note: numstat shows '-' for binary changes; we treat those as 0
NUMSTAT="$(mktemp)"
git diff --numstat --diff-filter=ACMR > "$NUMSTAT" || true
total_add=0
total_del=0
file_count=0
{
echo "### Changes for \`$JOB_ID\`"
echo ""
echo "| File | + | - | Δ |"
echo "|---|---:|---:|---:|"
} >> "$GITHUB_STEP_SUMMARY"
# Read tab-delimited: added<TAB>deleted<TAB>path
while IFS=$'\t' read -r add del path; do
[[ -z "${path:-}" ]] && continue
# Handle binary markers '-'
[[ "$add" =~ ^[0-9]+$ ]] || add=0
[[ "$del" =~ ^[0-9]+$ ]] || del=0
delta=$(( add - del ))
total_add=$(( total_add + add ))
total_del=$(( total_del + del ))
file_count=$(( file_count + 1 ))
# Escape pipes in path for Markdown safety
path_esc="${path//|/\\|}"
printf '| %s | %d | %d | %d |\n' "$path_esc" "$add" "$del" "$delta" >> "$GITHUB_STEP_SUMMARY"
done < "$NUMSTAT"
{
echo ""
echo "**Files changed:** $file_count"
echo ""
printf "**Total lines:** +%d / -%d (Δ %d)\n" "$total_add" "$total_del" "$(( total_add - total_del ))"
} >> "$GITHUB_STEP_SUMMARY"
- name: Upload artifact (per job; unique; overwrite safe)
if: steps.collect.outputs.nothing_to_upload != 'true'
uses: actions/upload-artifact@v6.0.0
with:
name: changes-${{ matrix.linuxfamily }}-${{ matrix.branch }}-${{ matrix.board }}-${{ github.run_attempt }}
path: artifact/${{ matrix.linuxfamily }}-${{ matrix.branch }}-${{ matrix.board }}
if-no-files-found: ignore
retention-days: 7
overwrite: true
aggregate-pr:
name: Aggregate changes & open PR
needs: [build-matrix, rewrite-configs]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Download all change artifacts (no merge)
continue-on-error: true
uses: actions/download-artifact@v7
with:
path: _artifacts
pattern: changes-*
- name: Apply all artifacts
shell: bash
run: |
set -euo pipefail
shopt -s nullglob
# Count artifacts
FOUND=0
for d in _artifacts/changes-*; do
[[ -d "$d" ]] || continue
FOUND=$((FOUND+1))
# Apply payload files (add/update)
if [[ -d "$d/payload" ]]; then
# rsync preserves paths; trailing slashes mean "copy contents"
rsync -a "$d/payload/" .
fi
# Accumulate deletions
if [[ -f "$d/deletions.txt" ]]; then
cat "$d/deletions.txt" >> /tmp/all_deletions.txt
fi
done
echo "Aggregated artifacts: $FOUND"
# Apply deletions (dedup + ignore non-existent)
if [[ -s /tmp/all_deletions.txt ]]; then
sort -u /tmp/all_deletions.txt > /tmp/all_deletions_uniq.txt
xargs -r -d '\n' git rm -f --ignore-unmatch < /tmp/all_deletions_uniq.txt || true
fi
# Did anything actually change?
if git diff --quiet; then
echo "NO_CHANGES=true" >> "$GITHUB_ENV"
fi
- name: Build PR body (summary table)
if: env.NO_CHANGES != 'true'
shell: bash
run: |
set -euo pipefail
rm -rf _artifacts || true
mkdir -p output/info
# Per-file stats
git diff --numstat > output/info/numstat.txt || true
total_add=0; total_del=0; files=0
{
echo "# Rewrite kernel configs"
echo
echo "### What this PR does"
echo "- Regenerates and **synchronizes Linux kernel config fragments** across boards/families based on the prepared inventory."
echo "- Runs \`./compile.sh rewrite-kernel-config\` for each scheduled (family, branch) and aggregates all changes into **one PR**."
echo "- No userspace changes; only **Kconfig option** updates (enable/disable/modules/values) aligned with the targeted kernel branches."
echo
echo "### How it was produced"
echo
echo "This PR is produced from [this](/armbian/build/tree/main/.github/workflows/rewrite-kernel-config-files.yml) GHA script."
echo
echo "1. Built a matrix: \`./compile.sh inventory-boards\` (deduped, sanitized)."
echo "2. Executed \`rewrite-kernel-config\` per matrix."
echo "3. Collected only changed files from each job as artifacts; aggregated and committed them here."
echo
echo "### Review tips"
echo "- Skim the table below for big deltas; open those configs to verify intent."
echo "- If a particular change is undesirable, comment on that file and we can exclude/adjust and re-run."
echo
echo "### Files changed"
echo
echo "| File | + | - | Δ |"
echo "|---|---:|---:|---:|"
while IFS=$'\t' read -r add del path; do
[[ -z "${path:-}" ]] && continue
[[ "$add" =~ ^[0-9]+$ ]] || add=0
[[ "$del" =~ ^[0-9]+$ ]] || del=0
delta=$(( add - del ))
total_add=$(( total_add + add ))
total_del=$(( total_del + del ))
files=$(( files + 1 ))
path_esc="${path//|/\\|}"
printf "| %s | %d | %d | %d |\n" "$path_esc" "$add" "$del" "$delta"
done < output/info/numstat.txt
echo
printf "**Files:** %d • **Lines:** +%d / -%d (Δ %d)\n" "$files" "$total_add" "$total_del" "$(( total_add - total_del ))"
echo
if compgen -G "output/info/annotated-configs/*.md" > /dev/null; then
echo "## Annotated configs"
for f in output/info/annotated-configs/*.md; do
echo "- ${f}"
done
echo
fi
} > PR_BODY.md
- name: Open / Update PR
if: env.NO_CHANGES != 'true'
uses: peter-evans/create-pull-request@v8
with:
add-paths: |
config/kernel/*
token: ${{ secrets.GITHUB_TOKEN }}
branch: update-kernel-configs
delete-branch: true
title: "`Automatic` kernel config rewrite"
commit-message: "Automatic: kernel config rewrite"
body-path: PR_BODY.md
labels: |
Needs review

66
.github/workflows/scorecard.yml vendored Normal file
View File

@ -0,0 +1,66 @@
name: Scan security
run-name: Scan scorecards security on ${{ github.event_name }}
on:
# Only the default branch is supported.
branch_protection_rule:
schedule:
# Weekly on Saturdays.
- cron: "30 1 * * 6"
push:
branches: [main]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
if: ${{ github.repository_owner == 'Armbian' }}
name: Scorecards analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Used to receive a badge. (Upcoming feature)
id-token: write
actions: read
contents: read
steps:
- name: "Checkout code"
uses: actions/checkout@v6
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@v2.4.3
with:
results_file: results.sarif
results_format: sarif
# (Optional) Read-only PAT token. Uncomment the `repo_token` line below if:
# - you want to enable the Branch-Protection check on a *public* repository, or
# - you are installing Scorecards on a *private* repository
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}
# Publish the results for public repositories to enable scorecard badges. For more details, see
# https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories, `publish_results` will automatically be set to `false`, regardless
# of the value entered here.
publish_results: true
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@v4
#5f532563584d71fdef14ee64d17bafb34f751ce5 # v1.0.26
with:
sarif_file: results.sarif

21
.github/workflows/sync-board-list.yml vendored Normal file
View File

@ -0,0 +1,21 @@
name: Sync board list
run-name: Update board list at armbian/os
on:
push:
paths:
- "config/boards/*.*"
branches: [main]
jobs:
update-board-list-dispatch:
name: Send dispatch
if: ${{ github.repository_owner == 'Armbian' }}
runs-on: ubuntu-latest
steps:
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@v4
with:
token: ${{ secrets.ACCESS_TOKEN }}
repository: armbian/os
event-type: "Refresh board list"

36
.github/workflows/sync-labels.yml vendored Normal file
View File

@ -0,0 +1,36 @@
name: Sync labels
run-name: Sync Labels from YML on ${{ github.event_name }}
on:
workflow_dispatch:
push:
branches:
- "main"
paths:
- ".github/labels.yml"
pull_request:
paths:
- ".github/labels.yml"
jobs:
labeler:
permissions:
contents: read # for actions/labeler to determine modified files
pull-requests: write # for actions/labeler to add labels to PRs
issues: write # for actions/labeler to add labels to issues
if: ${{ github.repository_owner == 'Armbian' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Run Labeler
uses: crazy-max/ghaction-github-labeler@v5
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
yaml-file: .github/labels.yml
dry-run: ${{ github.event_name == 'pull_request' }}
exclude: |
Maintenance*

View File

@ -0,0 +1,121 @@
name: Sync maintainers
# Script connects to the contacts database once per hour and updates BOARD_MAINTAINER property in the board config files.
# If there are any changes, it opens a Pull Request
#
# spdx-id: GPL-2.0-or-later
# copyright-owner: @igorpecovnik
on:
schedule:
- cron: "0 * * * *"
workflow_dispatch:
jobs:
Build:
name: "Maintainers sync"
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'armbian' }}
steps:
- name: "Checkout build repo"
uses: actions/checkout@v6
with:
repository: armbian/build
ref: main
fetch-depth: 0
clean: false
- name: "Install SSH key for storage"
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: "Download JSON file"
run: |
# download json that is prepared in https://github.com/armbian/armbian.github.io
curl -o /tmp/armbian_maintainers.json https://github.armbian.com/maintainers.json
- name: "Update maintainers"
run: |
# reset all maintainers so we generate from scratch
sed -i "s/BOARD_MAINTAINER.*/BOARD_MAINTAINER=\"\"/" config/boards/*.{conf,wip,eos,tvb}
# extract values fron JSON
declare -A MAINTAINERS
{
# By default, bash run the pipe command in subshells
# which make variable can't be assigned to.
# And yes, lastpipe can solve it
# But this is better.
while read -r i; do
NAME="$(echo "$i" | jq --raw-output '.First_Name')"
BOARD="$(echo "$i" | jq --raw-output '.Maintaining')"
MAINTAINER_GITHUB="$(echo "$i" | jq --raw-output '.Github' | cut -d"/" -f4)"
if [[ "$BOARD" != null && "$MAINTAINER_GITHUB" != null ]]; then
echo "- [$NAME](https://github.com/${MAINTAINER_GITHUB})"
while read -r i; do
echo -e " - $i"
MAINTAINERS["$i"]+="$MAINTAINER_GITHUB "
done < <( echo "$BOARD" | sed "s/,/\n/g" | sort -u )
fi
done < <(jq -c '.[]' /tmp/armbian_maintainers.json)
for cfg in config/boards/*.{conf,wip,csc,eos,tvb}; do
board_name="$(echo "${cfg##*/}" | sed -E 's/\..*//')"
declare -a maintainers
readarray -t maintainers < <(echo "${MAINTAINERS[${board_name}]}" | xargs -n1 | sort -u)
sed -i "s/BOARD_MAINTAINER=.*/BOARD_MAINTAINER=\"${maintainers[*]}\"/" "${cfg}"
done
} >> "$GITHUB_STEP_SUMMARY"
- name: "Mark csc for no maintainer"
run: |
grep BOARD_MAINTAINER=\"\" config/boards/*.{wip,conf} | cut -d":" -f1 |
while read -r line; do
if [[ "${line}" != "${line/.conf/.csc}" ]]; then
mv -v "$line" "${line/.conf/.csc}"
fi
if [[ "${line}" != "${line/.wip/.csc}" ]]; then
mv -v "$line" "${line/.wip/.csc}"
fi
done
- name: "Re-generate CODEOWNERS"
run: |
./.github/generate_CODEOWNERS.sh
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: '`Automatic` board configs status synchronise'
signoff: false
branch: update-maintainers
delete-branch: true
title: '`Automatic` board configs status synchronise'
body: |
Update maintainers and board status
- synced status from the database
- rename to .`csc` where we don't have anyone
If you want to become a board maintainer, [adjust data here](https://www.armbian.com/update-data/).
Ref:
- [Board Maintainers Procedures and Guidelines](https://docs.armbian.com/Board_Maintainers_Procedures_and_Guidelines/)
- [Contribute](https://docs.armbian.com/Process_Contribute/)
labels: |
Work in progress
#assignees: igorpecovnik
#reviewers: Must be org collaborator
draft: false

104
.github/workflows/sync-tools.yml vendored Normal file
View File

@ -0,0 +1,104 @@
name: Sync tools
run-name: Update Tools in Scripts by @${{ github.actor }}
#
# Some of our scripts download tools from a repo. These can't be bumped by dependabot, so this workflow is a self-created dependabot to bump versions of those tools to stay up-to-date.
# This workflow only creates a PR if the version was actually updated.
# To add a new tool, it just needs to be added to the matrix below by filling out all the variables.
#
permissions:
contents: write
pull-requests: write
on:
workflow_dispatch:
schedule:
- cron: "42 3 16 * *" # Run monthly on the 16th day of the month at 03:42 AM (random value as to not overload GitHub)
jobs:
update-tool-version:
name: Update ${{ matrix.tool.REPO_NAME }} version
runs-on: ubuntu-latest
# Add new tools here, no need to add anything anywhere else.
# Only works for tools hosted on GitHub for now.
strategy:
matrix:
tool:
# Shellcheck
- USER_NAME: "koalaman" # GitHub user name
REPO_NAME: "shellcheck" # GitHub repo name
PROJECT_NAME: "koalaman/shellcheck" # This is always USER_NAME/REPO_NAME (like in the GitHub URL)
VAR_FILE: "lib/tools/shellcheck.sh" # Where the version variable of the tool is saved
VERSION_VAR: "SHELLCHECK_VERSION" # Version variable how it appears in the script
# Shellcheck #2
- USER_NAME: "koalaman"
REPO_NAME: "shellcheck"
PROJECT_NAME: "koalaman/shellcheck"
VAR_FILE: "lib/functions/general/shellcheck.sh"
VERSION_VAR: "SHELLCHECK_VERSION"
# Shellfmt
- USER_NAME: "mvdan"
REPO_NAME: "sh"
PROJECT_NAME: "mvdan/sh"
VAR_FILE: "lib/tools/shellfmt.sh"
VERSION_VAR: "SHELLFMT_VERSION"
# ORAS
- USER_NAME: "oras-project"
REPO_NAME: "oras"
PROJECT_NAME: "oras-project/oras"
VAR_FILE: "lib/functions/general/oci-oras.sh"
VERSION_VAR: "ORAS_VERSION"
# Bat
- USER_NAME: "sharkdp"
REPO_NAME: "bat"
PROJECT_NAME: "sharkdp/bat"
VAR_FILE: "lib/functions/general/bat-cat.sh"
VERSION_VAR: "BATCAT_VERSION"
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Get current ${{ matrix.tool.PROJECT_NAME }} version
id: get-version-current
run: |
version_current=$(grep -Po '(?<=${{ matrix.tool.VERSION_VAR}}=\${${{ matrix.tool.VERSION_VAR}}:-)[0-9.]+(?=})' ${{ matrix.tool.VAR_FILE }})
echo "version_current=$version_current" >> $GITHUB_OUTPUT
- name: Get latest ${{ matrix.tool.PROJECT_NAME }} version
id: get-version-latest
# Multi-line string for CHANGE_LOG env, see https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
# Further exmplanation for the CHANGE_LOG env:
# The first 'sed' expression replaces "#123" with "username/repo#123" to link to the correct repo (would otherwise auto-link to own repo)
# The second 'sed' expression replaces GitHub URLs with "redirect.github.com" to prevent "This was referenced" in the external repo's PRs/issues
run: |
version_latest=$(curl --silent "https://api.github.com/repos/${{ matrix.tool.PROJECT_NAME }}/releases/latest" | jq -r .tag_name)
version_latest=${version_latest#v} # Removing the 'v' prefix since the script uses only plain numbers
echo "version_latest=$version_latest" >> $GITHUB_OUTPUT
- name: Update ${{ matrix.tool.VERSION_VAR}} in script
# @TODO Make sure that the version is actually higher, not lower (the 'latest' tag does not neccessarily mean that the version is higher!)
run: |
version_latest=${{ steps.get-version-latest.outputs.version_latest }}
sed -i "s/${{ matrix.tool.VERSION_VAR}}=\${${{ matrix.tool.VERSION_VAR}}:-[0-9.]*}/${{ matrix.tool.VERSION_VAR}}=\${${{ matrix.tool.VERSION_VAR}}:-$version_latest}/g" ${{ matrix.tool.VAR_FILE }}
- name: Create Pull Request to update ${{ matrix.tool.VERSION_VAR}} for ${{ matrix.tool.PROJECT_NAME }}
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "tools: Bump `${{ matrix.tool.VERSION_VAR}}` from ${{ steps.get-version-current.outputs.version_current }} to ${{ steps.get-version-latest.outputs.version_latest }}"
branch: update-version-${{ matrix.tool.VAR_FILE }}-${{ matrix.tool.PROJECT_NAME }}-${{ steps.get-version-latest.outputs.version_latest }}
delete-branch: true
title: "Bump ${{ matrix.tool.PROJECT_NAME}} from ${{ steps.get-version-current.outputs.version_current }} to ${{ steps.get-version-latest.outputs.version_latest }} in `${{ matrix.tool.VAR_FILE}}`"
body: |
Bump [${{ matrix.tool.PROJECT_NAME}}](https://github.com/${{ matrix.tool.PROJECT_NAME }}) from ${{ steps.get-version-current.outputs.version_current }} to ${{ steps.get-version-latest.outputs.version_latest }} by bumping `${{ matrix.tool.VERSION_VAR}}` in `${{ matrix.tool.VAR_FILE}}`.
Check <a href="https://github.com/${{ matrix.tool.PROJECT_NAME }}/releases/latest">the upstream release notes</a>.
<p><em>Please note that the above link only shows the release notes for the latest release.</em></p>
labels: Dependencies, Bash

98
.github/workflows/watchdog.yml vendored Normal file
View File

@ -0,0 +1,98 @@
#
# This action recreate action for building stable images
#
name: Watchdog
on:
schedule:
- cron: '*/30 * * * *'
workflow_dispatch:
permissions:
actions: write
contents: read
env:
GH_TOKEN: ${{ github.token }}
concurrency:
group: watchdog-${{ github.ref }}
cancel-in-progress: true
jobs:
gradle:
strategy:
fail-fast: false
max-parallel: 8
matrix:
# list scripts you want to watch and execute failed jobs x-times
script: ["rewrite-kernel-config-files"]
name: R
runs-on: ubuntu-latest
steps:
- name: "Restart ${{ matrix.script }}.yml"
run: |
set -e # Exit on any error
# Configuration
OWNER_REPO="${{ github.repository }}" # Use dynamic repo reference
ATTEMPTS="6" # Maximum retry attempts
SCRIPT="${{ matrix.script }}" # Workflow name to monitor
echo "::group::Workflow Lookup"
echo "Looking for workflow: ${SCRIPT}.yml in ${OWNER_REPO}"
# Get the workflow ID by searching for the workflow file path
WORKFLOW=$(gh api "/repos/${OWNER_REPO}/actions/workflows" \
| jq ".workflows[] | select(.path==\".github/workflows/${SCRIPT}.yml\")" \
| jq -r '.id')
# Validate that we found the workflow
if [[ -z "$WORKFLOW" ]]; then
echo "::error::Workflow '${SCRIPT}.yml' not found"
exit 1
fi
echo "Found workflow ID: ${WORKFLOW}"
echo "::endgroup::"
echo "::group::Run Analysis"
# Get the most recent workflow run (latest = first in array)
RUN_DATA=$(gh api "/repos/${OWNER_REPO}/actions/workflows/${WORKFLOW}/runs" \
| jq '.workflow_runs[0]')
# Extract run details
ID=$(echo "$RUN_DATA" | jq -r '.id')
STATUS=$(echo "$RUN_DATA" | jq -r '.conclusion')
ATTEMPT=$(echo "$RUN_DATA" | jq -r '.run_attempt')
# Validate that we have run data
if [[ -z "$ID" || "$ID" == "null" ]]; then
echo "::error::No workflow runs found"
exit 1
fi
echo "Latest run: ${ID}"
echo "Status: ${STATUS}"
echo "Attempt: ${ATTEMPT} of ${ATTEMPTS}"
echo "::endgroup::"
# Only rerun if:
# - We haven't exceeded max attempts (attempt < 6)
# - The run failed (not cancelled, success, etc)
if [[ "${ATTEMPT}" -lt "${ATTEMPTS}" ]] && [[ "$STATUS" == "failure" ]]; then
echo "::notice::Rerunning failed jobs for run ${ID} (attempt ${ATTEMPT})"
gh api --method POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/${OWNER_REPO}/actions/runs/${ID}/rerun-failed-jobs"
echo "Rerun triggered successfully"
else
echo "No rerun needed:"
echo " - Attempt: ${ATTEMPT}/${ATTEMPTS}"
echo " - Status: ${STATUS}"
fi

View File

@ -0,0 +1,27 @@
name: Welcome first-time contributor
on:
issues:
types: opened
jobs:
welcome-first-time-contributor:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: plbstl/first-contribution@v4
with:
labels: "Good first issue"
issue-opened-msg: |
### Hey @{fc-author}! 👋
Thanks for opening your first issue with the Armbian project — were glad to have you here! 🧡
Your input doesnt just help us improve the project — it benefits everyone who uses Armbian.
If you'd like to stay informed about project updates or collaborate more closely with the team,
you can optionally share some personal contact preferences at [armbian.com/update-data](https://www.armbian.com/update-data/).
This helps us keep in touch without relying solely on GitHub notifications.
Also, dont forget to ⭐ star the repo to support the work — and welcome aboard! 🚀

View File

@ -0,0 +1,26 @@
name: Welcome first-time PR contributor
on:
pull_request_target:
types: opened
jobs:
welcome-first-time-contributor:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: plbstl/first-contribution@v4
with:
pr-opened-msg: |
### Hey @{fc-author}! 👋
Thanks for submitting your first pull request to the Armbian project — we're excited to have you contributing! 🧡
Your effort doesnt just improve Armbian — it benefits the entire community of users and developers.
If you'd like to stay informed about project updates or collaborate more closely with the team,
you can optionally share some personal contact preferences at [armbian.com/update-data](https://www.armbian.com/update-data/).
This helps us keep in touch without relying solely on GitHub notifications.
Also, dont forget to ⭐ star the repo if you havent already — and welcome aboard! 🚀

2
.gitignore vendored
View File

@ -22,7 +22,7 @@ ubuntu-*-cloudimg-console.log
.DS_Store
*~
*.swp
**/__pycache__/
/__pycache__/*
# Mainly generated by merge tools like 'meld'
*.orig

View File

@ -57,7 +57,7 @@ Get help from users and contributors on troubleshooting, configuration, and deve
👉 [forum.armbian.com](https://forum.armbian.com)
### Real-time Chat
Join discussions with developers and community members on IRC or Discord.
Join discussions with developers and community members on Discord, IRC, or Matrix.
👉 [Community Chat](https://docs.armbian.com/Community_IRC/)
### Paid Consultation

View File

@ -109,7 +109,7 @@ runs:
- name: "Import GPG key"
if: ${{ inputs.armbian_pgp_key != '' }}
uses: crazy-max/ghaction-import-gpg@v7
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ inputs.armbian_pgp_key }}
passphrase: ${{ inputs.armbian_pgp_password }}

View File

@ -80,6 +80,7 @@ If you are unsure about the documentation then invoke `$ grep -r -A5 -B5 "BUILD_
- [branch]: Use specified [branch] kernel
- [none]: Exits with error
- **KERNEL_TEST_TARGET** ( comma-separated list of kernel releases or branches ): if test targets are different for testings. Also applies to build list generation. (internal switch)
- **KERNEL_UPGRADE_FREEZE** ( comma-separated list of kernels with versions obove which they stop updating, example: KERNEL_UPGRADE_FREEZE="vendor-rk35xx@24.8.1,current-rockchip-rk3588@24.8.2" )
- **FULL_DESKTOP** ( boolean ): defines whether to install desktop stack of applications such as office, thunderbird, etc..
- Values:
- yes: install desktop stack

View File

@ -1,66 +1,42 @@
# Qualcomm SM8550 octa core 8GB/12GB/16GB RAM SoC eMMC USB-C WiFi/BT
# Ayn Odin2 Configuration
declare -g BOARD_NAME="Ayn Odin2"
declare -g BOARD_VENDOR="ayntec"
declare -g BOARD_MAINTAINER="FantasyGmm Squishy123 kasimling"
declare -g BOARD_MAINTAINER="FantasyGmm"
declare -g BOARDFAMILY="sm8550"
declare -g KERNEL_TARGET="current,edge"
declare -g KERNEL_TEST_TARGET="current"
declare -g KERNEL_TARGET="current"
declare -g KERNEL_TEST_TARGET="edge"
declare -g EXTRAWIFI="no"
declare -g BOOTCONFIG="none"
declare -g BOOTFS_TYPE="fat"
declare -g BOOTSIZE="256"
declare -g IMAGE_PARTITION_TABLE="gpt"
declare -g BOOTIMG_CMDLINE_EXTRA="clk_ignore_unused pd_ignore_unused rw quiet rootwait"
# Use the full firmware, complete linux-firmware plus Armbian's
declare -g BOARD_FIRMWARE_INSTALL="-full"
declare -g DESKTOP_AUTOLOGIN="yes"
# Check to make sure variants are supported
declare -g VALID_BOARDS=("ayn-odin2" "ayn-odin2portal" "ayn-odin2mini" "ayn-thor")
declare -g WITH_GRUB="${WITH_GRUB:-no}"
if [[ ! " ${VALID_BOARDS[*]} " =~ " ${BOARD} " ]]; then
exit_with_error "Error: Invalid board '$BOARD'. Valid options are: ${VALID_BOARDS[*]}" >&2
fi
# set grub
if [[ "${WITH_GRUB}" == "yes" ]]; then
display_alert "GRUB DETECTED"
declare -g UEFI_GRUB_TERMINAL="gfxterm" # Use graphics in grub, for the Armbian wallpaper.
declare -g GRUB_CMDLINE_LINUX_DEFAULT="clk_ignore_unused pd_ignore_unused arm64.nopauth efi=noruntime fbcon=rotate:1 console=ttyMSM0,115200n8"
declare -g BOOT_FDT_FILE="qcom/qcs8550-${BOARD}.dtb"
declare -g SERIALCON="${SERIALCON:-tty1}"
enable_extension "grub"
enable_extension "grub-with-dtb" # important, puts the whole DTB handling in place.
else
declare -g BOOTFS_TYPE="fat"
declare -g BOOTSIZE="256"
declare -g IMAGE_PARTITION_TABLE="gpt"
declare -g BOOTIMG_CMDLINE_EXTRA="clk_ignore_unused pd_ignore_unused rw quiet rootwait"
function pre_umount_final_image__update_ABL_settings() {
if [ -z "$BOOTFS_TYPE" ]; then
return 0
fi
display_alert "Update ABL settings for " "${BOARD}" "info"
uuid_line=$(head -n 1 "${SDCARD}"/etc/fstab)
rootfs_image_uuid=$(echo "${uuid_line}" | awk '{print $1}' | awk -F '=' '{print $2}')
initrd_name=$(find "${SDCARD}/boot/" -type f -name "config-*" | sed 's/.*config-//')
sed -i "s/UUID_PLACEHOLDER/${rootfs_image_uuid}/g" "${MOUNT}"/boot/LinuxLoader.cfg
sed -i "s/INITRD_PLACEHOLDER/${initrd_name}/g" "${MOUNT}"/boot/LinuxLoader.cfg
}
fi
function ayn-odin2_is_userspace_supported() {
[[ "${RELEASE}" == "jammy" ]] && return 0
[[ "${RELEASE}" == "trixie" ]] && return 0
[[ "${RELEASE}" == "noble" ]] && return 0
return 1
}
function pre_customize_image__ayn-odin2_alsa_ucm_conf() {
if ! ayn-odin2_is_userspace_supported; then
return 0
fi
display_alert "Add alsa-ucm-conf for ${BOARD}" "${RELEASE}" "warn"
(
(
cd "${SDCARD}/usr/share/alsa" || exit 6
curl -L -o temp.zip "https://github.com/AYNTechnologies/alsa-ucm-conf/archive/refs/heads/ayn/v1.2.13.zip"
unzip -o temp.zip
unzip_dir=$(unzip -Z1 temp.zip | head -n1 | cut -d/ -f1)
cp -rf "${unzip_dir}/"* .
rm -rf "$unzip_dir" temp.zip
) )
)
}
function post_family_tweaks_bsp__ayn-odin2_firmware() {
@ -82,11 +58,23 @@ function post_family_tweaks_bsp__ayn-odin2_firmware() {
}
function post_family_tweaks__ayn-odin2_enable_services() {
if ! ayn-odin2_is_userspace_supported; then
if [[ "${RELEASE}" != "" ]]; then
display_alert "Missing userspace for ${BOARD}" "${RELEASE} does not have the userspace necessary to support the ${BOARD}" "warn"
fi
return 0
fi
if [[ "${RELEASE}" == "jammy" ]] || [[ "${RELEASE}" == "noble" ]]; then
display_alert "Adding Mesa PPA For Ubuntu ${BOARD}" "warn"
do_with_retries 3 chroot_sdcard add-apt-repository ppa:liujianfeng1994/qcom-mainline --yes --no-update
fi
# We need unudhcpd from armbian repo, so enable it
mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled "${SDCARD}"/etc/apt/sources.list.d/armbian.sources
do_with_retries 3 chroot_sdcard_apt_get_update
display_alert "Installing ${BOARD} tweaks" "warn"
display_alert "Installing ${BOARD} tweaks" "warn"
do_with_retries 3 chroot_sdcard_apt_get_install alsa-ucm-conf qbootctl qrtr-tools unudhcpd mkbootimg
# disable armbian repo back
mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled
@ -99,35 +87,45 @@ function post_family_tweaks__ayn-odin2_enable_services() {
chroot_sdcard systemctl mask suspend.target
chroot_sdcard systemctl enable usbgadget-rndis.service
cp "${SRC}/packages/bsp/${BOARD}/LinuxLoader.cfg" "${SDCARD}"/boot/
cp $SRC/packages/bsp/ayn-odin2/LinuxLoader.cfg "${SDCARD}"/boot/
return 0
}
function post_family_tweaks_bsp__ayn-odin2_bsp_firmware_in_initrd() {
display_alert "Adding to bsp-cli" "${BOARD}: firmware in initrd" "warn"
declare file_added_to_bsp_destination # Will be filled in by add_file_from_stdin_to_bsp_destination
add_file_from_stdin_to_bsp_destination "/etc/initramfs-tools/hooks/ayn-firmware" <<- 'FIRMWARE_HOOK'
#!/bin/bash
[[ "$1" == "prereqs" ]] && exit 0
. /usr/share/initramfs-tools/hook-functions
for f in $(find /lib/firmware/qcom/sm8550 -type f) ; do
add_firmware "${f#/lib/firmware/}"
done
add_firmware "qcom/a740_sqe.fw" # Extra one for dpu
add_firmware "qcom/gmu_gen70200.bin" # Extra one for gpu
add_firmware "qcom/vpu/vpu30_p4.mbn" # Extra one for vpu
# Extra one for wifi
for f in $(find /lib/firmware/ath12k/WCN7850/hw2.0 -type f) ; do
add_firmware "${f#/lib/firmware/}"
done
# Extra one for bt
for f in $(find /lib/firmware/qca -type f) ; do
add_firmware "${f#/lib/firmware/}"
done
FIRMWARE_HOOK
# Using odin2's firmware for now
add_file_from_stdin_to_bsp_destination "/etc/initramfs-tools/hooks/ayn-odin2-firmware" <<- 'FIRMWARE_HOOK'
#!/bin/bash
[[ "$1" == "prereqs" ]] && exit 0
. /usr/share/initramfs-tools/hook-functions
for f in /lib/firmware/qcom/sm8550/ayn/odin2portal/* ; do
add_firmware "${f#/lib/firmware/}"
done
add_firmware "qcom/a740_sqe.fw" # Extra one for dpu
add_firmware "qcom/gmu_gen70200.bin" # Extra one for gpu
add_firmware "qcom/vpu/vpu30_p4.mbn" # Extra one for vpu
# Extra one for wifi
for f in /lib/firmware/ath12k/WCN7850/hw2.0/* ; do
add_firmware "${f#/lib/firmware/}"
done
# Extra one for bt
for f in /lib/firmware/qca/* ; do
add_firmware "${f#/lib/firmware/}"
done
FIRMWARE_HOOK
run_host_command_logged chmod -v +x "${file_added_to_bsp_destination}"
}
function pre_umount_final_image__update_ABL_settings() {
if [ -z "$BOOTFS_TYPE" ]; then
return 0
fi
display_alert "Update ABL settings for " "${BOARD}" "info"
uuid_line=$(head -n 1 "${SDCARD}"/etc/fstab)
rootfs_image_uuid=$(echo "${uuid_line}" | awk '{print $1}' | awk -F '=' '{print $2}')
initrd_name=$(find "${SDCARD}/boot/" -type f -name "config-*" | sed 's/.*config-//')
sed -i "s/UUID_PLACEHOLDER/${rootfs_image_uuid}/g" "${MOUNT}"/boot/LinuxLoader.cfg
sed -i "s/INITRD_PLACEHOLDER/${initrd_name}/g" "${MOUNT}"/boot/LinuxLoader.cfg
}

View File

@ -1,5 +0,0 @@
# Qualcomm SM8550 octa core 8GB/12GB/16GB RAM SoC eMMC USB-C WiFi/BT
source "${SRC}/config/boards/ayn-odin2.csc"
declare -g BOARD_NAME="Ayn Odin2 Mini"
declare -g BOARD_VENDOR="ayntec"
declare -g BOARD_MAINTAINER="Squishy123"

View File

@ -1,5 +0,0 @@
# Qualcomm SM8550 octa core 8GB/12GB/16GB RAM SoC eMMC USB-C WiFi/BT
source "${SRC}/config/boards/ayn-odin2.csc"
declare -g BOARD_NAME="Ayn Odin2 Portal"
declare -g BOARD_VENDOR="ayntec"
declare -g BOARD_MAINTAINER="Squishy123"

View File

@ -1,5 +0,0 @@
# Qualcomm SM8550 octa core 8GB/12GB/16GB RAM SoC eMMC USB-C WiFi/BT
source "${SRC}/config/boards/ayn-odin2.csc"
declare -g BOARD_NAME="Ayn Thor"
declare -g BOARD_VENDOR="ayntec"
declare -g BOARD_MAINTAINER="Squishy123"

View File

@ -11,8 +11,8 @@ FULL_DESKTOP="yes"
SERIALCON="ttyAML0"
BOOT_LOGO="desktop"
BOOT_FDT_FILE="amlogic/meson-g12b-bananapi-cm4-cm4io.dtb"
BOOTBRANCH_BOARD="tag:v2026.01"
BOOTPATCHDIR="v2026.01"
BOOTBRANCH_BOARD="tag:v2025.01"
BOOTPATCHDIR="v2025.01"
# CPUFREQ (/etc/default/cpufrequtils)
CPUMIN=1000000

View File

@ -4,7 +4,7 @@ BOARD_VENDOR="sinovoip"
BOARDFAMILY="spacemit"
BOARD_MAINTAINER="pyavitz"
BOARD_VENDOR="spacemit"
KERNEL_TARGET="legacy,current,edge"
KERNEL_TARGET="current,edge"
BOOT_FDT_FILE="spacemit/k1-bananapi-f3.dtb"
BOOTDELAY=1
SRC_EXTLINUX="yes"

View File

@ -11,8 +11,8 @@ FULL_DESKTOP="yes"
SERIALCON="ttyAML0"
BOOT_LOGO="desktop"
BOOT_FDT_FILE="amlogic/meson-g12b-a311d-bananapi-m2s.dtb"
BOOTBRANCH_BOARD="tag:v2026.01"
BOOTPATCHDIR="v2026.01"
BOOTBRANCH_BOARD="tag:v2025.01"
BOOTPATCHDIR="v2025.01"
# CPUFREQ (/etc/default/cpufrequtils)
CPUMIN=1000000

View File

@ -12,8 +12,8 @@ KERNEL_TARGET="current,edge"
KERNEL_TEST_TARGET="current"
MODULES_BLACKLIST="rtw88_8821c rtw88_8821cu"
FORCE_BOOTSCRIPT_UPDATE="yes"
BOOTBRANCH_BOARD="tag:v2026.01"
BOOTPATCHDIR="v2026.01"
BOOTBRANCH_BOARD="tag:v2025.07"
BOOTPATCHDIR="v2025.07"
PACKAGE_LIST_BOARD="rfkill bluetooth bluez bluez-tools"
function post_family_tweaks_bsp__bananapi_firmware() {

View File

@ -11,8 +11,8 @@ SERIALCON="ttyAML0"
BOOT_LOGO="desktop"
BOOT_FDT_FILE="amlogic/meson-gxl-s905x-bestv-r3300-l.dtb"
PACKAGE_LIST_BOARD="alsa-ucm-conf" # Contain ALSA UCM top-level configuration file
BOOTBRANCH_BOARD="tag:v2026.01"
BOOTPATCHDIR="v2026.01"
BOOTBRANCH_BOARD="tag:v2025.04"
BOOTPATCHDIR="v2025.04"
enable_extension "gxlimg"
enable_extension "amlogic-fip-blobs"

View File

@ -12,8 +12,8 @@ SERIALCON="ttyAML0"
BOOT_LOGO="desktop"
BOOT_FDT_FILE="amlogic/meson-g12b-a311d-cainiao-cniot-core.dtb"
PACKAGE_LIST_BOARD="alsa-ucm-conf" # Contain ALSA UCM top-level configuration file
BOOTBRANCH_BOARD="tag:v2026.01"
BOOTPATCHDIR="v2026.01"
BOOTBRANCH_BOARD="tag:v2025.04"
BOOTPATCHDIR="v2025.04"
enable_extension "gxlimg"
enable_extension "amlogic-fip-blobs"

View File

@ -2,7 +2,7 @@
BOARD_NAME="Fine3399"
BOARD_VENDOR="rockchip"
BOARDFAMILY="rockchip64"
BOARD_MAINTAINER="Lemon1151"
BOARD_MAINTAINER=""
BOOTCONFIG="fine3399-rk3399_defconfig"
KERNEL_TARGET="current,edge"
KERNEL_TEST_TARGET="current"

View File

@ -1,12 +0,0 @@
# Rockchip RK3506B/J triple core 512MB SoC 1x100MBe NAND SD USB2
BOARD_NAME="ForLinx OK3506-S12"
BOARD_VENDOR="forlinx"
BOARDFAMILY="rockchip"
BOOTCONFIG="forlinx-ok3506-s12-rk3506j_defconfig"
BOARD_MAINTAINER="vidplace7"
KERNEL_TARGET="vendor"
BOOT_FDT_FILE="rk3506j-forlinx-OK3506-S12_nand-microsd.dtb"
IMAGE_PARTITION_TABLE="gpt"
SERIALCON="ttyFIQ0"
BOOT_SOC="rk3506"
DDR_BLOB="rk35/rk3506b_ddr_750MHz_v1.06.bin"

View File

@ -11,4 +11,3 @@ PACKAGE_LIST_BOARD="libubootenv-tool apparmor rfkill bluetooth bluez bluez-tools
DEFAULT_CONSOLE="serial"
HAS_VIDEO_OUTPUT="no"
MODULES_BLACKLIST="rtw88_8822cs"
enable_extension "jethub-burn"

View File

@ -11,4 +11,3 @@ PACKAGE_LIST_BOARD="libubootenv-tool apparmor rfkill bluetooth bluez bluez-tools
MODULES_BLACKLIST="simpledrm" # SimpleDRM conflicts with Panfrost
FULL_DESKTOP="yes"
SERIALCON="ttyAML0"
enable_extension "jethub-burn"

View File

@ -11,4 +11,3 @@ PACKAGE_LIST_BOARD="libubootenv-tool apparmor rfkill bluetooth bluez bluez-tools
DEFAULT_CONSOLE="serial"
HAS_VIDEO_OUTPUT="no"
MODULES_BLACKLIST="rtw88_8822cs"
enable_extension "jethub-burn"

View File

@ -28,8 +28,27 @@ function post_family_tweaks__kedge2_naming_audios() {
return 0
}
# Mainline U-Boot
# for the kedge2, we're counting on the blobs+u-boot in SPI working, as it comes from factory. It does not support bootscripts.
function post_family_config__uboot_kedge2() {
if [[ $BRANCH == "edge" || $BRANCH == "current" ]]; then
return
fi
display_alert "$BOARD" "Configuring ($BOARD) u-boot" "info"
declare -g BOOTSOURCE='https://github.com/khadas/u-boot.git'
declare -g BOOTBRANCH="commit:df276095a29a02f8e7ce4f451770c06486106594"
declare -g BOOTPATCHDIR="legacy/u-boot-khadas-edge2-rk3588"
declare -g BOOTCONFIG="khadas-edge2-rk3588s_defconfig"
declare -g SRC_EXTLINUX="yes" # For now, use extlinux. Thanks Monka
}
# Mainline U-Boot for current kernel
function post_family_config__kedge2_use_mainline_uboot() {
if [[ $BRANCH == "vendor" ]]; then
return
fi
display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info"
declare -g BOOTCONFIG="khadas-edge2-rk3588s_defconfig"

View File

@ -11,8 +11,6 @@ SERIALCON="ttyS0" # for vendor kernel
BOOTCONFIG="kvim1s_defconfig"
KHADAS_BOARD_ID="kvim1s" # used to compile the fip blobs
enable_extension "wayland-sessions-mask" # wayland is fairly broken on legacy board
declare -g KHADAS_OOWOW_BOARD_ID="VIM1S" # for use with EXT=output-image-oowow
OVERLAY_PREFIX='s4-s905y4'

View File

@ -45,61 +45,34 @@ function post_uboot_custom_postprocess__khadas_vim3l_uboot() {
# Enable extra u-boot .config options, this way we avoid patching defconfig
function post_config_uboot_target__extra_configs_for_khadas_vim3l() {
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable preboot & flash user LED in preboot" "info"
run_host_command_logged scripts/config --enable CONFIG_USE_PREBOOT
run_host_command_logged scripts/config --set-str CONFIG_PREBOOT "'led white:status on; led red:status on; sleep 0.1; led white:status off; led red:status off;'" # double quotes required due to run_host_command_logged's quirks
display_alert "u-boot for ${BOARD}" "u-boot: enable EFI debugging command" "info"
run_host_command_logged scripts/config --enable CMD_EFIDEBUG
run_host_command_logged scripts/config --enable CMD_NVEDIT_EFI
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable I2C support" "info"
display_alert "u-boot for ${BOARD}" "u-boot: enable I2C support" "info"
run_host_command_logged scripts/config --enable CONFIG_DM_I2C
run_host_command_logged scripts/config --enable CONFIG_SYS_I2C_MESON
run_host_command_logged scripts/config --enable CONFIG_CMD_I2C
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable GPIO expander support" "info" # to drive 'red' led
run_host_command_logged scripts/config --enable CONFIG_MAX7320_GPIO
run_host_command_logged scripts/config --enable CONFIG_CMD_PCA953X
run_host_command_logged scripts/config --enable CONFIG_DM_PCA953X
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable EFI debugging commands" "info"
run_host_command_logged scripts/config --enable CMD_EFIDEBUG
run_host_command_logged scripts/config --enable CMD_NVEDIT_EFI
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more filesystems support" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_BTRFS
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more compression support" "info"
display_alert "u-boot for ${BOARD}" "u-boot: enable more compression support" "info"
run_host_command_logged scripts/config --enable CONFIG_LZO
run_host_command_logged scripts/config --enable CONFIG_BZIP2
run_host_command_logged scripts/config --enable CONFIG_ZSTD
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable gpio LED support" "info"
display_alert "u-boot for ${BOARD}" "u-boot: enable kaslrseed support" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_KASLRSEED
display_alert "u-boot for ${BOARD}" "u-boot: enable gpio LED support" "info"
run_host_command_logged scripts/config --enable CONFIG_LED
run_host_command_logged scripts/config --enable CONFIG_LED_GPIO
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable some USB ethernet drivers" "info"
run_host_command_logged scripts/config --enable CONFIG_USB_HOST_ETHER
run_host_command_logged scripts/config --enable CONFIG_USB_ETHER_ASIX
run_host_command_logged scripts/config --enable CONFIG_USB_ETHER_ASIX88179
run_host_command_logged scripts/config --enable CONFIG_USB_ETHER_MCS7830
run_host_command_logged scripts/config --enable CONFIG_USB_ETHER_RTL8152
run_host_command_logged scripts/config --enable CONFIG_USB_ETHER_SMSC95XX
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable networking cmds" "info"
display_alert "u-boot for ${BOARD}" "u-boot: enable networking cmds" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_NFS
run_host_command_logged scripts/config --enable CONFIG_CMD_WGET
run_host_command_logged scripts/config --enable CONFIG_CMD_DNS
run_host_command_logged scripts/config --enable CONFIG_PROT_TCP
# @TODO: disabled; v2026.01 lwip has a few issues; check after v2026.04 as Kwiboo is already at-it
#display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable LWIP (new networking stack)" "info"
#run_host_command_logged scripts/config --enable CONFIG_CMD_MII
#run_host_command_logged scripts/config --enable CONFIG_NET_LWIP
# UMS, RockUSB, gadget stuff
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable UMS/RockUSB gadget" "info"
declare -a enable_configs=("CONFIG_CMD_USB_MASS_STORAGE" "CONFIG_USB_GADGET" "USB_GADGET_DOWNLOAD" "CONFIG_USB_FUNCTION_ACM")
for config in "${enable_configs[@]}"; do
run_host_command_logged scripts/config --enable "${config}"
done
# Auto-enabled by the above, force off...
run_host_command_logged scripts/config --disable USB_FUNCTION_FASTBOOT
run_host_command_logged scripts/config --enable CONFIG_PROT_TCP_SACK
}

View File

@ -3,7 +3,6 @@ BOARD_NAME="Khadas VIM4"
BOARD_VENDOR="khadas"
BOARDFAMILY="meson-s4t7"
KERNEL_TARGET="legacy"
KERNEL_TEST_TARGET="legacy"
BOARD_MAINTAINER="adeepn leggewie pyavitz rpardini"
SERIALCON="ttyS0" # for vendor kernel
# BOOT_FDT_FILE="amlogic/kvim4.dtb" # not set on purpose; u-boot auto-selects kvim4.dtb or kvim4n.dtb for "new VIM4"
@ -14,8 +13,6 @@ KHADAS_BOARD_ID="kvim4" # used to compile the fip blobs
declare -g KHADAS_OOWOW_BOARD_ID="VIM4" # for use with EXT=output-image-oowow
enable_extension "wayland-sessions-mask" # wayland is fairly broken on legacy board
OVERLAY_PREFIX='t7-a311d2'
function post_family_tweaks_bsp__enable_fan_service() {

View File

@ -10,8 +10,8 @@ BOOT_LOGO="desktop"
KERNEL_TARGET="current,edge"
KERNEL_TEST_TARGET="current"
FORCE_BOOTSCRIPT_UPDATE="yes"
BOOTBRANCH_BOARD="tag:v2026.01"
BOOTPATCHDIR="v2026.01"
BOOTBRANCH_BOARD="tag:v2025.07"
BOOTPATCHDIR="v2025.07"
PACKAGE_LIST_BOARD="rfkill bluetooth bluez bluez-tools"
# AIC8800

View File

@ -3,108 +3,10 @@ declare -g BOARD_NAME="Mekotronics R58X-4G"
declare -g BOARD_VENDOR="mekotronics"
declare -g BOARDFAMILY="rockchip-rk3588"
declare -g BOARD_MAINTAINER=""
declare -g KERNEL_TARGET="edge,vendor"
declare -g BOOT_FDT_FILE="rockchip/rk3588-blueberry-edge-v12-linux.dtb" # same name for mainline and vendor
declare -g DISPLAY_MANAGER="wayland"
declare -g ASOUND_STATE="asound.state.rk3588hd"
declare -g BOOT_SOC="rk3588"
declare -g IMAGE_PARTITION_TABLE="gpt"
# Does not have a UEFI_EDK2_BOARD_ID
declare -g KERNEL_TARGET="vendor"
declare -g BOOTCONFIG="mekotronics_r58x-rk3588_defconfig" # vendor u-boot; with NVMe and a DTS
declare -g BOOT_FDT_FILE="rockchip/rk3588-blueberry-edge-v12-linux.dtb" # Specific to this board
declare -g UEFI_EDK2_BOARD_ID="r58x" # This _only_ used for uefi-edk2-rk3588 extension
if [[ "${BRANCH}" == "vendor" || "${BRANCH}" == "legacy" ]]; then
display_alert "$BOARD" "vendor/legacy configuration applied for $BOARD / $BRANCH" "info"
declare -g BOOTCONFIG="mekotronics_r58x-rk3588_defconfig" # vendor u-boot; with NVMe and a DTS
# Source shared vendor configuration; it does BOOT_SCENARIO="spl-blobs" & hciattach - common to all vendor-kernel Meko's
source "${SRC}/config/sources/vendors/mekotronics/mekotronics-rk3588.conf.sh"
return 0 # this returns early so below code is only for current/edge branches
fi
# For current/edge branches:
display_alert "$BOARD" "applying mainline configuration for $BOARD / $BRANCH" "info"
declare -g BOOT_SCENARIO="tpl-blob-atf-mainline" # Mainline ATF
function post_family_config__mekor58x_4g_use_mainline_uboot() {
display_alert "$BOARD" "mainline u-boot overrides for $BOARD / $BRANCH" "info"
declare -g BOOTCONFIG="mekotronics-r58x-4g-rk3588_defconfig" # mainline
declare -g BOOTDELAY=1
declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git"
declare -g BOOTBRANCH="tag:v2026.04-rc2"
declare -g BOOTPATCHDIR="v2026.04"
declare -g BOOTDIR="u-boot-${BOARD}"
declare -g UBOOT_TARGET_MAP="BL31=bl31.elf ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin"
unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd
function write_uboot_platform() {
dd "if=$1/u-boot-rockchip.bin" "of=$2" bs=32k seek=1 conv=notrunc status=none
}
declare -g PLYMOUTH="no" # Disable plymouth as that only causes more confusion
}
# "rockchip-common: boot NVMe, SATA, USB, then eMMC last before PXE"
# include/configs/rockchip-common.h
# On the meko r58-r58x_4g: mmc0 is eMMC; there is no SDcard reader
# Enumerating usb is pretty slow so do it after nvme
function pre_config_uboot_target__mekor58x_4g_patch_rockchip_common_boot_order() {
declare -a rockchip_uboot_targets=("nvme" "scsi" "usb" "mmc0" "pxe" "dhcp" "spi") # for future make-this-generic delight
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: adjust boot order to '${rockchip_uboot_targets[*]}'" "info"
sed -i -e "s/#define BOOT_TARGETS.*/#define BOOT_TARGETS \"${rockchip_uboot_targets[*]}\"/" include/configs/rockchip-common.h
regular_git diff -u include/configs/rockchip-common.h || true
}
function pre_config_uboot_target__ekor58x_4g_patch_uboot_dtsi_for_ums() {
[[ "${BRANCH}" == "vendor" ]] && return 0 # Not for 'vendor' branch, which uses 2017.09 vendor u-boot from Radxa
display_alert "u-boot for ${BOARD}" "u-boot: add to u-boot dtsi for UMS" "info" # avoid a patch, just append to the dtsi file
# Append to the t6 u-boot dtsi file with stuff for enabling gadget/otg/peripheral mode
cat <<- EOD >> arch/arm/dts/rk3588-blueberry-edge-v12-linux-u-boot.dtsi
#include "rk3588-generic-u-boot.dtsi"
&u2phy0 { status = "okay"; };
&u2phy0_otg { status = "okay"; };
&usbdp_phy0 { status = "okay"; };
&usb_host0_xhci { dr_mode = "peripheral"; maximum-speed = "high-speed"; status = "okay"; };
EOD
}
function post_config_uboot_target__extra_configs_for_mekor58x_4g_mainline_environment_in_spi() {
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable board-specific configs" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_MISC
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable preboot & flash user LED in preboot" "info"
run_host_command_logged scripts/config --enable CONFIG_USE_PREBOOT
run_host_command_logged scripts/config --set-str CONFIG_PREBOOT "'led 4G on; sleep 0.1; led LAN on; sleep 0.1; led PWR on; sleep 0.1; led 4G off; sleep 0.1; led LAN off; sleep 0.1;'" # double quotes required due to run_host_command_logged's quirks
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable EFI debugging commands" "info"
run_host_command_logged scripts/config --enable CMD_EFIDEBUG
run_host_command_logged scripts/config --enable CMD_NVEDIT_EFI
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more filesystems support" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_BTRFS
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more compression support" "info"
run_host_command_logged scripts/config --enable CONFIG_LZO
run_host_command_logged scripts/config --enable CONFIG_BZIP2
run_host_command_logged scripts/config --enable CONFIG_ZSTD
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable gpio LED support" "info"
run_host_command_logged scripts/config --enable CONFIG_LED
run_host_command_logged scripts/config --enable CONFIG_LED_GPIO
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable networking cmds" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_NFS
run_host_command_logged scripts/config --enable CONFIG_CMD_WGET
run_host_command_logged scripts/config --enable CONFIG_CMD_DNS
run_host_command_logged scripts/config --enable CONFIG_PROT_TCP
run_host_command_logged scripts/config --enable CONFIG_PROT_TCP_SACK
# UMS, RockUSB, gadget stuff
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable UMS/RockUSB gadget" "info"
declare -a enable_configs=("CONFIG_CMD_USB_MASS_STORAGE" "CONFIG_USB_GADGET" "USB_GADGET_DOWNLOAD" "CONFIG_USB_FUNCTION_ROCKUSB" "CONFIG_USB_FUNCTION_ACM" "CONFIG_CMD_ROCKUSB" "CONFIG_CMD_USB_MASS_STORAGE")
for config in "${enable_configs[@]}"; do
run_host_command_logged scripts/config --enable "${config}"
done
# Auto-enabled by the above, force off...
run_host_command_logged scripts/config --disable USB_FUNCTION_FASTBOOT
}
# Source vendor-specific configuration
source "${SRC}/config/sources/vendors/mekotronics/mekotronics-rk3588.conf.sh"

View File

@ -3,145 +3,10 @@ declare -g BOARD_NAME="Mekotronics R58X-Pro"
declare -g BOARD_VENDOR="mekotronics"
declare -g BOARDFAMILY="rockchip-rk3588"
declare -g BOARD_MAINTAINER=""
declare -g KERNEL_TARGET="edge,vendor"
declare -g BOOT_FDT_FILE="rockchip/rk3588-mekotronics-r58x-pro.dtb" # mainline name; see below for vendor
declare -g DISPLAY_MANAGER="wayland"
declare -g ASOUND_STATE="asound.state.rk3588hd"
declare -g BOOT_SOC="rk3588"
declare -g IMAGE_PARTITION_TABLE="gpt"
# Does not have a UEFI_EDK2_BOARD_ID
declare -g KERNEL_TARGET="vendor"
declare -g BOOTCONFIG="mekotronics_r58x-rk3588_defconfig" # vendor u-boot; with NVMe and a DTS
declare -g BOOT_FDT_FILE="rockchip/rk3588-blueberry-edge-v12-maizhuo-linux.dtb" # Specific to this board
declare -g UEFI_EDK2_BOARD_ID="r58x" # This _only_ used for uefi-edk2-rk3588 extension
if [[ "${BRANCH}" == "vendor" || "${BRANCH}" == "legacy" ]]; then
display_alert "$BOARD" "vendor/legacy configuration applied for $BOARD / $BRANCH" "info"
declare -g BOOTCONFIG="mekotronics_r58x-rk3588_defconfig" # vendor u-boot; with NVMe and a DTS
declare -g BOOT_FDT_FILE="rockchip/rk3588-blueberry-edge-v12-maizhuo-linux.dtb" # different for vendor
# Source shared vendor configuration; it does BOOT_SCENARIO="spl-blobs" & hciattach - common to all vendor-kernel Meko's
source "${SRC}/config/sources/vendors/mekotronics/mekotronics-rk3588.conf.sh"
return 0 # this returns early so below code is only for current/edge branches
fi
# For current/edge branches:
display_alert "$BOARD" "applying mainline configuration for $BOARD / $BRANCH" "info"
declare -g BOOT_SCENARIO="tpl-blob-atf-mainline" # Mainline ATF
function post_family_config__meko_r58x_pro_use_mainline_uboot() {
display_alert "$BOARD" "mainline u-boot overrides for $BOARD / $BRANCH" "info"
declare -g BOOTCONFIG="mekotronics-r58x-pro-rk3588_defconfig" # mainline
declare -g BOOTDELAY=1
declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git"
declare -g BOOTBRANCH="tag:v2026.04-rc2"
declare -g BOOTPATCHDIR="v2026.04"
declare -g BOOTDIR="u-boot-${BOARD}"
declare -g UBOOT_TARGET_MAP="BL31=bl31.elf ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin"
unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd
function write_uboot_platform() {
dd "if=$1/u-boot-rockchip.bin" "of=$2" bs=32k seek=1 conv=notrunc status=none
}
declare -g PLYMOUTH="no" # Disable plymouth as that only causes more confusion
}
# "rockchip-common: boot NVMe, SATA, USB, then eMMC last before PXE"
# include/configs/rockchip-common.h
# On the meko r58x_pro: mmc0 is eMMC; there is no SDcard reader @TODO yes there is
# Enumerating usb is pretty slow so do it after nvme
function pre_config_uboot_target__meko_r58x_pro_patch_rockchip_common_boot_order() {
declare -a rockchip_uboot_targets=("nvme" "scsi" "usb" "mmc0" "pxe" "dhcp" "spi") # for future make-this-generic delight
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: adjust boot order to '${rockchip_uboot_targets[*]}'" "info"
sed -i -e "s/#define BOOT_TARGETS.*/#define BOOT_TARGETS \"${rockchip_uboot_targets[*]}\"/" include/configs/rockchip-common.h
regular_git diff -u include/configs/rockchip-common.h || true
}
function pre_config_uboot_target__meko_r58x_pro_patch_uboot_dtsi_for_ums() {
[[ "${BRANCH}" == "vendor" ]] && return 0 # Not for 'vendor' branch, which uses 2017.09 vendor u-boot from Radxa
display_alert "u-boot for ${BOARD}" "u-boot: add to u-boot dtsi for UMS" "info" # avoid a patch, just append to the dtsi file
# Append to the t6 u-boot dtsi file with stuff for enabling gadget/otg/peripheral mode
cat <<- EOD >> arch/arm/dts/rk3588-mekotronics-r58x-pro-u-boot.dtsi
#include "rk3588-generic-u-boot.dtsi"
&u2phy0 { status = "okay"; };
&u2phy0_otg { status = "okay"; };
&usbdp_phy0 { status = "okay"; };
&usb_host0_xhci { dr_mode = "peripheral"; maximum-speed = "high-speed"; status = "okay"; };
EOD
}
function post_config_uboot_target__extra_configs_for_meko_r58x_pro_mainline_environment_in_spi() {
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable board-specific configs" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_MISC
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable preboot & flash user LED in preboot" "info"
run_host_command_logged scripts/config --enable CONFIG_USE_PREBOOT
run_host_command_logged scripts/config --set-str CONFIG_PREBOOT "'led WIFI on; sleep 0.1; led LAN on; sleep 0.1; led PWR on; sleep 0.1; led WIFI off; sleep 0.1; led LAN off; sleep 0.1;'" # double quotes required due to run_host_command_logged's quirks
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable EFI debugging commands" "info"
run_host_command_logged scripts/config --enable CMD_EFIDEBUG
run_host_command_logged scripts/config --enable CMD_NVEDIT_EFI
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more filesystems support" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_BTRFS
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more compression support" "info"
run_host_command_logged scripts/config --enable CONFIG_LZO
run_host_command_logged scripts/config --enable CONFIG_BZIP2
run_host_command_logged scripts/config --enable CONFIG_ZSTD
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable gpio LED support" "info"
run_host_command_logged scripts/config --enable CONFIG_LED
run_host_command_logged scripts/config --enable CONFIG_LED_GPIO
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable networking cmds" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_NFS
run_host_command_logged scripts/config --enable CONFIG_CMD_WGET
run_host_command_logged scripts/config --enable CONFIG_CMD_DNS
run_host_command_logged scripts/config --enable CONFIG_PROT_TCP
run_host_command_logged scripts/config --enable CONFIG_PROT_TCP_SACK
# UMS, RockUSB, gadget stuff
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable UMS/RockUSB gadget" "info"
declare -a enable_configs=("CONFIG_CMD_USB_MASS_STORAGE" "CONFIG_USB_GADGET" "USB_GADGET_DOWNLOAD" "CONFIG_USB_FUNCTION_ROCKUSB" "CONFIG_USB_FUNCTION_ACM" "CONFIG_CMD_ROCKUSB" "CONFIG_CMD_USB_MASS_STORAGE")
for config in "${enable_configs[@]}"; do
run_host_command_logged scripts/config --enable "${config}"
done
# Auto-enabled by the above, force off...
run_host_command_logged scripts/config --disable USB_FUNCTION_FASTBOOT
}
# Small systemd service and timer to drive the LCD display with the hour-minute of the current time.
# Deploy the script and the systemd service in the BSP. It'll be enabled below in the image.
function post_family_tweaks_bsp__meko_r58x_pro_lcd_clock_add_systemd_service() {
display_alert "Extension: ${EXTENSION}: ${BOARD}" "adding LCD clock service and timer to BSP" "info"
: "${destination:?destination is not set}"
cat <<- 'LCD_CLOCK_SYSTEMD_SERVICE' > "$destination"/lib/systemd/system/lcd-clock.service
[Unit]
Description=Update segment LCD clock display
ConditionPathExists=/sys/devices/platform/lcd_vk2c21/display
[Service]
Type=oneshot
ExecStart=bash -c 'echo " $(date +%%H)-$(date +%%M) " > /sys/devices/platform/lcd_vk2c21/display'
LCD_CLOCK_SYSTEMD_SERVICE
cat <<- 'LCD_CLOCK_SYSTEMD_TIMER' > "$destination"/lib/systemd/system/lcd-clock.timer
[Unit]
Description=Update segment LCD clock every minute
[Timer]
OnBootSec=5
OnCalendar=*-*-* *:*:00
AccuracySec=1s
[Install]
WantedBy=timers.target
LCD_CLOCK_SYSTEMD_TIMER
return 0
}
# Enable the service created in the BSP above.
function post_family_tweaks__meko_r58x_pro_lcd_clock_service_in_image() {
display_alert "Extension: ${EXTENSION}: ${BOARD}" "LCD clock timer in the image" "info"
chroot_sdcard systemctl --no-reload enable "lcd-clock.timer"
return 0
}
# Source vendor-specific configuration
source "${SRC}/config/sources/vendors/mekotronics/mekotronics-rk3588.conf.sh"

View File

@ -3,8 +3,7 @@ declare -g BOARD_NAME="Mixtile Blade 3"
declare -g BOARD_VENDOR="mixtile"
declare -g BOARDFAMILY="rockchip-rk3588"
declare -g BOARD_MAINTAINER="rpardini"
# DO NOT put comments on same line as KERNEL_TARGET: edge builds and can be used for development with 'BRANCH=edge` forced; not enabled for end-users
declare -g KERNEL_TARGET="vendor"
declare -g KERNEL_TARGET="vendor" # edge builds and can be used for development with 'BRANCH=edge` forced; not enabled for end-users
declare -g BOOT_FDT_FILE="rockchip/rk3588-blade3-v101-linux.dtb" # Included in https://github.com/armbian/linux-rockchip/pull/64 # has a hook to change it for edge below
declare -g BOOT_SCENARIO="spl-blobs" # so we don't depend on defconfig naming convention
declare -g BOOT_SOC="rk3588" # so we don't depend on defconfig naming convention

View File

@ -39,7 +39,7 @@ function post_family_config__core3588e_use_mainline_uboot() {
declare -g BOOTPATCHDIR="v2026.01"
declare -g BOOTDIR="u-boot-${BOARD}"
declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-usb471.bin u-boot-rockchip-usb472.bin"
UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin"
unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd
function write_uboot_platform() {
@ -63,9 +63,6 @@ function post_config_uboot_target__extra_configs_for_core3588e_mainline_environm
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable board-specific configs" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_MISC
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable RAMBoot images" "info"
run_host_command_logged scripts/config --enable CONFIG_ROCKCHIP_MASKROM_IMAGE
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable preboot & flash user LED in preboot" "info"
run_host_command_logged scripts/config --enable CONFIG_USE_PREBOOT
run_host_command_logged scripts/config --set-str CONFIG_PREBOOT "'led sys_led on; sleep 0.1; led sys_led off'" # double quotes required due to run_host_command_logged's quirks

View File

@ -3,7 +3,7 @@ BOARD_NAME="SpacemiT MusePi Pro"
BOARDFAMILY="spacemit"
BOARD_MAINTAINER="pyavitz"
BOARD_VENDOR="spacemit"
KERNEL_TARGET="legacy,current,edge"
KERNEL_TARGET="current,edge"
BOOT_FDT_FILE="spacemit/k1-musepi-pro.dtb"
BOOTDELAY=1
SRC_EXTLINUX="yes"

View File

@ -3,8 +3,7 @@ BOARD_NAME="NanoPi M5"
BOARD_VENDOR="friendlyelec"
BOARDFAMILY="rk35xx"
BOOTCONFIG="nanopi-m5-rk3576_defconfig"
# WIP: current kernel (no comments on same line as KERNEL_TARGET)
KERNEL_TARGET="vendor,edge"
KERNEL_TARGET="vendor,edge" # WIP: current kernel
FULL_DESKTOP="yes"
ASOUND_STATE="asound.state.nanopi-m5"
BOOT_LOGO="desktop"

View File

@ -9,13 +9,14 @@ KERNEL_TEST_TARGET="current,edge"
BOOT_FDT_FILE="rockchip/rk3566-nanopi-r3s-lts.dtb"
IMAGE_PARTITION_TABLE="gpt"
BOOT_SCENARIO="spl-blobs"
enable_extension "uboot-btrfs"
function post_family_config__use_mainline_uboot() {
unset BOOTFS_TYPE
BOOTCONFIG="nanopi-r3s-lts-rk3566_defconfig"
BOOTSOURCE="https://github.com/u-boot/u-boot"
BOOTBRANCH="tag:v2026.01"
BOOTPATCHDIR="v2026.01"
BOOTBRANCH="tag:v2025.10"
BOOTPATCHDIR="v2025.10"
UBOOT_TARGET_MAP="BL31=$RKBIN_DIR/$BL31_BLOB ROCKCHIP_TPL=$RKBIN_DIR/$DDR_BLOB;;u-boot-rockchip.bin"

View File

@ -10,7 +10,7 @@ KERNEL_TEST_TARGET="current,edge"
BOOT_FDT_FILE="rockchip/rk3566-nanopi-r3s.dtb"
IMAGE_PARTITION_TABLE="gpt"
BOOT_SCENARIO="spl-blobs"
enable_extension "uboot-btrfs"
function post_family_config__use_mainline_uboot() {
if [[ "$BRANCH" == "vendor" ]]; then
@ -18,6 +18,7 @@ function post_family_config__use_mainline_uboot() {
fi
unset BOOT_FDT_FILE # boot.scr will use whatever u-boot detects and sets 'fdtfile' to
unset BOOTFS_TYPE
BOOTCONFIG="nanopi-r3s-rk3566_defconfig"
BOOTSOURCE="https://github.com/u-boot/u-boot"
BOOTBRANCH="tag:v2025.04"

View File

@ -13,11 +13,8 @@ IMAGE_PARTITION_TABLE="gpt"
FULL_DESKTOP="no"
BOOT_LOGO="desktop"
# Enable btrfs support in u-boot
enable_extension "uboot-btrfs"
BOOTBRANCH_BOARD="tag:v2026.01"
BOOTPATCHDIR="v2026.01"
BOOTBRANCH_BOARD="tag:v2024.07"
BOOTPATCHDIR="v2024.07"
BOOTCONFIG="nanopi-r5c-rk3568_defconfig"
OVERLAY_PREFIX="rockchip-rk3568"

View File

@ -4,7 +4,7 @@ BOARD_VENDOR="friendlyelec"
BOARDFAMILY="rk35xx"
BOOTCONFIG="hinlink_rk3528_defconfig"
BOARD_MAINTAINER=""
KERNEL_TARGET="vendor,current,edge"
KERNEL_TARGET="vendor"
FULL_DESKTOP="no"
HAS_VIDEO_OUTPUT="no"
BOOT_FDT_FILE="rockchip/rk3528-nanopi-rev01.dtb"
@ -12,26 +12,3 @@ BOOT_SCENARIO="spl-blobs"
IMAGE_PARTITION_TABLE="gpt"
BOOTFS_TYPE="ext4"
BOOTSIZE="512"
# Mainline kernel (current/edge) uses a different DTB filename than vendor kernel
# and RK3528 debug UART is UART0 (ttyS0), not UART2 (ttyS2) like other RK35xx SoCs
function post_family_config__nanopi_zero2_mainline() {
case "${BRANCH}" in
current|edge)
declare -g BOOT_FDT_FILE="rockchip/rk3528-nanopi-zero2.dtb"
declare -g SERIALCON="ttyS0"
display_alert "$BOARD" "Using ${BOOT_FDT_FILE} and SERIALCON=${SERIALCON} for ${BRANCH}" "info"
;;
esac
}
# Patch boot script: RK3528 NanoPi Zero2 uses UART0 (ttyS0) for serial console, not UART2 (ttyS2)
function post_family_tweaks__nanopi_zero2_serial_console() {
case "${BRANCH}" in
current|edge)
display_alert "$BOARD" "Adjusting boot.cmd serial console to ttyS0 for ${BRANCH}" "info"
sed -i 's/console=ttyS2,1500000/console=ttyS0,1500000/g' "${SDCARD}"/boot/boot.cmd
mkimage -C none -A arm -T script -d "${SDCARD}"/boot/boot.cmd "${SDCARD}"/boot/boot.scr
;;
esac
}

View File

@ -1,10 +0,0 @@
# Allwinner H5 quad core 2GB RAM Wifi GBE eMMC
BOARD_NAME="NanoPi K1 Plus"
BOARD_VENDOR="friendlyelec"
BOARDFAMILY="sun50iw2"
BOARD_MAINTAINER="igorpecovnik"
BOOTCONFIG="nanopi_k1_plus_defconfig"
DEFAULT_OVERLAYS="analog-codec"
KERNEL_TARGET="current,edge,legacy"
KERNEL_TEST_TARGET="current"
CRUSTCONFIG="h5_defconfig"

View File

@ -0,0 +1,10 @@
# Allwinner H5 quad core 2GB RAM Wifi GBE eMMC
BOARD_NAME="NanoPi K1 Plus"
BOARD_VENDOR="friendlyelec"
BOARDFAMILY="sun50iw2"
BOARD_MAINTAINER=""
BOOTCONFIG="nanopi_k1_plus_defconfig"
DEFAULT_OVERLAYS="analog-codec"
KERNEL_TARGET="current,edge,legacy"
KERNEL_TEST_TARGET="current"
CRUSTCONFIG="h5_defconfig"

View File

@ -1,17 +0,0 @@
# Dual-core Cortex-A35 + Cortex-M4, 512MB DDR
BOARD_NAME="NuMaker IoT MA35D16F90"
BOARD_VENDOR="nuvoton"
BOARDFAMILY="nuvoton-ma35d1"
# SD card boot (sdcard1 = SD1 slot on NuMaker IoT board)
BOOTCONFIG="ma35d1_sdcard1_defconfig"
KERNEL_TARGET="vendor"
FULL_DESKTOP="no"
BOOT_LOGO="no"
BOOT_FDT_FILE="nuvoton/ma35d1-iot-512m.dtb"
BOOT_SCENARIO="blobless"
IMAGE_PARTITION_TABLE="msdos"
DEFAULT_CONSOLE="serial"
SERIALCON="ttyS0:115200"
# Hardware features
HAS_VIDEO_OUTPUT="yes"

View File

@ -11,6 +11,7 @@ BOOTSOURCE='https://github.com/hardkernel/u-boot.git'
BOOTBRANCH='branch:odroidc-v2011.03'
BOOTPATCHDIR="legacy"
UBOOT_COMPILER="arm-linux-gnueabi-"
UBOOT_USE_GCC='< 4.9'
BOOTCONFIG="odroidc_config"
BOOTSCRIPT="boot-odroid-c1.ini:boot.ini"

View File

@ -1,100 +0,0 @@
# Amlogic S905X3 quad core 4GB RAM SoC GBE USB3 SPI 2 x SATA
BOARD_NAME="Odroid HC4"
BOARD_VENDOR="hardkernel"
BOARDFAMILY="meson-sm1"
BOARD_MAINTAINER="igorpecovnik"
BOOTCONFIG="odroid-hc4_defconfig"
KERNEL_TARGET="current,edge"
KERNEL_TEST_TARGET="current"
MODULES_BLACKLIST="simpledrm" # SimpleDRM conflicts with Panfrost
FULL_DESKTOP="no"
SERIALCON="ttyAML0"
BOOT_FDT_FILE="amlogic/meson-sm1-odroid-hc4.dtb"
PACKAGE_LIST_BOARD="lm-sensors fancontrol" # SPI, sensors, manual fan control via 'pwmconfig'
# Newer u-boot for the HC4. There's patches in `board_odroidhc4` for the defconfigs used in the UBOOT_TARGET_MAP below.
BOOTBRANCH_BOARD="tag:v2026.01"
BOOTPATCHDIR="v2026.01"
# We build u-boot twice: C4 config for SD cards, and HC4 (with SATA/PCI/SPI) config for SPI.
UBOOT_TARGET_MAP="
armbian_target=sd u-boot-dtb.img;;u-boot.bin.sd.bin:u-boot.bin u-boot-dtb.img
armbian_target=spi u-boot-dtb.img;;u-boot.bin:u-boot-spi.bin
"
# The SPI version (u-boot-spi.bin, built from odroid-hc4_defconfig above) is then used by nand-sata-install / armbian-install
function write_uboot_platform_mtd() {
declare -a extra_opts_flashcp=("--verbose")
if flashcp -h | grep -q -e '--partition'; then
echo "Confirmed flashcp supports --partition -- read and write only changed blocks." >&2
extra_opts_flashcp+=("--partition")
else
echo "flashcp does not support --partition, will write full SPI flash blocks." >&2
fi
flashcp "${extra_opts_flashcp[@]}" "${1}/u-boot-spi.bin" /dev/mtd0
}
# FIP blobs; the C4 & HC4 fip blobs are actually the same, still LE carries both.
function post_uboot_custom_postprocess__odroid_hc4_uboot() {
display_alert "Signing u-boot FIP" "${BOARD}" "info"
uboot_g12_postprocess "${SRC}"/cache/sources/amlogic-boot-fip/odroid-hc4 g12a
}
# Enable extra u-boot .config options, this way we avoid patching defconfig
function post_config_uboot_target__extra_configs_for_odroid_hc4() {
display_alert "u-boot for ${BOARD}" "u-boot: enable preboot & pci+usb start in preboot" "info"
run_host_command_logged scripts/config --enable CONFIG_USE_PREBOOT
run_host_command_logged scripts/config --set-str CONFIG_PREBOOT "'run boot_pci_enum; usb start'" # double quotes required due to run_host_command_logged's quirks
display_alert "u-boot for ${BOARD}" "u-boot: enable EFI debugging command" "info"
run_host_command_logged scripts/config --enable CMD_EFIDEBUG
run_host_command_logged scripts/config --enable CMD_NVEDIT_EFI
## WAIT ## display_alert "u-boot for ${BOARD}" "u-boot: disable EFI Video Framebuffer" "info"
## WAIT ## run_host_command_logged scripts/config --disable CONFIG_VIDEO_DT_SIMPLEFB # "Enables the code to pass the framebuffer to the kernel as a simple framebuffer in the device tree."
## WAIT ## # CONFIG_VIDEO_EFI is unrelated: its about _using_ an EFI framebuffer when booted by an EFI-capable bootloader earlier in the chain. Not about _providing_ an EFI framebuffer. That's simplefb.
## WAIT ## # CONFIG_FDT_SIMPLEFB seems to be rpi-specific and 100% unrelated here
display_alert "u-boot for ${BOARD}" "u-boot: enable I2C support" "info"
run_host_command_logged scripts/config --enable CONFIG_DM_I2C
run_host_command_logged scripts/config --enable CONFIG_SYS_I2C_MESON
run_host_command_logged scripts/config --enable CONFIG_CMD_I2C
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more filesystems support" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_BTRFS
display_alert "u-boot for ${BOARD}" "u-boot: enable more compression support" "info"
run_host_command_logged scripts/config --enable CONFIG_LZO
run_host_command_logged scripts/config --enable CONFIG_BZIP2
run_host_command_logged scripts/config --enable CONFIG_ZSTD
display_alert "u-boot for ${BOARD}" "u-boot: enable gpio LED support" "info"
run_host_command_logged scripts/config --enable CONFIG_LED
run_host_command_logged scripts/config --enable CONFIG_LED_GPIO
display_alert "u-boot for ${BOARD}" "u-boot: enable networking cmds" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_NFS
run_host_command_logged scripts/config --enable CONFIG_CMD_WGET
run_host_command_logged scripts/config --enable CONFIG_CMD_DNS
run_host_command_logged scripts/config --enable CONFIG_PROT_TCP
run_host_command_logged scripts/config --enable CONFIG_PROT_TCP_SACK
}
# @TODO: this is no longer needed in `edge` branch -- Neil has sent a patch with a trip for the cooling map in the DT - also doesn't hurt.
function post_family_tweaks__config_odroidhc4_fancontrol() {
display_alert "Configuring fancontrol" "for Odroid HC4" "info"
cat <<- FANCONTROL > "${SDCARD}"/etc/fancontrol
# Default config for the Odroid HC4 -- adjust to your needs (MINTEMP=40)
INTERVAL=10
DEVPATH=hwmon0=devices/virtual/thermal/thermal_zone0 hwmon2=devices/platform/pwm-fan
DEVNAME=hwmon0=cpu_thermal hwmon2=pwmfan
FCTEMPS=hwmon2/pwm1=hwmon0/temp1_input
FCFANS= hwmon2/pwm1=hwmon2/fan1_input
MINTEMP=hwmon2/pwm1=40
MAXTEMP=hwmon2/pwm1=60
MINSTART=hwmon2/pwm1=150
MINSTOP=hwmon2/pwm1=30
MAXPWM=hwmon2/pwm1=180
FANCONTROL
chroot_sdcard systemctl enable fancontrol.service
}

100
config/boards/odroidhc4.csc Normal file
View File

@ -0,0 +1,100 @@
# Amlogic S905X3 quad core 4GB RAM SoC GBE USB3 SPI 2 x SATA
BOARD_NAME="Odroid HC4"
BOARD_VENDOR="hardkernel"
BOARDFAMILY="meson-sm1"
BOARD_MAINTAINER=""
BOOTCONFIG="odroid-hc4_defconfig"
KERNEL_TARGET="current,edge"
KERNEL_TEST_TARGET="current"
MODULES_BLACKLIST="simpledrm" # SimpleDRM conflicts with Panfrost
FULL_DESKTOP="no"
SERIALCON="ttyAML0"
BOOT_FDT_FILE="amlogic/meson-sm1-odroid-hc4.dtb"
PACKAGE_LIST_BOARD="lm-sensors fancontrol" # SPI, sensors, manual fan control via 'pwmconfig'
# Newer u-boot for the HC4. There's patches in `board_odroidhc4` for the defconfigs used in the UBOOT_TARGET_MAP below.
BOOTBRANCH_BOARD="tag:v2026.01"
BOOTPATCHDIR="v2026.01"
# We build u-boot twice: C4 config for SD cards, and HC4 (with SATA/PCI/SPI) config for SPI.
UBOOT_TARGET_MAP="
armbian_target=sd u-boot-dtb.img;;u-boot.bin.sd.bin:u-boot.bin u-boot-dtb.img
armbian_target=spi u-boot-dtb.img;;u-boot.bin:u-boot-spi.bin
"
# The SPI version (u-boot-spi.bin, built from odroid-hc4_defconfig above) is then used by nand-sata-install / armbian-install
function write_uboot_platform_mtd() {
declare -a extra_opts_flashcp=("--verbose")
if flashcp -h | grep -q -e '--partition'; then
echo "Confirmed flashcp supports --partition -- read and write only changed blocks." >&2
extra_opts_flashcp+=("--partition")
else
echo "flashcp does not support --partition, will write full SPI flash blocks." >&2
fi
flashcp "${extra_opts_flashcp[@]}" "${1}/u-boot-spi.bin" /dev/mtd0
}
# FIP blobs; the C4 & HC4 fip blobs are actually the same, still LE carries both.
function post_uboot_custom_postprocess__odroid_hc4_uboot() {
display_alert "Signing u-boot FIP" "${BOARD}" "info"
uboot_g12_postprocess "${SRC}"/cache/sources/amlogic-boot-fip/odroid-hc4 g12a
}
# Enable extra u-boot .config options, this way we avoid patching defconfig
function post_config_uboot_target__extra_configs_for_odroid_hc4() {
display_alert "u-boot for ${BOARD}" "u-boot: enable preboot & pci+usb start in preboot" "info"
run_host_command_logged scripts/config --enable CONFIG_USE_PREBOOT
run_host_command_logged scripts/config --set-str CONFIG_PREBOOT "'run boot_pci_enum; usb start'" # double quotes required due to run_host_command_logged's quirks
display_alert "u-boot for ${BOARD}" "u-boot: enable EFI debugging command" "info"
run_host_command_logged scripts/config --enable CMD_EFIDEBUG
run_host_command_logged scripts/config --enable CMD_NVEDIT_EFI
## WAIT ## display_alert "u-boot for ${BOARD}" "u-boot: disable EFI Video Framebuffer" "info"
## WAIT ## run_host_command_logged scripts/config --disable CONFIG_VIDEO_DT_SIMPLEFB # "Enables the code to pass the framebuffer to the kernel as a simple framebuffer in the device tree."
## WAIT ## # CONFIG_VIDEO_EFI is unrelated: its about _using_ an EFI framebuffer when booted by an EFI-capable bootloader earlier in the chain. Not about _providing_ an EFI framebuffer. That's simplefb.
## WAIT ## # CONFIG_FDT_SIMPLEFB seems to be rpi-specific and 100% unrelated here
display_alert "u-boot for ${BOARD}" "u-boot: enable I2C support" "info"
run_host_command_logged scripts/config --enable CONFIG_DM_I2C
run_host_command_logged scripts/config --enable CONFIG_SYS_I2C_MESON
run_host_command_logged scripts/config --enable CONFIG_CMD_I2C
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more filesystems support" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_BTRFS
display_alert "u-boot for ${BOARD}" "u-boot: enable more compression support" "info"
run_host_command_logged scripts/config --enable CONFIG_LZO
run_host_command_logged scripts/config --enable CONFIG_BZIP2
run_host_command_logged scripts/config --enable CONFIG_ZSTD
display_alert "u-boot for ${BOARD}" "u-boot: enable gpio LED support" "info"
run_host_command_logged scripts/config --enable CONFIG_LED
run_host_command_logged scripts/config --enable CONFIG_LED_GPIO
display_alert "u-boot for ${BOARD}" "u-boot: enable networking cmds" "info"
run_host_command_logged scripts/config --enable CONFIG_CMD_NFS
run_host_command_logged scripts/config --enable CONFIG_CMD_WGET
run_host_command_logged scripts/config --enable CONFIG_CMD_DNS
run_host_command_logged scripts/config --enable CONFIG_PROT_TCP
run_host_command_logged scripts/config --enable CONFIG_PROT_TCP_SACK
}
# @TODO: this is no longer needed in `edge` branch -- Neil has sent a patch with a trip for the cooling map in the DT - also doesn't hurt.
function post_family_tweaks__config_odroidhc4_fancontrol() {
display_alert "Configuring fancontrol" "for Odroid HC4" "info"
cat <<- FANCONTROL > "${SDCARD}"/etc/fancontrol
# Default config for the Odroid HC4 -- adjust to your needs (MINTEMP=40)
INTERVAL=10
DEVPATH=hwmon0=devices/virtual/thermal/thermal_zone0 hwmon2=devices/platform/pwm-fan
DEVNAME=hwmon0=cpu_thermal hwmon2=pwmfan
FCTEMPS=hwmon2/pwm1=hwmon0/temp1_input
FCFANS= hwmon2/pwm1=hwmon2/fan1_input
MINTEMP=hwmon2/pwm1=40
MAXTEMP=hwmon2/pwm1=60
MINSTART=hwmon2/pwm1=150
MINSTOP=hwmon2/pwm1=30
MAXPWM=hwmon2/pwm1=180
FANCONTROL
chroot_sdcard systemctl enable fancontrol.service
}

View File

@ -13,8 +13,8 @@ IMAGE_PARTITION_TABLE="gpt"
FULL_DESKTOP="yes"
BOOT_LOGO="desktop"
BOOTBRANCH_BOARD="tag:v2026.01"
BOOTPATCHDIR="v2026.01" # but all changes are done in this board file, not patches
BOOTBRANCH_BOARD="tag:v2025.10"
BOOTPATCHDIR="v2025.10" # but all changes are done in this board file, not patches
BOOTCONFIG="odroid-m1-rk3568_defconfig"
BOOTDIR="u-boot-${BOARD}"
@ -88,8 +88,6 @@ function post_family_tweaks__odroidm1_rename_gmac_eth0() {
}
# Important: micro-USB OTG port is shared with lower blue USB3 type-A port; that won't work for booting.
# use the upper port, or the USB2 ports for booting.
function pre_config_uboot_target__odroidm1_patch_uboot_dtsi_for_ums() {
display_alert "u-boot for ${BOARD}" "u-boot: add to u-boot dtsi for UMS" "info" # avoid a patch, just append to the dtsi file
cat <<- UBOOT_BOARD_DTSI_OTG >> arch/arm/dts/rk3568-odroid-m1-u-boot.dtsi
@ -107,6 +105,7 @@ function pre_config_uboot_target__odroidm1_patch_rockchip_common_boot_order() {
}
# A better equivalent to patching a defconfig, do changes to .config via code.
# For UMS/RockUSB to work in u-boot, &usb_host0_xhci { dr_mode = "otg" } is required. See 0002-board-rockchip-ODROID-M1-override-kernel-DT-for-xhci-otg-dr_mode.patch
function post_config_uboot_target__extra_configs_for_odroid-m1() {
[[ "${BRANCH}" == "edge" || "${BRANCH}" == "current" ]] || return 0
@ -119,7 +118,7 @@ function post_config_uboot_target__extra_configs_for_odroid-m1() {
display_alert "u-boot for ${BOARD}" "u-boot: enable preboot & reset environment once in preboot" "info"
run_host_command_logged scripts/config --enable CONFIG_USE_PREBOOT
run_host_command_logged scripts/config --set-str CONFIG_PREBOOT "'echo armbian leds; led red:power on; led blue:heartbeat on; sleep 0.1; led red:power off; led blue:heartbeat off; sleep 0.1; led red:power on; if test a\${armbian}a = atwicea; then echo armbian env already set once; else echo armbian resetting environment once; env default -f -a; setenv armbian twice; saveenv; fi'" # double quote
run_host_command_logged scripts/config --set-str CONFIG_PREBOOT "'echo armbian leds; led led-0 on; led led-1 on; sleep 0.1; led led-0 off; led led-1 off; sleep 0.1; led led-0 on; if test a\${armbian}a = atwicea; then echo armbian env already set once; else echo armbian resetting environment once; env default -f -a; setenv armbian twice; saveenv; fi'" # double quote
display_alert "u-boot for ${BOARD}" "u-boot: enable EFI debugging command" "info"
run_host_command_logged scripts/config --enable CMD_EFIDEBUG
@ -152,7 +151,7 @@ function post_config_uboot_target__extra_configs_for_odroid-m1() {
run_host_command_logged scripts/config --enable CONFIG_CMD_XXD
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enabling UMS/RockUSB Gadget functionality" "info"
declare -a enable_configs=("CONFIG_CMD_USB_MASS_STORAGE" "CONFIG_USB_GADGET" "USB_GADGET_DOWNLOAD" "CONFIG_USB_FUNCTION_ROCKUSB" "CONFIG_USB_FUNCTION_ACM" "CONFIG_CMD_ROCKUSB")
declare -a enable_configs=("CONFIG_CMD_USB_MASS_STORAGE" "CONFIG_USB_GADGET" "USB_GADGET_DOWNLOAD" "CONFIG_USB_FUNCTION_ROCKUSB" "CONFIG_USB_FUNCTION_ACM" "CONFIG_CMD_ROCKUSB" "CONFIG_CMD_USB_MASS_STORAGE")
for config in "${enable_configs[@]}"; do
run_host_command_logged scripts/config --enable "${config}"
done

View File

@ -1,53 +0,0 @@
# Rockchip RK3588s SoC octa core 4-16GB SoC eMMC USB3 NvME
BOARD_NAME="Odroid M2"
BOARD_VENDOR="hardkernel"
BOARDFAMILY="rockchip64"
BOARD_MAINTAINER="mlegenovic"
BOOT_SOC="rk3588"
KERNEL_TARGET="current,edge"
KERNEL_TEST_TARGET="current"
BOOT_FDT_FILE="rockchip/rk3588s-odroid-m2.dtb"
BOOT_SCENARIO="binman"
IMAGE_PARTITION_TABLE="gpt"
FULL_DESKTOP="no"
BOOT_LOGO="yes"
BOOTBRANCH_BOARD="tag:v2025.10"
BOOTBRANCH="${BOOTBRANCH_BOARD}"
BOOTPATCHDIR="v2025.10"
BOOTCONFIG="odroid-m2-rk3588s_defconfig"
BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory
OVERLAY_PREFIX='rockchip-rk3588'
function post_family_config__uboot_config() {
display_alert "$BOARD" "u-boot ${BOOTBRANCH_BOARD} overrides" "info"
BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc
UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/$BL31_BLOB ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin"
unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already
# Just use the binman-provided u-boot-rockchip.bin, which is ready-to-go
function write_uboot_platform() {
dd if=${1}/u-boot-rockchip.bin of=${2} bs=32k seek=1 conv=fsync
}
}
# "rockchip-common: boot SD card first, then NVMe, then SATA, then USB, then mmc"
# On odroidm2, mmc0 is the eMMC, mmc1 is the SD card slot
function pre_config_uboot_target__odroidm2_patch_rockchip_common_boot_order() {
declare -a rockchip_uboot_targets=("mmc1" "nvme" "mmc0" "usb" "pxe" "dhcp") # for future make-this-generic delight
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: adjust boot order to '${rockchip_uboot_targets[*]}'" "info"
sed -i -e "s/#define BOOT_TARGETS.*/#define BOOT_TARGETS \"${rockchip_uboot_targets[*]}\"/" include/configs/rockchip-common.h
regular_git diff -u include/configs/rockchip-common.h || true
}
# add a network rule to rename default name
function post_family_tweaks__odroidm2_rename_gmac_eth0() {
display_alert "Creating network rename rule for Odroid M2"
mkdir -p "${SDCARD}"/etc/udev/rules.d/
cat <<- EOF > "${SDCARD}"/etc/udev/rules.d/70-rename-lan.rules
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", KERNEL=="end*", NAME="eth0"
EOF
}

View File

@ -0,0 +1,52 @@
# Rockchip RK3588s SoC octa core 4-16GB SoC eMMC USB3 NvME
BOARD_NAME="Odroid M2"
BOARD_VENDOR="hardkernel"
BOARDFAMILY="rockchip64"
BOARD_MAINTAINER="mlegenovic"
BOOT_SOC="rk3588"
KERNEL_TARGET="edge"
BOOT_FDT_FILE="rockchip/rk3588s-odroid-m2.dtb"
BOOT_SCENARIO="binman"
IMAGE_PARTITION_TABLE="gpt"
FULL_DESKTOP="no"
BOOT_LOGO="yes"
BOOTBRANCH_BOARD="tag:v2025.04-rc5"
BOOTBRANCH="${BOOTBRANCH_BOARD}"
BOOTPATCHDIR="v2025.04"
BOOTCONFIG="odroid-m2-rk3588s_defconfig"
BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory
OVERLAY_PREFIX='rockchip-rk3588'
function post_family_config__uboot_config() {
display_alert "$BOARD" "u-boot ${BOOTBRANCH_BOARD} overrides" "info"
BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc
UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/$BL31_BLOB ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin"
unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already
# Just use the binman-provided u-boot-rockchip.bin, which is ready-to-go
function write_uboot_platform() {
dd if=${1}/u-boot-rockchip.bin of=${2} bs=32k seek=1 conv=fsync
}
}
# "rockchip-common: boot SD card first, then NVMe, then SATA, then USB, then mmc"
# On odroidm2, mmc0 is the eMMC, mmc1 is the SD card slot
function pre_config_uboot_target__odroidm2_patch_rockchip_common_boot_order() {
declare -a rockchip_uboot_targets=("mmc1" "nvme" "mmc0" "usb" "pxe" "dhcp") # for future make-this-generic delight
display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: adjust boot order to '${rockchip_uboot_targets[*]}'" "info"
sed -i -e "s/#define BOOT_TARGETS.*/#define BOOT_TARGETS \"${rockchip_uboot_targets[*]}\"/" include/configs/rockchip-common.h
regular_git diff -u include/configs/rockchip-common.h || true
}
# add a network rule to rename default name
function post_family_tweaks__odroidm2_rename_gmac_eth0() {
display_alert "Creating network rename rule for Odroid M2"
mkdir -p "${SDCARD}"/etc/udev/rules.d/
cat <<- EOF > "${SDCARD}"/etc/udev/rules.d/70-rename-lan.rules
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", KERNEL=="end*", NAME="eth0"
EOF
}

View File

@ -1,82 +0,0 @@
# Allwinner H6 quad core 2GB RAM SoC GBE USB3
BOARD_NAME="Orange Pi 3 LTS"
BOARD_VENDOR="xunlong"
BOARDFAMILY="sun50iw6"
BOARD_MAINTAINER="pyavitz"
BOOT_FDT_FILE="allwinner/sun50i-h6-orangepi-3-lts.dtb"
BOOTCONFIG="orangepi_3_lts_defconfig"
BOOT_LOGO="desktop"
CRUSTCONFIG="pine_h64_defconfig"
KERNEL_TARGET="current,edge"
KERNEL_TEST_TARGET="current"
PACKAGE_LIST_BOARD="rfkill bluetooth bluez bluez-tools"
SRC_EXTLINUX="yes"
SRC_CMDLINE="console=tty1 console=ttyS0,115200n8 loglevel=1"
function post_family_config__use_orangepi3lts_uboot() {
case $BRANCH in
* )
declare -g ATFBRANCH="tag:lts-v2.12.9"
declare -g BOOTPATCHDIR="v2026.01"
declare -g BOOTBRANCH_BOARD="tag:${BOOTPATCHDIR}"
declare -g BOOTBRANCH="${BOOTBRANCH_BOARD}"
;;
esac
}
# UWE5622 Wireless
function post_family_tweaks_bsp__uwe5622_wireless() {
if [[ -f "$SRC/packages/bsp/sunxi/sprd-bluetooth" ]] && \
[[ -f "$SRC/packages/bsp/sunxi/aw859a-wifi.service" ]] && \
[[ -f "$SRC/packages/blobs/bt/hciattach/hciattach_opi_${ARCH}_upstream" ]]; then
display_alert "$BOARD" "Installing UWE5622 Tweaks" "info"
mkdir -p "${destination}"/usr/bin
mkdir -p "${destination}"/etc/systemd/system
cp -f "$SRC/packages/bsp/sunxi/sprd-bluetooth" "${destination}"/usr/bin
cp -f "$SRC/packages/blobs/bt/hciattach/hciattach_opi_${ARCH}_upstream" "${destination}"/usr/bin/hciattach_opi
chmod +x "${destination}"/usr/bin/sprd-bluetooth
chmod +x "${destination}"/usr/bin/hciattach_opi
cat > "${destination}"/etc/systemd/system/sprd-bluetooth.service <<- EOT
[Unit]
Description=SPRD Bluetooth
After=bluetooth.service bluetooth.target
[Service]
Type=simple
ExecStartPre=/usr/sbin/rfkill unblock all
ExecStart=/usr/bin/sprd-bluetooth
TimeoutSec=0
RemainAfterExit=true
[Install]
WantedBy=multi-user.target
EOT
mkdir -p "${destination}"/etc/modules-load.d
# Add needed wireless modules
cat > "${destination}"/etc/modules-load.d/uwe5622-wireless.conf <<- EOT
hci_uart
bnep
rfcomm
sprdbt_tty
sprdwl_ng
EOT
fi
}
# Enable UWE5622 Wireless Services
function post_family_tweaks__enable_uwe5622_wireless_services() {
display_alert "$BOARD" "Enabling UWE5622 Wireless Services" "info"
chroot_sdcard systemctl --no-reload enable sprd-bluetooth.service
}
function post_family_config__opi3lts_set_asoundstate_file() {
declare -g ASOUND_STATE='asound.state.sun50iw6-current'
}
function post_family_tweaks__opi3lts_configure_pulse_audio() {
if [[ $BUILD_DESKTOP == yes ]]; then
sed -i "s/auto-profiles = yes/auto-profiles = no/" ${SDCARD}/usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf
echo "load-module module-alsa-sink device=hw:0,0 sink_name=AudioCodec-Playback sink_properties=\"device.description='Audio Codec'\"" >> ${SDCARD}/etc/pulse/default.pa
echo "load-module module-alsa-sink device=hw:1,0 sink_name=HDMI-Playback sink_properties=\"device.description='HDMI Audio'\"" >> ${SDCARD}/etc/pulse/default.pa
fi
}

View File

@ -0,0 +1,24 @@
# Allwinner H6 quad core 2GB RAM SoC GBE USB3
BOARD_NAME="Orange Pi 3 LTS"
BOARD_VENDOR="xunlong"
BOARDFAMILY="sun50iw6"
BOARD_MAINTAINER=""
BOOTCONFIG="orangepi_3_lts_defconfig"
BOOT_LOGO="desktop"
KERNEL_TARGET="current,edge,legacy"
KERNEL_TEST_TARGET="current"
CRUSTCONFIG="orangepi_3_lts_defconfig"
enable_extension "uwe5622-allwinner"
function post_family_config__opi3lts_set_asoundstate_file() {
declare -g ASOUND_STATE='asound.state.sun50iw6-current'
}
function post_family_tweaks__opi3lts_configure_pulse_audio() {
if [[ $BUILD_DESKTOP == yes ]]; then
sed -i "s/auto-profiles = yes/auto-profiles = no/" ${SDCARD}/usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf
echo "load-module module-alsa-sink device=hw:0,0 sink_name=AudioCodec-Playback sink_properties=\"device.description='Audio Codec'\"" >> ${SDCARD}/etc/pulse/default.pa
echo "load-module module-alsa-sink device=hw:1,0 sink_name=HDMI-Playback sink_properties=\"device.description='HDMI Audio'\"" >> ${SDCARD}/etc/pulse/default.pa
fi
}

View File

@ -4,13 +4,12 @@ BOARD_VENDOR="xunlong"
BOARDFAMILY="rk35xx"
BOARD_MAINTAINER=""
BOOTCONFIG="orangepi-3b-rk3566_defconfig"
BOOTCONFIG_SATA="orangepi-3b-sata-rk3566_defconfig"
BOOT_SOC="rk3566"
KERNEL_TARGET="vendor,current,edge"
KERNEL_TARGET="vendor,edge"
FULL_DESKTOP="yes"
BOOT_LOGO="desktop"
IMAGE_PARTITION_TABLE="gpt"
BOOT_SCENARIO="binman"
BOOT_SCENARIO="spl-blobs"
BOOT_SUPPORT_SPI="yes"
BOOT_SPI_RKSPI_LOADER="yes"
@ -19,42 +18,29 @@ function post_family_config__orangepi3b_use_mainline_uboot() {
display_alert "$BOARD" "Using mainline U-Boot for $BOARD / $BRANCH" "info"
declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git"
declare -g BOOTBRANCH="tag:v2026.01"
declare -g BOOTPATCHDIR="v2026.01"
declare -g BOOTBRANCH="tag:v2024.10"
declare -g BOOTPATCHDIR="v2024.10"
declare -g BOOTDELAY=1
declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB} $BOOTCONFIG_SATA;;u-boot-rockchip-spi-sata.bin
BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB} $BOOTCONFIG;;u-boot-rockchip.bin u-boot-rockchip-spi.bin"
}
declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin u-boot.itb idbloader.img idbloader-spi.img"
unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already
function pre_config_uboot_target__orangepi3b_patch_uboot_bootconfig_hack_for_sata() {
display_alert "u-boot for ${BOARD}" "u-boot: hack bootconfig for sata spi image" "info"
# Just use the binman-provided u-boot-rockchip.bin, which is ready-to-go
function write_uboot_platform() {
dd if=${1}/u-boot-rockchip.bin of=${2} bs=32k seek=1 conv=fsync
}
if [[ $target_make == *"orangepi-3b-sata-rk3566_defconfig"* ]]; then
cp configs/orangepi-3b-rk3566_defconfig configs/orangepi-3b-sata-rk3566_defconfig
echo "CONFIG_DWC_AHCI=y" >> configs/orangepi-3b-sata-rk3566_defconfig
BOOTCONFIG="orangepi-3b-sata-rk3566_defconfig"
target_make=${target_make/orangepi-3b-sata-rk3566_defconfig/}
else
BOOTCONFIG="orangepi-3b-rk3566_defconfig"
target_make=${target_make/orangepi-3b-rk3566_defconfig/}
fi
}
function post_config_uboot_target__orangepi3b_keep_sata_bootconfig() {
display_alert "u-boot for ${BOARD}" "u-boot: hack bootconfig for sata spi image" "info"
if [[ $BOOTCONFIG == "orangepi-3b-sata-rk3566_defconfig" ]]; then
cp .config "${uboottempdir}/.config.sata"
fi
}
function pre_package_uboot_image__orangepi3b_copy_sataconfig_to_package() {
if [[ -f "${uboottempdir}/.config.sata" ]]; then
run_host_command_logged cp "${uboottempdir}/.config.sata" "$uboottempdir/usr/lib/u-boot/orangepi-3b-sata-rk3566_defconfig"
run_host_command_logged rm "${uboottempdir}/.config.sata"
fi
# Smarter/faster/better to-spi writer using flashcp (hopefully with --partition), using the binman-provided 'u-boot-rockchip-spi.bin'
function write_uboot_platform_mtd() {
declare -a extra_opts_flashcp=("--verbose")
if flashcp -h | grep -q -e '--partition'; then
echo "Confirmed flashcp supports --partition -- read and write only changed blocks." >&2
extra_opts_flashcp+=("--partition")
else
echo "flashcp does not support --partition, will write full SPI flash blocks." >&2
fi
flashcp "${extra_opts_flashcp[@]}" "${1}/u-boot-rockchip-spi.bin" /dev/mtd0
}
}
function post_family_tweaks_bsp__orangepi3b() {

View File

@ -34,17 +34,13 @@ function post_family_config__orangepi5plus_use_mainline_uboot() {
display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info"
# To reuse ATF code in rockchip64_common, let's change the BOOT_SCENARIO and call prepare_boot_configuration() again
declare -g BOOT_SCENARIO="tpl-blob-atf-mainline"
prepare_boot_configuration
declare -g BOOTCONFIG="orangepi-5-plus-rk3588_defconfig"
declare -g BOOTDELAY=1
declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git"
declare -g BOOTBRANCH="tag:v2026.01"
declare -g BOOTPATCHDIR="v2026.01"
declare -g BOOTBRANCH="tag:v2025.10"
declare -g BOOTPATCHDIR="v2025.10"
declare -g BOOTDIR="u-boot-${BOARD}"
declare -g UBOOT_TARGET_MAP="BL31=bl31.elf ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin"
declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin"
unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already
# Just use the binman-provided u-boot-rockchip.bin, which is ready-to-go
@ -56,3 +52,13 @@ function post_family_config__orangepi5plus_use_mainline_uboot() {
flashcp -v -p "$1/u-boot-rockchip-spi.bin" /dev/mtd0
}
}
function post_config_uboot_target__extra_configs_for_rock5b_mainline_environment_in_spi() {
[[ "${BRANCH}" == "vendor" ]] && return 0
display_alert "$BOARD" "u-boot configs for ${BOOTBRANCH} u-boot config BRANCH=${BRANCH}" "info"
run_host_command_logged scripts/config --set-val CONFIG_BOARD_RNG_SEED "y"
run_host_command_logged scripts/config --set-val ARMV8_CRYPTO "y"
run_host_command_logged scripts/config --set-val ARMV8_CE_SHA1 "y"
run_host_command_logged scripts/config --set-val ARMV8_CE_SHA256 "y"
}

View File

@ -26,8 +26,8 @@ function post_family_config__orangepi5_use_mainline_uboot() {
declare -g BOOTCONFIG="orangepi-5-rk3588s_defconfig"
declare -g BOOTDELAY=1
declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git"
declare -g BOOTBRANCH="tag:v2026.04-rc3"
declare -g BOOTPATCHDIR="v2026.04"
declare -g BOOTBRANCH="tag:v2025.10"
declare -g BOOTPATCHDIR="v2025.10"
declare -g BOOTDIR="u-boot-${BOARD}"
declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB} $BOOTCONFIG_SATA;;u-boot-rockchip-spi-sata.bin
BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB} $BOOTCONFIG;;u-boot-rockchip.bin u-boot-rockchip-spi.bin"

View File

@ -14,6 +14,7 @@ BOOT_SCENARIO="spl-blobs"
BOOT_SUPPORT_SPI="yes"
BOOT_SPI_RKSPI_LOADER="yes"
IMAGE_PARTITION_TABLE="gpt"
KERNEL_UPGRADE_FREEZE="vendor-rk35xx@24.8.1"
function post_family_tweaks__orangepi5pro_naming_audios() {
display_alert "$BOARD" "Renaming orangepi5pro audios" "info"

View File

@ -6,4 +6,4 @@ BOARD_MAINTAINER=""
BOOTCONFIG="orangepi_lite2_defconfig"
KERNEL_TARGET="current,edge,legacy"
KERNEL_TEST_TARGET="current"
CRUSTCONFIG="pine_h64_defconfig"
CRUSTCONFIG="orangepi_3_lts_defconfig"

View File

@ -6,4 +6,4 @@ BOARD_MAINTAINER=""
BOOTCONFIG="orangepi_one_plus_defconfig"
KERNEL_TARGET="current,edge,legacy"
KERNEL_TEST_TARGET="current"
CRUSTCONFIG="pine_h64_defconfig"
CRUSTCONFIG="orangepi_3_lts_defconfig"

Some files were not shown because too many files have changed in this diff Show More