Skip to content

12.4.rc3

12.4.rc3 #40

Workflow file for this run

# Home Assistant Operating System build workflow
name: JetHome OS build
on:
release:
types: [published]
workflow_dispatch:
inputs:
boards:
description: 'List of boards to build (comma separated identifiers)'
required: false
type: string
publish:
description: 'Publish build artifacts'
required: true
type: boolean
default: true
env:
PYTHON_VERSION: "3.10"
jobs:
prepare:
name: Prepare build
runs-on: ubuntu-22.04
permissions:
contents: read
pull-requests: read
packages: write
outputs:
version_dev: ${{ steps.version_dev.outputs.version_dev }}
version_main: ${{ steps.version.outputs.version_main }}
version_full: ${{ steps.version.outputs.version_full }}
channel: ${{ steps.channel.outputs.channel }}
matrix: ${{ steps.generate_matrix.outputs.result }}
build_container_image: ghcr.io/${{ github.repository_owner }}/haos-builder@${{ steps.build_haos_builder.outputs.digest }}
publish_build: ${{ steps.check_publish.outputs.publish_build }}
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Check if build should be published
id: check_publish
env:
PUBLISH_FLAG: ${{ inputs.publish }}
run: |
if [ "${{ github.repository }}" == "jethub-homeassistant/operating-system" ]; then
if [ "${PUBLISH_FLAG}" != "true" ] && [ "${{ github.event_name }}" != "release" ]; then
echo "publish_build=false" >> "$GITHUB_OUTPUT"
else
echo "publish_build=true" >> "$GITHUB_OUTPUT"
fi
else
echo "publish_build=false" >> "$GITHUB_OUTPUT"
fi
- name: Generate development version
shell: bash
id: version_dev
if: ${{ github.event_name != 'release' }}
env:
PUBLISH_BUILD: ${{ steps.check_publish.outputs.publish_build }}
run: |
version_dev="dev$(date --utc +'%Y%m%d')"
if [ "${{ env.PUBLISH_BUILD }}" != "true" ]; then
version_dev="dev$(date +%s)"
fi
echo "Development version \"${version_dev}\""
echo "version_dev=${version_dev}" >> $GITHUB_OUTPUT
- name: Set version suffix
if: ${{ github.event_name != 'release' }}
env:
VERSION_DEV: ${{ steps.version_dev.outputs.version_dev }}
run: |
sed -i -E "s/(^VERSION_SUFFIX=\").*(\"$)/\1${VERSION_DEV}\2/" buildroot-external/meta
- name: Get version
id: version
run: |
. ${GITHUB_WORKSPACE}/buildroot-external/meta
echo "version_main=${VERSION_MAJOR}.${VERSION_MINOR}" >> $GITHUB_OUTPUT
if [ -z "${VERSION_SUFFIX}" ]; then
version_full="${VERSION_MAJOR}.${VERSION_MINOR}"
else
version_full="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_SUFFIX}"
fi
echo "version_full=${version_full}" >> $GITHUB_OUTPUT
echo "Full version number of this release is \"${version_full}\"."
- name: Validate version
id: version_check
if: ${{ github.event_name == 'release' }}
run: |
if [ "${{ steps.version.outputs.version_full }}" != "${{ github.event.release.tag_name }}" ]; then
echo "Version number in Buildroot metadata does not match tag (${{ steps.version.outputs.version_full }} vs ${{ github.event.release.tag_name }})."
exit 1
fi
- name: Get channel
id: channel
run: |
if [[ "${{ github.event_name }}" == "release" ]]; then
if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then
echo "channel=beta" >> "$GITHUB_OUTPUT"
else
echo "channel=stable" >> "$GITHUB_OUTPUT"
fi
else
echo "channel=dev" >> "$GITHUB_OUTPUT"
fi
- name: Create build matrix
uses: actions/github-script@v7
id: generate_matrix
with:
script: |
const boards = require('./.github/workflows/jh-matrix.json')
if ("${{ github.event_name }}" == "release") {
return { "board": boards }
}
const boardFilter = "${{ github.event.inputs.boards }}"
if (boardFilter == "") {
console.log("Run full build for all boards")
return { "board": boards }
} else {
console.log("Run partial build")
const boardSet = new Set(boardFilter.split(","))
const buildBoards = boards.filter(b => boardSet.has(b.id))
return { "board": buildBoards }
}
- name: Set up Docker Buildx
uses: docker/[email protected]
- name: Log in to the GitHub container registry
uses: docker/[email protected]
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push
uses: docker/[email protected]
id: build_haos_builder
with:
context: .
file: Dockerfile
tags: ghcr.io/${{ github.repository_owner }}/haos-builder
cache-from: ghcr.io/${{ github.repository_owner }}/haos-builder:cache-${{ steps.version.outputs.version_main }}
cache-to: ghcr.io/${{ github.repository_owner }}/haos-builder:cache-${{ steps.version.outputs.version_main }}
push: true
build:
name: Build for ${{ matrix.board.id }}
permissions:
contents: write # for actions/upload-release-asset to upload release asset
needs: prepare
strategy:
fail-fast: ${{ github.event_name == 'release' }}
matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
runs-on: self-hosted
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
submodules: true
persist-credentials: false
- name: Setup Python version ${{ env.PYTHON_VERSION }}
if: ${{ github.event_name != 'release' }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install AWS CLI
if: 0 #${{ github.event_name != 'release' && needs.prepare.outputs.publish_build == 'true' }}
run: pip install awscli
- name: Set version suffix
if: ${{ github.event_name != 'release' }}
env:
VERSION_DEV: ${{ needs.prepare.outputs.version_dev }}
run: |
sed -i -E "s/(^VERSION_SUFFIX=\").*(\"$)/\1${VERSION_DEV}\2/" buildroot-external/meta
- name: 'Add release PKI certs'
env:
RAUC_CERTIFICATE: ${{ secrets.RAUC_CERTIFICATE }}
RAUC_PRIVATE_KEY: ${{ secrets.RAUC_PRIVATE_KEY }}
run: |
echo -e "-----BEGIN CERTIFICATE-----\n${RAUC_CERTIFICATE}\n-----END CERTIFICATE-----" > cert.pem
echo -e "-----BEGIN PRIVATE KEY-----\n${RAUC_PRIVATE_KEY}\n-----END PRIVATE KEY-----" > key.pem
- name: Free space on build drive
run: |
# Inspired by https://github.com/easimon/maximize-build-space/blob/v7/action.yml
sudo rm -rf /usr/local/lib/android/sdk/ndk
sudo rm -rf /opt/hostedtoolcache/CodeQL
sudo mkdir -p /mnt/cache/dl
sudo mkdir /mnt/output
sudo chown -R runner:runner /mnt/cache /mnt/output
sudo apt-get update; sudo apt-get install -y nfs-client
sudo mount -t nfs 10.180.76.22:/cache/buildroot-haos/dl /mnt/cache/dl || true
WORKSPACE_OWNER="$(stat -c '%U:%G' "${GITHUB_WORKSPACE}")"
# output directory is symlinked for easier access from workspace
# but for build container it must be mounted as a volume
#sudo ln -sf /mnt/output "${GITHUB_WORKSPACE}/output"
sudo chown -R "${WORKSPACE_OWNER}" /mnt/cache
sudo chown -R "${WORKSPACE_OWNER}" /mnt/output
df -h
- name: "Restore cache: object files"
uses: actions/cache/restore@v4
with:
path: /mnt/cache/cc
key: haos-cc-${{ matrix.board.id }}
- name: Build
run: |
BUILDER_UID="$(id -u)"
BUILDER_GID="$(id -g)"
docker run --rm --privileged \
-e BUILDER_UID="${BUILDER_UID}" -e BUILDER_GID="${BUILDER_GID}" \
-v "${GITHUB_WORKSPACE}:/build" \
-v "/mnt/cache:/cache" \
${{ needs.prepare.outputs.build_container_image }} \
make BUILDDIR=/build ${{ matrix.board.defconfig }}
- name: Check output
run: |
find output/images/haos*
- name: Upload artifacts
if: ${{ github.event_name != 'release' && needs.prepare.outputs.publish_build == 'true' }}
uses: burnett01/[email protected]
with:
rsh: -q
switches: -aW --include="haos_*" --exclude="*"
path: "output/images/"
remote_path: ${{ secrets.DEV_TARGET_PATH }}/${{ needs.prepare.outputs.version_main }}.${{ needs.prepare.outputs.version_dev }}/
remote_host: ${{ secrets.DEV_HOST }}
remote_port: ${{ secrets.DEV_PORT }}
remote_user: ${{ secrets.DEV_USERNAME }}
remote_key: ${{ secrets.DEV_SSH_KEY }}
- name: Check Linux config
run: |
docker run --rm --privileged \
-e BUILDER_UID="$(id -u)" -e BUILDER_GID="$(id -g)" \
-v "${GITHUB_WORKSPACE}:/build" \
-v "/mnt/cache:/cache" \
${{ needs.prepare.outputs.build_container_image }} \
make -C buildroot O="/build/output" BR2_EXTERNAL="/build/buildroot-external" \
BR2_CHECK_DOTCONFIG_OPTS="--github-format --strip-path-prefix=/build/" linux-check-dotconfig
- name: Upload release assets
if: ${{ github.event_name == 'release' }}
uses: shogo82148/actions-upload-release-asset@v1
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: output/images/haos_*
- name: Print cache stats
run: |
echo "Cache size: $(du -sh /mnt/cache/cc)"
echo "Files total: $(find /mnt/cache/cc -mindepth 1 -type f | wc -l)"
echo "Old files to remove: $(find /mnt/cache/cc -mindepth 1 -type f -not -anewer output/Makefile | wc -l)"
find /mnt/cache/cc -mindepth 1 -type f -not -anewer output/Makefile -delete
echo "Cache size after pruning: $(du -sh /mnt/cache/cc)"
- name: "Save cache: object files"
if: github.ref == 'refs/heads/dev-jethub'
uses: actions/cache/save@v4
with:
path: /mnt/cache/cc
key: haos-cc-${{ matrix.board.id }}-${{ github.run_id }}
- name: Generate build summary
run: |
echo "# ${{ matrix.board.id }} build summary" >> $GITHUB_STEP_SUMMARY
echo "## Artifacts" >> $GITHUB_STEP_SUMMARY
echo "| File | Size (bytes) | Size (formatted) |" >> $GITHUB_STEP_SUMMARY
echo "|:-|:-|:-|" >> $GITHUB_STEP_SUMMARY
for f in output/images/haos_*; do
echo "| $(basename $f) | $(du -b $f | cut -f1) | $(du -bh $f | cut -f1) |" >> $GITHUB_STEP_SUMMARY
done
echo "## Partitions" >> $GITHUB_STEP_SUMMARY
echo "| File | Size (bytes) | Size (formatted) |" >> $GITHUB_STEP_SUMMARY
echo "|:-|:-|:-|" >> $GITHUB_STEP_SUMMARY
for f in boot.vfat kernel.img rootfs.squashfs overlay.ext4 data.ext4; do
echo "| ${f} | $(du -b output/images/$f | cut -f1) | $(du -bh output/images/$f | cut -f1) |" >> $GITHUB_STEP_SUMMARY
done
- name: Upload OS image artifact
uses: actions/upload-artifact@v4
if: ${{ github.event_name != 'release' && needs.prepare.outputs.publish_build != 'true' }}
with:
name: haos_${{ matrix.board.id }}-${{ needs.prepare.outputs.version_full }}.img.xz
path: |
output/images/haos_${{ matrix.board.id }}-${{ needs.prepare.outputs.version_full }}.img.xz
- name: Upload RAUC bundle artifact
uses: actions/upload-artifact@v4
if: ${{ github.event_name != 'release' && needs.prepare.outputs.publish_build != 'true' }}
with:
name: haos_${{ matrix.board.id }}-${{ needs.prepare.outputs.version_full }}.raucb
path: |
output/images/haos_${{ matrix.board.id }}-${{ needs.prepare.outputs.version_full }}.raucb
bump_version:
name: Bump ${{ needs.prepare.outputs.channel }} channel version
if: ${{ github.repository == 'jethub-homeassistant/operating-system' && needs.prepare.outputs.publish_build == 'true' }}
needs: [ build, prepare ]
runs-on: ubuntu-22.04
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Initialize git
uses: jethub-homeassistant/actions/helpers/git-init@master-jethub
with:
name: ${{ secrets.GIT_NAME }}
email: ${{ secrets.GIT_EMAIL }}
token: ${{ secrets.GIT_TOKEN }}
- name: Bump Home Assistant OS ${{ needs.prepare.outputs.channel }} channel version
uses: jethub-homeassistant/actions/helpers/version-push@master-jethub
with:
key: "hassos[]"
key-description: "Home Assistant OS"
version: ${{ needs.prepare.outputs.version_full }}
channel: ${{ needs.prepare.outputs.channel }}
- name: Bump Home Assistant OS beta channel version on stable release
if: ${{ needs.prepare.outputs.channel == 'stable' }}
uses: jethub-homeassistant/actions/helpers/version-push@master-jethub
with:
key: "hassos[]"
key-description: "Home Assistant OS"
version: ${{ needs.prepare.outputs.version_full }}
channel: beta
- name: Bump stable Home Assistant version for RPi Imager
if: 0 #${{ github.event_name == 'release' && needs.prepare.outputs.channel == 'stable' }}
uses: "./.github/actions/bump-rpi-imager-version"
with:
version: ${{ needs.prepare.outputs.version_full }}
release-date: ${{ github.event.release.published_at }}