The full top-level shape
You've seen the pieces. Here's the full top-level shape of a workflow file, in the order GitHub expects:
name— display name.run-name— per-run name (template-driven, optional).on— events.permissions— what theGITHUB_TOKENcan do.env— workflow-level env vars.defaults— default shell, working dir.concurrency— cancel-in-progress group.jobs— the actual work.
Commonly missed fields
permissions— by default,GITHUB_TOKENis overly permissive. Setpermissions: read-allat workflow level and override per job to enforce least-privilege.concurrency— without it, every push starts a new run. With it, you can cancel in-progress runs on the same branch / PR.defaults.run.shell— explicitly setbashon Linux/macOS if your scripts need bash-isms (Mac defaultshcan surprise you).