CI-12: CI grades test_freeze.py against the real hwsim at a pinned admin/goodwe #125

Merged
admin merged 8 commits from CI-12 into release/1.0 2026-09-25 18:19:44 +02:00
Owner

CI-12, part B. Draft. Do not merge until admin/goodwe#54 (part A) is merged and .gitea/infra-pin holds that merge's SHA.

⚠️ The pin value is temporary. .gitea/infra-pin currently holds a783602ea131d49bc0c904333c1ccb101aac02d0, the head of admin/goodwe#54, which is not on master yet. After #54 merges, set the pin to the master commit it produces (git ls-remote …/admin/goodwe.git refs/heads/master) and push. infra-pin / fresh stays red until then, as intended.

What changes

  • .gitea/infra-pin: the one place the admin/goodwe commit is pinned, with a one-line comment on how to bump it.
  • checks.yml, new step check out admin/goodwe at the pin in .gitea/infra-pin: reads the pin from the merged tree, fetches that exact SHA into $WS/goodwe (the sibling test_freeze.py looks for), and checks that it got that SHA and that sim/hwsim.py exists. If any of that fails, the job fails. The tests step passes GOODWE_REQUIRE_HWSIM=1, and any CI: lines a test prints are echoed on PASS, so the log shows which transport part 3 used.
  • test_freeze.py: with GOODWE_REQUIRE_HWSIM set, a missing hwsim exits 1 instead of falling back to the stub. A local run that uses the stub prints STUB USED: ….
  • .gitea/workflows/infra-pin.yml → context infra-pin / fresh. It runs on every PR and on every push to release/1.0. It goes red with STALE: .gitea/infra-pin is <pin> but admin/goodwe master is <head> when the two differ. It is not a required check, and branch protection is unchanged.
  • README "CI and the infra pin": when and how to bump the pin.

Access: the infra checkout uses this workflow's own GITHUB_TOKEN. No secret was added, and no setting was changed.

Proof runs (throwaway commits on this branch, then restored) are listed in the comments below.

🤖 Generated with Claude Code

CI-12, part B. **Draft. Do not merge until admin/goodwe#54 (part A) is merged and `.gitea/infra-pin` holds that merge's SHA.** ⚠️ **The pin value is temporary.** `.gitea/infra-pin` currently holds `a783602ea131d49bc0c904333c1ccb101aac02d0`, the head of admin/goodwe#54, which is not on master yet. After #54 merges, set the pin to the master commit it produces (`git ls-remote …/admin/goodwe.git refs/heads/master`) and push. `infra-pin / fresh` stays red until then, as intended. **What changes** - `.gitea/infra-pin`: the one place the admin/goodwe commit is pinned, with a one-line comment on how to bump it. - `checks.yml`, new step `check out admin/goodwe at the pin in .gitea/infra-pin`: reads the pin from the merged tree, fetches that exact SHA into `$WS/goodwe` (the sibling `test_freeze.py` looks for), and checks that it got that SHA and that `sim/hwsim.py` exists. **If any of that fails, the job fails.** The tests step passes `GOODWE_REQUIRE_HWSIM=1`, and any `CI: ` lines a test prints are echoed on PASS, so the log shows which transport part 3 used. - `test_freeze.py`: with `GOODWE_REQUIRE_HWSIM` set, a missing hwsim exits 1 instead of falling back to the stub. A local run that uses the stub prints `STUB USED: …`. - `.gitea/workflows/infra-pin.yml` → context `infra-pin / fresh`. It runs on every PR and on every push to release/1.0. It goes red with `STALE: .gitea/infra-pin is <pin> but admin/goodwe master is <head>` when the two differ. It is **not** a required check, and branch protection is unchanged. - README "CI and the infra pin": when and how to bump the pin. **Access:** the infra checkout uses this workflow's own `GITHUB_TOKEN`. No secret was added, and no setting was changed. Proof runs (throwaway commits on this branch, then restored) are listed in the comments below. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
admin added 1 commit 2026-09-25 01:57:18 +02:00
CI-12: CI grades test_freeze.py against the real hwsim at a pinned admin/goodwe
infra-pin / fresh (pull_request) Failing after 1s
checks / unit (pull_request) Failing after 2s
6e3399322a
- .gitea/infra-pin: the one place the admin/goodwe commit is pinned.
- checks.yml: checks out admin/goodwe at the pin as the sibling test_freeze.py
  looks for; any failure fails the job. Tests run with GOODWE_REQUIRE_HWSIM=1,
  and `CI: ` lines are echoed on PASS so the log shows which transport ran.
