A job is identified by a key under jobs: and is configured with runs-on: to declare which runner label it should use, such as ubuntu-latest. Jobs run in parallel by default, but you can express dependencies between them with needs: job_id. By default, dependent jobs only run after the named needs job completes successfully, providing a straightforward way to express sequenced pipelines.
For repetitive jobs, the matrix strategy lets you run the same job multiple times in parallel with different variable combinations, defined under jobs.
Conditional execution is controlled with the if: key on jobs and steps. The expressions success(), failure(), always(), and cancelled() are particularly useful: success() runs only when previous steps or jobs succeeded, failure() runs only when something failed, always() runs regardless of outcome, and cancelled() runs only when the workflow was cancelled. Concurrency, configured at the workflow level, provides another control knob, grouping runs so that duplicate executions of the same workflow on the same branch cancel one another, typically with cancel-in-progress: true.