Skip to content

Commit c8b0899

Browse files
authored
Merge pull request #772 from tempus2016/chore/ci-tooling-expansion
chore(ci): data/release gates, CodeQL, dependency review, dev container
2 parents 4cf5b81 + 750fd56 commit c8b0899

27 files changed

Lines changed: 1246 additions & 387 deletions

‎.devcontainer/devcontainer.json‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"name": "TaskMate dev",
3+
"image": "mcr.microsoft.com/devcontainers/python:1-3.13-bookworm",
4+
"features": {
5+
"ghcr.io/devcontainers/features/node:1": {
6+
"version": "20"
7+
}
8+
},
9+
"forwardPorts": [8123],
10+
"portsAttributes": {
11+
"8123": {
12+
"label": "Home Assistant",
13+
"onAutoForward": "notify"
14+
}
15+
},
16+
"postCreateCommand": "bash .devcontainer/setup.sh",
17+
"remoteUser": "vscode",
18+
"customizations": {
19+
"vscode": {
20+
"extensions": [
21+
"charliermarsh.ruff",
22+
"ms-python.python",
23+
"dbaeumer.vscode-eslint",
24+
"esbenp.prettier-vscode",
25+
"redhat.vscode-yaml",
26+
"github.vscode-github-actions"
27+
],
28+
"settings": {
29+
"python.defaultInterpreterPath": "/usr/local/bin/python",
30+
"editor.formatOnSave": false,
31+
"[python]": {
32+
"editor.defaultFormatter": "charliermarsh.ruff"
33+
},
34+
"files.trimTrailingWhitespace": true,
35+
"files.insertFinalNewline": true
36+
}
37+
}
38+
}
39+
}

‎.devcontainer/setup.sh‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env bash
2+
# Provisions the dev container: test harness, linters, and a throwaway Home
3+
# Assistant config with TaskMate symlinked in. Runs once, on container create.
4+
set -euo pipefail
5+
6+
echo "==> Installing Python tooling"
7+
python -m pip install --upgrade pip
8+
pip install -r requirements_test.txt
9+
pip install ruff==0.15.12 pre-commit homeassistant
10+
11+
echo "==> Installing Node tooling"
12+
npm ci
13+
14+
echo "==> Installing git hooks"
15+
pre-commit install || echo "pre-commit install skipped"
16+
17+
echo "==> Preparing a Home Assistant config at ./dev-config"
18+
mkdir -p dev-config/custom_components
19+
# Symlink, not copy — edits to the integration are live in the running HA.
20+
ln -sfn "$(pwd)/custom_components/taskmate" dev-config/custom_components/taskmate
21+
22+
if [ ! -f dev-config/configuration.yaml ]; then
23+
cat > dev-config/configuration.yaml <<'YAML'
24+
# Minimal Home Assistant config for TaskMate development.
25+
default_config:
26+
27+
logger:
28+
default: info
29+
logs:
30+
custom_components.taskmate: debug
31+
32+
# Cards are served by the integration itself at /taskmate/<card>.js and
33+
# registered automatically, so no lovelace resources block is needed here.
34+
YAML
35+
fi
36+
37+
cat <<'EOF'
38+
39+
Setup complete.
40+
41+
Run tests pytest -v
42+
Lint ruff check custom_components/taskmate tests scripts && npm run lint
43+
Data checks python3 scripts/check_translations.py && python3 scripts/check_data_files.py
44+
Start Home Assistant hass -c dev-config
45+
then open the forwarded port 8123 and add the
46+
TaskMate integration from Settings -> Devices & services
47+
48+
EOF

‎.github/CODEOWNERS‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Auto-requests review on every PR (including from forks) and makes the
2+
# ownership explicit. Matches the "codeowners" field in manifest.json.
3+
4+
* @tempus2016
5+
6+
# Areas worth an explicit line — these are the ones where an outside PR is most
7+
# likely to land, and where a silent change is most expensive.
8+
/.github/ @tempus2016
9+
/custom_components/taskmate/www/ @tempus2016
10+
/custom_components/taskmate/translations/ @tempus2016
11+
/blueprints/ @tempus2016
12+
/hacs.json @tempus2016
13+
/custom_components/taskmate/manifest.json @tempus2016

‎.github/CONTRIBUTING.md‎

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ custom_components/taskmate/
4040

4141
## Development setup
4242

