Skip to content

JH Build images

JH Build images #646

Workflow file for this run

name: JH Build images
# yamllint disable-line rule:truthy
on:
workflow_dispatch:
release:
types: ["published"]
schedule:
- cron: "0 10 * * *"
env:
BUILD_TYPE: core
DEFAULT_PYTHON: "3.12"
PIP_TIMEOUT: 60
UV_HTTP_TIMEOUT: 60
UV_SYSTEM_PYTHON: "true"
jobs:
init:
name: Initialize build
if: github.repository_owner == 'jethub-homeassistant'
runs-on: ubuntu-latest
outputs:
architectures: ${{ steps.info.outputs.architectures }}
version: ${{ steps.version.outputs.version }}
channel: ${{ steps.version.outputs.channel }}
publish: ${{ steps.version.outputs.publish }}
steps:
- name: Checkout the repository
uses: actions/[email protected]
with:
fetch-depth: 0
- name: update build.yaml
run: cp -f build-jethub.yaml build.yaml
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/[email protected]
with:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Get information
id: info
uses: jethub-homeassistant/actions/helpers/info@master-jethub
- name: Get version
id: version
uses: jethub-homeassistant/actions/helpers/version@master-jethub
with:
type: ${{ env.BUILD_TYPE }}
- name: Verify version
uses: jethub-homeassistant/actions/helpers/verify-version@master-jethub
with:
ignore-dev: true
- name: Fail if translations files are checked in
run: |
if [ -n "$(find homeassistant/components/*/translations -type f)" ]; then
echo "Translations files are checked in, please remove the following files:"
find homeassistant/components/*/translations -type f
exit 1
fi
- name: Download Translations from upstream
run: |
VERSION=$(curl -s https://version.home-assistant.io/beta.json | jq -r '.homeassistant."qemuarm-64"')
docker create --name temp-core ghcr.io/home-assistant/aarch64-homeassistant:$VERSION
docker cp temp-core:"/usr/src/homeassistant/homeassistant" ./
docker rm temp-core
- name: Archive translations
shell: bash
run: find ./homeassistant/components/*/translations -name "*.json" | tar zcvf translations.tar.gz -T -
- name: Upload translations
uses: actions/[email protected]
with:
name: translations
path: translations.tar.gz
if-no-files-found: error
overwrite: true
build_base:
name: Build ${{ matrix.arch }} base core image
if: github.repository_owner == 'jethub-homeassistant'
needs: init
runs-on: ${{ vars.RUNNER }}
permissions:
contents: read
packages: write
id-token: write
strategy:
fail-fast: false
matrix:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/[email protected]
- name: update build.yaml
run: cp -f build-jethub.yaml build.yaml
- name: Download nightly wheels of frontend
if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{secrets.GITHUB_TOKEN}}
repo: home-assistant/frontend
branch: dev
workflow: nightly.yaml
workflow_conclusion: success
name: wheels
- name: Download nightly wheels of intents
if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{secrets.GITHUB_TOKEN}}
repo: home-assistant/intents-package
branch: main
workflow: nightly.yaml
workflow_conclusion: success
name: package
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
if: needs.init.outputs.channel == 'dev'
uses: actions/[email protected]
with:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Set up yq
run: |
BINARY=yq_linux_amd64
VERSION=v4.44.2
wget https://github.com/mikefarah/yq/releases/download/${VERSION}/${BINARY}.tar.gz -O - |\
tar xz && sudo mv ${BINARY} /usr/bin/yq && sudo chmod +x /usr/bin/yq
- name: Adjust nightly version
if: needs.init.outputs.channel == 'dev'
shell: bash
env:
UV_PRERELEASE: allow
run: |
python3 -m pip install "$(grep '^uv' < requirements_test.txt)"
uv pip install packaging tomli
uv pip install .
python3 script/version_bump.py nightly --set-nightly-version "${{ needs.init.outputs.version }}"
if [[ "$(ls home_assistant_frontend*.whl)" =~ ^home_assistant_frontend-(.*)-py3-none-any.whl$ ]]; then
echo "Found frontend wheel, setting version to: ${BASH_REMATCH[1]}"
frontend_version="${BASH_REMATCH[1]}" yq \
--inplace e -o json \
'.requirements = ["home-assistant-frontend=="+env(frontend_version)]' \
homeassistant/components/frontend/manifest.json
sed -i "s|home-assistant-frontend==.*|home-assistant-frontend==${BASH_REMATCH[1]}|" \
homeassistant/package_constraints.txt
sed -i "s|home-assistant-frontend==.*||" requirements_all.txt
fi
if [[ "$(ls home_assistant_intents*.whl)" =~ ^home_assistant_intents-(.*)-py3-none-any.whl$ ]]; then
echo "Found intents wheel, setting version to: ${BASH_REMATCH[1]}"
yq \
--inplace e -o json \
'del(.requirements[] | select(contains("home-assistant-intents")))' \
homeassistant/components/conversation/manifest.json
intents_version="${BASH_REMATCH[1]}" yq \
--inplace e -o json \
'.requirements += ["home-assistant-intents=="+env(intents_version)]' \
homeassistant/components/conversation/manifest.json
sed -i "s|home-assistant-intents==.*|home-assistant-intents==${BASH_REMATCH[1]}|" \
homeassistant/package_constraints.txt
sed -i "s|home-assistant-intents==.*||" requirements_all.txt
fi
- name: Adjustments for armhf
if: matrix.arch == 'armhf'
run: |
# Pandas has issues building on armhf, it is expected they
# will drop the platform in the near future (they consider it
# "flimsy" on 386). The following packages depend on pandas,
# so we comment them out.
sed -i "s|env-canada|# env-canada|g" requirements_all.txt
sed -i "s|noaa-coops|# noaa-coops|g" requirements_all.txt
sed -i "s|pyezviz|# pyezviz|g" requirements_all.txt
sed -i "s|pykrakenapi|# pykrakenapi|g" requirements_all.txt
- name: Download translations
uses: actions/[email protected]
with:
name: translations
- name: Extract translations
run: |
tar xvf translations.tar.gz
rm translations.tar.gz
- name: Write meta info file
shell: bash
run: |
echo "${{ github.sha }};${{ github.ref }};${{ github.event_name }};${{ github.actor }}" > rootfs/OFFICIAL_IMAGE
- name: Login to GitHub Container Registry
uses: docker/[email protected]
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build base image
uses: jethub-homeassistant/[email protected]
with:
args: |
$BUILD_ARGS \
--${{ matrix.arch }} \
--cosign \
--target /data \
--generic ${{ needs.init.outputs.version }}
build_machine:
name: Build ${{ matrix.machine }} machine core image
if: github.repository_owner == 'jethub-homeassistant'
needs: ["init", "build_base"]
runs-on: ${{ vars.RUNNER }}
permissions:
contents: read
packages: write
id-token: write
strategy:
matrix:
machine:
- jethub-h1
- jethub-h2
- jethub-d1
- jethub-d1p
- jethub-d2
- generic-x86-64
- intel-nuc
- khadas-vim3
- odroid-c2
- odroid-c4
- odroid-m1
- odroid-n2
- odroid-xu
- qemuarm
- qemuarm-64
- qemux86
- qemux86-64
- raspberrypi
- raspberrypi2
- raspberrypi3
- raspberrypi3-64
- raspberrypi4
- raspberrypi4-64
- raspberrypi5-64
- tinker
steps:
- name: Checkout the repository
uses: actions/[email protected]
- name: update build.yaml
run: cp -f build-jethub.yaml build.yaml
- name: Set build additional args
run: |
# Create general tags
if [[ "${{ needs.init.outputs.version }}" =~ d ]]; then
echo "BUILD_ARGS=--additional-tag dev" >> $GITHUB_ENV
elif [[ "${{ needs.init.outputs.version }}" =~ b ]]; then
echo "BUILD_ARGS=--additional-tag beta" >> $GITHUB_ENV
else
echo "BUILD_ARGS=--additional-tag stable" >> $GITHUB_ENV
fi
- name: Login to GitHub Container Registry
uses: docker/[email protected]
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build base image
uses: jethub-homeassistant/[email protected]
with:
args: |
$BUILD_ARGS \
--target /data/machine \
--cosign \
--machine "${{ needs.init.outputs.version }}=${{ matrix.machine }}"
publish_ha:
name: Publish version files
if: github.repository_owner == 'jethub-homeassistant'
needs: ["init", "build_machine"]
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/[email protected]
- name: update build.yaml
run: cp -f build-jethub.yaml build.yaml
- 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: Update version file
uses: jethub-homeassistant/actions/helpers/version-push@master-jethub
with:
key: "homeassistant[]"
key-description: "Home Assistant Core"
version: ${{ needs.init.outputs.version }}
channel: ${{ needs.init.outputs.channel }}
- name: Update version file (stable -> beta)
if: needs.init.outputs.channel == 'stable'
uses: jethub-homeassistant/actions/helpers/version-push@master-jethub
with:
key: "homeassistant[]"
key-description: "Home Assistant Core"
version: ${{ needs.init.outputs.version }}
channel: beta
publish_container:
name: Publish meta container for ${{ matrix.registry }}
if: github.repository_owner == 'jethub-homeassistant'
needs: ["init", "build_base"]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
strategy:
matrix:
registry: ["ghcr.io/jethub-homeassistant", "cr.jethome.work/ha"]
steps:
- name: Checkout the repository
uses: actions/[email protected]
- name: Install Cosign
uses: sigstore/[email protected]
with:
cosign-release: "v2.2.3"
- name: update build.yaml
run: cp -f build-jethub.yaml build.yaml
- name: Login to DockerHub
if: matrix.registry == 'cr.jethome.work/ha'
uses: docker/[email protected]
with:
registry: cr.jethome.work
username: ${{ secrets.CR_USERNAME }}
password: ${{ secrets.CR_TOKEN }}
- name: Login to GitHub Container Registry
if: matrix.registry == 'ghcr.io/jethub-homeassistant'
uses: docker/[email protected]
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Meta Image
shell: bash
run: |
export DOCKER_CLI_EXPERIMENTAL=enabled
function create_manifest() {
local tag_l=${1}
local tag_r=${2}
local registry=${{ matrix.registry }}
docker manifest create "${registry}/home-assistant:${tag_l}" \
"${registry}/amd64-homeassistant:${tag_r}" \
"${registry}/i386-homeassistant:${tag_r}" \
"${registry}/armhf-homeassistant:${tag_r}" \
"${registry}/armv7-homeassistant:${tag_r}" \
"${registry}/aarch64-homeassistant:${tag_r}"
docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/amd64-homeassistant:${tag_r}" \
--os linux --arch amd64
docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/i386-homeassistant:${tag_r}" \
--os linux --arch 386
docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/armhf-homeassistant:${tag_r}" \
--os linux --arch arm --variant=v6
docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/armv7-homeassistant:${tag_r}" \
--os linux --arch arm --variant=v7
docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/aarch64-homeassistant:${tag_r}" \
--os linux --arch arm64 --variant=v8
docker manifest push --purge "${registry}/home-assistant:${tag_l}"
cosign sign --yes "${registry}/home-assistant:${tag_l}"
}
function validate_image() {
local image=${1}
if ! cosign verify --certificate-oidc-issuer https://token.actions.githubusercontent.com --certificate-identity-regexp https://github.com/jethub-homeassistant/core/.* "${image}"; then
echo "Invalid signature!"
exit 1
fi
}
function push_dockerhub() {
local image=${1}
local tag=${2}
docker tag "ghcr.io/jethub-homeassistant/${image}:${tag}" "cr.jethome.work/ha/${image}:${tag}"
docker push "cr.jethome.work/ha/${image}:${tag}"
cosign sign --yes "cr.jethome.work/ha/${image}:${tag}"
}
# Pull images from github container registry and verify signature
docker pull "ghcr.io/jethub-homeassistant/amd64-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/jethub-homeassistant/i386-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/jethub-homeassistant/armhf-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/jethub-homeassistant/armv7-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/jethub-homeassistant/aarch64-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/jethub-homeassistant/amd64-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/jethub-homeassistant/i386-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/jethub-homeassistant/armhf-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/jethub-homeassistant/armv7-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/jethub-homeassistant/aarch64-homeassistant:${{ needs.init.outputs.version }}"
if [[ "${{ matrix.registry }}" == "cr.jethome.work/ha" ]]; then
# Upload images to dockerhub
push_dockerhub "amd64-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "i386-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "armhf-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "armv7-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "aarch64-homeassistant" "${{ needs.init.outputs.version }}"
fi
# Create version tag
create_manifest "${{ needs.init.outputs.version }}" "${{ needs.init.outputs.version }}"
# Create general tags
if [[ "${{ needs.init.outputs.version }}" =~ d ]]; then
create_manifest "dev" "${{ needs.init.outputs.version }}"
elif [[ "${{ needs.init.outputs.version }}" =~ b ]]; then
create_manifest "beta" "${{ needs.init.outputs.version }}"
create_manifest "rc" "${{ needs.init.outputs.version }}"
else
create_manifest "stable" "${{ needs.init.outputs.version }}"
create_manifest "latest" "${{ needs.init.outputs.version }}"
create_manifest "beta" "${{ needs.init.outputs.version }}"
create_manifest "rc" "${{ needs.init.outputs.version }}"
# Create series version tag (e.g. 2021.6)
v="${{ needs.init.outputs.version }}"
create_manifest "${v%.*}" "${{ needs.init.outputs.version }}"
fi