A CI/CD pipeline is a sequence of stages defined in a config file that lives in your repo, like .github/workflows/ci.yml for GitHub Actions or .gitlab-ci.yml for GitLab. When you push a commit or open a pull request, the platform spins up a fresh, isolated runner (a container or VM), checks out your code, and walks through the stages in order.
A typical stage order is: install dependencies, run linters, compile or build, run unit tests, build a container image, run integration tests against that image, then deploy. If any stage exits with a non-zero code, the pipeline stops and the commit is marked as failed. Nothing downstream runs.
Two ideas make this reliable. First, every run starts from a clean machine, so there is no leftover state from the last build (this is why a pipeline catches the classic it works on my machine bug). Second, the build produces an immutable artifact, usually a Docker image tagged with the commit SHA. The exact same artifact that passed tests in staging is the one promoted to production, so you never accidentally ship something that was never tested.