Skip to content

Build Nightly Images (cronjob) #1091

Build Nightly Images (cronjob)

Build Nightly Images (cronjob) #1091

# template file: 050.single_header.yaml
name: "Build Nightly Images (cronjob)"
on:
schedule:
- cron: '00 8 * * *'
push:
branches:
- 'main'
paths:
- 'userpatches/targets-release-nightly.yaml'
workflow_call:
inputs:
ref: # commit id
required: false
type: string
extraParamsAllBuilds: # addional build parameter
required: false
type: string
secrets:
ORG_MEMBERS:
required: true
workflow_dispatch:
inputs:
skipImages:
description: 'Skip building images? no = build images, yes = skip images'
required: true
options: [ 'yes', 'no' ]
type: choice
default: 'no'
checkOci:
description: 'Check OCI for existing artifacts? yes = check OCI, no = always build everything'
required: true
options: [ 'yes', 'no' ]
type: choice
default: 'yes'
extraParamsAllBuilds:
description: 'Extra params for all builds/jobs (prepare/artifact/image) (eg: DEBUG=yes)'
required: false
default: ''
type: string
branch:
type: choice
description: 'Framework build branch'
options:
# branches
- main
- test
- v24.11
default: 'main'
board:
type: choice
description: 'Board'
options:
# boards
- aml-a311d-cc
- aml-c400-plus
- aml-s905d3-cc
- aml-s9xx-box
- aml-t95z-plus
- armsom-aim7-io
- armsom-cm5-io
- armsom-cm5-rpi-cm4-io
- armsom-sige1
- armsom-sige3
- armsom-sige5
- armsom-sige7
- armsom-w3
- avaota-a1
- bananapi
- bananapicm4io
- bananapim1plus
- bananapim2plus
- bananapim2pro
- bananapim2s
- bananapim2ultra
- bananapim2zero
- bananapim3
- bananapim4zero
- bananapim5
- bananapim64
- bananapim7
- bananapipro
- bananapir2
- bananapir2pro
- beaglev
- beelinkx2
- bigtreetech-cb1
- bigtreetech-cb2
- cherryba-m1
- clearfogbase
- clearfogpro
- clockworkpi-a06
- cm3588-nas
- coolpi-cm5
- coolpi-genbook
- core3566
- cubieboard
- cubieboard2
- cubieboard4
- cubietruck
- cubox-i
- cyber-aib-rk3588
- dshanpi-r1
- fine3399
- firefly-itx-3588j
- firefly-rk3399
- fxblox-rk1
- gateway-gz80x
- h96-tvbox-3566
- helios4
- helios64
- hikey960
- hinlink-h28k
- hinlink-h66k
- hinlink-h68k
- hinlink-h88k
- hinlink-hnas
- hinlink-ht2
- indiedroid-nova
- inovato-quadra
- jethubj100
- jethubj200
- jethubj80
- jetson-nano
- jp-tvbox-3566
- khadas-edge
- khadas-edge2
- khadas-vim1
- khadas-vim1s
- khadas-vim2
- khadas-vim3
- khadas-vim3l
- khadas-vim4
- lafrite
- lckfb-taishanpi
- leez-p710
- lepotato
- lime
- lime-a33
- lime-a64
- lime2
- longanpi-3h
- longanpi-4b
- lubancat2
- luckfox-core3566
- macchiatobin-doubleshot
- mangopi-m28k
- mba8mpxl
- mba8mpxl-ras314
- mekotronics-r58-minipc
- mekotronics-r58x
- mekotronics-r58x-4g
- mekotronics-r58x-pro
- melea1000
- mixtile-blade3
- mixtile-edge2
- mk808c
- mkspi
- nanopct4
- nanopct6
- nanopct6-lts
- nanopi-m6
- nanopi-r1
- nanopi-r1s-h5
- nanopi-r2c
- nanopi-r2s
- nanopi-r4s
- nanopi-r4se
- nanopi-r5c
- nanopi-r5s
- nanopi-r6c
- nanopi-r6s
- nanopia64
- nanopiair
- nanopiduo
- nanopiduo2
- nanopik1plus
- nanopik2-s905
- nanopim4
- nanopim4v2
- nanopineo
- nanopineo2
- nanopineo2black
- nanopineo3
- nanopineo4
- nanopineocore2
- nanopineoplus2
- odroidc1
- odroidc2
- odroidc4
- odroidhc4
- odroidm1
- odroidn2
- odroidn2l
- odroidxu4
- olimex-a20-olinuxino-micro
- olimex-teres-a64
- olinux-som-a13
- onecloud
- oneplus-kebab
- orangepi-r1
- orangepi-r1plus
- orangepi-r1plus-lts
- orangepi-rk3399
- orangepi2
- orangepi3
- orangepi3-lts
- orangepi3b
- orangepi4
- orangepi4-lts
- orangepi5
- orangepi5-max
- orangepi5-plus
- orangepi5pro
- orangepilite
- orangepilite2
- orangepione
- orangepioneplus
- orangepipc
- orangepipc2
- orangepipcplus
- orangepiplus
- orangepiplus2e
- orangepiprime
- orangepiwin
- orangepizero
- orangepizero2
- orangepizero2w
- orangepizero3
- orangepizeroplus
- orangepizeroplus2-h3
- orangepizeroplus2-h5
- panther-x2
- pcduino3
- phytiumpi
- pine64
- pine64so
- pinebook-a64
- pinebook-pro
- pinecube
- pineh64
- pineh64-b
- qemu-uboot-arm64
- qemu-uboot-x86
- qemu-uefi-x86
- quartz64a
- quartz64b
- radxa-e20c
- radxa-e25
- radxa-e52c
- radxa-zero
- radxa-zero2
- radxa-zero3
- recore
- renegade
- retro-lite-cm5
- retroidpocket-rp5
- retroidpocket-rpmini
- rk322x-box
- rk3318-box
- rk3328-heltec
- roc-rk3399-pc
- rock-3a
- rock-3c
- rock-4se
- rock-5-cm-rpi-cm4-io
- rock-5-cmio
- rock-5-itx
- rock-5a
- rock-5b
- rock-5b-plus
- rock-5c
- rock-s0
- rock64
- rockpi-4a
- rockpi-4b
- rockpi-4bplus
- rockpi-4c
- rockpi-4cplus
- rockpi-e
- rockpi-n10
- rockpi-s
- rockpro64
- rpi4b
- rpi5b
- sakurapi-rk3308b
- sk-am62b
- sk-am64b
- sk-am68
- sk-tda4vm
- star64
- station-m1
- station-m2
- station-m3
- station-p1
- station-p2
- sunvell-r69
- sweet-potato
- tanix-tx6
- thinkpad-x13s
- tinker-edge-r
- tinkerboard
- tinkerboard-2
- tritium-h3
- tritium-h5
- turing-rk1
- udoo
- uefi-arm64
- uefi-riscv64
- uefi-x86
- unleashed
- unmatched
- visionfive
- visionfive2
- wdk2023
- wsl2-arm64
- wsl2-x86
- x96-mate
- x96q
- xiaobao-nas
- xiaomi-elish
- xt-q8l-v10
- youyeetoo-r1-v3
- z28pro
- zeropi
- all
default: 'all'
maintainer:
type: choice
description: 'Maintainer'
options:
# maintainers
- 150balbes
- 1ubuntuuser
- AGM1968
- AaronNGray
- ColorfulRhino
- DylanHP
- FantasyGmm
- Heisath
- HeyMeco
- IsMrX
- Janmcha
- JohnTheCoolingFan
- Kreyren
- Manouchehri
- NicoD-SBC
- PanderMusubi
- PeterChrz
- SeeleVolleri
- StephenGraf
- SuperKali
- TRSx80
- TheSnowfield
- Tonymac32
- ZazaBR
- adeepn
- ahoneybun
- alexl83
- amazingfate
- andyshrk
- brentr
- catalinii
- chainsx
- chraac
- clee
- davidandreoletti
- devdotnetorg
- efectn
- eliasbakken
- engineer-80
- fridtjof
- ginkage
- glneo
- hoochiwetech
- hzyitc
- igorpecovnik
- janprunk
- jeanrhum
- joekhoobyar
- juanlufont
- krachlatte
- lanefu
- lbmendes
- linhz0hz
- mahdichi
- mattx433
- mhawkins-consultant
- monkaBlyat
- paolosabatino
- prahal
- pyavitz
- redrathnure
- rpardini
- schmiedelm
- schwar3kat
- sgjava
- sicXnull
- sputnik2019
- teknoid
- utlark
- vamzii
- viraniac
- all
default: 'all'
targetsFilterInclude:
description: 'TARGETS_FILTER_INCLUDE, example: "BOARD:odroidhc4,BOARD:odroidn2"'
required: false
default: ''
type: string
nightlybuild:
description: 'yes = nighlty, no = stable'
required: false
options: [ 'yes', 'no' ]
type: choice
default: 'yes'
bumpversion:
type: boolean
description: "Bump version"
default: 'true'
versionOverride:
description: 'Version override'
required: false
default: ''
env:
# For easier reuse across the multiple chunks ('armbian/build' repo)
BUILD_REPOSITORY: "armbian/build"
BUILD_REF: "${{ inputs.ref || inputs.branch || 'main' }}" # branch or tag or sha1
# For easier reuse across the multiple chunks ('armbian/os' repo)
USERPATCHES_REPOSITORY: "armbian/os"
USERPATCHES_REF: "main" # branch or tag or sha1
USERPATCHES_DIR: "userpatches" # folder inside USERPATCHES_REPOSITORY
# Github repository for releases. Normally its the one where we executing script
RELEASE_REPOSITORY: "os"
# Armbian envs. Adjust to your needs.
# This makes builds faster, but only if the Docker images are up-to-date with all dependencies, Python, tools, etc. Otherwise it makes it... slower.
DOCKER_SKIP_UPDATE: "yes" # Do not apt update/install/requirements/etc during Dockerfile build, trust that Docker images are up-to-date.
# Added to every build, even the prepare job.
EXTRA_PARAMS_ALL_BUILDS: "${{ inputs.extraParamsAllBuilds || 'UPLOAD_TO_OCI_ONLY=yes' }}"
# Version management
VERSION_OVERRIDE: "${{ github.event.inputs.versionOverride }}"
VERSION_BUMP: "${{ github.event.inputs.bumpversion || 'true' }}"
# To use GitHub CLI in a GitHub Actions workflow
GH_TOKEN: "${{ secrets.ACCESS_TOKEN }}"
# Added to every image build arguments.
EXTRA_PARAMS_IMAGE: "COMPRESS_OUTPUTIMAGE=xz,sha SHOW_DEBIAN=yes SHARE_LOG=yes "
# To ensure that only a single workflow using the same concurrency group will run at a time
concurrency:
group: pipeline
cancel-in-progress: false
jobs:
# additional security check
team_check:
permissions:
actions: write
name: "Team check"
runs-on: [ "ubuntu-latest" ]
steps:
- name: "Check membership"
uses: armbian/actions/team-check@main
with:
ORG_MEMBERS: ${{ secrets.ORG_MEMBERS }}
GITHUB_TOKEN: "${{ env.GH_TOKEN }}"
TEAM: "Release manager"
sources_prep:
needs: team_check
name: "Store sources hashes"
runs-on: [ "self-hosted", "Linux", 'super' ]
steps:
# Clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: 0
clean: false # true is default
path: os
# clone the build system repo (`armbian/build`)
- name: Checkout build repo
if: ${{ ( ! github.event.inputs.versionOverride ) && ( env.VERSION_BUMP == 'true' ) && ( inputs.ref == '' ) }}
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ env.BUILD_REF }}
fetch-depth: 0
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
path: build
# clone the rkbin repo (`armbian/rkbin`)
- name: Checkout build repo
if: ${{ ( ! github.event.inputs.versionOverride ) && ( env.VERSION_BUMP == 'true' ) && ( inputs.ref == '' ) }}
uses: actions/checkout@v4
with:
repository: armbian/rkbin
ref: master
fetch-depth: 0
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
path: rkbin
# clone the build docker (`armbian/docker-armbian-build`)
- name: Checkout build repo
if: ${{ ( ! github.event.inputs.versionOverride ) && ( env.VERSION_BUMP == 'true' ) && ( inputs.ref == '' ) }}
uses: actions/checkout@v4
with:
repository: armbian/docker-armbian-build
ref: main
fetch-depth: 0
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
path: docker-armbian-build
# clone the build system repo (`armbian/documentation`)
- name: Checkout build repo
if: ${{ ( ! github.event.inputs.versionOverride ) && ( env.VERSION_BUMP == 'true' ) && ( inputs.ref == '' ) }}
uses: actions/checkout@v4
with:
repository: armbian/documentation
ref: master
fetch-depth: 0
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
path: documentation
# clone the armbian-config NG repo (`armbian/configng`)
- name: Checkout build repo
if: ${{ ( ! github.event.inputs.versionOverride ) && ( env.VERSION_BUMP == 'true' ) && ( inputs.ref == '' ) }}
uses: actions/checkout@v4
with:
repository: armbian/configng
ref: main
fetch-depth: 0
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
path: configng
- name: Prepare Git_sources JSON
if: ${{ ( ! github.event.inputs.versionOverride ) && ( env.VERSION_BUMP == 'true' ) && ( inputs.ref == '' ) }}
run: |
cd build
bash ./compile.sh targets
cat output/info/git_sources.json
BUILD=$(git rev-parse HEAD)
cd ../documentation
DOCUMENTATION=$(git rev-parse HEAD)
cd ../docker-armbian-build
DOCKER_ARMBIAN_BUILD=$(git rev-parse HEAD)
cd ../rkbin
RKBIN=$(git rev-parse HEAD)
cd ../configng
ARMBIANCONFIGNG=$(git rev-parse HEAD)
cd ..
# add build repository
sed -i '0,/{/s//{\n "source": "https:\/\/github.com\/armbian\/build", \n "branch": "main", \n "sha1": "'$BUILD'"\n },\n &/' build/output/info/git_sources.json
# add documentation repository
sed -i '0,/{/s//{\n "source": "https:\/\/github.com\/armbian\/documentation", \n "branch": "master", \n "sha1": "'$DOCUMENTATION'"\n },\n &/' build/output/info/git_sources.json
# add rkbin repository
sed -i '0,/{/s//{\n "source": "https:\/\/github.com\/armbian\/rkbin", \n "branch": "master", \n "sha1": "'$RKBIN'"\n },\n &/' build/output/info/git_sources.json
# add armbianconfig repository
#sed -i '0,/{/s//{\n "source": "https:\/\/github.com\/armbian\/configng", \n "branch": "main", \n "sha1": "'$ARMBIANCONFIGNG'"\n },\n &/' build/output/info/git_sources.json
# add docker-armbian-build repository
sed -i '0,/{/s//{\n "source": "https:\/\/github.com\/armbian\/docker-armbian-build", \n "branch": "main", \n "sha1": "'$DOCKER_ARMBIAN_BUILD'"\n },\n &/' build/output/info/git_sources.json
cp build/output/info/git_sources.json os/
- name: Update scripts
if: ${{ ( ! github.event.inputs.versionOverride ) && ( env.VERSION_BUMP == 'true' ) && ( inputs.ref == '' ) }}
run: |
#sudo chown -R $USER:$USER .git
cd os
if git status --porcelain | grep .; then
git config --global user.email "[email protected]"
git config --global user.name "Armbianworker"
git config pull.rebase false
git pull
git add git_sources.json
git commit git_sources.json --allow-empty -m "Update external GIT commits"
git push
fi
version_prep:
needs: sources_prep
name: "Bump version"
runs-on: ubuntu-latest
steps:
# Clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: 0
clean: false # true is default.
- name: Determine version
id: versionfile
run: |
# file = where version is getting stored, different for stable and nightly
# skip_tag = we only upload nighlty to GH releases
echo "file=nightly" >> $GITHUB_OUTPUT
echo "skip_tag=false" >> $GITHUB_OUTPUT
echo "pre_release=true" >> $GITHUB_OUTPUT
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
echo "file=stable" >> $GITHUB_OUTPUT
echo "skip_tag=true" >> $GITHUB_OUTPUT
echo "pre_release=false" >> $GITHUB_OUTPUT
fi
# Bump version automatically
- name: Bump version
if: ${{ ( ! github.event.inputs.versionOverride ) && ( inputs.ref == '' ) && ( env.VERSION_BUMP == 'true' ) }}
id: changelog
uses: TriPSs/[email protected]
with:
github-token: ${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}
git-message: 'Bump release to {version}'
git-user-name: armbianworker
git-user-email: [email protected]
output-file: 'false'
skip-version-file: 'false'
skip-on-empty: 'false'
skip-commit: 'false'
skip-ci: 'false'
skip-tag: "${{ steps.versionfile.outputs.skip_tag }}"
version-file: "${{ steps.versionfile.outputs.file }}.json"
pre-release: "${{ steps.versionfile.outputs.pre_release }}"
git-branch: 'main'
tag-prefix: ''
pre-release-identifier: 'trunk'
- name: Read version from file if nor overriden
if: ${{ ! github.event.inputs.versionOverride || env.VERSION_BUMP == 'false' }}
run: |
mkdir -p downloads
cat "${{ steps.versionfile.outputs.file }}.json" | jq '.version' | sed "s/\"//g" | sed 's/^/VERSION_OVERRIDE=/' >> $GITHUB_ENV
cat "${{ steps.versionfile.outputs.file }}.json" | jq '.version' | sed "s/\"//g" > downloads/version
- name: 'Upload Artifact'
uses: actions/upload-artifact@v4
with:
name: assets-for-download-nightly
path: downloads
retention-days: 5
- name: "Generate body file"
if: ${{ (github.event.inputs.skipImages || 'no') != 'yes' }}
run: |
echo "
<p align='center'>
<a href='https://www.armbian.com'>
<img src='https://raw.githubusercontent.com/armbian/.github/master/profile/tux-two.png' width='400'></a></p>
<h1 align=center>Rolling releases</h1>
<p align=center>
<a href='https://www.armbian.com'><img alt='Armbian Linux stable' src='https://img.shields.io/badge/dynamic/json?label=Armbian%20Linux%20current&query=CURRENT&color=f71000&cacheSeconds=600&style=for-the-badge&url=https%3A%2F%2Fgithub.com%2Farmbian%2Fscripts%2Freleases%2Fdownload%2Fstatus%2Frunners_capacity.json'></a>
<a href='https://www.armbian.com'><img alt='Armbian Linux rolling' src='https://img.shields.io/badge/dynamic/json?label=Armbian%20Linux%20edge&query=EDGE&color=34be5b&cacheSeconds=600&style=for-the-badge&url=https%3A%2F%2Fgithub.com%2Farmbian%2Fscripts%2Freleases%2Fdownload%2Fstatus%2Frunners_capacity.json'></a>
</p>
<br>
- rolling releases are available at the bottom of <a href='https://www.armbian.com/download/' target=_blanks>official download pages</a>
- if you want to change automated builds variants, edit <a href='https://github.com/armbian/os/tree/main/userpatches'>.yaml files</a>
- for old builds with unknown support status check <a href='https://archive.armbian.com' target=_blank>archives</a>
<br>
&nbsp;
</p>" > body.html
- uses: ncipollo/release-action@v1
if: ${{ (github.event.inputs.nightlybuild || 'yes') == 'yes' && (github.event.inputs.skipImages || 'no') != 'yes' }}
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
tag: "${{ env.VERSION_OVERRIDE }}"
name: "${{ env.VERSION_OVERRIDE }}"
bodyFile: "body.html"
prerelease: "true"
allowUpdates: true
removeArtifacts: true
token: ${{ env.GH_TOKEN }}
- name: Save
id: releases
run: |
echo "version=${{ env.VERSION_OVERRIDE }}" >> $GITHUB_OUTPUT
outputs:
# not related to matrix
version: ${{ steps.releases.outputs.version }}
matrix_prep:
name: "JSON matrix: 17/16 :: 17 artifact chunks, 16 image chunks"
if: ${{ github.repository_owner == 'armbian' }}
needs: [ version_prep ]
runs-on: [ "self-hosted", "Linux", 'super' ]
steps:
# Cleaning self hosted runners
- name: Runner clean
uses: armbian/actions/runner-clean@main
# clone the build system repo (`armbian/build`)
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ env.BUILD_REF }}
fetch-depth: 0
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
path: build
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: 0
clean: false # true is default.
path: userpatches
# clone the torrent lists
- name: "Checkout torrent lists"
uses: actions/checkout@v4
with:
repository: XIU2/TrackersListCollection
clean: false
ref: master # true is default
path: trackerslist
fetch-depth: 1
- name: "grab the sha1 of the latest commit of the build repo ${{ env.BUILD_REPOSITORY }}#${{ env.BUILD_REF }}"
id: latest-commit
run: |
cd build
echo "sha1=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv build/userpatches
rsync -av userpatches/${{env.USERPATCHES_DIR}}/. build/userpatches/
- name: GitHub cache
id: cache-restore
uses: actions/cache@v4
with:
path: |
cache/memoize
cache/oci/positive
key: ${{ runner.os }}-matrix-cache-${{ github.sha }}-${{ steps.latest-commit.outputs.sha1 }}"
restore-keys: |
${{ runner.os }}-matrix-cache-
# Login to ghcr.io, we're gonna do a lot of OCI lookups.
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: ${{ secrets.GITHUB_TOKEN }} # GitHub actions builtin token. repo has to have pkg access.
- name: Prepare Info JSON and Matrices
id: prepare-matrix
run: |
FILTERS="${{ github.event.inputs.targetsFilterInclude }}"
if [ -z "${FILTERS}" ] && [ "${{ github.event.inputs.board }}" != "all" ] && [ -n "${{ github.event.inputs.board }}" ]; then
FILTERS='"BOARD:${{ github.event.inputs.board }}"'
fi
if [ -z "${FILTERS}" ] && [ "${{ github.event.inputs.maintainer }}" != "all" ] && [ -n "${{ github.event.inputs.board }}" ]; then
FILTERS='"BOARD_MAINTAINERS:${{ github.event.inputs.maintainer }}"'
fi
# this sets outputs "artifact-matrix" #and "image-matrix"
cd build
bash ./compile.sh gha-matrix armbian-images \
REVISION="${{ needs.version_prep.outputs.version }}" \
TARGETS_FILTER_INCLUDE="${FILTERS}" \
BETA=${{ github.event.inputs.nightlybuild || 'yes' }} \
CLEAN_INFO=yes \
CLEAN_MATRIX=yes \
MATRIX_ARTIFACT_CHUNKS=17 \
MATRIX_IMAGE_CHUNKS=16 \
CHECK_OCI=${{ github.event.inputs.checkOci || 'yes' }} \
TARGETS_FILENAME="targets-release-nightly.yaml" \
SKIP_IMAGES=${{ github.event.inputs.skipImages || 'no'}} \
${{env.EXTRA_PARAMS_ALL_BUILDS}} SHARE_LOG=yes # IMAGES_ONLY_OUTDATED_ARTIFACTS=yes
- name: "Logs: ${{ steps.prepare-matrix.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.prepare-matrix.outputs.logs_url }}"
- name: Get server list from NetBox
id: prepare-urls
run: |
cp trackerslist/best.txt build/output/info/best-torrent-servers.txt
timeout 10 curl -s -H "Authorization: Token ${{ secrets.NETBOX_TOKEN }}" -H \
"Accept: application/json; indent=4" "https://stuff.armbian.com/netbox/api/virtualization/virtual-machines/?limit=500&name__empty=false&device_role=Mirror&tag=images&status=active" \
| jq '.results[] | .name' | grep -v null | sed "s/\"//g" > build/output/info/servers.csv
timeout 10 curl -s -H "Authorization: Token ${{ secrets.NETBOX_TOKEN }}" -H \
"Accept: application/json; indent=4" "https://stuff.armbian.com/netbox/api/virtualization/virtual-machines/?limit=500&name__empty=false&device_role=Mirror&tag=images&status=active" \
| jq '.results[] | .name, .custom_fields["download_path_images"]' | sed "s/\"//g" | sed "s|null|dl|" | sed "s/\"//g" | xargs -n2 -d'\n' | sed "s/ /\//g" \
| jq -cnR '[inputs | select(length>0)]' | jq -c '.[]' | sed "s/\"//g" | sort -R > build/output/info/servers-download.csv
timeout 10 curl -s -H "Authorization: Token ${{ secrets.NETBOX_TOKEN }}" -H "Accept: application/json; indent=4" \
"https://stuff.armbian.com/netbox/api/virtualization/virtual-machines/?limit=500&name__empty=false&tag=push&tag=images&status=active" \
| jq '.results[] | .name,.custom_fields["path"],.custom_fields["port"],.custom_fields["username"]' | sed "s|null|beta|" | sed "s/\"//g" | xargs -n4 -d'\n' \
| sed "s/ /,/g" | jq -cnR '[inputs | select(length>0)]' | jq -c '.[]' | sed "s/\"//g" | sort -R > build/output/info/servers-upload.csv
# Store output/info folder in a GitHub Actions artifact
- uses: actions/upload-artifact@v4
name: Upload output/info as GitHub Artifact
with:
name: build-info-json
path: build/output/info
- name: chown cache memoize/oci back to normal user
run: sudo chown -R $USER:$USER build/cache/memoize build/cache/oci/positive
outputs:
# not related to matrix
build-sha1: ${{ steps.latest-commit.outputs.sha1 }}
version: ${{ needs.version_prep.outputs.version }}
# template file: 150.per-chunk-artifacts_prep-outputs.yaml
# artifacts-1 of 17
artifacts-chunk-json-1: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-1 }}
artifacts-chunk-not-empty-1: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-1 }}
artifacts-chunk-size-1: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-1 }}
# artifacts-2 of 17
artifacts-chunk-json-2: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-2 }}
artifacts-chunk-not-empty-2: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-2 }}
artifacts-chunk-size-2: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-2 }}
# artifacts-3 of 17
artifacts-chunk-json-3: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-3 }}
artifacts-chunk-not-empty-3: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-3 }}
artifacts-chunk-size-3: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-3 }}
# artifacts-4 of 17
artifacts-chunk-json-4: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-4 }}
artifacts-chunk-not-empty-4: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-4 }}
artifacts-chunk-size-4: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-4 }}
# artifacts-5 of 17
artifacts-chunk-json-5: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-5 }}
artifacts-chunk-not-empty-5: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-5 }}
artifacts-chunk-size-5: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-5 }}
# artifacts-6 of 17
artifacts-chunk-json-6: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-6 }}
artifacts-chunk-not-empty-6: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-6 }}
artifacts-chunk-size-6: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-6 }}
# artifacts-7 of 17
artifacts-chunk-json-7: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-7 }}
artifacts-chunk-not-empty-7: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-7 }}
artifacts-chunk-size-7: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-7 }}
# artifacts-8 of 17
artifacts-chunk-json-8: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-8 }}
artifacts-chunk-not-empty-8: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-8 }}
artifacts-chunk-size-8: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-8 }}
# artifacts-9 of 17
artifacts-chunk-json-9: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-9 }}
artifacts-chunk-not-empty-9: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-9 }}
artifacts-chunk-size-9: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-9 }}
# artifacts-10 of 17
artifacts-chunk-json-10: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-10 }}
artifacts-chunk-not-empty-10: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-10 }}
artifacts-chunk-size-10: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-10 }}
# artifacts-11 of 17
artifacts-chunk-json-11: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-11 }}
artifacts-chunk-not-empty-11: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-11 }}
artifacts-chunk-size-11: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-11 }}
# artifacts-12 of 17
artifacts-chunk-json-12: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-12 }}
artifacts-chunk-not-empty-12: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-12 }}
artifacts-chunk-size-12: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-12 }}
# artifacts-13 of 17
artifacts-chunk-json-13: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-13 }}
artifacts-chunk-not-empty-13: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-13 }}
artifacts-chunk-size-13: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-13 }}
# artifacts-14 of 17
artifacts-chunk-json-14: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-14 }}
artifacts-chunk-not-empty-14: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-14 }}
artifacts-chunk-size-14: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-14 }}
# artifacts-15 of 17
artifacts-chunk-json-15: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-15 }}
artifacts-chunk-not-empty-15: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-15 }}
artifacts-chunk-size-15: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-15 }}
# artifacts-16 of 17
artifacts-chunk-json-16: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-16 }}
artifacts-chunk-not-empty-16: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-16 }}
artifacts-chunk-size-16: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-16 }}
# artifacts-17 of 17
artifacts-chunk-json-17: ${{ steps.prepare-matrix.outputs.artifacts-chunk-json-17 }}
artifacts-chunk-not-empty-17: ${{ steps.prepare-matrix.outputs.artifacts-chunk-not-empty-17 }}
artifacts-chunk-size-17: ${{ steps.prepare-matrix.outputs.artifacts-chunk-size-17 }}
# template file: 151.per-chunk-images_prep-outputs.yaml
# artifacts-1 of 16
images-chunk-json-1: ${{ steps.prepare-matrix.outputs.images-chunk-json-1 }}
images-chunk-not-empty-1: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-1 }}
images-chunk-size-1: ${{ steps.prepare-matrix.outputs.images-chunk-size-1 }}
# artifacts-2 of 16
images-chunk-json-2: ${{ steps.prepare-matrix.outputs.images-chunk-json-2 }}
images-chunk-not-empty-2: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-2 }}
images-chunk-size-2: ${{ steps.prepare-matrix.outputs.images-chunk-size-2 }}
# artifacts-3 of 16
images-chunk-json-3: ${{ steps.prepare-matrix.outputs.images-chunk-json-3 }}
images-chunk-not-empty-3: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-3 }}
images-chunk-size-3: ${{ steps.prepare-matrix.outputs.images-chunk-size-3 }}
# artifacts-4 of 16
images-chunk-json-4: ${{ steps.prepare-matrix.outputs.images-chunk-json-4 }}
images-chunk-not-empty-4: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-4 }}
images-chunk-size-4: ${{ steps.prepare-matrix.outputs.images-chunk-size-4 }}
# artifacts-5 of 16
images-chunk-json-5: ${{ steps.prepare-matrix.outputs.images-chunk-json-5 }}
images-chunk-not-empty-5: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-5 }}
images-chunk-size-5: ${{ steps.prepare-matrix.outputs.images-chunk-size-5 }}
# artifacts-6 of 16
images-chunk-json-6: ${{ steps.prepare-matrix.outputs.images-chunk-json-6 }}
images-chunk-not-empty-6: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-6 }}
images-chunk-size-6: ${{ steps.prepare-matrix.outputs.images-chunk-size-6 }}
# artifacts-7 of 16
images-chunk-json-7: ${{ steps.prepare-matrix.outputs.images-chunk-json-7 }}
images-chunk-not-empty-7: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-7 }}
images-chunk-size-7: ${{ steps.prepare-matrix.outputs.images-chunk-size-7 }}
# artifacts-8 of 16
images-chunk-json-8: ${{ steps.prepare-matrix.outputs.images-chunk-json-8 }}
images-chunk-not-empty-8: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-8 }}
images-chunk-size-8: ${{ steps.prepare-matrix.outputs.images-chunk-size-8 }}
# artifacts-9 of 16
images-chunk-json-9: ${{ steps.prepare-matrix.outputs.images-chunk-json-9 }}
images-chunk-not-empty-9: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-9 }}
images-chunk-size-9: ${{ steps.prepare-matrix.outputs.images-chunk-size-9 }}
# artifacts-10 of 16
images-chunk-json-10: ${{ steps.prepare-matrix.outputs.images-chunk-json-10 }}
images-chunk-not-empty-10: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-10 }}
images-chunk-size-10: ${{ steps.prepare-matrix.outputs.images-chunk-size-10 }}
# artifacts-11 of 16
images-chunk-json-11: ${{ steps.prepare-matrix.outputs.images-chunk-json-11 }}
images-chunk-not-empty-11: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-11 }}
images-chunk-size-11: ${{ steps.prepare-matrix.outputs.images-chunk-size-11 }}
# artifacts-12 of 16
images-chunk-json-12: ${{ steps.prepare-matrix.outputs.images-chunk-json-12 }}
images-chunk-not-empty-12: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-12 }}
images-chunk-size-12: ${{ steps.prepare-matrix.outputs.images-chunk-size-12 }}
# artifacts-13 of 16
images-chunk-json-13: ${{ steps.prepare-matrix.outputs.images-chunk-json-13 }}
images-chunk-not-empty-13: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-13 }}
images-chunk-size-13: ${{ steps.prepare-matrix.outputs.images-chunk-size-13 }}
# artifacts-14 of 16
images-chunk-json-14: ${{ steps.prepare-matrix.outputs.images-chunk-json-14 }}
images-chunk-not-empty-14: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-14 }}
images-chunk-size-14: ${{ steps.prepare-matrix.outputs.images-chunk-size-14 }}
# artifacts-15 of 16
images-chunk-json-15: ${{ steps.prepare-matrix.outputs.images-chunk-json-15 }}
images-chunk-not-empty-15: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-15 }}
images-chunk-size-15: ${{ steps.prepare-matrix.outputs.images-chunk-size-15 }}
# artifacts-16 of 16
images-chunk-json-16: ${{ steps.prepare-matrix.outputs.images-chunk-json-16 }}
images-chunk-not-empty-16: ${{ steps.prepare-matrix.outputs.images-chunk-not-empty-16 }}
images-chunk-size-16: ${{ steps.prepare-matrix.outputs.images-chunk-size-16 }}
# template file: 250.single_aggr-jobs.yaml
# ------ aggregate all artifact chunks into a single dependency -------
all-artifacts-ready:
name: "17 artifacts chunks ready"
runs-on: ubuntu-latest # not going to run, anyway, but is required.
if: ${{ !cancelled() && ( 1 == 2 ) }} # eg: never run.
needs: [ "matrix_prep", "build-artifacts-chunk-1","build-artifacts-chunk-2","build-artifacts-chunk-3","build-artifacts-chunk-4","build-artifacts-chunk-5","build-artifacts-chunk-6","build-artifacts-chunk-7","build-artifacts-chunk-8","build-artifacts-chunk-9","build-artifacts-chunk-10","build-artifacts-chunk-11","build-artifacts-chunk-12","build-artifacts-chunk-13","build-artifacts-chunk-14","build-artifacts-chunk-15","build-artifacts-chunk-16","build-artifacts-chunk-17" ] # <-- HERE: all artifact chunk numbers.
steps:
- name: fake step
run: uptime
all-images-ready:
name: "16 image chunks ready"
runs-on: ubuntu-latest # not going to run, anyway, but is required.
if: ${{ !cancelled() && ( 1 == 2 ) }} # eg: never run.
needs: [ "matrix_prep", "build-images-chunk-1","build-images-chunk-2","build-images-chunk-3","build-images-chunk-4","build-images-chunk-5","build-images-chunk-6","build-images-chunk-7","build-images-chunk-8","build-images-chunk-9","build-images-chunk-10","build-images-chunk-11","build-images-chunk-12","build-images-chunk-13","build-images-chunk-14","build-images-chunk-15","build-images-chunk-16" ] # <-- HERE: all image chunk numbers.
steps:
- name: fake step
run: uptime
all-artifacts-and-images-ready:
name: "17 artifacts and 16 image chunks ready"
runs-on: ubuntu-latest # not going to run, anyway, but is required.
if: ${{ !cancelled() && ( 1 == 2 ) }} # eg: never run.
needs: [ "matrix_prep", "all-artifacts-ready", "all-images-ready" ]
steps:
- name: fake step
run: uptime
# template file: 550.per-chunk-artifacts_job.yaml
"build-artifacts-chunk-1": # templated "build-artifacts-chunk-1"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-1 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-1) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A1' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-2": # templated "build-artifacts-chunk-2"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-2 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-2) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A2' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-3": # templated "build-artifacts-chunk-3"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-3 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-3) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A3' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-4": # templated "build-artifacts-chunk-4"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-4 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-4) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A4' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-5": # templated "build-artifacts-chunk-5"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-5 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-5) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A5' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-6": # templated "build-artifacts-chunk-6"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-6 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-6) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A6' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-7": # templated "build-artifacts-chunk-7"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-7 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-7) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A7' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-8": # templated "build-artifacts-chunk-8"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-8 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-8) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A8' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-9": # templated "build-artifacts-chunk-9"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-9 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-9) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A9' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-10": # templated "build-artifacts-chunk-10"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-10 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-10) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A10' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-11": # templated "build-artifacts-chunk-11"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-11 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-11) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A11' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-12": # templated "build-artifacts-chunk-12"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-12 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-12) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A12' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-13": # templated "build-artifacts-chunk-13"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-13 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-13) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A13' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-14": # templated "build-artifacts-chunk-14"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-14 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-14) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A14' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-15": # templated "build-artifacts-chunk-15"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-15 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-15) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A15' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-16": # templated "build-artifacts-chunk-16"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-16 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-16) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A16' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
"build-artifacts-chunk-17": # templated "build-artifacts-chunk-17"
if: ${{ github.repository_owner == 'armbian' && needs.matrix_prep.outputs.artifacts-chunk-not-empty-17 == 'yes' }} # <-- HERE: Chunk number.
needs: [ "matrix_prep" ]
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.artifacts-chunk-json-17) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty A17' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: Build ${{matrix.desc}}
timeout-minutes: 60
id: build
run: |
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" SHOW_DEBUG=yes SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build.outputs.logs_url }}"
# template file: 650.per-chunk-images_job.yaml
"build-images-chunk-1": # templated "build-images-chunk-1"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-1 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-1) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I1' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-2": # templated "build-images-chunk-2"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-2 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-2) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I2' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-3": # templated "build-images-chunk-3"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-3 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-3) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I3' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-4": # templated "build-images-chunk-4"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-4 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-4) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I4' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-5": # templated "build-images-chunk-5"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-5 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-5) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I5' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-6": # templated "build-images-chunk-6"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-6 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-6) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I6' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-7": # templated "build-images-chunk-7"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-7 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-7) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I7' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-8": # templated "build-images-chunk-8"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-8 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-8) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I8' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-9": # templated "build-images-chunk-9"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-9 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-9) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I9' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-10": # templated "build-images-chunk-10"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-10 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-10) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I10' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-11": # templated "build-images-chunk-11"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-11 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-11) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I11' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-12": # templated "build-images-chunk-12"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-12 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-12) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I12' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-13": # templated "build-images-chunk-13"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-13 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-13) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I13' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-14": # templated "build-images-chunk-14"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-14 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-14) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I14' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-15": # templated "build-images-chunk-15"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-15 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-15) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I15' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
"build-images-chunk-16": # templated "build-images-chunk-16"
needs: [ "matrix_prep", "all-artifacts-ready" ]
timeout-minutes: 240
if: ${{ !failure() && !cancelled() && ( github.repository_owner == 'armbian' ) && ( needs.matrix_prep.outputs.images-chunk-not-empty-16 == 'yes' ) }} # <-- HERE: Chunk number.
strategy:
fail-fast: false # let other jobs try to complete if one fails
matrix: ${{ fromJSON(needs.matrix_prep.outputs.images-chunk-json-16) }} # <-- HERE: Chunk number.
name: ${{ matrix.desc || 'Empty I16' }} # <-- HERE: Chunk number.
runs-on: ${{ matrix.runs_on }}
steps:
- name: Install dependencies
run: |
if [ ! -e /usr/bin/mktorrent ]; then
sudo apt-get update
sudo apt-get install -y mktorrent
fi
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: ${{ matrix.fdepth }}
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
rm -rf userpatches.repo
- name: "Cleanup leftover output"
run: |
rm -f userpatches/VERSION
- name: ${{matrix.desc}}
id: build-one-image
timeout-minutes: 60
run: |
# calculate loop from runner name
if [ -z "${ImageOS}" ]; then
USE_FIXED_LOOP_DEVICE=$(echo ${RUNNER_NAME} | rev | cut -d"-" -f1 | rev | sed 's/^0*//' | sed -e 's/^/\/dev\/loop/')
fi
bash ./compile.sh ${{ matrix.invocation }} REVISION="${{ needs.matrix_prep.outputs.version }}" USE_FIXED_LOOP_DEVICE="$USE_FIXED_LOOP_DEVICE" SHARE_LOG=yes MAKE_FOLDERS="archive" IMAGE_VERSION=${{ needs.matrix_prep.outputs.version }} ${{env.EXTRA_PARAMS_IMAGE}} ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
if: always()
run: |
echo "Logs: ${{ steps.build-one-image.outputs.logs_url }}"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Check API rate limits
run: |
# install dependencies
if ! command -v "gh" > /dev/null 2>&1; then
sudo apt-get -y -qq install gh
fi
while true
do
API_CALLS_TOTAL=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.limit')
API_CALLS_LEFT=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /rate_limit | jq -r '.rate.remaining')
PERCENT=$(( API_CALLS_LEFT * 100 / API_CALLS_TOTAL ))
if (( $PERCENT > 20 )); then
echo "API rate in good shape $PERCENT % free"
exit 0
fi
echo "API rate lower then 20%, sleping 10m"
sleep 10m
done
# show current api rate
curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ACCESS_TOKEN }}" https://api.github.com/rate_limit
- name: Import GPG key
env:
GPG_KEY1: ${{ secrets.GPG_KEY1 }}
if: env.GPG_KEY1 != null
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Sign
env:
GPG_PASSPHRASE1: ${{ secrets.GPG_PASSPHRASE1 }}
if: env.GPG_PASSPHRASE1 != null
run: |
echo ${{ secrets.GPG_PASSPHRASE1 }} | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes output/images/*/archive/*.xz
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
- name: Generate torrent
timeout-minutes: 3
run: |
TRACKERS=$(cat output/info/best-torrent-servers.txt | sed '/^\s*$/d' | sort -R | while read line; do printf " --announce=""${line}"; done)
BOARD=$(ls -1 output/images/ | head -1)
FILE=$(ls -1 output/images/*/archive/*.xz | head -1 | rev | cut -d"/" -f1 | rev)
WEBSEEDS="https://github.com/armbian/os/releases/download/${{ needs.matrix_prep.outputs.version }}/${FILE}"
# nighly images are GH only
rm -f servers.txt
if [ "${{ github.event.inputs.nightlybuild || 'yes' }}" == "no" ]; then
WEBSEEDS=$(for server in $(cat output/info/servers-download.csv)
do
echo "http://$server/$SERVER_PATH" | sed "s|$|${BOARD}\/archive\/${FILE},|"
done | sed 's/ \+/\n/g')
fi
cd output/images/*/archive/
mktorrent --comment="Armbian torrent for ${FILE}" --verbose ${TRACKERS} --web-seed="${WEBSEEDS}" ${FILE}
#- name: Choose random user for upload
# run: |
#arr[0]="${{ secrets.ACCESS_TOKEN }}"
#arr[1]="${{ secrets.ACCESS_TOKEN_ARMBIANWORKER }}"
#rand=$[ $RANDOM % 2 ]
#echo "upload_user=${arr[$rand]}" >> $GITHUB_ENV
- name: "Upload artefacts"
timeout-minutes: 60
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'yes' || env.RELEASE_REPOSITORY == 'community' || env.RELEASE_REPOSITORY == 'distribution' }}
uses: ncipollo/release-action@v1
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
artifacts: "output/images/*/*/Armbian_*.*"
tag: "${{ needs.matrix_prep.outputs.version }}"
omitBody: true
replacesArtifacts: true
omitName: true
makeLatest: false
omitPrereleaseDuringUpdate: true
allowUpdates: true
artifactErrorsFailBuild: true
token: "${{ env.GH_TOKEN }}"
#token: ${{ secrets.ACCESS_TOKEN }}
#token: ${{ env.upload_user }}
- name: Deploy to servers
timeout-minutes: 240
if: ${{ ( github.event.inputs.nightlybuild || 'yes' ) == 'no' && env.RELEASE_REPOSITORY == 'os' }}
#if: ${{ github.event.inputs.uploadtoserver == 'armbian' || github.event.inputs.uploadtoserver == 'both' }}
run: |
# generate control file which checks mirrors
sudo date +%s > output/images/control
cat output/info/servers-upload.csv | \
while read i; do
SERVER_URL=$(echo $i | cut -d "," -f1)
SERVER_PORT=$(echo $i | cut -d "," -f3)
SERVER_PATH=$(echo $i | cut -d "," -f2)
SERVER_USERNAME=$(echo $i | cut -d "," -f4)
# clean
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${SERVER_URL}"
# upload
rsync --progress -e \
"ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=accept-new" \
-rvP output/images/ "${SERVER_USERNAME}@${SERVER_URL}:${SERVER_PATH}/incoming/${{ github.actor }}/"
done
# cleaning self hosted runners
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
if: always()
uses: armbian/actions/runner-clean@main
# template file: 750.single_repo.yaml
# ------ publish packages to repository -------
publish-debs-to-repo:
name: "Download artifacts from ORAS cache"
runs-on: [ repository ]
if: ${{ !failure() && !cancelled() && github.event.inputs.targetsFilterInclude == '' && inputs.ref == '' }} # eg: run if dependencies worked. See https://github.com/orgs/community/discussions/45058#discussioncomment-4817378
needs: [ "matrix_prep", "all-artifacts-ready" ]
steps:
- name: "Runner clean ${{ needs.matrix_prep.outputs.version }}"
uses: armbian/actions/runner-clean@main
# Prepare dependencies.
# If no /usr/bin/gpg, install gnupg2
# If no /usr/bin/reprepro, install reprepro
# If no /usr/bin/lftp, install lftp
- name: Install dependencies
run: |
if [ ! -e /usr/bin/gpg ]; then
sudo apt-get update
sudo apt-get install -y gnupg2
fi
if [ ! -e /usr/bin/reprepro ]; then
sudo apt-get update
sudo apt-get install -y reprepro
fi
if [ ! -e /usr/bin/lftp ]; then
sudo apt-get update
sudo apt-get install -y lftp
fi
# Login to ghcr.io, for later uploading rootfs to ghcr.io
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}" # GitHub username or org
password: "${{ secrets.GITHUB_TOKEN }}" # GitHub actions builtin token. repo has to have pkg access.
# cleanup the place where we will clone the userpatches repo, to avoid git going insane and cleaning everything later
- name: Cleanup userpatches repo
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: rm -rf userpatches.repo
- name: Checkout build repo
uses: actions/checkout@v4 # We don't need to clone git, really. A wget would suffice for GH-hosted runners. But using clone is better for Igor-hosted runners.
with:
repository: ${{ env.BUILD_REPOSITORY }}
ref: ${{ needs.matrix_prep.outputs.build-sha1 }}
fetch-depth: 0
clean: false # true is default. it *will* delete the hosts /dev if mounted inside.
# clone the userpatches repo (`armbian/os`)
- name: "Checkout userpatches repo: ${{env.USERPATCHES_REPOSITORY}}#${{env.USERPATCHES_REF}}"
uses: actions/checkout@v4
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
with:
repository: ${{ env.USERPATCHES_REPOSITORY }}
ref: ${{ env.USERPATCHES_REF }}
fetch-depth: 0
clean: false # true is default.
path: userpatches.repo
- name: "Put userpatches in place, and remove userpatches repo"
if: ${{ ( env.USERPATCHES_REPOSITORY != '' ) && ( env.USERPATCHES_REF != '' ) }}
run: |
mkdir -pv userpatches
rsync -av userpatches.repo/${{env.USERPATCHES_DIR}}/. userpatches/
#rm -rf userpatches.repo
# Clean off output/info, if any
# Clean off debs and debs-beta
- name: Cleanup output/info
run: |
rm -rfv output/info output/debs output/debs-beta
mkdir -pv output
# Download the artifacts (output/info) produced by the prepare-matrix job.
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: build-info-json
path: output/info
# List the artifacts we downloaded
- name: List artifacts
run: |
ls -laht output/info
- name: Download the debs
id: download-debs
run: |
bash ./compile.sh debs-to-repo-download REVISION="${{ needs.matrix_prep.outputs.version }}" BETA=${{ github.event.inputs.nightlybuild || 'yes' }} SHARE_LOG=yes ${{env.EXTRA_PARAMS_ALL_BUILDS}}
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_KEY1 }}
passphrase: ${{ secrets.GPG_PASSPHRASE1 }}
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.KEY_UPLOAD }}
known_hosts: ${{ secrets.KNOWN_HOSTS_ARMBIAN_UPLOAD }}
if_key_exists: replace
- name: Sync parts when making single images / maintainer
# if: ${{ (github.event.inputs.skipImages || 'no') == 'no' }}
run: |
echo "fix permissions"
sudo chown -R $USER:$USER output/.
TARGET=""
if [ "'no'" == "'yes'" ] && [ "'yes'" == "'no'" ]; then
#if [ "${{ github.event.inputs.skipImages}}" == "no" ] || [ "'no'" == "no" ]; then
echo "Save to users folder"
TARGET="partial/${{ github.actor }}/"
else
# drop nightly repository
sudo rm -rf /outgoing/repository-beta/*
# sync to stable from the list
rsync -e "ssh -p ${{ secrets.HOST_UPLOAD_PORT }}" --include-from=userpatches.repo/stable-repo.sync \
--exclude='*' --progress -va output/debs*/. \
${{ secrets.HOST_UPLOAD_USER }}@${{ secrets.HOST_UPLOAD }}:/incoming/${TARGET}
fi
sudo chown -R ${{ secrets.HOST_UPLOAD_USER }}:${{ secrets.HOST_UPLOAD_USER }} /incoming/.
echo "sync all parts"
rsync -e "ssh -p ${{ secrets.HOST_UPLOAD_PORT }}" -arvc \
--include='debs***' \
--exclude='*' \
--remove-source-files \
--delete \
output/ ${{ secrets.HOST_UPLOAD_USER }}@${{ secrets.HOST_UPLOAD }}:/incoming/${TARGET}
# clean
find output/. -type d -empty -delete
- name: "Run repository update action"
if: ${{ (github.event.inputs.skipImages || 'no') == 'yes' }}
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.DISPATCH }}
repository: armbian/os
event-type: "Repository update"
- name: "Logs debs-to-repo-download: ${{ steps.download-debs.outputs.logs_url }}"
run: |
echo "Logs debs-to-repo-download: ${{ steps.download-debs.outputs.logs_url }}"
outputs:
# not related to matrix
version: ${{ needs.matrix_prep.outputs.version }}
# template file: 950.single_footer.yaml
# ------ aggregate all artifact chunks into a single dependency -------
closing:
name: "Footer"
runs-on: ubuntu-latest
if: ${{ !failure() && !cancelled() && inputs.ref == '' && (github.event.inputs.nightlybuild || 'yes') == 'yes' }}
needs: [ "matrix_prep", "all-artifacts-ready", "all-images-ready" ]
steps:
- name: "Run webindex update action"
if: ${{ (github.event.inputs.skipImages || 'no') == 'no' }}
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.DISPATCH }}
repository: armbian/os
event-type: "Webindex update"
- name: "Download all workflow run artifacts"
if: ${{ (github.event.inputs.skipImages || 'no') != 'yes' }}
uses: actions/download-artifact@v4
with:
name: assets-for-download-nightly
path: downloads
- name: "Read version"
run: |
echo "version=$(cat downloads/version 2>/dev/null || true)" >> $GITHUB_ENV
# Delete artifact
- uses: geekyeggo/delete-artifact@v5
with:
name: assets-for-download-nightly
failOnError: false
# Cleaning releases
#
# To do: we need to differentiate between pre and releases and optimise clenaing procees. Following action doesn't know to handle this best
#- uses: dev-drprasad/[email protected]
# with:
# repo: armbian/os
# keep_latest: 16
# env:
# GITHUB_TOKEN: "${{ env.GH_TOKEN }}"
# Cleaning logs
- name: "Keep only 14 days of workflow logs"
uses: igorjs/gh-actions-clean-workflow@v6
with:
token: "${{ env.GH_TOKEN }}"
runs_older_than: 7 # optional
runs_to_keep: 0 # optional
# Switch pre-release to release
- uses: ncipollo/release-action@v1
if: ${{ (github.event.inputs.skipImages || 'no') != 'yes' && (github.event.inputs.nightlybuild || 'yes') == 'yes' }}
with:
repo: "${{ env.RELEASE_REPOSITORY }}"
tag: "${{ env.version }}"
omitBody: true
omitName: true
allowUpdates: true
makeLatest: true
token: "${{ env.GH_TOKEN }}"