- test_freeze.py: GOODWE_REQUIRE_HWSIM refuses the stub; a local stub run
  prints a STUB USED line.
- infra-pin.yml: a separate, non-required check that goes red naming both
  SHAs when admin/goodwe master has moved past the pin.
- README: when and how to bump the pin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
Owner

Blocked: CI has no credential that can read admin/goodwe. Head 6e33993, runs 845 (checks) and 846 (infra-pin). Both fail at their first access to admin/goodwe:

remote: Repository not found
fatal: repository 'http://192.168.2.147:3000/admin/goodwe.git/' not found
FAIL: could not fetch admin/goodwe at a783602ea131d49bc0c904333c1ccb101aac02d0.

This workflow's GITHUB_TOKEN is scoped to admin/goodwe-addon, and admin/goodwe is private. Neither repo has any Actions secrets. Per the CI-12 brief I have not created or changed any secret or repo setting. The owner needs to choose how CI gets read access to admin/goodwe, for example a read-only token stored as a secret on this repo. Once that exists, only the TOKEN: line in the two infra steps changes.

The fail-closed path does work: with the checkout failing, checks / unit went red and did not fall back to the stub. The three deliberate proofs (real-hwsim pass, stale-pin red/green, broken checkout) are on hold until access exists.

🤖 Generated with Claude Code

**Blocked: CI has no credential that can read admin/goodwe.** Head 6e33993, runs 845 (`checks`) and 846 (`infra-pin`). Both fail at their first access to admin/goodwe: ``` remote: Repository not found fatal: repository 'http://192.168.2.147:3000/admin/goodwe.git/' not found FAIL: could not fetch admin/goodwe at a783602ea131d49bc0c904333c1ccb101aac02d0. ``` This workflow's `GITHUB_TOKEN` is scoped to admin/goodwe-addon, and admin/goodwe is private. Neither repo has any Actions secrets. Per the CI-12 brief I have not created or changed any secret or repo setting. The owner needs to choose how CI gets read access to admin/goodwe, for example a read-only token stored as a secret on this repo. Once that exists, only the `TOKEN:` line in the two infra steps changes. The fail-closed path does work: with the checkout failing, `checks / unit` went red and did not fall back to the stub. The three deliberate proofs (real-hwsim pass, stale-pin red/green, broken checkout) are on hold until access exists. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
admin added 1 commit 2026-09-25 16:08:58 +02:00
CI-12 round 2: INFRA_READ_TOKEN for admin/goodwe; the pin tracks release/1.0
checks / unit (pull_request) Failing after 3s
infra-pin / fresh (pull_request) Failing after 1s
fe80047235
- checks.yml's infra checkout and infra-pin.yml's admin/goodwe ls-remote use
  the INFRA_READ_TOKEN secret; the self fetch keeps GITHUB_TOKEN.
- infra-pin.yml compares against admin/goodwe refs/heads/release/1.0; STALE
  message, comments and README follow.
- test_control.py / test_alloc.py: drop the claim that CI cannot reach
  admin/goodwe.
- .gitea/infra-pin is DELIBERATELY one release/1.0 merge behind (d84ac01) for
  the "infra-pin / fresh goes red" proof; the next commit sets it to HEAD.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
admin added 1 commit 2026-09-25 16:10:49 +02:00
CI-12: .gitea/infra-pin to admin/goodwe release/1.0 HEAD (56a933e), restoring the proof pin
checks / unit (pull_request) Failing after 3s
infra-pin / fresh (pull_request) Failing after 1s
d0891a6bca
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
Owner

CI-12 round 2 status: still blocked on the credential. Left as draft / WIP.