43+
### One-click: dev container / Codespaces
44+
45+
The repo ships a dev container. Open it in GitHub Codespaces, or in VS Code with
46+
the Dev Containers extension ("Reopen in Container"). Setup installs the test
47+
harness, ruff, ESLint and pre-commit, and creates a scratch HA config at
48+
`dev-config/` with the integration symlinked in — so `hass -c dev-config` gives
49+
you a real Home Assistant on port 8123 with your working copy live.
50+
51+
### Manual
52+
4353
The fastest loop is a real Home Assistant instance with the integration
4454
bind-mounted:
4555

@@ -52,18 +62,35 @@ bind-mounted:
5262

5363
## Code quality
5464

55-
Two checks gate every PR into `main`. Run them locally before pushing:
65+
Run these locally before pushing:
5666

5767
```bash
5868
# Lint (matches the "Ruff" CI check)
59-
ruff check .
69+
ruff check custom_components/taskmate tests scripts
70+
71+
# Cards and panel (matches the "ESLint" CI check)
72+
npm ci && npm run lint
6073

6174
# Tests (matches the "Run tests" CI check)
6275
pytest
76+
77+
# Every locale matches en.json (matches the "Translation parity" CI check)
78+
python3 scripts/check_translations.py
79+
80+
# Blueprints, sentences and packaging metadata parse (matches "Data files")
81+
python3 scripts/check_data_files.py
6382
```
6483

65-
`hassfest` and HACS validation also run in CI to keep the integration
66-
compliant.
84+
Or install the hooks once and let them run on commit:
85+
86+
```bash
87+
pip install pre-commit
88+
pre-commit install
89+
pre-commit run --all-files
90+
```
91+
92+
`hassfest`, HACS validation, dependency review and a workflow-security audit
93+
(`zizmor`) also run in CI, alongside GitHub's CodeQL code scanning.
6794

6895
## Translations
6996

@@ -75,6 +102,10 @@ be asked to include the translations.
75102
Backend strings live in `custom_components/taskmate/translations/` and
76103
`strings.json`; card strings live under `www/locales/`.
77104

105+
This is enforced in CI: `scripts/check_translations.py` fails the build if any
106+
locale's key set differs from `en.json` in either catalogue. Run it locally to
107+
see exactly which keys are missing.
108+
78109
## Submitting a pull request
79110

80111
1. Fork and create a feature branch.

‎.github/ISSUE_TEMPLATE/bug_report.yml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,15 @@ body:
175175
attributes:
176176
label: Home Assistant Logs
177177
description: |
178-
Paste any relevant log output here.
179-
178+
Paste any relevant log output here.
179+
180180
To get debug logs, add this to configuration.yaml, restart HA, reproduce the issue, then copy the logs from Settings → System → Logs:
181181
```yaml
182182
logger:
183183
logs:
184184
custom_components.taskmate: debug
185185
```
186-
186+
187187
Filter by "taskmate" to find relevant entries.
188188
render: text
189189
placeholder: |
@@ -223,7 +223,7 @@ body:
223223
label: Additional Context
224224
description: |
225225
Anything else that might be relevant — screenshots, screen recordings, recent changes to your setup, etc.
226-
226+
227227
You can drag and drop images directly into this text box.
228228
229229
- type: checkboxes

