Skip to content

Commit b09b6e5

Browse files
authored
Modernize and migrate builder workflow to new builder actions (#130)
1 parent 86cb836 commit b09b6e5

File tree

6 files changed

+177
-106
lines changed

6 files changed

+177
-106
lines changed

.github/workflows/build-app.yaml

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
name: Build app
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
app:
7+
required: true
8+
type: string
9+
publish:
10+
required: true
11+
type: boolean
12+
13+
jobs:
14+
prepare:
15+
name: Prepare
16+
if: github.repository == 'home-assistant/apps-example'
17+
runs-on: ubuntu-latest
18+
outputs:
19+
architectures: ${{ steps.info.outputs.architectures }}
20+
build_matrix: ${{ steps.matrix.outputs.matrix }}
21+
image_name: ${{ steps.normalize.outputs.image_name }}
22+
registry_prefix: ${{ steps.normalize.outputs.registry_prefix }}
23+
version: ${{ steps.normalize.outputs.version }}
24+
steps:
25+
- name: Check out the repository
26+
uses: actions/checkout@v6.0.2
27+
28+
- name: Get app information
29+
id: info
30+
uses: home-assistant/actions/helpers/info@master
31+
with:
32+
path: "./${{ inputs.app }}"
33+
34+
- name: Normalize app information
35+
id: normalize
36+
run: |
37+
image="${{ steps.info.outputs.image }}"
38+
echo "image_name=${image##*/}" >> "$GITHUB_OUTPUT"
39+
echo "registry_prefix=${image%/*}" >> "$GITHUB_OUTPUT"
40+
# Strip surrounding quotes that the info action includes from YAML string values
41+
version="${{ steps.info.outputs.version }}"
42+
echo "version=${version//[\"\']/}" >> "$GITHUB_OUTPUT"
43+
44+
- name: Prepare build matrix
45+
id: matrix
46+
uses: home-assistant/builder/actions/prepare-multi-arch-matrix@2026.03.2
47+
with:
48+
architectures: ${{ steps.info.outputs.architectures }}
49+
image-name: ${{ steps.normalize.outputs.image_name }}
50+
registry-prefix: ${{ steps.normalize.outputs.registry_prefix }}
51+
52+
build:
53+
name: Build ${{ matrix.arch }} image
54+
needs: prepare
55+
runs-on: ${{ matrix.os }}
56+
permissions:
57+
contents: read
58+
id-token: write
59+
packages: write
60+
strategy:
61+
fail-fast: false
62+
matrix: ${{ fromJSON(needs.prepare.outputs.build_matrix) }}
63+
steps:
64+
- name: Check out the repository
65+
uses: actions/checkout@v6.0.2
66+
with:
67+
persist-credentials: false
68+
69+
- name: Build image
70+
uses: home-assistant/builder/actions/build-image@2026.03.2
71+
with:
72+
arch: ${{ matrix.arch }}
73+
container-registry-password: ${{ secrets.GITHUB_TOKEN }}
74+
context: "./${{ inputs.app }}"
75+
image: ${{ matrix.image }}
76+
image-tags: |
77+
${{ needs.prepare.outputs.version }}
78+
latest
79+
push: ${{ inputs.publish }}
80+
version: ${{ needs.prepare.outputs.version }}
81+
82+
manifest:
83+
name: Publish multi-arch manifest
84+
needs: [prepare, build]
85+
if: inputs.publish
86+
runs-on: ubuntu-latest
87+
permissions:
88+
id-token: write
89+
packages: write
90+
steps:
91+
- name: Publish multi-arch manifest
92+
uses: home-assistant/builder/actions/publish-multi-arch-manifest@2026.03.2
93+
with:
94+
architectures: ${{ needs.prepare.outputs.architectures }}
95+
container-registry-password: ${{ secrets.GITHUB_TOKEN }}
96+
image-name: ${{ needs.prepare.outputs.image_name }}
97+
image-tags: |
98+
${{ needs.prepare.outputs.version }}
99+
latest
100+
registry-prefix: ${{ needs.prepare.outputs.registry_prefix }}

.github/workflows/builder.yaml

Lines changed: 47 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,81 @@
11
name: Builder
22

33
env:
4-
BUILD_ARGS: "--test"
5-
MONITORED_FILES: "build.yaml config.yaml Dockerfile rootfs"
4+
MONITORED_FILES: "config.json config.yaml config.yml Dockerfile rootfs"
65

76
on:
8-
push:
7+
pull_request:
98
branches:
109
- main
11-
pull_request:
10+
push:
1211
branches:
1312
- main
1413

14+
permissions:
15+
contents: read
16+
1517
jobs:
1618
init:
17-
runs-on: ubuntu-latest
1819
name: Initialize builds
20+
runs-on: ubuntu-latest
1921
outputs:
20-
changed_addons: ${{ steps.changed_addons.outputs.addons }}
21-
changed: ${{ steps.changed_addons.outputs.changed }}
22+
changed: ${{ steps.filter.outputs.changed }}
23+
changed_apps: ${{ steps.filter.outputs.changed_apps }}
2224
steps:
2325
- name: Check out the repository
2426
uses: actions/checkout@v6.0.2
2527

2628
- name: Get changed files
2729
id: changed_files
28-
uses: jitterbit/get-changed-files@v1
30+
uses: tj-actions/changed-files@v47
2931

3032
- name: Find app directories
31-
id: addons
33+
id: apps
3234
uses: home-assistant/actions/helpers/find-addons@master
3335

34-
- name: Get changed apps
35-
id: changed_addons
36+
- name: Filter changed apps
37+
id: filter
38+
env:
39+
APPS: ${{ steps.apps.outputs.addons }}
40+
CHANGED_FILES: ${{ steps.changed_files.outputs.all_changed_files }}
3641
run: |
37-
declare -a changed_addons
38-
for addon in ${{ steps.addons.outputs.addons }}; do
39-
if [[ "${{ steps.changed_files.outputs.all }}" =~ $addon ]]; then
40-
for file in ${{ env.MONITORED_FILES }}; do
41-
if [[ "${{ steps.changed_files.outputs.all }}" =~ $addon/$file ]]; then
42-
if [[ ! "${changed_addons[@]}" =~ $addon ]]; then
43-
changed_addons+=("\"${addon}\",");
44-
fi
45-
fi
46-
done
47-
fi
48-
done
42+
changed_apps=()
4943
50-
changed=$(echo ${changed_addons[@]} | rev | cut -c 2- | rev)
44+
# If the workflow file itself changed, rebuild all apps
45+
if [[ "${CHANGED_FILES}" =~ \.github/workflows/(builder|build-app)\.yaml ]]; then
46+
changed_apps=(${APPS})
47+
else
48+
for app in ${APPS}; do
49+
for file in ${MONITORED_FILES}; do
50+
if [[ "${CHANGED_FILES}" =~ ${app}/${file} ]]; then
51+
changed_apps+=("${app}")
52+
break
53+
fi
54+
done
55+
done
56+
fi
5157
52-
if [[ -n ${changed} ]]; then
53-
echo "Changed apps: $changed";
54-
echo "changed=true" >> $GITHUB_OUTPUT;
55-
echo "addons=[$changed]" >> $GITHUB_OUTPUT;
58+
if [[ ${#changed_apps[@]} -gt 0 ]]; then
59+
echo "changed=true" >> "$GITHUB_OUTPUT"
60+
echo "changed_apps=$(jq -nc '$ARGS.positional' --args "${changed_apps[@]}")" >> "$GITHUB_OUTPUT"
5661
else
57-
echo "No app had any monitored files changed (${{ env.MONITORED_FILES }})";
62+
echo "changed=false" >> "$GITHUB_OUTPUT"
5863
fi
59-
build:
64+
65+
build-app:
66+
name: Build ${{ matrix.app }}
6067
needs: init
61-
runs-on: ubuntu-latest
6268
if: needs.init.outputs.changed == 'true'
63-
name: Build ${{ matrix.arch }} ${{ matrix.addon }} app
64-
strategy:
65-
matrix:
66-
addon: ${{ fromJson(needs.init.outputs.changed_addons) }}
67-
arch: ["aarch64", "amd64"]
6869
permissions:
6970
contents: read
71+
id-token: write
7072
packages: write
71-
72-
steps:
73-
- name: Check out repository
74-
uses: actions/checkout@v6.0.2
75-
76-
- name: Get information
77-
id: info
78-
uses: home-assistant/actions/helpers/info@master
79-
with:
80-
path: "./${{ matrix.addon }}"
81-
82-
- name: Check if app should be built
83-
id: check
84-
run: |
85-
if [[ "${{ steps.info.outputs.image }}" == "null" ]]; then
86-
echo "Image property is not defined, skipping build"
87-
echo "build_arch=false" >> $GITHUB_OUTPUT;
88-
elif [[ "${{ steps.info.outputs.architectures }}" =~ ${{ matrix.arch }} ]]; then
89-
echo "build_arch=true" >> $GITHUB_OUTPUT;
90-
echo "image=$(echo ${{ steps.info.outputs.image }} | cut -d'/' -f3)" >> $GITHUB_OUTPUT;
91-
if [[ -z "${{ github.head_ref }}" ]] && [[ "${{ github.event_name }}" == "push" ]]; then
92-
echo "BUILD_ARGS=" >> $GITHUB_ENV;
93-
fi
94-
else
95-
echo "${{ matrix.arch }} is not a valid arch for ${{ matrix.addon }}, skipping build";
96-
echo "build_arch=false" >> $GITHUB_OUTPUT;
97-
fi
98-
99-
- name: Login to GitHub Container Registry
100-
if: env.BUILD_ARGS != '--test'
101-
uses: docker/login-action@v4.0.0
102-
with:
103-
registry: ghcr.io
104-
username: ${{ github.repository_owner }}
105-
password: ${{ secrets.GITHUB_TOKEN }}
106-
107-
- name: Build ${{ matrix.addon }} app
108-
if: steps.check.outputs.build_arch == 'true'
109-
uses: home-assistant/builder@2026.02.1
110-
with:
111-
args: |
112-
${{ env.BUILD_ARGS }} \
113-
--${{ matrix.arch }} \
114-
--target /data/${{ matrix.addon }} \
115-
--image "${{ steps.check.outputs.image }}" \
116-
--docker-hub "ghcr.io/${{ github.repository_owner }}" \
117-
--addon
73+
strategy:
74+
fail-fast: false
75+
matrix:
76+
app: ${{ fromJSON(needs.init.outputs.changed_apps) }}
77+
uses: ./.github/workflows/build-app.yaml
78+
with:
79+
app: ${{ matrix.app }}
80+
publish: ${{ github.event_name == 'push' }}
81+
secrets: inherit

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,20 @@ _Example app to use as a blueprint for new apps._
2020
<!--
2121
2222
Notes to developers after forking or using the github template feature:
23-
- While developing comment out the 'image' key from 'example/config.yaml' to make the supervisor build the app
23+
- While developing comment out the 'image' key from 'example/config.yaml' to make the supervisor build the app locally.
2424
- Remember to put this back when pushing up your changes.
2525
- When you merge to the 'main' branch of your repository a new build will be triggered.
2626
- Make sure you adjust the 'version' key in 'example/config.yaml' when you do that.
2727
- Make sure you update 'example/CHANGELOG.md' when you do that.
28-
- The first time this runs you might need to adjust the image configuration on github container registry to make it public
29-
- You may also need to adjust the GitHub Actions configuration (Settings > Actions > General > Workflow > Read & Write)
30-
- Adjust the 'image' key in 'example/config.yaml' so it points to your username instead of 'home-assistant'.
31-
- This is where the build images will be published to.
28+
- The first time this runs you might need to adjust the image configuration on github container registry to make it public.
29+
- You may also need to adjust the GitHub Actions configuration (Settings > Actions > General > Workflow > Read & Write).
30+
- Update the repository check in '.github/workflows/build-app.yaml' to match your repository name
31+
(the 'github.repository' condition in the 'prepare' job).
32+
- Adjust the 'image' key in 'example/config.yaml' so it points to your username instead of 'home-assistant'
33+
(e.g., 'ghcr.io/my-username/my-app').
3234
- Rename the example directory.
3335
- The 'slug' key in 'example/config.yaml' should match the directory name.
34-
- Adjust all keys/url's that points to 'home-assistant' to now point to your user/fork.
36+
- Adjust all keys/urls that point to 'home-assistant' to now point to your user/fork.
3537
- Share your repository on the forums https://community.home-assistant.io/c/projects/9
3638
- Do awesome stuff!
3739
-->

example/Dockerfile

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,28 @@
11
# https://developers.home-assistant.io/docs/apps/configuration#app-dockerfile
2-
ARG BUILD_FROM
3-
FROM $BUILD_FROM
2+
ARG BUILD_FROM=ghcr.io/home-assistant/base:3.23
3+
FROM ${BUILD_FROM}
44

55
# Execute during the build of the image
6-
ARG TEMPIO_VERSION BUILD_ARCH
6+
ARG TEMPIO_VERSION=2021.09.0
7+
ARG TARGETARCH
78
RUN \
8-
curl -sSLf -o /usr/bin/tempio \
9-
"https://github.com/home-assistant/tempio/releases/download/${TEMPIO_VERSION}/tempio_${BUILD_ARCH}"
9+
if [ -z "${TARGETARCH}" ]; then \
10+
echo "TARGETARCH is not set, please use Docker BuildKit for the build." && exit 1; \
11+
fi \
12+
&& case "${TARGETARCH}" in \
13+
amd64) tempio_arch="amd64" ;; \
14+
arm64) tempio_arch="aarch64" ;; \
15+
*) echo "Unsupported TARGETARCH: ${TARGETARCH}" && exit 1 ;; \
16+
esac \
17+
&& curl -sSLf -o /usr/bin/tempio \
18+
"https://github.com/home-assistant/tempio/releases/download/${TEMPIO_VERSION}/tempio_${tempio_arch}"
1019

1120
# Copy root filesystem
1221
COPY rootfs /
22+
23+
LABEL \
24+
io.hass.type="addon" \
25+
org.opencontainers.image.title="Home Assistant App: Example app" \
26+
org.opencontainers.image.description="Example app to use as a blueprint for new apps." \
27+
org.opencontainers.image.source="https://github.com/home-assistant/apps-example" \
28+
org.opencontainers.image.licenses="Apache License 2.0"

example/build.yaml

Lines changed: 0 additions & 11 deletions
This file was deleted.

example/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ options:
1414
message: "Hello world..."
1515
schema:
1616
message: "str?"
17-
image: "ghcr.io/home-assistant/{arch}-app-example"
17+
image: "ghcr.io/home-assistant/app-example"

0 commit comments

Comments
 (0)