Sfoglia il codice sorgente

ci: fix all workflow errors — action upgrades, CodeQL conflict, config syntax

Problems fixed:

1. CodeQL default setup conflict
   Root cause: GitHub's repo-level default CodeQL setup was 'configured',
   which conflicts with our custom codeql.yml. GitHub rejects SARIF uploads
   from advanced configurations when default setup is active.
   Fix: disabled default setup via API; our custom workflow now has sole
   ownership of code scanning.

2. codeql-action upgraded v3 → v4
   v3 is deprecated (forced Node 24 from 2026-06-16, full removal Dec 2026).
   Updated github/codeql-action/init and /analyze from @v3 to @v4.
   Added 'actions: read' permission required by codeql-action@v4.

3. actions/checkout upgraded v4 → v6 (all three workflows)
   v4 runs on Node 20 which is deprecated from 2026-06-16.
   v6 is the current stable release targeting Node 24.

4. actions/setup-python upgraded v5 → v6 (validate.yml)
   Same Node 20 → Node 24 migration.

5. softprops/action-gh-release upgraded v2 → v3 (release.yml)
   Added explicit GITHUB_TOKEN env var as required by v3.

6. codeql-config.yml: removed invalid 'query-filters / tags contain' block
   This syntax is not supported by CodeQL v4 and caused a config parse
   error. MD5 suppression is handled correctly inline in api.py with
   a noqa comment and explanatory rationale.

7. validate.yml: removed bogus FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 env var
   This is not a real GitHub Actions environment variable.
Conexo Casa 4 mesi fa
parent
commit
f46dfcfa2c

+ 7 - 9
.github/codeql-config.yml

@@ -1,21 +1,19 @@
 name: "Solar of Things CodeQL config"
 
-# Only scan the actual integration code, not stale root copies or test fixtures
+# Only scan the actual integration code — ignore dist/ and any future test fixtures
 paths:
   - custom_components/solar_of_things
 
 paths-ignore:
   - dist/
   - tests/
-  - "*.md"
+  - "**/*.md"
 
 queries:
   - uses: security-extended
 
-query-filters:
-  # The Siseli API mandates MD5(password) as a protocol requirement — the server
-  # rejects plaintext. This is not password storage and the transport is HTTPS.
-  # Suppress the weak-hashing alert for this specific protocol-compliance usage.
-  - exclude:
-      id: py/weak-sensitive-data-hashing
-      tags contain: weak-cryptography
+# Note: py/weak-sensitive-data-hashing is suppressed inline in api.py with
+# "# noqa: S324" and an explanatory comment. The Siseli portal API requires
+# MD5(password) — the server returns error code 7 for plaintext. This is a
+# protocol requirement of the upstream service, not password storage, and is
+# transmitted over HTTPS only.

+ 4 - 3
.github/workflows/codeql.yml

@@ -12,6 +12,7 @@ on:
 permissions:
   contents: read
   security-events: write
+  actions: read
 
 jobs:
   analyze:
@@ -20,15 +21,15 @@ jobs:
 
     steps:
       - name: Checkout
-        uses: actions/checkout@v4
+        uses: actions/checkout@v6
 
       - name: Initialize CodeQL
-        uses: github/codeql-action/init@v3
+        uses: github/codeql-action/init@v4
         with:
           languages: python
           config-file: .github/codeql-config.yml
 
       - name: Perform CodeQL Analysis
-        uses: github/codeql-action/analyze@v3
+        uses: github/codeql-action/analyze@v4
         with:
           category: "/language:python"

+ 6 - 6
.github/workflows/release.yml

@@ -15,7 +15,7 @@ jobs:
 
     steps:
       - name: Checkout
-        uses: actions/checkout@v4
+        uses: actions/checkout@v6
 
       - name: Read version from manifest
         id: version
@@ -26,10 +26,9 @@ jobs:
 
       - name: Build HACS release ZIP
         run: |
-          # ZIP contains the full custom_components tree so HACS / manual users
-          # can extract directly into their HA config directory.
           zip -r solar-of-things-ha.zip custom_components/solar_of_things/ \
             -x "*.pyc" -x "__pycache__/*"
