CI and CD Become Two Separate Files
Why stage two splits one workflow into ci.yaml and deploy.yaml, and why a git hook can never replace what CI actually guarantees.
Say a second contributor joins the project from the maturity-stages post. They open a pull request. Right now, nothing runs until it's merged, because the only trigger you have is push to main.
That's backwards. You want to know a change is safe before it reaches main, not after.
One workflow file becomes two
Up to now, push and pull_request have lived as two triggers inside the same file. Stage two splits them into two separate files entirely.
ci.yaml triggers on pull_request, and only checks the change. deploy.yaml triggers on push to main, and only ships it. Two files, two jobs named build, one in each, doing the identical steps.
Separate files, not just separate jobs, is what makes CI and CD independently readable. Anyone auditing "what happens when code ships" doesn't have to skim past everything "what happens when a PR opens" to find it, and vice versa. The cost is that the two build jobs can no longer share an artifact directly, since artifacts don't cross workflow-file boundaries. That's a real tradeoff, and it's exactly the gap a shared, reusable job definition exists to close.
Why a git hook can't do this job
It's tempting to reach for a pre-commit hook, something like Husky, to catch problems before they even reach a PR.
Hooks run on a machine you don't control. One developer has the hook installed and configured correctly. Another skipped the setup step, or just ran git commit --no-verify because they were in a hurry. Now two machines disagree about whether the same commit is valid, and neither of them is authoritative.
CI doesn't have that problem, because every job runs on the exact same fresh machine every time. If it says a change is broken, that's true for everyone, not true for whoever remembered to install the hook. A hook is a convenience for catching mistakes early on your own machine. It is never a substitute for a check nobody can skip.
The Essentials
- CI checks a change, CD ships it, and stage two gives them separate files.
ci.yamlonpull_request,deploy.yamlon push to main. - A git hook can't replace CI, because it runs on a machine you don't control. Someone always finds a way to skip it. CI can't be skipped the same way.
Further Reading and Watching
Keep reading