updates2mqtt 1.4.0__tar.gz → 1.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- updates2mqtt-1.4.2/.github/workflows/auto_assign_issue.yml +18 -0
- updates2mqtt-1.4.2/.github/workflows/auto_assign_pr.yml +18 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/.github/workflows/docker-publish.yml +2 -2
- updates2mqtt-1.4.2/.github/workflows/main.yml +18 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/.github/workflows/pypi-publish.yml +4 -1
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/.github/workflows/python-package.yml +23 -2
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/.gitignore +1 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/.pre-commit-config.yaml +2 -2
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/CHANGELOG.md +9 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/PKG-INFO +11 -2
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/README.md +10 -1
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/common_packages.yaml +26 -2
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/conftest.py +68 -5
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/home_assistant.md +7 -0
- updates2mqtt-1.4.2/docs/images/updates2mqtt-dark-256x256.png +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/installation.md +16 -2
- updates2mqtt-1.4.2/docs/robots.txt +4 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/troubleshooting.md +80 -2
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/examples/config.yaml.maximal +2 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/examples/docker-compose.yaml +1 -1
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/mkdocs.yml +21 -3
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/pyproject.toml +8 -3
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/src/updates2mqtt/app.py +15 -10
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/src/updates2mqtt/config.py +3 -1
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/src/updates2mqtt/hass_formatter.py +20 -4
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/src/updates2mqtt/integrations/docker.py +10 -4
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/src/updates2mqtt/model.py +4 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/src/updates2mqtt/mqtt.py +14 -11
- updates2mqtt-1.4.2/tests/test_app.py +130 -0
- updates2mqtt-1.4.2/tests/test_hass_formatter.py +68 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/tests/test_mqtt.py +6 -6
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/uv.lock +251 -45
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/.dockerignore +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/.github/dependabot.yml +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/.hintrc +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/.python-version +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/.safety-project.ini +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/Dockerfile +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/LICENSE +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/SECURITY.md +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/configuration.md +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/examples/config_maximal.md +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/examples/config_minimal.md +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/examples/docker_compose.md +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/images/ha_entities.png +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/images/ha_mqtt_discovery.png +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/images/ha_update_detail.png +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/images/ha_update_dialog.png +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/images/ha_update_page.png +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/images/logo-blank-256x256.png +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/index.md +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/docs/local_builds.md +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/examples/config.yaml.minimal +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/no_config.yaml +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/refresh-deps.sh +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/scripts/healthcheck.sh +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/src/updates2mqtt/__init__.py +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/src/updates2mqtt/__main__.py +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/src/updates2mqtt/integrations/__init__.py +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/src/updates2mqtt/integrations/git_utils.py +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/src/updates2mqtt/py.typed +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/tests/__init__.py +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/tests/test_config.py +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/tests/test_docker.py +0 -0
- {updates2mqtt-1.4.0 → updates2mqtt-1.4.2}/tests/test_git_utils.py +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Issue assignment
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issues:
|
|
5
|
+
types: [opened]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
auto-assign:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
issues: write
|
|
12
|
+
steps:
|
|
13
|
+
- name: 'Auto-assign issue'
|
|
14
|
+
uses: pozil/auto-assign-issue@39c06395cbac76e79afc4ad4e5c5c6db6ecfdd2e
|
|
15
|
+
with:
|
|
16
|
+
assignees: jeyrb
|
|
17
|
+
numOfAssignee: 1
|
|
18
|
+
allowSelfAssign: true
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: PR assignment
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, edited, synchronize, reopened]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
auto-assign:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
pull-requests: write
|
|
12
|
+
steps:
|
|
13
|
+
- name: 'Auto-assign PR'
|
|
14
|
+
uses: pozil/auto-assign-issue@39c06395cbac76e79afc4ad4e5c5c6db6ecfdd2e
|
|
15
|
+
with:
|
|
16
|
+
repo-token: ${{ secrets.MY_PERSONAL_ACCESS_TOKEN }}
|
|
17
|
+
assignees: jeyrb
|
|
18
|
+
numOfAssignee: 1
|
|
@@ -25,7 +25,7 @@ jobs:
|
|
|
25
25
|
#
|
|
26
26
|
steps:
|
|
27
27
|
- name: Checkout repository
|
|
28
|
-
uses: actions/checkout@
|
|
28
|
+
uses: actions/checkout@v6
|
|
29
29
|
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
|
|
30
30
|
- name: Log in to the Container registry
|
|
31
31
|
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef
|
|
@@ -42,7 +42,7 @@ jobs:
|
|
|
42
42
|
uses: docker/setup-buildx-action@v3
|
|
43
43
|
- name: Extract metadata (tags, labels) for Docker
|
|
44
44
|
id: meta
|
|
45
|
-
uses: docker/metadata-action@
|
|
45
|
+
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051
|
|
46
46
|
with:
|
|
47
47
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
48
48
|
tags: |
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Issue assignment
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issues:
|
|
5
|
+
types: [opened]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
auto-assign:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
issues: write
|
|
12
|
+
steps:
|
|
13
|
+
- name: 'Auto-assign issue'
|
|
14
|
+
uses: pozil/auto-assign-issue@v2
|
|
15
|
+
with:
|
|
16
|
+
assignees: jeyrb
|
|
17
|
+
numOfAssignee: 1
|
|
18
|
+
allowSelfAssign: true
|
|
@@ -2,13 +2,16 @@ name: Publish Python 🐍 distribution 📦 to PyPI and TestPyPI
|
|
|
2
2
|
|
|
3
3
|
on: push
|
|
4
4
|
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
|
|
5
8
|
jobs:
|
|
6
9
|
build:
|
|
7
10
|
name: Build distribution 📦
|
|
8
11
|
runs-on: ubuntu-latest
|
|
9
12
|
|
|
10
13
|
steps:
|
|
11
|
-
- uses: actions/checkout@
|
|
14
|
+
- uses: actions/checkout@v6
|
|
12
15
|
with:
|
|
13
16
|
persist-credentials: false
|
|
14
17
|
- name: uv-setup
|
|
@@ -15,7 +15,7 @@ jobs:
|
|
|
15
15
|
permissions:
|
|
16
16
|
contents: write
|
|
17
17
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
18
|
+
- uses: actions/checkout@v6
|
|
19
19
|
- name: uv-setup
|
|
20
20
|
# Install a specific uv version using the installer
|
|
21
21
|
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
@@ -27,11 +27,32 @@ jobs:
|
|
|
27
27
|
run: uv sync --all-extras --dev
|
|
28
28
|
|
|
29
29
|
- name: Ruff
|
|
30
|
-
uses:
|
|
30
|
+
uses: astral-sh/ruff-action@v3
|
|
31
31
|
- name: Test with pytest
|
|
32
32
|
run: uv run pytest tests
|
|
33
33
|
- name: Build a binary wheel and a source tarball
|
|
34
34
|
run: uv build
|
|
35
|
+
- name: Generate badges
|
|
36
|
+
env:
|
|
37
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
38
|
+
run: |
|
|
39
|
+
uv run genbadge coverage -i cov.xml -o badges/coverage.svg
|
|
40
|
+
uv run genbadge tests -i junit/test-results.xml -o badges/tests.svg
|
|
41
|
+
|
|
42
|
+
git config --global user.name "github-actions[bot]"
|
|
43
|
+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
44
|
+
TEMP_DIR=$(mktemp -d)
|
|
45
|
+
cd $TEMP_DIR
|
|
46
|
+
git clone --single-branch --branch badges https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git . 2>/dev/null
|
|
47
|
+
cp -r ${{ github.workspace }}/badges .
|
|
48
|
+
git add badges
|
|
49
|
+
if git commit -m "Update badges [skip ci]"; then
|
|
50
|
+
git push origin badges --force
|
|
51
|
+
echo "Badges updated successfully"
|
|
52
|
+
else
|
|
53
|
+
echo "No changes to badges"
|
|
54
|
+
fi
|
|
55
|
+
|
|
35
56
|
- name: Prep for mkdocs
|
|
36
57
|
run: uv pip compile pyproject.toml -o requirements_docs.txt --group mkdocs
|
|
37
58
|
- name: Deploy docs
|
|
@@ -17,11 +17,11 @@ repos:
|
|
|
17
17
|
- id: check-shebang-scripts-are-executable
|
|
18
18
|
name: Check shell scripts are executable
|
|
19
19
|
- repo: https://github.com/astral-sh/uv-pre-commit
|
|
20
|
-
rev: 0.9.
|
|
20
|
+
rev: 0.9.16
|
|
21
21
|
hooks:
|
|
22
22
|
- id: uv-lock
|
|
23
23
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
24
|
-
rev: v0.14.
|
|
24
|
+
rev: v0.14.8
|
|
25
25
|
hooks:
|
|
26
26
|
# Run the linter.
|
|
27
27
|
- id: ruff-check
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 1.4.2
|
|
4
|
+
- Replace `origin` in config MQTT message with `device` for better HomeAssistant compatibility
|
|
5
|
+
- An `area` can be defined in the Home Assistant section of config and this will then be used as `suggested_area` for device
|
|
6
|
+
- Icon and release note info added for Owntone and Homarr
|
|
7
|
+
## 1.4.1
|
|
8
|
+
- More logging for Docker discovery on why Home Assistant doesn't show an update button
|
|
9
|
+
- More test cases
|
|
10
|
+
- `MqttClient` is now `MqttPublisher` to avoid confusion with actual MQTT client
|
|
11
|
+
- Task cleanup now only interrupts explicit list of tasks - healthcheck and discovery tasks
|
|
3
12
|
## 1.4.0
|
|
4
13
|
- MQTT protocol can now be set, to one of `3.1`,`3.11` or `5`
|
|
5
14
|
- Debug messages now provided for `on_subscribe` and `on_unsubscribe` callbacks
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: updates2mqtt
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.2
|
|
4
4
|
Summary: System update and docker image notification and execution over MQTT
|
|
5
5
|
Project-URL: Homepage, https://updates2mqtt.rhizomatics.org.uk
|
|
6
6
|
Project-URL: Repository, https://github.com/rhizomatics/updates2mqtt
|
|
@@ -35,18 +35,27 @@ Requires-Dist: structlog>=25.4.0
|
|
|
35
35
|
Requires-Dist: usingversion>=0.1.2
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
{ align=left }
|
|
39
39
|
|
|
40
40
|
# updates2mqtt
|
|
41
41
|
|
|
42
|
+
[](https://github.com/rhizomatics)
|
|
43
|
+
|
|
42
44
|
[](https://pypi.org/project/updates2mqtt/)
|
|
43
45
|
[](https://github.com/rhizomatics/supernotify)
|
|
46
|
+
[](https://updates2mqtt.rhizomatics.org.uk/developer/coverage/)
|
|
47
|
+

|
|
44
48
|
[](https://results.pre-commit.ci/latest/github/rhizomatics/updates2mqtt/main)
|
|
45
49
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/pypi-publish.yml)
|
|
46
50
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/python-package.yml)
|
|
47
51
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/github-code-scanning/codeql)
|
|
48
52
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/dependabot/dependabot-updates)
|
|
49
53
|
|
|
54
|
+
|
|
55
|
+
<br/>
|
|
56
|
+
<br/>
|
|
57
|
+
|
|
58
|
+
|
|
50
59
|
## Summary
|
|
51
60
|
|
|
52
61
|
Let Home Assistant tell you about new updates to Docker images for your containers.
|
|
@@ -1,15 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
{ align=left }
|
|
2
2
|
|
|
3
3
|
# updates2mqtt
|
|
4
4
|
|
|
5
|
+
[](https://github.com/rhizomatics)
|
|
6
|
+
|
|
5
7
|
[](https://pypi.org/project/updates2mqtt/)
|
|
6
8
|
[](https://github.com/rhizomatics/supernotify)
|
|
9
|
+
[](https://updates2mqtt.rhizomatics.org.uk/developer/coverage/)
|
|
10
|
+

|
|
7
11
|
[](https://results.pre-commit.ci/latest/github/rhizomatics/updates2mqtt/main)
|
|
8
12
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/pypi-publish.yml)
|
|
9
13
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/python-package.yml)
|
|
10
14
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/github-code-scanning/codeql)
|
|
11
15
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/dependabot/dependabot-updates)
|
|
12
16
|
|
|
17
|
+
|
|
18
|
+
<br/>
|
|
19
|
+
<br/>
|
|
20
|
+
|
|
21
|
+
|
|
13
22
|
## Summary
|
|
14
23
|
|
|
15
24
|
Let Home Assistant tell you about new updates to Docker images for your containers.
|
|
@@ -26,7 +26,7 @@ common_packages:
|
|
|
26
26
|
caddy:
|
|
27
27
|
docker:
|
|
28
28
|
image_name: caddy
|
|
29
|
-
logo_url: https://
|
|
29
|
+
logo_url: https://avatars.githubusercontent.com/u/12955528?s=48&v=4
|
|
30
30
|
release_notes_url: https://github.com/caddyserver/caddy/releases
|
|
31
31
|
|
|
32
32
|
uptime-kuma:
|
|
@@ -81,4 +81,28 @@ common_packages:
|
|
|
81
81
|
docker:
|
|
82
82
|
image_name: jellyfin/jellyfin
|
|
83
83
|
logo_url: https://avatars.githubusercontent.com/u/45698031?s=48&v=4
|
|
84
|
-
release_notes_url: https://github.com/jellyfin/jellyfin/releases
|
|
84
|
+
release_notes_url: https://github.com/jellyfin/jellyfin/releases
|
|
85
|
+
|
|
86
|
+
owntone:
|
|
87
|
+
docker:
|
|
88
|
+
image_name: owntone/owntone
|
|
89
|
+
logo_url: https://raw.githubusercontent.com/owntone/owntone-server/443fb684871e005a7e442a08cc4d610208abbe6c/docs/assets/logo.svg
|
|
90
|
+
release_notes_url: https://github.com/owntone/owntone-server/releases
|
|
91
|
+
|
|
92
|
+
homarr:
|
|
93
|
+
docker:
|
|
94
|
+
image_name: ghcr.io/homarr-labs/homarr
|
|
95
|
+
logo_url: https://github.com/homarr-labs/homarr/blob/dev/docs/img/logo/2340450-2-title.png?raw=true
|
|
96
|
+
release_notes_url: https://github.com/homarr-labs/homarr/releases
|
|
97
|
+
|
|
98
|
+
nextcloud:
|
|
99
|
+
docker:
|
|
100
|
+
image_name: nextcloud
|
|
101
|
+
logo_url: https://avatars.githubusercontent.com/u/19211038?s=48&v=4
|
|
102
|
+
release_notes_url: https://github.com/nextcloud/docker/releases
|
|
103
|
+
|
|
104
|
+
n8n:
|
|
105
|
+
docker:
|
|
106
|
+
image_name: docker.n8n.io/n8nio/n8n
|
|
107
|
+
logo_url: https://avatars.githubusercontent.com/u/45487711?s=48&v=4
|
|
108
|
+
release_notes_url: https://github.com/n8n-io/n8n/releases
|
|
@@ -1,26 +1,89 @@
|
|
|
1
|
-
|
|
1
|
+
# python
|
|
2
|
+
from collections.abc import AsyncGenerator, Callable
|
|
3
|
+
from typing import Any
|
|
4
|
+
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
|
2
5
|
|
|
3
6
|
import paho.mqtt.client
|
|
4
7
|
import pytest
|
|
5
8
|
from docker import DockerClient
|
|
6
9
|
from docker.models.containers import Container, ContainerCollection
|
|
7
10
|
from docker.models.images import Image, RegistryData
|
|
11
|
+
from omegaconf import DictConfig, OmegaConf
|
|
8
12
|
|
|
13
|
+
import updates2mqtt.app
|
|
14
|
+
from updates2mqtt.app import (
|
|
15
|
+
App, # relative import as required
|
|
16
|
+
MqttPublisher,
|
|
17
|
+
)
|
|
18
|
+
from updates2mqtt.config import Config
|
|
9
19
|
from updates2mqtt.model import Discovery, ReleaseProvider
|
|
10
20
|
|
|
11
21
|
|
|
22
|
+
@pytest.fixture
|
|
23
|
+
def app_with_mocked_external_dependencies(
|
|
24
|
+
monkeypatch, # noqa: ANN001
|
|
25
|
+
mock_provider_class: type,
|
|
26
|
+
mock_publisher_class: type,
|
|
27
|
+
) -> App:
|
|
28
|
+
cfg: DictConfig = OmegaConf.structured(Config)
|
|
29
|
+
monkeypatch.setattr(updates2mqtt.app, "load_app_config", lambda *_args, **__kwargs: cfg)
|
|
30
|
+
monkeypatch.setattr(updates2mqtt.app, "DockerProvider", mock_provider_class)
|
|
31
|
+
monkeypatch.setattr(updates2mqtt.app, "MqttPublisher", mock_publisher_class)
|
|
32
|
+
app: App = App()
|
|
33
|
+
return app
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.fixture
|
|
37
|
+
def mock_discoveries(mock_provider: ReleaseProvider) -> list[Discovery]:
|
|
38
|
+
return [Discovery(mock_provider, "thing-1", "test001")]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@pytest.fixture
|
|
42
|
+
def mock_discovery_generator(mock_discoveries: list[Discovery]) -> Callable[..., AsyncGenerator[Discovery, Any]]:
|
|
43
|
+
async def g(*args: Any) -> AsyncGenerator[Discovery]: # noqa: ARG001
|
|
44
|
+
for d in mock_discoveries:
|
|
45
|
+
yield d
|
|
46
|
+
|
|
47
|
+
return g
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@pytest.fixture
|
|
51
|
+
def mock_provider_class(mock_provider: ReleaseProvider) -> type:
|
|
52
|
+
class MockReleaseProvider(ReleaseProvider):
|
|
53
|
+
def __new__(cls, *args: Any, **kwargs: Any) -> ReleaseProvider: # type: ignore[misc] # noqa: ARG004
|
|
54
|
+
return mock_provider
|
|
55
|
+
|
|
56
|
+
return MockReleaseProvider
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@pytest.fixture
|
|
60
|
+
def mock_publisher_class(mock_publisher: MqttPublisher) -> type:
|
|
61
|
+
class MockPublisher(MqttPublisher):
|
|
62
|
+
def __new__(cls, *args: Any, **kwargs: Any) -> MqttPublisher: # type: ignore[misc] # noqa: ARG004
|
|
63
|
+
return mock_publisher
|
|
64
|
+
|
|
65
|
+
return MockPublisher
|
|
66
|
+
|
|
67
|
+
|
|
12
68
|
@pytest.fixture
|
|
13
69
|
def mock_provider() -> ReleaseProvider:
|
|
14
|
-
provider =
|
|
70
|
+
provider: ReleaseProvider = AsyncMock(spec=ReleaseProvider)
|
|
15
71
|
provider.source_type = "unit_test"
|
|
16
|
-
provider.command.return_value = True
|
|
17
|
-
provider.resolve.return_value = Discovery(
|
|
72
|
+
provider.command.return_value = True # type: ignore[attr-defined]
|
|
73
|
+
provider.resolve.return_value = Discovery( # type: ignore[attr-defined]
|
|
18
74
|
provider, "fooey", session="test-mqtt-123", current_version="v2", latest_version="v2"
|
|
19
75
|
)
|
|
20
|
-
provider.hass_state_format.return_value = {"fixture": "test_exec"}
|
|
76
|
+
provider.hass_state_format.return_value = {"fixture": "test_exec"} # type: ignore[attr-defined]
|
|
21
77
|
return provider
|
|
22
78
|
|
|
23
79
|
|
|
80
|
+
@pytest.fixture
|
|
81
|
+
def mock_publisher(mock_mqtt_client: paho.mqtt.client.Client) -> MqttPublisher:
|
|
82
|
+
publisher: MqttPublisher = AsyncMock(MqttPublisher)
|
|
83
|
+
publisher.client = mock_mqtt_client
|
|
84
|
+
return publisher
|
|
85
|
+
|
|
86
|
+
|
|
24
87
|
@pytest.fixture
|
|
25
88
|
def mock_mqtt_client() -> paho.mqtt.client.Client:
|
|
26
89
|
return MagicMock(spec=paho.mqtt.client.Client, name="MQTT Client Fixture")
|
|
@@ -16,6 +16,13 @@ The `homeassistant` default topic prefix matches the default updates2mqtt config
|
|
|
16
16
|
|
|
17
17
|

|
|
18
18
|
|
|
19
|
+
## Device Creation
|
|
20
|
+
|
|
21
|
+
A Home Assistant device will be created for each Updates2MQTT agent on each server, and Home Assistant
|
|
22
|
+
will then group all the relevant entities together on this device page. Use `device_creation: false` in the
|
|
23
|
+
`homeassistant` config block if you want to switch off this behaviour, and `area` if you want to provide
|
|
24
|
+
a `suggested_area` for the device.
|
|
25
|
+
|
|
19
26
|
## MQTT Topics
|
|
20
27
|
|
|
21
28
|
There are 3 separate types of MQTT topic used for HomeAssisstant integration:
|
|
Binary file
|
|
@@ -12,8 +12,22 @@ See `examples` directory for a working `docker-compose.yaml`.
|
|
|
12
12
|
|
|
13
13
|
If you want to update and restart containers, then the file system paths to the location of the directory where the docker compose file lives must be available in the updates2mqtt container.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
```yaml
|
|
16
|
+
volumes:
|
|
17
|
+
# Must have config directory mapped
|
|
18
|
+
- ./conf:/app/conf
|
|
19
|
+
# Must have the Docker daemon socket mapped
|
|
20
|
+
- /var/run/docker.sock:/var/run/docker.sock
|
|
21
|
+
# This list of paths is only needed when containers are to be updated
|
|
22
|
+
# The paths here are completely dependent on where your docker-compose files live
|
|
23
|
+
# and the internal/external paths must be exactly the same
|
|
24
|
+
- /my/container/home:/my/container/home
|
|
25
|
+
- /more/containers:/more/containers
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The example `docker-compose.yaml` mounts `/my/container/home` for this purpose, so if your containers are in
|
|
29
|
+
`/my/container/home/app1`, `/my/container/home/app2` etc, then updates2mqtt will be able to find them in
|
|
30
|
+
order to restart them. Map as many root paths as needed.
|
|
17
31
|
|
|
18
32
|
### Without Docker
|
|
19
33
|
|
|
@@ -1,14 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags:
|
|
3
|
+
- docker
|
|
4
|
+
- docker-compose
|
|
5
|
+
- homeassistant
|
|
6
|
+
- mqtt
|
|
7
|
+
- paho
|
|
8
|
+
---
|
|
1
9
|
# Troubleshooting
|
|
2
10
|
|
|
3
|
-
##
|
|
11
|
+
## General
|
|
4
12
|
|
|
5
|
-
|
|
13
|
+
Things that need to work:
|
|
14
|
+
|
|
15
|
+
- Docker API access to list and inspect containers
|
|
16
|
+
- MQTT Publication of results
|
|
17
|
+
- Home Assistant discovering the Update entities on MQTT
|
|
18
|
+
- Home Assistant generating update notices in UI when there's a new version
|
|
19
|
+
- Command Topic message sent by Home Assistant when Update button clicked
|
|
20
|
+
- Docker Compose available from shell to make updates and restart
|
|
21
|
+
- Git command available in shell to check for local repo updates and pull
|
|
22
|
+
|
|
23
|
+
## Updates2MQTT Logs
|
|
24
|
+
|
|
25
|
+
If running under docker, and following the container naming guidance, then see the
|
|
26
|
+
logs using:
|
|
27
|
+
|
|
28
|
+
`docker logs updates2mqtt`
|
|
29
|
+
|
|
30
|
+
or change to the directory where the `docker-compose.yaml` is installed and do `docker compose logs`
|
|
31
|
+
|
|
32
|
+
### Changing Log Level
|
|
33
|
+
|
|
34
|
+
Update the `config.yaml` and change the log level to DEBUG, which will show much
|
|
35
|
+
more diagnostic information.
|
|
6
36
|
|
|
7
37
|
```yaml
|
|
8
38
|
log:
|
|
9
39
|
level: DEBUG
|
|
10
40
|
```
|
|
11
41
|
|
|
42
|
+
When you have everything working, its best to change the log level back, so
|
|
43
|
+
your container isn't generating big logs.
|
|
44
|
+
|
|
45
|
+
### Going Inside Container
|
|
46
|
+
|
|
47
|
+
From the `docker-compose.yaml` directory, execute
|
|
48
|
+
|
|
49
|
+
`docker compose exec -it updates2mqtt bash`
|
|
50
|
+
|
|
51
|
+
(if you have an old Docker install, you may need to use `docker-compose` instead of `docker compose`)
|
|
52
|
+
|
|
53
|
+
This will give you shell access inside the container, which is a good way of checking
|
|
54
|
+
for path issues, permissio issues etc. For example, if you have compose directories in the
|
|
55
|
+
`/containers` directory, you could `cd /containers` and validate that Updates2MQTT can see the
|
|
56
|
+
other compose directories, `ls` the contents, and run `docker compose` or `git` actions there.
|
|
57
|
+
|
|
12
58
|
## MQTT
|
|
13
59
|
|
|
14
60
|
If the host, port, user and password for MQTT are incorrect then usually this
|
|
@@ -58,6 +104,38 @@ Oddly, the Paho MQTT client used by Updates2MQTT is known to [report success eve
|
|
|
58
104
|
|
|
59
105
|
There's also an alternative to MQTT Discovery in HA, using plain yaml, the [MQTT Update Integration](https://www.home-assistant.io/integrations/update.mqtt/#configuration). The [BBQKees Boiler Gateway](https://bbqkees-electronics.nl/wiki/home-automations/home-assistant-configuration.html) has some detailed steps and examples for MQTT Discovery too.
|
|
60
106
|
|
|
107
|
+
#### No Update Button
|
|
108
|
+
|
|
109
|
+
If there's an update showing, but no *Update* button present, then there's a few reasons, which
|
|
110
|
+
can be checked directly from the config and log:
|
|
111
|
+
|
|
112
|
+
- Config has the `allow_pull`,`allow_restart` and `allow_build` all overridden to `False`
|
|
113
|
+
- A new version reference can't be found
|
|
114
|
+
- The compose working directory can't be found
|
|
115
|
+
- This is sourced from the `com.docker.compose.project.working_dir` label, which can be seen in `docker inspect`
|
|
116
|
+
- This only stops restart, not pull, so if `allow_pull` is on, the Update button will still show
|
|
117
|
+
- The git repo path can't be found for a local build
|
|
118
|
+
|
|
119
|
+
The current state of this can be seen in MQTT, the config message will have two extra
|
|
120
|
+
values as below:
|
|
121
|
+
|
|
122
|
+
```yaml
|
|
123
|
+
"command_topic": "updates2mqtt/dockernuc/docker",
|
|
124
|
+
"payload_install": "docker|homarr|install"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### Home Assistant Logs
|
|
128
|
+
|
|
129
|
+
Use the [System Log](https://www.home-assistant.io/integrations/system_log/) to check
|
|
130
|
+
for MQTT errors, or for positive confirmation that Update entities have been discovered. The
|
|
131
|
+
*raw* log will show more, and allow you to scroll back for hours.
|
|
132
|
+
|
|
133
|
+
The [Logger Integration](https://www.home-assistant.io/integrations/logger/#viewing-logs)
|
|
134
|
+
lets you tweak the levels of specific integrations. This is less useful for Updates2MQTT,
|
|
135
|
+
since all the work is happening outside of Home Assistant, however it can be useful
|
|
136
|
+
for general MQTT issues, and the examples in the Home Assistant documentation shows how
|
|
137
|
+
to tune the MQTT integration.
|
|
138
|
+
|
|
61
139
|
## Docker
|
|
62
140
|
|
|
63
141
|
More detailed information on the Docker API and compatibility with Docker engine versions can be found at Docker's own [Docker Engine API](https://docs.docker.com/reference/api/engine/) reference.
|
|
@@ -5,7 +5,7 @@ services:
|
|
|
5
5
|
volumes:
|
|
6
6
|
- ./conf:/app/conf # Config file lives at /app/conf/config.yaml inside the container
|
|
7
7
|
- /var/run/docker.sock:/var/run/docker.sock # Access to Docker daemon for container updates
|
|
8
|
-
- /home/
|
|
8
|
+
- /my/container/home:/my/container/home # Optional, map all root paths for docker compose directories
|
|
9
9
|
restart: always
|
|
10
10
|
env_file: ./.env # Environment variables file
|
|
11
11
|
healthcheck:
|
|
@@ -4,13 +4,18 @@ site_description: Notify and take action on server updates via MQTT, with HomeAs
|
|
|
4
4
|
|
|
5
5
|
repo_name: rhizomatics/updates2mqtt
|
|
6
6
|
repo_url: https://github.com/rhizomatics/updates2mqtt
|
|
7
|
+
edit_uri: edit/main/docs/
|
|
7
8
|
|
|
8
9
|
theme:
|
|
9
10
|
name: material
|
|
10
11
|
highlightjs: true
|
|
11
|
-
logo: images/
|
|
12
|
+
logo: images/updates2mqtt-dark-256x256.png
|
|
12
13
|
language: en
|
|
14
|
+
icon:
|
|
15
|
+
repo: fontawesome/brands/github
|
|
13
16
|
features:
|
|
17
|
+
- content.action.edit
|
|
18
|
+
- content.action.view
|
|
14
19
|
- content.code.copy
|
|
15
20
|
- content.code.select
|
|
16
21
|
- content.code.annotate
|
|
@@ -24,14 +29,24 @@ theme:
|
|
|
24
29
|
- navigation.top
|
|
25
30
|
- toc.follow
|
|
26
31
|
- toc.integrate
|
|
32
|
+
- search.suggest
|
|
33
|
+
- search
|
|
34
|
+
- search.share
|
|
27
35
|
plugins:
|
|
28
36
|
- search
|
|
29
37
|
- autorefs
|
|
30
38
|
- pagetree
|
|
31
39
|
- optimize
|
|
32
|
-
- tags
|
|
40
|
+
- tags:
|
|
41
|
+
tags: false
|
|
42
|
+
- git-revision-date-localized:
|
|
43
|
+
enable_creation_date: true
|
|
44
|
+
- meta-descriptions
|
|
33
45
|
- minify:
|
|
34
46
|
minify_html: true
|
|
47
|
+
- coverage:
|
|
48
|
+
page_path: developer/coverage
|
|
49
|
+
html_report_dir: htmlcov
|
|
35
50
|
- mkdocstrings:
|
|
36
51
|
handlers:
|
|
37
52
|
# See: https://mkdocstrings.github.io/python/usage/
|
|
@@ -40,6 +55,10 @@ plugins:
|
|
|
40
55
|
show_source: false
|
|
41
56
|
show_root_heading: true
|
|
42
57
|
summary: true
|
|
58
|
+
show_inheritance_diagram: false
|
|
59
|
+
overloads_only: true
|
|
60
|
+
show_if_no_docstring: false
|
|
61
|
+
|
|
43
62
|
markdown_extensions:
|
|
44
63
|
- admonition
|
|
45
64
|
- pymdownx.details
|
|
@@ -52,7 +71,6 @@ markdown_extensions:
|
|
|
52
71
|
pygments_lang_class: true
|
|
53
72
|
- pymdownx.inlinehilite
|
|
54
73
|
- pymdownx.superfences
|
|
55
|
-
- admonition
|
|
56
74
|
- smarty
|
|
57
75
|
- toc:
|
|
58
76
|
permalink: true
|
|
@@ -7,7 +7,7 @@ authors = [
|
|
|
7
7
|
]
|
|
8
8
|
|
|
9
9
|
requires-python = ">=3.13"
|
|
10
|
-
version = "1.4.
|
|
10
|
+
version = "1.4.2"
|
|
11
11
|
license="Apache-2.0"
|
|
12
12
|
keywords=["mqtt", "docker", "updates", "automation","home-assistant","homeassistant","selfhosting"]
|
|
13
13
|
|
|
@@ -56,16 +56,20 @@ dev = [
|
|
|
56
56
|
"pytest-mqtt>=0.6.0",
|
|
57
57
|
"pytest-subprocess>=1.5.3",
|
|
58
58
|
"coverage",
|
|
59
|
+
"icdiff",
|
|
60
|
+
"genbadge[all]"
|
|
59
61
|
]
|
|
60
62
|
mkdocs=[
|
|
63
|
+
"mkdocs",
|
|
61
64
|
"mkdocs-material",
|
|
62
|
-
"mkdocstrings",
|
|
63
65
|
"mkdocs-minify-plugin",
|
|
64
66
|
"mkdocs-autorefs",
|
|
65
67
|
"mkdocs-pagetree-plugin",
|
|
66
68
|
"mkdocs-coverage",
|
|
67
69
|
"mkdocstrings[python]",
|
|
68
70
|
"pymdown-extensions",
|
|
71
|
+
"mkdocs-git-revision-date-localized-plugin",
|
|
72
|
+
"mkdocs-meta-descriptions-plugin",
|
|
69
73
|
"pngquant"
|
|
70
74
|
]
|
|
71
75
|
|
|
@@ -154,10 +158,11 @@ norecursedirs = [
|
|
|
154
158
|
".git",
|
|
155
159
|
"templates",
|
|
156
160
|
]
|
|
161
|
+
|
|
157
162
|
pythonpath = [
|
|
158
163
|
"."
|
|
159
164
|
]
|
|
160
|
-
addopts = "--cov --cov-report=lcov:lcov.info --cov-report=term --import-mode=importlib"
|
|
165
|
+
addopts = "--junitxml=junit/test-results.xml --cov --cov-report=lcov:lcov.info --cov-report=xml --cov-report=html --cov-report=term --import-mode=importlib"
|
|
161
166
|
|
|
162
167
|
[tool.coverage.run]
|
|
163
168
|
branch = true
|