Skip to content

Commit 5752577

Browse files
saironclaude
andauthored
Update info helper for new app build workflows (#135)
* Update info helper for new app build workflows Extract additional app metadata (name, slug, description, url) from config files and validate required options per the app configuration spec. The action now errors when required fields (name, version, slug, description, arch) are missing. Also marks build.* files as deprecated with a warning to move base image, build arguments and labels to Dockerfile. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Update tests for info helper required config validation Add required fields (name, slug, description) to test config files and add companion config files alongside deprecated build test files so required field validation passes. Add workflow steps to validate the new outputs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add warning if image is not set --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5f5b077 commit 5752577

7 files changed

Lines changed: 172 additions & 0 deletions

File tree

.github/workflows/helpers.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,21 @@ jobs:
103103
if [[ '${{ steps.info.outputs.version }}' != '"1.0.0"' ]]; then
104104
exit 1
105105
fi
106+
107+
- name: Validate name
108+
run: |
109+
if [[ '${{ steps.info.outputs.name }}' != '"Example App"' ]]; then
110+
exit 1
111+
fi
112+
113+
- name: Validate slug
114+
run: |
115+
if [[ '${{ steps.info.outputs.slug }}' != '"example_app"' ]]; then
116+
exit 1
117+
fi
118+
119+
- name: Validate description
120+
run: |
121+
if [[ '${{ steps.info.outputs.description }}' != '"An example Home Assistant app"' ]]; then
122+
exit 1
123+
fi

helpers/info/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Home Assistant Helper: Info
2+
3+
Extracts build metadata (supported architectures, Docker image, and version) from configuration files.
4+
5+
## Inputs
6+
7+
| Input | Required | Default | Description |
8+
|--------|----------|---------|----------------------------------------------------|
9+
| `path` | no | `.` | Relative directory path to the configuration files |
10+
11+
## Outputs
12+
13+
| Output | Description |
14+
|-----------------|--------------------------------------------------|
15+
| `architectures` | JSON array of supported architectures |
16+
| `image` | Docker image from app config file (if any) |
17+
| `version` | Version from app config file (required) |
18+
| `name` | Name from app config file (required) |
19+
| `slug` | Slug from app config file (required) |
20+
| `description` | Description from app config file (required) |
21+
| `url` | URL from app config file (if any) |
22+
23+
## Configuration File Resolution
24+
25+
The action searches for files in the given `path`, checking extensions in order: `json`, `yml`, `yaml`. The **first match wins**.
26+
27+
### Architectures
28+
29+
Resolved from the first file found:
30+
31+
| Priority | File | Source | Description |
32+
|----------|--------------|----------------------|---------------------------------------------------------------------------------------|
33+
| 1 | `build.*` | `.build_from` (keys) | **Deprecated** — base image, build arguments and labels should be moved to Dockerfile |
34+
| 2 | `config.*` | `.arch` | App configuration — architectures listed directly in the `arch` field |
35+
36+
If neither file exists, `architectures` defaults to `[]`.
37+
38+
### App Metadata
39+
40+
Resolved from `config.*` (app configuration, first matching extension):
41+
42+
| Key | Required | Example output |
43+
|----------------|----------|------------------------------------------------|
44+
| `.name` | yes | `"Example App"` |
45+
| `.version` | yes | `"2024.12.1"` |
46+
| `.slug` | yes | `"example_app"` |
47+
| `.description` | yes | `"An example Home Assistant app"` |
48+
| `.arch` | yes | `["amd64","aarch64"]` |
49+
| `.image` | no | `"ghcr.io/home-assistant/{arch}-app-example"` |
50+
| `.url` | no | `"https://github.com/home-assistant/example"` |
51+
52+
A warning is emitted for each required option that is missing or null. See [App Configuration](https://developers.home-assistant.io/docs/apps/configuration) for full documentation.
53+
54+
If no config file exists, all values default to `""`.
55+
56+
## Example Usage
57+
58+
```yaml
59+
- uses: home-assistant/actions/helpers/info@master
60+
id: info
61+
with:
62+
path: my-app
63+
64+
- run: |
65+
echo "Architectures: ${{ steps.info.outputs.architectures }}"
66+
echo "Image: ${{ steps.info.outputs.image }}"
67+
echo "Version: ${{ steps.info.outputs.version }}"
68+
echo "Name: ${{ steps.info.outputs.name }}"
69+
echo "Slug: ${{ steps.info.outputs.slug }}"
70+
echo "Description: ${{ steps.info.outputs.description }}"
71+
echo "URL: ${{ steps.info.outputs.url }}"
72+
```

helpers/info/action.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@ outputs:
1515
version:
1616
description: Returns the version defined in the config file for add-ons if any
1717
value: ${{ steps.info.outputs.version }}
18+
name:
19+
description: Returns the name defined in the config file
20+
value: ${{ steps.info.outputs.name }}
21+
description:
22+
description: Returns the description defined in the config file
23+
value: ${{ steps.info.outputs.description }}
24+
slug:
25+
description: Returns the slug defined in the config file
26+
value: ${{ steps.info.outputs.slug }}
27+
url:
28+
description: Returns the url defined in the config file
29+
value: ${{ steps.info.outputs.url }}
1830
runs:
1931
using: "composite"
2032
steps:
@@ -27,9 +39,14 @@ runs:
2739
archs=[]
2840
image=""
2941
version=""
42+
name=""
43+
slug=""
44+
description=""
45+
url=""
3046
3147
for file_type in json yml yaml; do
3248
if [[ -f "$INPUTS_PATH/build.${file_type}" ]]; then
49+
echo "::warning::build.${file_type} is deprecated, move base image, build arguments and labels to Dockerfile"
3350
archs=$(yq e -N -M '.build_from | keys' -o=json -I=0 "$INPUTS_PATH/build.${file_type}")
3451
break
3552
elif [[ -f "$INPUTS_PATH/config.${file_type}" ]]; then
@@ -42,13 +59,54 @@ runs:
4259
if [[ -f "$INPUTS_PATH/config.${file_type}" ]]; then
4360
image=$(yq e -N -M '.image' -o=json -I=0 "$INPUTS_PATH/config.${file_type}")
4461
version=$(yq e -N -M '.version' -o=json -I=0 "$INPUTS_PATH/config.${file_type}")
62+
name=$(yq e -N -M '.name' -o=json -I=0 "$INPUTS_PATH/config.${file_type}")
63+
slug=$(yq e -N -M '.slug' -o=json -I=0 "$INPUTS_PATH/config.${file_type}")
64+
description=$(yq e -N -M '.description' -o=json -I=0 "$INPUTS_PATH/config.${file_type}")
65+
url=$(yq e -N -M '.url' -o=json -I=0 "$INPUTS_PATH/config.${file_type}")
4566
fi
4667
done
4768
69+
invalid=false
70+
if [[ "$name" == "null" || -z "$name" ]]; then
71+
echo "::error::Required config option 'name' is missing"
72+
invalid=true
73+
fi
74+
if [[ "$version" == "null" || -z "$version" ]]; then
75+
echo "::error::Required config option 'version' is missing"
76+
invalid=true
77+
fi
78+
if [[ "$slug" == "null" || -z "$slug" ]]; then
79+
echo "::error::Required config option 'slug' is missing"
80+
invalid=true
81+
fi
82+
if [[ "$description" == "null" || -z "$description" ]]; then
83+
echo "::error::Required config option 'description' is missing"
84+
invalid=true
85+
fi
86+
if [[ "$archs" == "[]" || "$archs" == "null" || -z "$archs" ]]; then
87+
echo "::error::Required config option 'arch' is missing"
88+
invalid=true
89+
fi
90+
if [[ "$invalid" == "true" ]]; then
91+
exit 1
92+
fi
93+
94+
if [[ "$image" == "null" || -z "$image" ]]; then
95+
echo "::warning::Config option 'image' is not set, app will be built locally when installed from the repository"
96+
fi
97+
4898
echo "Architectures: $archs"
4999
echo "Image: $image"
50100
echo "Version: $version"
101+
echo "Name: $name"
102+
echo "Slug: $slug"
103+
echo "Description: $description"
104+
echo "URL: $url"
51105
52106
echo "architectures=$archs" >> "$GITHUB_OUTPUT"
53107
echo "image=$image" >> "$GITHUB_OUTPUT"
54108
echo "version=$version" >> "$GITHUB_OUTPUT"
109+
echo "name=$name" >> "$GITHUB_OUTPUT"
110+
echo "slug=$slug" >> "$GITHUB_OUTPUT"
111+
echo "description=$description" >> "$GITHUB_OUTPUT"
112+
echo "url=$url" >> "$GITHUB_OUTPUT"

test_files/build_json/config.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "Example App",
3+
"slug": "example_app",
4+
"description": "An example Home Assistant app",
5+
"arch": ["aarch64","armv7","armhf","amd64","i386"],
6+
"version": "1.0.0"
7+
}

test_files/build_yaml/config.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
name: "Example App"
3+
slug: "example_app"
4+
description: "An example Home Assistant app"
5+
arch:
6+
- aarch64
7+
- armv7
8+
- armhf
9+
- amd64
10+
- i386
11+
version: "1.0.0"

test_files/config_json/config.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
{
2+
"name": "Example App",
3+
"slug": "example_app",
4+
"description": "An example Home Assistant app",
25
"arch": ["aarch64","armv7","armhf","amd64","i386"],
36
"image": "ghcr.io/example/{arch}-example",
47
"version": "1.0.0"

test_files/config_yaml/config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
---
2+
name: "Example App"
3+
slug: "example_app"
4+
description: "An example Home Assistant app"
25
arch:
36
- aarch64
47
- armv7

0 commit comments

Comments
 (0)