fix(wails3): forward task, and report inputs no caller can reach - #81
Conversation
The v3 stack runs the project's own Taskfile target rather than composing a command, so which target runs is the entire configuration. The root action never declared `task` and the orchestrator never forwarded it, so every v3 build ran <os>:build no matter what the caller asked for — and a caller that asked got no error, because Actions ignores a `with:` key the action does not declare. lthn/desktop asked for darwin:package, got darwin:build, and its next step failed on a bundle that was never created. macOS and Windows both went red; the release published nothing. The asymmetry report could not have caught it. It compares a callee's callers against each other, so an input *no* caller wires reads as unanimous agreement rather than as a dead option — and that is the worse case, because the option is documented on the callee and unreachable through the caller. Those are now their own section: 79 of them across the repo, most deliberate (a wrapper choosing not to expose a knob), and the counter is in the default output so the number moving is visible. Co-Authored-By: Virgil <virgil@lethean.io>
📝 WalkthroughWalkthroughThe action adds an optional Wails v3 ChangesWails v3 task forwarding
Contract diagnostics
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Warning Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@action.yml`:
- Around line 66-72: The task input is not propagated across both
composite-action boundaries. In action.yml, add task: ${{ inputs.task }} to the
directory-orchestrator with block; in actions/action.yml, declare task in the
orchestrator inputs block before its existing forwarding to the Wails v3
wrapper, preserving the configured task through to actions/build/wails3/build.
In `@tests/action_contracts.py`:
- Around line 163-168: Update the contract-checking logic around the
callers/missing calculation to verify each forwarded `${{ inputs.<name> }}`
against the callee’s declared inputs before marking that edge reachable. Treat
undeclared callee inputs as missing and emit the existing dangling-input
diagnostic, ensuring they can contribute to the unreachable-callee result.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: bb1e405f-92c9-43ba-8363-68c565ccc892
📒 Files selected for processing (3)
action.ymlactions/action.ymltests/action_contracts.py
| task: | ||
| description: > | ||
| Wails v3 stack: the Taskfile target to run. Empty runs <os>:build, which | ||
| produces a bare binary — a project wanting the bundle or an installer | ||
| names its package target here. | ||
| required: false | ||
| default: "" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== files =="
git ls-files | rg '(^|/)action\.yml$'
echo "== action.yml around task/input declarations =="
if [ -f action.yml ]; then
nl -ba action.yml | sed -n '1,120p'
fi
echo "== actions/action.yml relevant sections =="
if [ -f actions/action.yml ]; then
nl -ba actions/action.yml | sed -n '1,230p'
fi
echo "== task input mentions =="
rg -n "task:|inputs\.task|task \(\$|task:" -S .Repository: dAppCore/build
Length of output: 1358
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== action.yml first 130 lines =="
awk 'NR>=1 && NR<=130 {printf "%5d\t%s\n", NR, $0}' action.yml
echo "== actions/action.yml first 230 lines =="
awk 'NR>=1 && NR<=230 {printf "%5d\t%s\n", NR, $0}' actions/action.yml
echo "== task input mentions =="
rg -n "task:|inputs\.task|task" -S action.yml actions -g '*.yml' -g '*.yaml'Repository: dAppCore/build
Length of output: 19727
🌐 Web query:
GitHub Actions composite actions with key not declared in inputs ignored documentation
💡 Result:
In GitHub Actions, composite actions do not automatically create INPUT_<VARIABLE_NAME> environment variables for their inputs, unlike Docker or JavaScript actions [1][2]. Consequently, if an input is passed to a composite action but is not declared in its metadata (the action.yml file), the action has no native way to access that undeclared input via the inputs context [1][3]. Key technical points regarding this behavior: 1. Absence of Automatic Env Vars: Composite actions do not receive input values as environment variables automatically [1][4]. Authors must explicitly map inputs to environment variables within the steps section of the action.yml file if they wish to access them as environment variables [5][6]. 2. Declaration Requirement: Because composite actions rely on the inputs context to access values, an input must be explicitly defined in the inputs section of the metadata [1][7]. If a user provides an input that is not declared in the action's metadata, that value is effectively ignored by the action logic [7]. The action cannot dynamically "see" or reference inputs that were not part of its design [7]. 3. Recommended Practice: To use inputs within a composite action, you must declare them in the metadata and then explicitly map them into each step where they are required, either by direct reference using ${{ inputs.input-id }} or by defining them in the env block of the specific step [5][6]. If you are encountering issues where inputs are being ignored, ensure they are declared in your action.yml file and correctly passed through the steps as shown in official documentation [6][8]. Using linting tools or static analysis, such as eslint-plugin-github-actions, can help detect references to undeclared inputs that would otherwise cause failures or incorrect behavior at runtime [7].
Citations:
- 1: https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax
- 2: https://docs.github.com/en/enterprise-cloud@latest/actions/reference/workflows-and-actions/metadata-syntax
- 3: https://docs.github.com/en/actions/reference/workflows-and-actions/contexts
- 4: https://docs.github.com/en/enterprise-server@3.18/actions/reference/workflows-and-actions/metadata-syntax
- 5: INPUT_* environment variables are missing in composite actions actions/runner#665
- 6: https://docs.github.com/en/actions/tutorials/create-actions/create-a-composite-action
- 7: https://nick2bad4u.github.io/eslint-plugin-github-actions-2/docs/rules/no-unknown-input-reference-in-composite/
- 8: https://docs.github.com/actions/creating-actions/creating-a-composite-action
Complete task propagation through both composite-action boundaries.
task is declared on the root action, but the root does not pass it to actions/action.yml; the orchestrator forwards it to the Wails v3 wrapper but declares no task input, so composite-action metadata treats it as absent and actions/build/wails3/build resolves to the <os>:build fallback.
action.yml: includetask: ${{ inputs.task }}in the directory-orchestratorwith:block.actions/action.yml: declaretaskin the orchestratorinputsblock before forwarding it to the Wails v3 wrapper.
📍 Affects 2 files
action.yml#L66-L72(this comment)actions/action.yml#L175-L180
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@action.yml` around lines 66 - 72, The task input is not propagated across
both composite-action boundaries. In action.yml, add task: ${{ inputs.task }} to
the directory-orchestrator with block; in actions/action.yml, declare task in
the orchestrator inputs block before its existing forwarding to the Wails v3
wrapper, preserving the configured task through to actions/build/wails3/build.
Source: MCP tools
| missing = sorted(c for c, ok in callers.items() if not ok) | ||
| if missing and len(missing) != len(callers): | ||
| has = sorted(c for c, ok in callers.items() if ok) | ||
| asymmetries.append( | ||
| f" {callee} :: {name}\n" | ||
| f" wired by {', '.join(has)}\n" | ||
| f" not by {', '.join(missing)}") | ||
| if not missing: | ||
| continue | ||
| if len(missing) == len(callers): | ||
| unreachable.append(f" {callee} :: {name}\n" | ||
| f" reached by no caller ({', '.join(missing)})") |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== repo files =="
git ls-files | sed -n '1,120p'
echo "== locate action_contracts.py and action.yml =="
fd -a 'action_contracts.py|action.yml' . | sed 's#^\./##'
echo "== relevant sections =="
if [ -f tests/action_contracts.py ]; then
wc -l tests/action_contracts.py
sed -n '120,190p' tests/action_contracts.py | cat -n
fi
echo "== workflow and action references =="
rg -n "forward|forwarded|inputs|uses:.*action|action.yml|task" -S . --glob '!node_modules' --glob '!dist' --glob '!build' | sed -n '1,240p'Repository: dAppCore/build
Length of output: 29282
Do not treat missing callee inputs as reachable.
The contract checker currently records reachability from ${{ inputs.<name> }} in the caller’s with: block without confirming that <name> is declared by the callee’s inputs. Since actions/action.yml uses ${{ inputs.task }} but does not declare task, this edge is treated as usable and the chain remains broken. Validate forwarded inputs against the callee’s declared inputs before reporting them as reachable and emitting a dangling-input diagnostic where appropriate.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/action_contracts.py` around lines 163 - 168, Update the
contract-checking logic around the callers/missing calculation to verify each
forwarded `${{ inputs.<name> }}` against the callee’s declared inputs before
marking that edge reachable. Treat undeclared callee inputs as missing and emit
the existing dangling-input diagnostic, ensuring they can contribute to the
unreachable-callee result.
Source: MCP tools
The v3 stack runs the project's own Taskfile target rather than composing a command, so which target runs is the entire configuration. The root action never declared
taskand the orchestrator never forwarded it — so every v3 build ran<os>:buildregardless of what the caller asked for, and a caller that asked got no error, because Actions ignores awith:key the action does not declare.lthn/desktopasked fordarwin:package, gotdarwin:build, and its next step failed on a bundle that was never created:macOS and Windows both went red and the release published nothing.
Why the contract check missed it
--asymmetriescompares a callee's callers against each other, so an input that no caller wires reads as unanimous agreement rather than as a dead option. That is the worse case — the option is declared and documented on the callee, and unreachable through the caller.Those now get their own section, and the count appears in the default output so a change in the number is visible:
79, down from 80 with this fix. Most of the rest are deliberate — a wrapper choosing not to expose a knob — so this reports rather than fails.
🤖 Generated with Claude Code
Co-Authored-By: Virgil virgil@lethean.io
Summary by CodeRabbit
New Features
taskinput for Wails v3 projects, allowing a specific Taskfile target to be selected.Tests