This commit is contained in:
Robert Resch 2025-04-02 16:49:33 +02:00
parent d20568e83c
commit 55e63a6060
No known key found for this signature in database
GPG Key ID: 9D9D9DCB43120143

View File

@ -46,10 +46,10 @@ jobs:
with: with:
type: ${{ env.BUILD_TYPE }} type: ${{ env.BUILD_TYPE }}
- name: Verify version # - name: Verify version
uses: home-assistant/actions/helpers/verify-version@master # uses: home-assistant/actions/helpers/verify-version@master
with: # with:
ignore-dev: true # ignore-dev: true
- name: Fail if translations files are checked in - name: Fail if translations files are checked in
run: | run: |
@ -206,333 +206,333 @@ jobs:
--target /data \ --target /data \
--generic ${{ needs.init.outputs.version }} --generic ${{ needs.init.outputs.version }}
build_machine: # build_machine:
name: Build ${{ matrix.machine }} machine core image # name: Build ${{ matrix.machine }} machine core image
if: github.repository_owner == 'home-assistant' # if: github.repository_owner == 'home-assistant'
needs: ["init", "build_base"] # needs: ["init", "build_base"]
runs-on: ubuntu-latest # runs-on: ubuntu-latest
permissions: # permissions:
contents: read # contents: read
packages: write # packages: write
id-token: write # id-token: write
strategy: # strategy:
matrix: # matrix:
machine: # machine:
- generic-x86-64 # - generic-x86-64
- intel-nuc # - intel-nuc
- khadas-vim3 # - khadas-vim3
- odroid-c2 # - odroid-c2
- odroid-c4 # - odroid-c4
- odroid-m1 # - odroid-m1
- odroid-n2 # - odroid-n2
- odroid-xu # - odroid-xu
- qemuarm # - qemuarm
- qemuarm-64 # - qemuarm-64
- qemux86 # - qemux86
- qemux86-64 # - qemux86-64
- raspberrypi # - raspberrypi
- raspberrypi2 # - raspberrypi2
- raspberrypi3 # - raspberrypi3
- raspberrypi3-64 # - raspberrypi3-64
- raspberrypi4 # - raspberrypi4
- raspberrypi4-64 # - raspberrypi4-64
- raspberrypi5-64 # - raspberrypi5-64
- tinker # - tinker
- yellow # - yellow
- green # - green
steps: # steps:
- name: Checkout the repository # - name: Checkout the repository
uses: actions/checkout@v4.2.2 # uses: actions/checkout@v4.2.2
- name: Set build additional args # - name: Set build additional args
run: | # run: |
# Create general tags # # Create general tags
if [[ "${{ needs.init.outputs.version }}" =~ d ]]; then # if [[ "${{ needs.init.outputs.version }}" =~ d ]]; then
echo "BUILD_ARGS=--additional-tag dev" >> $GITHUB_ENV # echo "BUILD_ARGS=--additional-tag dev" >> $GITHUB_ENV
elif [[ "${{ needs.init.outputs.version }}" =~ b ]]; then # elif [[ "${{ needs.init.outputs.version }}" =~ b ]]; then
echo "BUILD_ARGS=--additional-tag beta" >> $GITHUB_ENV # echo "BUILD_ARGS=--additional-tag beta" >> $GITHUB_ENV
else # else
echo "BUILD_ARGS=--additional-tag stable" >> $GITHUB_ENV # echo "BUILD_ARGS=--additional-tag stable" >> $GITHUB_ENV
fi # fi
- name: Login to GitHub Container Registry # - name: Login to GitHub Container Registry
uses: docker/login-action@v3.4.0 # uses: docker/login-action@v3.4.0
with: # with:
registry: ghcr.io # registry: ghcr.io
username: ${{ github.repository_owner }} # username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} # password: ${{ secrets.GITHUB_TOKEN }}
- name: Build base image # - name: Build base image
uses: home-assistant/builder@2025.03.0 # uses: home-assistant/builder@2025.03.0
with: # with:
args: | # args: |
$BUILD_ARGS \ # $BUILD_ARGS \
--target /data/machine \ # --target /data/machine \
--cosign \ # --cosign \
--machine "${{ needs.init.outputs.version }}=${{ matrix.machine }}" # --machine "${{ needs.init.outputs.version }}=${{ matrix.machine }}"
publish_ha: # publish_ha:
name: Publish version files # name: Publish version files
environment: ${{ needs.init.outputs.channel }} # environment: ${{ needs.init.outputs.channel }}
if: github.repository_owner == 'home-assistant' # if: github.repository_owner == 'home-assistant'
needs: ["init", "build_machine"] # needs: ["init", "build_machine"]
runs-on: ubuntu-latest # runs-on: ubuntu-latest
steps: # steps:
- name: Checkout the repository # - name: Checkout the repository
uses: actions/checkout@v4.2.2 # uses: actions/checkout@v4.2.2
- name: Initialize git # - name: Initialize git
uses: home-assistant/actions/helpers/git-init@master # uses: home-assistant/actions/helpers/git-init@master
with: # with:
name: ${{ secrets.GIT_NAME }} # name: ${{ secrets.GIT_NAME }}
email: ${{ secrets.GIT_EMAIL }} # email: ${{ secrets.GIT_EMAIL }}
token: ${{ secrets.GIT_TOKEN }} # token: ${{ secrets.GIT_TOKEN }}
- name: Update version file # - name: Update version file
uses: home-assistant/actions/helpers/version-push@master # uses: home-assistant/actions/helpers/version-push@master
with: # with:
key: "homeassistant[]" # key: "homeassistant[]"
key-description: "Home Assistant Core" # key-description: "Home Assistant Core"
version: ${{ needs.init.outputs.version }} # version: ${{ needs.init.outputs.version }}
channel: ${{ needs.init.outputs.channel }} # channel: ${{ needs.init.outputs.channel }}
- name: Update version file (stable -> beta) # - name: Update version file (stable -> beta)
if: needs.init.outputs.channel == 'stable' # if: needs.init.outputs.channel == 'stable'
uses: home-assistant/actions/helpers/version-push@master # uses: home-assistant/actions/helpers/version-push@master
with: # with:
key: "homeassistant[]" # key: "homeassistant[]"
key-description: "Home Assistant Core" # key-description: "Home Assistant Core"
version: ${{ needs.init.outputs.version }} # version: ${{ needs.init.outputs.version }}
channel: beta # channel: beta
publish_container: # publish_container:
name: Publish meta container for ${{ matrix.registry }} # name: Publish meta container for ${{ matrix.registry }}
environment: ${{ needs.init.outputs.channel }} # environment: ${{ needs.init.outputs.channel }}
if: github.repository_owner == 'home-assistant' # if: github.repository_owner == 'home-assistant'
needs: ["init", "build_base"] # needs: ["init", "build_base"]
runs-on: ubuntu-latest # runs-on: ubuntu-latest
permissions: # permissions:
contents: read # contents: read
packages: write # packages: write
id-token: write # id-token: write
strategy: # strategy:
fail-fast: false # fail-fast: false
matrix: # matrix:
registry: ["ghcr.io/home-assistant", "docker.io/homeassistant"] # registry: ["ghcr.io/home-assistant", "docker.io/homeassistant"]
steps: # steps:
- name: Checkout the repository # - name: Checkout the repository
uses: actions/checkout@v4.2.2 # uses: actions/checkout@v4.2.2
- name: Install Cosign # - name: Install Cosign
uses: sigstore/cosign-installer@v3.8.1 # uses: sigstore/cosign-installer@v3.8.1
with: # with:
cosign-release: "v2.2.3" # cosign-release: "v2.2.3"
- name: Login to DockerHub # - name: Login to DockerHub
if: matrix.registry == 'docker.io/homeassistant' # if: matrix.registry == 'docker.io/homeassistant'
uses: docker/login-action@v3.4.0 # uses: docker/login-action@v3.4.0
with: # with:
username: ${{ secrets.DOCKERHUB_USERNAME }} # username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} # password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry # - name: Login to GitHub Container Registry
if: matrix.registry == 'ghcr.io/home-assistant' # if: matrix.registry == 'ghcr.io/home-assistant'
uses: docker/login-action@v3.4.0 # uses: docker/login-action@v3.4.0
with: # with:
registry: ghcr.io # registry: ghcr.io
username: ${{ github.repository_owner }} # username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} # password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Meta Image # - name: Build Meta Image
shell: bash # shell: bash
run: | # run: |
export DOCKER_CLI_EXPERIMENTAL=enabled # export DOCKER_CLI_EXPERIMENTAL=enabled
function create_manifest() { # function create_manifest() {
local tag_l=${1} # local tag_l=${1}
local tag_r=${2} # local tag_r=${2}
local registry=${{ matrix.registry }} # local registry=${{ matrix.registry }}
docker manifest create "${registry}/home-assistant:${tag_l}" \ # docker manifest create "${registry}/home-assistant:${tag_l}" \
"${registry}/amd64-homeassistant:${tag_r}" \ # "${registry}/amd64-homeassistant:${tag_r}" \
"${registry}/i386-homeassistant:${tag_r}" \ # "${registry}/i386-homeassistant:${tag_r}" \
"${registry}/armhf-homeassistant:${tag_r}" \ # "${registry}/armhf-homeassistant:${tag_r}" \
"${registry}/armv7-homeassistant:${tag_r}" \ # "${registry}/armv7-homeassistant:${tag_r}" \
"${registry}/aarch64-homeassistant:${tag_r}" # "${registry}/aarch64-homeassistant:${tag_r}"
docker manifest annotate "${registry}/home-assistant:${tag_l}" \ # docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/amd64-homeassistant:${tag_r}" \ # "${registry}/amd64-homeassistant:${tag_r}" \
--os linux --arch amd64 # --os linux --arch amd64
docker manifest annotate "${registry}/home-assistant:${tag_l}" \ # docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/i386-homeassistant:${tag_r}" \ # "${registry}/i386-homeassistant:${tag_r}" \
--os linux --arch 386 # --os linux --arch 386
docker manifest annotate "${registry}/home-assistant:${tag_l}" \ # docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/armhf-homeassistant:${tag_r}" \ # "${registry}/armhf-homeassistant:${tag_r}" \
--os linux --arch arm --variant=v6 # --os linux --arch arm --variant=v6
docker manifest annotate "${registry}/home-assistant:${tag_l}" \ # docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/armv7-homeassistant:${tag_r}" \ # "${registry}/armv7-homeassistant:${tag_r}" \
--os linux --arch arm --variant=v7 # --os linux --arch arm --variant=v7
docker manifest annotate "${registry}/home-assistant:${tag_l}" \ # docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/aarch64-homeassistant:${tag_r}" \ # "${registry}/aarch64-homeassistant:${tag_r}" \
--os linux --arch arm64 --variant=v8 # --os linux --arch arm64 --variant=v8
docker manifest push --purge "${registry}/home-assistant:${tag_l}" # docker manifest push --purge "${registry}/home-assistant:${tag_l}"
cosign sign --yes "${registry}/home-assistant:${tag_l}" # cosign sign --yes "${registry}/home-assistant:${tag_l}"
} # }
function validate_image() { # function validate_image() {
local image=${1} # local image=${1}
if ! cosign verify --certificate-oidc-issuer https://token.actions.githubusercontent.com --certificate-identity-regexp https://github.com/home-assistant/core/.* "${image}"; then # if ! cosign verify --certificate-oidc-issuer https://token.actions.githubusercontent.com --certificate-identity-regexp https://github.com/home-assistant/core/.* "${image}"; then
echo "Invalid signature!" # echo "Invalid signature!"
exit 1 # exit 1
fi # fi
} # }
function push_dockerhub() { # function push_dockerhub() {
local image=${1} # local image=${1}
local tag=${2} # local tag=${2}
docker tag "ghcr.io/home-assistant/${image}:${tag}" "docker.io/homeassistant/${image}:${tag}" # docker tag "ghcr.io/home-assistant/${image}:${tag}" "docker.io/homeassistant/${image}:${tag}"
docker push "docker.io/homeassistant/${image}:${tag}" # docker push "docker.io/homeassistant/${image}:${tag}"
cosign sign --yes "docker.io/homeassistant/${image}:${tag}" # cosign sign --yes "docker.io/homeassistant/${image}:${tag}"
} # }
# Pull images from github container registry and verify signature # # Pull images from github container registry and verify signature
docker pull "ghcr.io/home-assistant/amd64-homeassistant:${{ needs.init.outputs.version }}" # docker pull "ghcr.io/home-assistant/amd64-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/home-assistant/i386-homeassistant:${{ needs.init.outputs.version }}" # docker pull "ghcr.io/home-assistant/i386-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/home-assistant/armhf-homeassistant:${{ needs.init.outputs.version }}" # docker pull "ghcr.io/home-assistant/armhf-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/home-assistant/armv7-homeassistant:${{ needs.init.outputs.version }}" # docker pull "ghcr.io/home-assistant/armv7-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/home-assistant/aarch64-homeassistant:${{ needs.init.outputs.version }}" # docker pull "ghcr.io/home-assistant/aarch64-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/home-assistant/amd64-homeassistant:${{ needs.init.outputs.version }}" # validate_image "ghcr.io/home-assistant/amd64-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/home-assistant/i386-homeassistant:${{ needs.init.outputs.version }}" # validate_image "ghcr.io/home-assistant/i386-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/home-assistant/armhf-homeassistant:${{ needs.init.outputs.version }}" # validate_image "ghcr.io/home-assistant/armhf-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/home-assistant/armv7-homeassistant:${{ needs.init.outputs.version }}" # validate_image "ghcr.io/home-assistant/armv7-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/home-assistant/aarch64-homeassistant:${{ needs.init.outputs.version }}" # validate_image "ghcr.io/home-assistant/aarch64-homeassistant:${{ needs.init.outputs.version }}"
if [[ "${{ matrix.registry }}" == "docker.io/homeassistant" ]]; then # if [[ "${{ matrix.registry }}" == "docker.io/homeassistant" ]]; then
# Upload images to dockerhub # # Upload images to dockerhub
push_dockerhub "amd64-homeassistant" "${{ needs.init.outputs.version }}" # push_dockerhub "amd64-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "i386-homeassistant" "${{ needs.init.outputs.version }}" # push_dockerhub "i386-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "armhf-homeassistant" "${{ needs.init.outputs.version }}" # push_dockerhub "armhf-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "armv7-homeassistant" "${{ needs.init.outputs.version }}" # push_dockerhub "armv7-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "aarch64-homeassistant" "${{ needs.init.outputs.version }}" # push_dockerhub "aarch64-homeassistant" "${{ needs.init.outputs.version }}"
fi # fi
# Create version tag # # Create version tag
create_manifest "${{ needs.init.outputs.version }}" "${{ needs.init.outputs.version }}" # create_manifest "${{ needs.init.outputs.version }}" "${{ needs.init.outputs.version }}"
# Create general tags # # Create general tags
if [[ "${{ needs.init.outputs.version }}" =~ d ]]; then # if [[ "${{ needs.init.outputs.version }}" =~ d ]]; then
create_manifest "dev" "${{ needs.init.outputs.version }}" # create_manifest "dev" "${{ needs.init.outputs.version }}"
elif [[ "${{ needs.init.outputs.version }}" =~ b ]]; then # elif [[ "${{ needs.init.outputs.version }}" =~ b ]]; then
create_manifest "beta" "${{ needs.init.outputs.version }}" # create_manifest "beta" "${{ needs.init.outputs.version }}"
create_manifest "rc" "${{ needs.init.outputs.version }}" # create_manifest "rc" "${{ needs.init.outputs.version }}"
else # else
create_manifest "stable" "${{ needs.init.outputs.version }}" # create_manifest "stable" "${{ needs.init.outputs.version }}"
create_manifest "latest" "${{ needs.init.outputs.version }}" # create_manifest "latest" "${{ needs.init.outputs.version }}"
create_manifest "beta" "${{ needs.init.outputs.version }}" # create_manifest "beta" "${{ needs.init.outputs.version }}"
create_manifest "rc" "${{ needs.init.outputs.version }}" # create_manifest "rc" "${{ needs.init.outputs.version }}"
# Create series version tag (e.g. 2021.6) # # Create series version tag (e.g. 2021.6)
v="${{ needs.init.outputs.version }}" # v="${{ needs.init.outputs.version }}"
create_manifest "${v%.*}" "${{ needs.init.outputs.version }}" # create_manifest "${v%.*}" "${{ needs.init.outputs.version }}"
fi # fi
build_python: # build_python:
name: Build PyPi package # name: Build PyPi package
environment: ${{ needs.init.outputs.channel }} # environment: ${{ needs.init.outputs.channel }}
needs: ["init", "build_base"] # needs: ["init", "build_base"]
runs-on: ubuntu-latest # runs-on: ubuntu-latest
permissions: # permissions:
contents: read # contents: read
id-token: write # id-token: write
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true' # if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
steps: # steps:
- name: Checkout the repository # - name: Checkout the repository
uses: actions/checkout@v4.2.2 # uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }} # - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.5.0 # uses: actions/setup-python@v5.5.0
with: # with:
python-version: ${{ env.DEFAULT_PYTHON }} # python-version: ${{ env.DEFAULT_PYTHON }}
- name: Download translations # - name: Download translations
uses: actions/download-artifact@v4.2.1 # uses: actions/download-artifact@v4.2.1
with: # with:
name: translations # name: translations
- name: Extract translations # - name: Extract translations
run: | # run: |
tar xvf translations.tar.gz # tar xvf translations.tar.gz
rm translations.tar.gz # rm translations.tar.gz
- name: Build package # - name: Build package
shell: bash # shell: bash
run: | # run: |
# Remove dist, build, and homeassistant.egg-info # # Remove dist, build, and homeassistant.egg-info
# when build locally for testing! # # when build locally for testing!
pip install build # pip install build
python -m build # python -m build
- name: Upload package to PyPI # - name: Upload package to PyPI
uses: pypa/gh-action-pypi-publish@v1.12.4 # uses: pypa/gh-action-pypi-publish@v1.12.4
with: # with:
skip-existing: true # skip-existing: true
hassfest-image: # hassfest-image:
name: Build and test hassfest image # name: Build and test hassfest image
runs-on: ubuntu-latest # runs-on: ubuntu-latest
permissions: # permissions:
contents: read # contents: read
packages: write # packages: write
attestations: write # attestations: write
id-token: write # id-token: write
needs: ["init"] # needs: ["init"]
if: github.repository_owner == 'home-assistant' # if: github.repository_owner == 'home-assistant'
env: # env:
HASSFEST_IMAGE_NAME: ghcr.io/home-assistant/hassfest # HASSFEST_IMAGE_NAME: ghcr.io/home-assistant/hassfest
HASSFEST_IMAGE_TAG: ghcr.io/home-assistant/hassfest:${{ needs.init.outputs.version }} # HASSFEST_IMAGE_TAG: ghcr.io/home-assistant/hassfest:${{ needs.init.outputs.version }}
steps: # steps:
- name: Checkout repository # - name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 # uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Login to GitHub Container Registry # - name: Login to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 # uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with: # with:
registry: ghcr.io # registry: ghcr.io
username: ${{ github.repository_owner }} # username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} # password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docker image # - name: Build Docker image
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 # uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with: # with:
context: . # So action will not pull the repository again # context: . # So action will not pull the repository again
file: ./script/hassfest/docker/Dockerfile # file: ./script/hassfest/docker/Dockerfile
load: true # load: true
tags: ${{ env.HASSFEST_IMAGE_TAG }} # tags: ${{ env.HASSFEST_IMAGE_TAG }}
- name: Run hassfest against core # - name: Run hassfest against core
run: docker run --rm -v ${{ github.workspace }}:/github/workspace ${{ env.HASSFEST_IMAGE_TAG }} --core-path=/github/workspace # run: docker run --rm -v ${{ github.workspace }}:/github/workspace ${{ env.HASSFEST_IMAGE_TAG }} --core-path=/github/workspace
- name: Push Docker image # - name: Push Docker image
if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true' # if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true'
id: push # id: push
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 # uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with: # with:
context: . # So action will not pull the repository again # context: . # So action will not pull the repository again
file: ./script/hassfest/docker/Dockerfile # file: ./script/hassfest/docker/Dockerfile
push: true # push: true
tags: ${{ env.HASSFEST_IMAGE_TAG }},${{ env.HASSFEST_IMAGE_NAME }}:latest # tags: ${{ env.HASSFEST_IMAGE_TAG }},${{ env.HASSFEST_IMAGE_NAME }}:latest
- name: Generate artifact attestation # - name: Generate artifact attestation
if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true' # if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true'
uses: actions/attest-build-provenance@c074443f1aee8d4aeeae555aebba3282517141b2 # v2.2.3 # uses: actions/attest-build-provenance@c074443f1aee8d4aeeae555aebba3282517141b2 # v2.2.3
with: # with:
subject-name: ${{ env.HASSFEST_IMAGE_NAME }} # subject-name: ${{ env.HASSFEST_IMAGE_NAME }}
subject-digest: ${{ steps.push.outputs.digest }} # subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true # push-to-registry: true