GitHub Releases

Publish versions of your project with GitHub Releases: tags, semantic version numbers, release notes, downloadable files and automation.

Lesson 16 of 30Advanced17 min read

When your project reaches a point worth sharing, a new feature set, an important fix or a first stable version, you release it. A release tells users: "this exact version is ready, here's what changed, and here's how to get it".

In Git, a version is marked with a tag, a permanent name such as v1.2.0 for one commit. GitHub Releases builds on tags by adding a page for each version, with a title, release notes written in Markdown, downloadable files and automatic source code archives. Users can subscribe to be notified of new releases, and other tools can check for the latest version.

In this lesson you'll learn how version numbers work, create a release on the website and from the terminal, generate release notes automatically from pull requests, attach files for download, and publish releases automatically with GitHub Actions.

Semantic versioning

Most projects number versions as MAJOR.MINOR.PATCH, a scheme called semantic versioning (SemVer):

PartIncrease it whenExample
MAJORYou make a change that breaks existing use1.4.2 to 2.0.0
MINORYou add features without breaking anything1.4.2 to 1.5.0
PATCHYou fix bugs only1.4.2 to 1.4.3

Versions below 1.0.0 signal that the project is still settling and anything may change. Labels such as 2.0.0-beta.1 mark pre-release versions for testing. The number itself tells users whether upgrading is likely to be safe.

Creating a release on GitHub

On the repository's main page, click Releases, then Draft a new release:

  1. Choose a tag: pick an existing tag or type a new one, such as v1.2.0, to create it on the chosen branch.
  2. Title: often the version, sometimes with a name: "v1.2.0: Dark mode".
  3. Notes: describe what changed, or click Generate release notes.
  4. Attach files: drag in downloads such as a zip of a built site or an installer.
  5. Tick Set as a pre-release for test versions, or Save draft to finish later, then Publish release.

GitHub automatically adds Source code (zip) and (tar.gz) archives of the tagged commit.

Release notes and changelogs

Good release notes are written for users, not developers. Group changes under headings such as New, Fixed and Breaking changes, and explain anything people must do to upgrade.

Generate release notes lists every pull request merged since the previous release, with its author and a link, and thanks new contributors. You can control the categories with a .github/release.yml file that maps labels like enhancement and bug to headings. Many projects also keep a CHANGELOG.md in the repository with the same information for every version.

Releases from the terminal and from Actions

GitHub CLI creates releases in one command:

Terminal
gh release create v1.2.0 --generate-notes

For full automation, a workflow can run whenever a tag starting with v is pushed: it builds the project, runs the tests and creates the release with the built files attached. Then releasing is just git tag and git push, and every release is built the same way.

GitHub Releases Syntax

Release commands

git tag -a v1.2.0 -m "Version 1.2.0"
git push origin v1.2.0
gh release create v1.2.0 --title "v1.2.0" --generate-notes
gh release create v1.2.0 dist/site.zip --notes-file NOTES.md
gh release create v2.0.0-beta.1 --prerelease
gh release list
gh release download v1.2.0

GitHub Releases Summary

  • A release is a GitHub page for a tagged version, with notes and downloadable files.
  • Semantic versioning: MAJOR for breaking changes, MINOR for features, PATCH for fixes.
  • Generate release notes lists merged pull requests and new contributors automatically.
  • Mark test versions as pre-releases; save drafts to finish later.
  • Use gh release create or an Actions workflow on tag pushes to automate releases.

GitHub Releases Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Creating a release with generated notes

Terminal
git tag -a v1.2.0 -m "Dark mode and faster search"
git push origin v1.2.0
gh release create v1.2.0 --title "v1.2.0: Dark mode" --generate-notes
Output
To https://github.com/samlee/recipe-box.git
 * [new tag]         v1.2.0 -> v1.2.0
https://github.com/samlee/recipe-box/releases/tag/v1.2.0
Line-by-line explanation
  1. Lines 1 to 2Create and push an annotated tag, as in the Git tags lesson.
  2. Line 3Create the release on that tag. GitHub prints the release page's address.
Example 2

Generated release notes

Markdown
## What's Changed
* Add dark mode toggle by @samlee in #41
* Speed up recipe search by @priya in #44
* Fix crash when basket is empty by @ben in #45

## New Contributors
* @ben made their first contribution in #45

