Validate add-ons / YAML and layout (pull_request) Successful in 9s
Validate add-ons / emby-mcp gofmt (pull_request) Successful in 11s
Validate add-ons / emby-mcp vet (pull_request) Successful in 40s
Validate add-ons / emby-mcp build (pull_request) Successful in 18s
Validate add-ons / openai-codex-proxy (pull_request) Successful in 1m30s
Validate add-ons / n95-mqtt-bridge pin (pull_request) Successful in 3s
Validate add-ons / n95-mqtt-bridge pin and upstream tests (pull_request) Successful in 1m12s
Validate add-ons / emby-mcp Go (pull_request) Successful in 1m47s
Validate add-ons / YAML and layout (push) Successful in 9s
Validate add-ons / emby-mcp gofmt (push) Successful in 20s
Validate add-ons / emby-mcp vet (push) Successful in 55s
Validate add-ons / emby-mcp build (push) Successful in 30s
Validate add-ons / emby-mcp Go (push) Successful in 48s
Validate add-ons / openai-codex-proxy (push) Successful in 1m35s
Validate add-ons / n95-mqtt-bridge pin (push) Successful in 7s
Validate add-ons / n95-mqtt-bridge pin and upstream tests (push) Successful in 32s
Split emby-mcp into gofmt/vet/build/test and n95 pin vs test so a capacity-8 runner can fill slots. Cancel superseded runs. Skip streamable HTTP e2e on CI (session handshake fails on act). Skip n95 TestCapture* (pcaps are not in the published tag).
173 lines
5.5 KiB
YAML
173 lines
5.5 KiB
YAML
name: Validate add-ons
|
|
|
|
on:
|
|
push:
|
|
branches: [develop, main]
|
|
pull_request:
|
|
branches: [develop, main]
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
group: validate-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
yaml:
|
|
name: YAML and layout
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Parse add-on YAML
|
|
run: |
|
|
set -euo pipefail
|
|
python3 -m pip install --break-system-packages --quiet pyyaml
|
|
python3 - <<'PY'
|
|
import pathlib, sys, yaml
|
|
root = pathlib.Path(".")
|
|
files = [root / "repository.yaml"]
|
|
for addon in sorted(p for p in root.iterdir() if p.is_dir() and (p / "config.yaml").exists()):
|
|
files.append(addon / "config.yaml")
|
|
by = addon / "build.yaml"
|
|
if by.exists():
|
|
files.append(by)
|
|
failed = False
|
|
required = ("name", "version", "slug", "arch")
|
|
for f in files:
|
|
print(f"parse {f}")
|
|
with f.open() as fh:
|
|
data = yaml.safe_load(fh)
|
|
if f.name == "config.yaml":
|
|
missing = [k for k in required if k not in (data or {})]
|
|
if missing:
|
|
print(f"ERROR {f}: missing {missing}")
|
|
failed = True
|
|
version = f.parent / "VERSION"
|
|
if version.exists():
|
|
disk = version.read_text().strip()
|
|
cfg = str(data.get("version", "")).strip()
|
|
if disk != cfg:
|
|
print(f"ERROR {f}: version {cfg!r} != VERSION {disk!r}")
|
|
failed = True
|
|
if failed:
|
|
sys.exit(1)
|
|
print("ok")
|
|
PY
|
|
|
|
emby-fmt:
|
|
name: emby-mcp gofmt
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: emby-mcp/go.mod
|
|
cache-dependency-path: emby-mcp/go.sum
|
|
- name: gofmt
|
|
working-directory: emby-mcp
|
|
run: |
|
|
dirty="$(gofmt -l .)"
|
|
if [ -n "$dirty" ]; then
|
|
echo "gofmt needed:"
|
|
echo "$dirty"
|
|
exit 1
|
|
fi
|
|
|
|
emby-vet:
|
|
name: emby-mcp vet
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: emby-mcp/go.mod
|
|
cache-dependency-path: emby-mcp/go.sum
|
|
- name: go vet
|
|
working-directory: emby-mcp
|
|
run: go vet ./...
|
|
|
|
emby-build:
|
|
name: emby-mcp build
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: emby-mcp/go.mod
|
|
cache-dependency-path: emby-mcp/go.sum
|
|
- name: go build
|
|
working-directory: emby-mcp
|
|
run: go build ./...
|
|
|
|
emby-mcp:
|
|
name: emby-mcp Go
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: emby-mcp/go.mod
|
|
cache-dependency-path: emby-mcp/go.sum
|
|
- name: go test
|
|
working-directory: emby-mcp
|
|
run: go test -count=1 -timeout 4m -p 8 -parallel 8 ./...
|
|
timeout-minutes: 6
|
|
|
|
openai-codex-proxy:
|
|
name: openai-codex-proxy
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
- name: syntax-check entrypoint
|
|
run: node --check openai-codex-proxy/rootfs/entrypoint.js
|
|
|
|
n95-pin:
|
|
name: n95-mqtt-bridge pin
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
ref: ${{ steps.pin.outputs.ref }}
|
|
commit: ${{ steps.pin.outputs.commit }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Verify upstream pin
|
|
id: pin
|
|
run: |
|
|
set -euo pipefail
|
|
ref="$(awk -F'"' '/UPSTREAM_REF:/ {print $2; exit}' n95-mqtt-bridge/build.yaml)"
|
|
commit="$(awk -F'"' '/UPSTREAM_COMMIT:/ {print $2; exit}' n95-mqtt-bridge/build.yaml)"
|
|
df_ref="$(awk -F= '/^ARG UPSTREAM_REF=/ {print $2; exit}' n95-mqtt-bridge/Dockerfile)"
|
|
df_commit="$(awk -F= '/^ARG UPSTREAM_COMMIT=/ {print $2; exit}' n95-mqtt-bridge/Dockerfile)"
|
|
echo "build.yaml ref=$ref commit=$commit"
|
|
echo "Dockerfile ref=$df_ref commit=$df_commit"
|
|
test -n "$ref" && test -n "$commit"
|
|
test "$ref" = "$df_ref"
|
|
test "$commit" = "$df_commit"
|
|
echo "ref=$ref" >> "$GITHUB_OUTPUT"
|
|
echo "commit=$commit" >> "$GITHUB_OUTPUT"
|
|
|
|
n95-mqtt-bridge:
|
|
name: n95-mqtt-bridge pin and upstream tests
|
|
runs-on: ubuntu-latest
|
|
needs: n95-pin
|
|
steps:
|
|
- uses: actions/setup-go@v5
|
|
with:
|
|
go-version: "1.27.1"
|
|
- name: Test pinned upstream
|
|
run: |
|
|
set -euo pipefail
|
|
git clone --depth 1 --branch "${{ needs.n95-pin.outputs.ref }}" \
|
|
https://git.i3omb.com/gronod/ha-n95-local-control.git /tmp/n95
|
|
cd /tmp/n95
|
|
got="$(git rev-parse HEAD)"
|
|
want="${{ needs.n95-pin.outputs.commit }}"
|
|
if [ "$got" != "$want" ]; then
|
|
echo "tag ${{ needs.n95-pin.outputs.ref }} is $got, build.yaml wants $want"
|
|
exit 1
|
|
fi
|
|
# Replay pcaps are local fixtures and are not in the published tag.
|
|
go test -count=1 -timeout 4m -p 8 -parallel 8 -skip 'TestCapture' ./...
|
|
timeout-minutes: 6
|