Pushed fe80047 (INFRA_READ_TOKEN, pin tracks release/1.0, README, stale comments in test_control.py / test_alloc.py), then d0891a6 (pin = admin/goodwe release/1.0 HEAD 56a933e). ls-remote confirms CI-12 is at d0891a6.

INFRA_READ_TOKEN is injected: it is masked as TOKEN: *** in the step env. admin/goodwe still refuses it (runs 847/848 on fe80047, 850/851 on d0891a6):

remote: Forbidden
fatal: unable to access 'http://192.168.2.147:3000/admin/goodwe.git/': The requested URL returned error: 403
FAIL: could not fetch admin/goodwe at 56a933e1466f3fa2d8a3ca5d12c9161d9f037195.

infra-pin / fresh gets the same 403 on its ls-remote. For comparison, a malformed token gives Failed to authenticate user, and round 1's job token gave repository not found. This 403 is different from both. I have not established the cause. Whoever owns the token needs to confirm that its owner can read admin/goodwe and that it has the read:repository scope. I did not create or change any secret, user or setting.

Other CI-12 pieces: admin/goodwe#54 is closed unmerged. #55 is the freeze guard for master. #56 adds addon-pin, the release/1.0 push-side staleness check, shown red (run 849) and green (run 852).

🤖 Generated with Claude Code

CI-12 round 2 status: **still blocked on the credential. Left as draft / WIP.** Pushed fe80047 (INFRA_READ_TOKEN, pin tracks release/1.0, README, stale comments in test_control.py / test_alloc.py), then d0891a6 (pin = admin/goodwe release/1.0 HEAD 56a933e). ls-remote confirms CI-12 is at d0891a6. `INFRA_READ_TOKEN` is injected: it is masked as `TOKEN: ***` in the step env. admin/goodwe still refuses it (runs 847/848 on fe80047, 850/851 on d0891a6): ``` remote: Forbidden fatal: unable to access 'http://192.168.2.147:3000/admin/goodwe.git/': The requested URL returned error: 403 FAIL: could not fetch admin/goodwe at 56a933e1466f3fa2d8a3ca5d12c9161d9f037195. ``` `infra-pin / fresh` gets the same 403 on its `ls-remote`. For comparison, a malformed token gives `Failed to authenticate user`, and round 1's job token gave `repository not found`. This 403 is different from both. I have not established the cause. Whoever owns the token needs to confirm that its owner can read admin/goodwe and that it has the `read:repository` scope. I did not create or change any secret, user or setting. Other CI-12 pieces: admin/goodwe#54 is closed unmerged. #55 is the freeze guard for master. #56 adds `addon-pin`, the release/1.0 push-side staleness check, shown red (run 849) and green (run 852). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
admin added 1 commit 2026-09-25 17:27:08 +02:00
CI-12: test_tariff.py no longer says CI cannot see the infra repo
infra-pin / fresh (pull_request) Successful in 1s
checks / unit (pull_request) Successful in 8m47s
c493a6d67a
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
admin added 1 commit 2026-09-25 17:36:38 +02:00
THROWAWAY (CI-12 proof 2): pin one release/1.0 merge behind (d84ac01); reverted next
checks / unit (pull_request) Successful in 8m43s
infra-pin / fresh (pull_request) Failing after 1s
54cc5263fb
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
admin added 1 commit 2026-09-25 17:45:39 +02:00
CI-12: restore .gitea/infra-pin to admin/goodwe release/1.0 HEAD (56a933e)
checks / unit (pull_request) Successful in 8m43s
infra-pin / fresh (pull_request) Successful in 1s
c63eda0b0f
This reverts commit 54cc5263fb (the proof-2 throwaway).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
admin marked the pull request as ready for review 2026-09-25 17:54:40 +02:00
Author
Owner

CI-12 round 2: the new INFRA_READ_TOKEN works. Ready for review. Head is c63eda0, confirmed with ls-remote.

Proof 1. Run 854 (c493a6d, which also fixes the stale comment in test_tariff.py) and run 858 (c63eda0): checks / unit green, all 35 test files PASS.

