Build the mental model
A GitHub Release is not a separate Git concept — it's built directly on top of a tag. Every release points at exactly one tag, and that tag points at exactly one commit.
- A title
- Formatted release notes describing what changed
- Optional downloadable assets (binaries, zipped builds, checksums)
The relationship only goes one direction — you can have a tag with no release, but you cannot have a release with no tag; GitHub attaches or creates one at publish time.
| Concept | Where it lives |
|---|---|
| Tag | Plain Git object; works with git tag, git checkout, git describe — no GitHub account needed |
| Release | GitHub-specific page in the Releases tab; built from a tag, adds notes and assets |
Developers work with tags through plain git commands, no GitHub account required. End users read release notes and download assets through GitHub's interface, never touching git directly.
WHAT A RELEASE ADDS ON TOP OF A TAG
-----------------------------------
WHAT A RELEASE ADDS ON TOP OF A TAG
--------------------------------------
git tag v1.1.0 ---------------> one commit, pinned
|
| GitHub wraps the tag with:
v
+-------------------------------------+
| GitHub Release "v1.1.0" |
| - release notes / changelog |
| - downloadable assets (files) |
| - a page in the Releases tab |
+-------------------------------------+Connect it to a real scenario
Create and push the tag
`git tag -a v1.1.0 -m "Version 1.1.0"` then `git push origin v1.1.0` — GitHub now knows the commit it points to.
Draft the release on GitHub
Releases page > "Draft a new release" > pick the tag you just pushed.
Write or auto-generate notes
GitHub can auto-generate a changelog from commit messages and merged pull requests.
Attach assets
Drag build artifacts onto the release form to attach them.
Release creation is GitHub, not git
Tagging and pushing are plain git commands, but the release itself is only created through GitHub's web UI or the `gh` CLI.
Try the working example
# A local bare repo stands in for the GitHub-hosted remote, so the push
# below is genuinely real -- only the "create the Release from this tag on
# GitHub" step afterward has no terminal equivalent.
git init -q --bare ../remote-demo.git
git init -q -b main
git config user.name "Thuta Learner"
git config user.email "learner@example.com"
git remote add origin ../remote-demo.git
echo "console.log('v1.1');" > app.js
git add app.js
GIT_AUTHOR_DATE="2026-01-02T09:00:00" GIT_COMMITTER_DATE="2026-01-02T09:00:00" \
git commit -m "Ship v1.1 feature"
git push -u origin main
git tag -a v1.1.0 -m "Version 1.1.0"
git push origin v1.1.0$ git tag -a v1.1.0 -m "Version 1.1.0"
$ git push origin v1.1.0
To github.com:yourname/project.git
* [new tag] v1.1.0 -> v1.1.05-minute try-it
Push a tag to a repository you control on GitHub (or a practice repo), then open the Releases tab and draft a release from that tag. Add release notes, and if you want, attach a small text file as an asset. Notice that the tag existed the moment you pushed it, but the release only exists after you publish it from GitHub's interface.
One important caution
Pushing a tag does not automatically create a GitHub Release — you still have to draft and publish the release yourself from GitHub's interface or the `gh` CLI.
Deleting a release from GitHub's UI does not delete the underlying tag (and vice versa) — the two have to be cleaned up separately.
GitHub Docs: About releases — Git & GitHub