**Full Changelog**: v1.1.0...v1.2.0
Output
The release page lists three merged pull requests with
links, welcomes Ben as a new contributor and links to a
comparison of every change between v1.1.0 and v1.2.0.
Line-by-line explanation
  1. Lines 2 to 4One line per merged pull request since the previous release.
  2. Lines 6 to 7First-time contributors are thanked automatically.
  3. Line 9A link comparing the two tags.
Example 3

Releasing automatically on a tag push

YAML
name: Release
on:
  push:
    tags: ["v*"]
permissions:
  contents: write
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - run: zip -r site.zip dist
      - run: gh release create ${{ github.ref_name }} site.zip --generate-notes
        env:
          GH_TOKEN: ${{ github.token }}
Output
Pushing tag v1.3.0 starts the workflow. A few minutes
later, release v1.3.0 appears with notes and site.zip
attached for download.
Line-by-line explanation
  1. Lines 3 to 4Run only when a tag starting with v is pushed.
  2. Lines 5 to 6Allow the workflow to create releases.
  3. Lines 12 to 13Build the project and package the output.
  4. Line 14github.ref_name is the tag's name, such as v1.3.0.

Common GitHub Releases Mistakes

Version numbers that don't mean anything

Don't
v1 -> v2 -> v2-final -> v2-final-really
Do
v1.0.0 -> v1.1.0 -> v1.1.1 -> v2.0.0

Release notes for developers only

Don't
Refactored useSearch hook, bumped deps, misc fixes
Do
New: search results appear as you type.
Fixed: the basket no longer shows NaN when empty.

Moving a published tag

Don't
git tag -f v1.2.0 && git push -f origin v1.2.0
Do
git tag -a v1.2.1 -m "Fix login redirect" && git push origin v1.2.1

GitHub Releases in Real Projects

Releases in practice

Tools such as VS Code, Node.js and countless libraries publish every version as a GitHub release, and package managers and update checkers read the "latest release" to tell users when to upgrade. Desktop and command-line apps attach installers for each operating system to their releases. Many teams release on a regular rhythm, such as every two weeks, with an Actions workflow doing all the work.

GitHub Releases FAQ

Does deleting a GitHub release delete its tag?

No. Deleting a release removes the release page, its notes and uploaded files, but the Git tag stays in the repository. Delete the tag separately with git push origin --delete v1.0.0 if you really want it gone.

How do I link to the latest release download?

Use https://github.com/OWNER/REPO/releases/latest/download/FILE-NAME. It always points at the file of that name in the most recent release, so the link in your README never needs updating. This only works if each release uses the same file name for that asset.

Do releases include the source code automatically?

Yes. GitHub adds Source code (zip) and Source code (tar.gz) downloads to every release, generated from the tagged commit. You only need to upload extra files such as compiled programs or installers.

Can I edit a release after publishing it?

Yes. Open the release and choose to edit it to change the title, notes or files, or to mark it as a pre-release. Avoid changing which commit the tag points at, because people may already have downloaded that version.

Do I need to create the tag before creating a release?

No. On the new release form you can type a tag name that doesn't exist yet and pick the branch or commit it should point at; GitHub creates the tag when you publish. If you already pushed the tag from your computer, just select it.

GitHub Releases Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Fill in the blankseasy

Complete the command that creates a release with automatically written notes.

gh release create v1.0.0 --
Predict the outputeasy

Version 2.3.4 gets a bug fix only. What's the next version?

Predict the outputmedium

Version 2.3.4 removes a function that people relied on. What's the next version?

Multiple choicemedium

What does a pre-release mean?

Multiple choicehard

What does on: push: tags: ["v*"] do in a workflow?

GitHub Releases Quiz

5 questions to check what you learned.

  1. What does every GitHub release point to?

    • A Git tag marking one commit
    • A branch
    • An issue
    • A fork
  2. Which change should increase the MINOR number?

    • A bug fix
    • A new feature that doesn't break existing use
    • A breaking change
    • A typo in the README
  3. What does GitHub add to every release automatically?

    • Source code archives in zip and tar.gz formats
    • An installer
    • A changelog file
    • A new branch
  4. Who should release notes mainly be written for?

    • The CI system
    • The people using the project
    • Only the maintainers
    • Search engines
  5. v1.2.0 was published with a bug. What's the right fix?

    • Delete v1.2.0 and recreate it on a new commit
    • Rename the release
    • Force push main
    • Fix the bug and publish v1.2.1