When you write uses: actions/checkout@v4 in a GitHub Actions workflow, you are not pinning anything. You are trusting a promise.
A tag is a movable pointer. Whoever owns that repository can repoint v4 at a different commit tomorrow, after you reviewed it, and every run of your pipeline will silently pull the new code. In a job that holds a registry login, a PyPI token, or a signing key, that is exactly the place you do not want a mutable reference.
I recently went through a project's workflows and pinned the remaining actions to commit SHAs. Here is what I actually learned doing it — beyond "just use the SHA".
A tag is a promise; a SHA is a fact
Compare these two lines:







