Skip to content

Build LinuxBox-Dev Images #299

Build LinuxBox-Dev Images

Build LinuxBox-Dev Images #299

Workflow file for this run

name: Build LinuxBox-Dev Images
#
# Generates beta, stable or RC images for LinuxBox devices. You can select build runners. By default it generates all images, but you can build images only for one target
# Images are placed at www.arnmbian.com and nighly beta also at https://github.com/armbian/build/releases/tag/latest
#
on:
workflow_run:
workflows: ["Build train"]
types:
- completed
workflow_dispatch:
inputs:
choice:
type: choice
description: Build targets
options:
- beta
- stable
- rc
runner:
type: choice
description: Build runners for CLI
options:
- small
- ubuntu-latest
sourcerepo:
description: Source repository
required: false
default: 'nightly'
packagesrepo:
type: choice
description: Beta packages repository
options:
- "yes"
- "no"
board:
description: "Board: trhubv3, trhubv3b, linuxbox"
required: false
default: "trhubv3"
dist:
description: "Distribution: cn, us, kr"
required: false
default: "us"
revision:
description: "Revision (optional)"
required: false
default: "v1.13.01.12"
advanced:
description: 'Single board (grep -w tinkerboard |)'
required: false
default: ''
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
Cancel:
if: ${{ github.repository_owner == 'Armbian' && github.event.schedule == '' }}
name: "Cancel currently active"
runs-on: small
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]
with:
access_token: ${{ secrets.GITHUB_TOKEN }}
clean:
if: ${{ github.repository_owner == 'Armbian' }}
name: Purge older releases
needs: [ Cancel ]
runs-on: [ubuntu-latest]
steps:
- name: Purge
uses: dev-drprasad/[email protected]
with:
keep_latest: 7
delete_tag_pattern: trunk
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: igorjs/gh-actions-clean-workflow@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
days_old: 14
fake:
if: ${{ github.repository_owner == 'Armbian' }}
runs-on: small
needs: [ clean ]
name: Source changes
outputs:
changes: ${{steps.list_releases.outputs.changes}}
version: ${{steps.list_releases.outputs.version}}
steps:
- run: |
echo "not empty" > changes
- uses: actions/checkout@v3
if: ${{ github.repository_owner == 'Armbian' && github.event.inputs.choice != 'stable' && github.event.inputs.choice != 'rc' }}
with:
fetch-depth: 1
path: build
clean: false
ref: nightly
- name: "Get latest release version"
if: ${{ github.repository_owner == 'Armbian' && github.event.inputs.choice != 'stable' && github.event.inputs.choice != 'rc' }}
id: list_releases
run: |
RELE=$(curl -ks https://api.github.com/repos/armbian/build/releases/latest ^| grep "browser_download_url" | grep -o -P '(?<=Armbian.).*(?=_)' | cut -d"_" -f1 | sort | uniq | head -1)
SOUR=$(cat build/VERSION)
# skip if version in git is the same as at release
if [[ "$RELE" == "$SOUR" ]]; then
echo ::set-output name=changes::$(echo 'true')
fi
# output version
echo ::set-output name=version::$(echo ${SOUR})
- uses: actions/upload-artifact@v3
with:
path: changes
name: changes
if-no-files-found: ignore
- uses: actions/upload-artifact@v3
with:
path: changes
name: changes
if-no-files-found: ignore
generaterelease:
needs: [ fake ]
if: ${{ github.repository_owner == 'Armbian' && needs.fake.outputs.changes != 'true' }}
runs-on: ubuntu-latest
name: "Update latest release"
steps:
- run: |
echo "Env: ${{ github.event.inputs.choice }}"
echo "Env: ${{ github.event.inputs.runner }}"
echo "Env: ${{ github.event.inputs.sourcerepo }}"
echo "Branch: ${{ github.event.inputs.branch }}"
echo "Version: ${{ needs.fake.outputs.version }}"
- uses: actions/checkout@v3
if: ${{ github.repository_owner == 'Armbian' && github.event.inputs.choice != 'stable' && github.event.inputs.choice != 'rc' }}
with:
fetch-depth: 1
- uses: dev-drprasad/[email protected]
if: ${{ github.repository_owner == 'Armbian' && github.event.inputs.choice != 'stable' && github.event.inputs.choice != 'rc' }}
with:
delete_release: true
tag_name: latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: ncipollo/release-action@v1
if: ${{ github.repository_owner == 'Armbian' && github.event.inputs.choice != 'stable' && github.event.inputs.choice != 'rc' }}
with:
artifacts: "LICENSE"
tag: "${{ needs.fake.outputs.version }}"
name: "Build in progress"
bodyFile: ".github/Releases-wip.md"
allowUpdates: true
removeArtifacts: true
token: ${{ secrets.GITHUB_TOKEN }}
merge:
needs: [ generaterelease ]
uses: armbian/scripts/.github/workflows/merge-from-branch.yml@master
with:
branch: 'nightly'
runner: small
secrets:
GPG_KEY2: ${{ secrets.GPG_KEY2 }}
GPG_PASSPHRASE2: ${{ secrets.GPG_PASSPHRASE2 }}
x86:
needs: [ merge ]
uses: armbian/scripts/.github/workflows/build-with-docker.yml@master
with:
variant: 'cli:${{ github.event.inputs.choice }}'
sourcerepo: '${{ github.event.inputs.sourcerepo }}'
packagesrepo: '${{ github.event.inputs.packagesrepo }}'
runner: ubuntu-latest
part: 1
of: 1
include: 'grep uefi-x86 | ${{ github.event.inputs.advanced }}'
exclude: ''
uploading: false
secrets:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
GPG_KEY2: ${{ secrets.GPG_KEY2 }}
GPG_PASSPHRASE2: ${{ secrets.GPG_PASSPHRASE2 }}
SCRIPTS_ACCESS_TOKEN: ${{ secrets.SCRIPTS_ACCESS_TOKEN }}
SSH_KEY_TORRENTS: ${{ secrets.KEY_TORRENTS }}
KNOWN_HOSTS_UPLOAD: ${{ secrets.KNOWN_HOSTS_UPLOAD }}
x86-desktop:
needs: [ merge ]
uses: armbian/scripts/.github/workflows/build-with-docker.yml@master
with:
variant: 'desktop:${{ github.event.inputs.choice }}'
sourcerepo: '${{ github.event.inputs.sourcerepo }}'
packagesrepo: '${{ github.event.inputs.packagesrepo }}'
runner: "big"
part: 1
of: 1
include: 'grep uefi-x86 | ${{ github.event.inputs.advanced }}'
exclude: ''
uploading: false
secrets:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
GPG_KEY2: ${{ secrets.GPG_KEY2 }}
GPG_PASSPHRASE2: ${{ secrets.GPG_PASSPHRASE2 }}
SCRIPTS_ACCESS_TOKEN: ${{ secrets.SCRIPTS_ACCESS_TOKEN }}
SSH_KEY_TORRENTS: ${{ secrets.KEY_TORRENTS }}
KNOWN_HOSTS_UPLOAD: ${{ secrets.KNOWN_HOSTS_UPLOAD }}
cli1:
needs: [ merge ]
uses: armbian/scripts/.github/workflows/build-with-docker.yml@master
with:
variant: 'cli:${{ github.event.inputs.choice }}'
sourcerepo: '${{ github.event.inputs.sourcerepo }}'
packagesrepo: '${{ github.event.inputs.packagesrepo }}'
runner: ubuntu-latest
part: 1
of: 2
include: '${{ github.event.inputs.advanced }}'
exclude: 'grep -v uefi-x86 | '
uploading: false
secrets:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
GPG_KEY2: ${{ secrets.GPG_KEY2 }}
GPG_PASSPHRASE2: ${{ secrets.GPG_PASSPHRASE2 }}
SCRIPTS_ACCESS_TOKEN: ${{ secrets.SCRIPTS_ACCESS_TOKEN }}
SSH_KEY_TORRENTS: ${{ secrets.KEY_TORRENTS }}
KNOWN_HOSTS_UPLOAD: ${{ secrets.KNOWN_HOSTS_UPLOAD }}
cli2:
needs: [ merge ]
uses: armbian/scripts/.github/workflows/build-with-docker.yml@master
with:
variant: 'cli:${{ github.event.inputs.choice }}'
sourcerepo: '${{ github.event.inputs.sourcerepo }}'
packagesrepo: '${{ github.event.inputs.packagesrepo }}'
runner: '${{ github.event.inputs.runner }}'
part: 2
of: 2
include: '${{ github.event.inputs.advanced }}'
exclude: 'grep -v uefi-x86 | '
uploading: false
secrets:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
GPG_KEY2: ${{ secrets.GPG_KEY2 }}
GPG_PASSPHRASE2: ${{ secrets.GPG_PASSPHRASE2 }}
SCRIPTS_ACCESS_TOKEN: ${{ secrets.SCRIPTS_ACCESS_TOKEN }}
SSH_KEY_TORRENTS: ${{ secrets.KEY_TORRENTS }}
KNOWN_HOSTS_UPLOAD: ${{ secrets.KNOWN_HOSTS_UPLOAD }}
desktop1:
needs: [ merge ]
uses: armbian/scripts/.github/workflows/build-with-docker.yml@master
with:
variant: 'desktop:${{ github.event.inputs.choice }}'
sourcerepo: '${{ github.event.inputs.sourcerepo }}'
packagesrepo: '${{ github.event.inputs.packagesrepo }}'
runner: "big"
part: 1
of: 2
include: '${{ github.event.inputs.advanced }}'
exclude: 'grep -v uefi-x86 | '
uploading: false
secrets:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
GPG_KEY2: ${{ secrets.GPG_KEY2 }}
GPG_PASSPHRASE2: ${{ secrets.GPG_PASSPHRASE2 }}
SCRIPTS_ACCESS_TOKEN: ${{ secrets.SCRIPTS_ACCESS_TOKEN }}
SSH_KEY_TORRENTS: ${{ secrets.KEY_TORRENTS }}
KNOWN_HOSTS_UPLOAD: ${{ secrets.KNOWN_HOSTS_UPLOAD }}
desktop2:
needs: [ merge ]
uses: armbian/scripts/.github/workflows/build-with-docker.yml@master
with:
variant: 'desktop:${{ github.event.inputs.choice }}'
sourcerepo: '${{ github.event.inputs.sourcerepo }}'
packagesrepo: '${{ github.event.inputs.packagesrepo }}'
runner: "big"
part: 2
of: 2
include: '${{ github.event.inputs.advanced }}'
exclude: 'grep -v uefi-x86 | '
uploading: false
secrets:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
GPG_KEY2: ${{ secrets.GPG_KEY2 }}
GPG_PASSPHRASE2: ${{ secrets.GPG_PASSPHRASE2 }}
SCRIPTS_ACCESS_TOKEN: ${{ secrets.SCRIPTS_ACCESS_TOKEN }}
SSH_KEY_TORRENTS: ${{ secrets.KEY_TORRENTS }}
KNOWN_HOSTS_UPLOAD: ${{ secrets.KNOWN_HOSTS_UPLOAD }}
linuxbox-build:
name: Build LinuxBox firmware
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: hubv3
- name: Free up disk space
run: |
echo "=== Initial disk usage ==="
df -h
echo ""
echo "=== Removing unnecessary software ==="
# Remove Android SDK
sudo rm -rf /usr/local/lib/android || true
# Remove .NET
sudo rm -rf /usr/share/dotnet || true
# Remove Haskell
sudo rm -rf /opt/ghc || true
sudo rm -rf /usr/local/.ghcup || true
# Remove CodeQL
sudo rm -rf /opt/hostedtoolcache/CodeQL || true
# Remove large tool caches
sudo rm -rf /opt/hostedtoolcache/* || true
# Remove large packages
sudo apt-get remove -y '^aspnetcore-.*' '^dotnet-.*' '^llvm-.*' 'php.*' '^mongodb-.*' '^mysql-.*' azure-cli google-chrome-stable firefox powershell mono-devel libgl1-mesa-dri || true
# Remove Docker images and containers
docker rmi $(docker image ls -aq) >/dev/null 2>&1 || true
docker system prune -a -f || true
# Remove swap
sudo swapoff -a || true
sudo rm -f /mnt/swapfile || true
sudo rm -f /swapfile || true
echo ""
echo "=== Disk usage after cleanup ==="
df -h
echo ""
echo "=== Cleaning up previous build artifacts ==="
sudo rm -rf /mnt/linuxbox /mnt/output
echo "=== Final disk usage ==="
df -h
- name: Install dependencies
run: |
sudo apt-get update
# Install essential build tools for U-boot and kernel compilation
sudo apt-get install -y uuid-runtime systemd acl sudo git dialog psmisc uuid curl gawk ca-certificates \
gcc build-essential python3 python3-dev python3-venv python3-pip pv xz-utils patchutils \
binfmt-support qemu-user-static \
bc bison flex libssl-dev libncurses5-dev libncursesw5-dev \
device-tree-compiler u-boot-tools swig libpython3-dev \
gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu \
ccache ntpdate imagemagick pixz
sudo apt-get autoremove -y || true
sudo apt-get clean || true
# Clean apt cache
sudo rm -rf /var/lib/apt/lists/* || true
sudo rm -rf /var/cache/apt/archives/* || true
- name: Setup QEMU for ARM emulation
run: |
echo "Setting up QEMU for ARM emulation..."
sudo systemctl restart systemd-binfmt.service || true
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes || true
echo "Verifying QEMU registration..."
ls -la /proc/sys/fs/binfmt_misc/ || true
cat /proc/sys/fs/binfmt_misc/qemu-aarch64 || echo "qemu-aarch64 not registered"
- name: Setup output directory symlink
run: |
echo "Setting up output directory symlink..."
sudo mkdir -p /mnt/output
sudo chown -R $USER:$USER /mnt/output
ln -s /mnt/output ${{ github.workspace }}/output
echo "Symlink created: ${{ github.workspace }}/output -> /mnt/output"
ls -lah ${{ github.workspace }}/
- name: Make script executable
run: chmod +x make_armbian_for_hubv3.sh
- name: Clean build cache
run: |
echo "Cleaning potentially corrupted build cache..."
# Remove any existing U-boot build artifacts that might cause issues
sudo rm -rf cache/sources/u-boot/*/build 2>/dev/null || true
sudo rm -rf cache/sources/u-boot/*/.config 2>/dev/null || true
sudo rm -rf cache/sources/u-boot/*/include/config 2>/dev/null || true
sudo rm -rf cache/sources/u-boot/*/include/generated 2>/dev/null || true
sudo rm -rf cache/sources/linux-*/build 2>/dev/null || true
# Ensure proper ownership of cache directory
sudo chown -R $USER:$USER cache/ 2>/dev/null || true
echo "Build cache cleaned"
- name: Build firmware
env:
NO_APT_CACHER: yes
run: |
if [ -n "${{ github.event.inputs.revision }}" ]; then
./make_armbian_for_hubv3.sh -b ${{ github.event.inputs.board }} -d ${{ github.event.inputs.dist }} -r ${{ github.event.inputs.revision }}
else
./make_armbian_for_hubv3.sh -b ${{ github.event.inputs.board }} -d ${{ github.event.inputs.dist }}
fi
- name: List output files for debugging
run: |
echo "Checking output directory structure..."
ls -lah output/ || echo "output/ not found"
ls -lah output/images/ || echo "output/images/ not found"
find output -name "*.img" -type f 2>/dev/null || echo "No .img files found in output/"
echo "Disk usage after build:"
df -h
- name: Upload images as artifact
uses: actions/upload-artifact@v4
with:
name: LinuxBox-images${{ github.event.inputs.revision && format('-{0}', github.event.inputs.revision) || '' }}
path: |
output/images/*.img
output/images/*.xz
if-no-files-found: warn
- name: Clean up after upload
run: |
echo "Cleaning up after successful upload..."
sudo rm -rf /mnt/output /mnt/linuxbox
echo "Final disk usage:"
df -h
jobsend:
name: finish
needs: [x86,x86-desktop,cli1,desktop1,cli2,desktop2,linuxbox-build]
runs-on: [ubuntu-latest]
if: ${{ github.repository_owner == 'Armbian' && github.event.inputs.choice != 'stable' && github.event.inputs.choice != 'rc' }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 1
ref: nightly
- name: Make build list
run: |
sudo npm install --location=global json || true
truncate README.me --size=0 || true
echo "VERSION=$(cat VERSION)" >> $GITHUB_ENV
cat ".github/Releases.md" >> README.tmp
echo -en "&nbsp;\n\n" >> README.tmp
echo "| Image &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | GPG | SHA | Release | Branch | Variant | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Size | Kernel |" >> README.tmp
echo "| --- | :--: | :--: | :--: | :--: | :--: | --: | --: |" >> README.tmp
gh release view --json assets 2>/dev/null | python3 -mjson.tool | sed '1,2d;$d' | json -ga name url size -d, | sort | (
while read -r line; do
name=$(echo $line | cut -d"," -f1 | awk '{print tolower($0)}')
url=$(echo $line | cut -d"," -f2)
size=$(echo $line | cut -d"," -f3)
if [ "${name: -3}" == ".xz" ]; then
board_name=$(echo $name | cut -d"_" -f3)
source config/boards/$board_name.*
out_release=$(echo $name | cut -d"_" -f4)
out_branch=$(echo $name | cut -d"_" -f5)
out_kernel=$(echo $name | cut -d"_" -f6-7 | cut -d"." -f1-3 | cut -d"_" -f1)
out_desktop=$(echo $name | cut -d"_" -f7)
out_desktop=${out_desktop:-cli}
out_size=$(echo "scale=2; $size/1024/1024" | bc -l)" Mb"
echo -ne "| [$BOARD_NAME]($url) | [:file_folder:]($url".asc") | [:file_folder:]($url".sha") | $out_release | $out_branch | $out_desktop | $out_size | $out_kernel |\n" >> README.tmp
fi
done
)
cat README.tmp
- uses: ncipollo/release-action@v1
with:
tag: "${{ env.VERSION }}"
bodyFile: "README.tmp"
name: "Armbian ${{ env.VERSION }}"
allowUpdates: true
token: ${{ secrets.GITHUB_TOKEN }}