+          echo "ZIP size: $(du -sh solar-of-things-ha.zip | cut -f1)"
           echo "ZIP contents:"
           unzip -l solar-of-things-ha.zip
 
@@ -38,19 +37,20 @@ jobs:
         run: |
           TAG="${GITHUB_REF_NAME}"
           VER="${TAG#v}"
-          # Grab lines between current version header and next version header
           NOTES=$(awk "/^## \[${VER}\]/{flag=1; next} /^## \[/{flag=0} flag" CHANGELOG.md)
           if [ -z "$NOTES" ]; then
             NOTES=$(head -60 CHANGELOG.md)
           fi
           printf '%s' "$NOTES" > release_notes.txt
-          echo "notes_file=release_notes.txt" >> "$GITHUB_OUTPUT"
 
       - name: Create GitHub Release & upload asset
-        uses: softprops/action-gh-release@v2
+        uses: softprops/action-gh-release@v3
         with:
           tag_name: ${{ github.ref_name }}
           name: "${{ github.ref_name }} — Solar of Things HA Integration"
           body_path: release_notes.txt
           draft: false
+          prerelease: false
           files: solar-of-things-ha.zip
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

+ 15 - 16
.github/workflows/validate.yml

@@ -9,9 +9,6 @@ on:
 permissions:
   contents: read
 
-env:
-  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
-
 jobs:
   lint:
     name: Lint & validate integration
@@ -19,10 +16,10 @@ jobs:
 
     steps:
       - name: Checkout
-        uses: actions/checkout@v4
+        uses: actions/checkout@v6
 
       - name: Set up Python
-        uses: actions/setup-python@v5
+        uses: actions/setup-python@v6
         with:
           python-version: "3.12"
 
@@ -31,18 +28,18 @@ jobs:
           pip install --quiet --upgrade pip
           pip install --quiet voluptuous requests pycryptodome
 
-      - name: Validate custom_components/solar_of_things/manifest.json
+      - name: Validate manifest.json
         run: |
           python3 - <<'PY'
           import json, sys
           m = json.load(open("custom_components/solar_of_things/manifest.json"))
-          required = ["domain","name","version","config_flow","iot_class",
-                      "requirements","integration_type","homeassistant"]
+          required = ["domain", "name", "version", "config_flow", "iot_class",
+                      "requirements", "integration_type", "homeassistant"]
           missing = [k for k in required if k not in m]
           if missing:
               print(f"manifest.json missing keys: {missing}")
               sys.exit(1)
-          print(f"manifest.json OK (version={m['version']}, type={m['integration_type']})")
+          print(f"manifest.json OK — version={m['version']}, type={m['integration_type']}, ha>={m['homeassistant']}")
           PY
 
       - name: Validate hacs.json
@@ -55,19 +52,21 @@ jobs:
           if missing:
               print(f"hacs.json missing keys: {missing}")
               sys.exit(1)
-          print(f"hacs.json OK (name={h['name']}, homeassistant={h['homeassistant']})")
+          print(f"hacs.json OK — name={h['name']}, homeassistant>={h['homeassistant']}")
           PY
 
       - name: Validate strings / translations sync
         run: |
           python3 - <<'PY'
           import json, sys
-          s = json.load(open("custom_components/solar_of_things/strings.json"))
-          t = json.load(open("custom_components/solar_of_things/translations/en.json"))
-          # Both must parse as valid JSON and have at minimum a config key
-          for label, obj in [("strings.json", s), ("translations/en.json", t)]:
+          base = "custom_components/solar_of_things"
+          for label, path in [
+              ("strings.json",        f"{base}/strings.json"),
+              ("translations/en.json", f"{base}/translations/en.json"),
+          ]:
+              obj = json.load(open(path))
               if "config" not in obj:
-                  print(f"{label} missing 'config' key")
+                  print(f"{label} missing required 'config' key")
                   sys.exit(1)
               print(f"{label} OK")
           PY
@@ -85,7 +84,7 @@ jobs:
           pip install --quiet pytest pytest-asyncio || true
           if [ -d tests ]; then
             python3 -m pytest tests/ -v --tb=short \
-              || echo "Tests done (failures allowed on CI without full HA fixtures)"
+              || echo "Tests completed (failures tolerated without full HA fixtures)"
           else
             echo "No tests directory — skipping"
           fi