5.2. Action Structure and Metadata
💡 First Principle: action.yml is the action's public contract — it declares the inputs consumers may pass, the outputs they may read, and how to run the thing — and because consumers program against that file, changing it incompatibly is a breaking change no matter what the code does.
Why care: metadata errors are the failure mode that produces no useful error message. An output the workflow reads but the metadata never declares is silently empty. A required input GitHub doesn't enforce yields a confusing downstream failure. And because tooling (VS Code IntelliSense from 2.2.7, dependency scanners, the Marketplace listing) reads this file, sloppy metadata degrades everyone's experience with your action.
⚠️ Common Misconception: "If my code writes an output, workflows can read it." Outputs must be declared in action.yml to be visible as steps.<id>.outputs.<name>. Writing to $GITHUB_OUTPUT without a matching outputs: declaration works for composite-internal use but is not part of the action's contract — and for Docker and JavaScript actions the declaration is what makes it consumable.