infra: admin/goodwe @ 56a933e Merge pull request 'COMM-01: …' (#53) from COMM-01 into release/1.0
PASS  test_freeze.py  (34s)
CI: test_freeze part 3 (the live HTTP transport) ran against: the rig hwsim at /w/goodwe/sim/hwsim.py

Proof 2. Throwaway commit 54cc526 pins d84ac01, one release/1.0 merge behind:

  • run 857, infra-pin / fresh, red: STALE: .gitea/infra-pin is d84ac01b09c53af5de8029c1125bd4d4cfc7b3cd but admin/goodwe release/1.0 is 56a933e1466f3fa2d8a3ca5d12c9161d9f037195.
  • run 856, checks / unit on the same commit, green against infra: admin/goodwe @ d84ac01.

Revert commit c63eda0 restores the pin to 56a933e:

  • run 859, green: OK: .gitea/infra-pin 56a933e1466f3fa2d8a3ca5d12c9161d9f037195 is admin/goodwe release/1.0 HEAD.

Proof 3. A failed checkout fails the job: runs 845, 847 and 850.

Proof 4. admin/goodwe#56 (addon-pin) was shown red in run 849 and green in run 852.

CI-12 round 2: the new `INFRA_READ_TOKEN` works. Ready for review. Head is c63eda0, confirmed with ls-remote. **Proof 1.** Run 854 (c493a6d, which also fixes the stale comment in test_tariff.py) and run 858 (c63eda0): `checks / unit` green, all 35 test files PASS. ``` infra: admin/goodwe @ 56a933e Merge pull request 'COMM-01: …' (#53) from COMM-01 into release/1.0 PASS test_freeze.py (34s) CI: test_freeze part 3 (the live HTTP transport) ran against: the rig hwsim at /w/goodwe/sim/hwsim.py ``` **Proof 2.** Throwaway commit 54cc526 pins d84ac01, one release/1.0 merge behind: - run 857, `infra-pin / fresh`, red: `STALE: .gitea/infra-pin is d84ac01b09c53af5de8029c1125bd4d4cfc7b3cd but admin/goodwe release/1.0 is 56a933e1466f3fa2d8a3ca5d12c9161d9f037195.` - run 856, `checks / unit` on the same commit, green against `infra: admin/goodwe @ d84ac01`. Revert commit c63eda0 restores the pin to 56a933e: - run 859, green: `OK: .gitea/infra-pin 56a933e1466f3fa2d8a3ca5d12c9161d9f037195 is admin/goodwe release/1.0 HEAD.` **Proof 3.** A failed checkout fails the job: runs 845, 847 and 850. **Proof 4.** admin/goodwe#56 (`addon-pin`) was shown red in run 849 and green in run 852.
admin added 1 commit 2026-09-25 18:01:19 +02:00
CI-12 review: INFRA_READ_TOKEN via an env-set header, not a remote URL
checks / unit (pull_request) Successful in 8m42s
infra-pin / fresh (pull_request) Successful in 1s
841424463a
The long-lived token no longer lands in $WS/goodwe/.git/config (mounted into
the tests' container, left behind by a failed job) or in git's argv. A missing
secret (fork PR) fails with its own message. README: addon-pin is not re-run
after a bump.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LyR88rXETvwhTgx6yHE39p
Author
Owner

Review (CI-12), round 1. Reviewed at c63eda0. I pushed one fix commit: 8414244.

R1: fixed in 8414244. INFRA_READ_TOKEN was written into $WS/goodwe/.git/config through git remote add origin http://x-access-token:TOKEN@…. It is a long-lived PAT, unlike GITHUB_TOKEN, and that file:

  • is mounted :ro into the container that runs this PR's own test_*.py;
  • stays on the shared runner host if the job dies before clean up. The Sep 9 /home/homelab/ci/checks-145/goodwe/.git/config still holds an (expired, job-scoped) token that way.

The token was also in git's argv while the fetch ran, where ps shows it to any local user. The fix: git fetch "$URL" "$PIN" runs with GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=http.extraHeader GIT_CONFIG_VALUE_0="Authorization: token $TOKEN", so nothing is stored and nothing is in argv. infra-pin.yml's ls-remote got the same change. I checked locally that Gitea 1.27.3 accepts Authorization: token for git smart-HTTP, and that no token ends up in .git/.

R2: fixed in 8414244. A fork PR, or a run without the secret, now fails with FAIL: secret INFRA_READ_TOKEN is not available…. Before this it also failed, but with git's could not read Username. Neither version falls back to the stub: GOODWE_REQUIRE_HWSIM=1 plus the refusal in test_freeze.py close that path too.

Checked, no change needed:

  • No set -x anywhere.
  • On error, git 2.43 prints the URL with the credentials stripped (tested).
  • The runner masks the secret: run 858's log shows TOKEN: ***.
  • The SELF fetches still use GITHUB_TOKEN. Only admin/goodwe access uses INFRA_READ_TOKEN.
  • Branch protection on release/1.0 and master is unchanged. The only required context is checks / unit (pull_request), so infra-pin / fresh is advisory.

R3: README sentence added in 8414244. This is about the window between an infra release/1.0 push and the bump.

  • While the bump is pending, the infra commit carries a red addon-pin / fresh, and every add-on PR shows infra-pin / fresh red. checks / unit keeps grading against the old pin, which is correct.
  • addon-pin runs once per infra push. That push's SHA cannot be pinned before it exists, so the check is red on every push that moves release/1.0, and nothing re-runs it after the bump. The README now says so, and names infra-pin / fresh green on the bump as the all-clear.
  • "Visible" means the commit and branch status plus the Actions tab in the Gitea UI. I have not verified whether this Gitea emails anyone about a failed run.

Verified independently:

  • Run 858 log: infra: admin/goodwe @ 56a933e, then CI: test_freeze part 3 … ran against: the rig hwsim at /w/goodwe/sim/hwsim.py.
  • Docs are the right size: a 3-line README section, plus one-line pointers in the workflow headers.

Merge order. I keep the proposed order: #56 first, then I bump this pin to #56's merge SHA, then merge this, then goodwe#55. #56's merge is a merge commit, so its SHA is unknown until it lands. The alternative is to fast-forward #56 and pin its head (731e21b) here first, which would leave add-on release/1.0 pinned for a while to a commit that is not on infra release/1.0. Either order leaves exactly one stale red somewhere, and I prefer it on the infra side, where it is explained above. The add-on side, which developers see, then ends green.

**Review (CI-12), round 1.** Reviewed at c63eda0. I pushed one fix commit: 8414244. **R1: fixed in 8414244.** `INFRA_READ_TOKEN` was written into `$WS/goodwe/.git/config` through `git remote add origin http://x-access-token:TOKEN@…`. It is a long-lived PAT, unlike `GITHUB_TOKEN`, and that file: - is mounted `:ro` into the container that runs this PR's own `test_*.py`; - stays on the shared runner host if the job dies before `clean up`. The Sep 9 `/home/homelab/ci/checks-145/goodwe/.git/config` still holds an (expired, job-scoped) token that way. The token was also in git's argv while the fetch ran, where `ps` shows it to any local user. The fix: `git fetch "$URL" "$PIN"` runs with `GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=http.extraHeader GIT_CONFIG_VALUE_0="Authorization: token $TOKEN"`, so nothing is stored and nothing is in argv. `infra-pin.yml`'s `ls-remote` got the same change. I checked locally that Gitea 1.27.3 accepts `Authorization: token` for git smart-HTTP, and that no token ends up in `.git/`. **R2: fixed in 8414244.** A fork PR, or a run without the secret, now fails with `FAIL: secret INFRA_READ_TOKEN is not available…`. Before this it also failed, but with git's `could not read Username`. Neither version falls back to the stub: `GOODWE_REQUIRE_HWSIM=1` plus the refusal in test_freeze.py close that path too. **Checked, no change needed:** - No `set -x` anywhere. - On error, git 2.43 prints the URL with the credentials stripped (tested). - The runner masks the secret: run 858's log shows `TOKEN: ***`. - The SELF fetches still use `GITHUB_TOKEN`. Only admin/goodwe access uses `INFRA_READ_TOKEN`. - Branch protection on release/1.0 and master is unchanged. The only required context is `checks / unit (pull_request)`, so `infra-pin / fresh` is advisory. **R3: README sentence added in 8414244. This is about the window between an infra release/1.0 push and the bump.** - While the bump is pending, the infra commit carries a red `addon-pin / fresh`, and every add-on PR shows `infra-pin / fresh` red. `checks / unit` keeps grading against the old pin, which is correct. - `addon-pin` runs once per infra push. That push's SHA cannot be pinned before it exists, so the check is red on every push that moves release/1.0, and nothing re-runs it after the bump. The README now says so, and names `infra-pin / fresh` green on the bump as the all-clear. - "Visible" means the commit and branch status plus the Actions tab in the Gitea UI. I have not verified whether this Gitea emails anyone about a failed run. **Verified independently:** - Run 858 log: `infra: admin/goodwe @ 56a933e`, then `CI: test_freeze part 3 … ran against: the rig hwsim at /w/goodwe/sim/hwsim.py`. - Docs are the right size: a 3-line README section, plus one-line pointers in the workflow headers. **Merge order.** I keep the proposed order: #56 first, then I bump this pin to #56's merge SHA, then merge this, then goodwe#55. #56's merge is a merge commit, so its SHA is unknown until it lands. The alternative is to fast-forward #56 and pin its head (731e21b) here first, which would leave add-on release/1.0 pinned for a while to a commit that is not on infra release/1.0. Either order leaves exactly one stale red somewhere, and I prefer it on the infra side, where it is explained above. The add-on side, which developers see, then ends green.
admin added 1 commit 2026-09-25 18:10:31 +02:00
CI-12: .gitea/infra-pin to admin/goodwe release/1.0 HEAD (2d026df, goodwe#56 merged)
checks / unit (pull_request) Successful in 8m42s
infra-pin / fresh (pull_request) Successful in 1s
8ff42ea85d
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LyR88rXETvwhTgx6yHE39p
admin merged commit 6a8a5ffa27 into release/1.0 2026-09-25 18:19:44 +02:00
Author
Owner

Merged as 6a8a5ffa (head 8ff42ea pinned). release/1.0 = 6a8a5ff, confirmed with git ls-remote.

  • 8ff42ea bumps .gitea/infra-pin to 2d026dfa, the goodwe#56 merge. On that head, run 863 (checks / unit) shows infra: admin/goodwe @ 2d026df, PASS test_freeze.py and CI: … ran against: the rig hwsim at /w/goodwe/sim/hwsim.py. Run 864 (infra-pin / fresh) is OK.
  • The R1/R2 fix (8414244) was proven by run 860 (checks, real hwsim at 56a933e) and run 861 (infra-pin OK). The header auth works with INFRA_READ_TOKEN.
  • After the merge, the release/1.0 push ran infra-pin / fresh: run 865, green. checks.yml is pull_request/workflow_dispatch only, so it has no push run.
  • Follow-up, not blocking: see goodwe#56. Under the runner's pipefail, a missing pin file exits on git's own fatal: line rather than on the workflow's message. The job is still red.
**Merged** as 6a8a5ffa (head 8ff42ea pinned). `release/1.0` = 6a8a5ff, confirmed with `git ls-remote`. - 8ff42ea bumps `.gitea/infra-pin` to 2d026dfa, the goodwe#56 merge. On that head, run 863 (`checks / unit`) shows `infra: admin/goodwe @ 2d026df`, `PASS test_freeze.py` and `CI: … ran against: the rig hwsim at /w/goodwe/sim/hwsim.py`. Run 864 (`infra-pin / fresh`) is OK. - The R1/R2 fix (8414244) was proven by run 860 (checks, real hwsim at 56a933e) and run 861 (infra-pin OK). The header auth works with `INFRA_READ_TOKEN`. - After the merge, the release/1.0 push ran `infra-pin / fresh`: run 865, green. `checks.yml` is `pull_request`/`workflow_dispatch` only, so it has no push run. - Follow-up, not blocking: see goodwe#56. Under the runner's `pipefail`, a missing pin file exits on git's own `fatal:` line rather than on the workflow's message. The job is still red.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/goodwe-addon#125