‎.github/ISSUE_TEMPLATE/feature_request.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ body:
1010
attributes:
1111
value: |
1212
Thanks for suggesting a new feature! Please fill in as much detail as you can — the more context you give, the easier it is to understand and implement.
13-
13+
1414
Before submitting, please search [existing issues](https://github.com/tempus2016/taskmate/issues) to check if this has already been requested.
1515
1616
# ── Feature Summary ───────────────────────────────────────────────────────────
@@ -132,7 +132,7 @@ body:
132132
label: Additional Context
133133
description: |
134134
Anything else that helps explain your situation — ages of children, how you currently use TaskMate, screenshots of what you'd like to see, mockups, etc.
135-
135+
136136
You can drag and drop images directly into this box.
137137
138138
# ── Checklist ─────────────────────────────────────────────────────────────────

‎.github/dependabot.yml‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ updates:
88
labels:
99
- "dependencies"
1010
- "ci"
11+
# Don't bump onto a release that's hours old — a freshly published action
12+
# version is the one most likely to be yanked or compromised.
13+
cooldown:
14+
default-days: 7
1115

1216
# Dev tooling only (eslint) — nothing here ships in the integration.
1317
# Grouped so routine bumps arrive as one PR rather than one per package.
@@ -19,9 +23,27 @@ updates:
1923
labels:
2024
- "dependencies"
2125
- "ci"
26+
cooldown:
27+
default-days: 7
2228
groups:
2329
npm-dev-dependencies:
2430
dependency-type: "development"
2531
update-types:
2632
- "minor"
2733
- "patch"
34+
35+
# The HA test harness in requirements_test.txt is deliberately pinned so a new
36+
# upstream release can't flip the required "Run tests" check on its own. This
37+
# entry doesn't undo that — it just raises one PR when a newer pin exists, so
38+
# the decision to move is explicit instead of never noticed. Limit 1 on
39+
# purpose: this should be a quiet trickle, not a queue.
40+
- package-ecosystem: "pip"
41+
directory: "/"
42+
schedule:
43+
interval: "monthly"
44+
open-pull-requests-limit: 1
45+
labels:
46+
- "dependencies"
47+
- "ci"
48+
cooldown:
49+
default-days: 14

‎.github/release.yml‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Groups GitHub's auto-generated release notes by label. This does not replace
2+
# the hand-written release notes — it shapes the "What's Changed" list that
3+
# GitHub appends when you click "Generate release notes", so dependency bumps
4+
# collapse into one section instead of padding the top of the list.
5+
changelog:
6+
exclude:
7+
labels:
8+
- duplicate
9+
- invalid
10+
- wontfix
11+
- stale
12+
authors:
13+
- dependabot
14+
categories:
15+
- title: New features
16+
labels:
17+
- enhancement
18+
19+
- title: Bug fixes
20+
labels:
21+
- bug
22+
23+
- title: Cards & UI
24+
labels:
25+
- cards
26+
27+
- title: Translations
28+
labels:
29+
- translations
30+
31+
- title: Documentation
32+
labels:
33+
- documentation
34+
35+
- title: CI & maintenance
36+
labels:
37+
- ci
38+
- tests
39+
40+
- title: Dependencies
41+
labels:
42+
- dependencies
43+
44+
- title: Other changes
45+
labels:
46+
- "*"

‎.github/workflows/data-checks.yml‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Data checks
2+
3+
# Guards the two classes of breakage the Python test suite can't see:
4+
# 1. a locale that drifted out of sync with en.json (renders raw keys in the UI)
5+
# 2. a shipped YAML/JSON file that doesn't parse (blows up at install time)
6+
7+
on:
8+
push:
9+
branches: [main]
10+
pull_request:
11+
branches: [main]
12+
workflow_dispatch:
13+
14+
concurrency:
15+
group: ${{ github.workflow }}-${{ github.ref }}
16+
cancel-in-progress: true
17+
18+
permissions:
19+
contents: read
20+
21+
jobs:
22+
translations:
23+
name: Translation parity
24+
runs-on: ubuntu-latest
25+
26+
steps:
27+
- name: Check out repository
28+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
29+
with:
30+
persist-credentials: false
31+
32+
- name: Set up Python
33+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
34+
with:
35+
python-version: "3.12"
36+
37+
- name: Check every locale matches en.json
38+
run: python3 scripts/check_translations.py
39+
40+
data-files:
41+
name: Data files
42+
runs-on: ubuntu-latest
43+
44+
steps:
45+
- name: Check out repository
46+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
47+
with:
48+
persist-credentials: false
49+
50+
- name: Set up Python
51+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
52+
with:
53+
python-version: "3.12"
54+
55+
- name: Install PyYAML
56+
run: python -m pip install --upgrade pip pyyaml
57+
58+
- name: Parse blueprints, sentences, locales and metadata
59+
run: python3 scripts/check_data_files.py
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Dependency review
2+
3+
# Fails a PR that introduces a dependency with a known vulnerability, or one
4+
# under a licence we don't want to ship. Only the npm dev tooling and the test
5+
# requirements are in scope today — the integration itself has no runtime
6+
# requirements — but this is the gate that keeps it that way.
7+
8+
on:
9+
pull_request:
10+
branches: [main]
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
dependency-review:
17+
name: Dependency review
18+
runs-on: ubuntu-latest
19+
20+
permissions:
21+
contents: read
22+
pull-requests: write
23+
24+
steps:
25+
- name: Check out repository
26+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
27+
with:
28+
persist-credentials: false
29+
30+
- name: Review dependency changes
31+
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
32+
with:
33+
fail-on-severity: moderate
34+
comment-summary-in-pr: on-failure

0 commit comments

Comments
 (0)