Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Prepare Release

on:
push:
tags:
- 'v*'

permissions:
contents: write
pull-requests: write

jobs:
call-prepare:
uses: leoweyr/github-release-workflow/.github/workflows/reusable-prepare-release.yml@develop
secrets:
ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14 changes: 14 additions & 0 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Publish Release

on:
pull_request:
types: [closed]

permissions:
contents: write

jobs:
call-publish:
uses: leoweyr/github-release-workflow/.github/workflows/reusable-publish-release.yml@develop
secrets:
ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
94 changes: 94 additions & 0 deletions .github/workflows/reusable-prepare-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
name: Prepare Release

on:
workflow_call:
inputs:
node-verions:
description: 'Node.js version to use.'
required: false
type: string
default: '20'
commit-user-name:
description: 'Git user name for commit'
required: false
type: string
default: 'github-actions[bot]'
commit-user-email:
description: 'Git user email for commit.'
required: false
type: string
default: 'github-actions[bot]@users.noreply.github.com'
secrets:
ACCESS_TOKEN:
required: true
description: 'GitHub Token for authentication.'

jobs:
prepare-release:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Checkout Config
uses: actions/checkout@v4
with:
repository: 'leoweyr/github-release-workflow'
path: .change-log-config
sparse-checkout: src/cliff.toml

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-verions }}

- name: Set Environment Variables
run: echo "TAG_NAME=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV

- name: Create Release Branch
run: |
git config --global user.name "${{ inputs.commit-user-name }}"
git config --global user.email "${{ inputs.commit-user-email }}"
git checkout -b release/${{ env.TAG_NAME }}

- name: Generate Changelog Content for PR Body
env:
GITHUB_REPO: ${{ github.repository }}
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: |
npx git-cliff --config .change-log-config/src/cliff.toml --verbose --latest --strip all > pr_body_raw.md

- name: Save PR Body to File
run: |
cat pr_body_raw.md | tail -n +2 > pr_body_cleaned.md

- name: Update CHANGELOG.md File
env:
GITHUB_REPO: ${{ github.repository }}
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: |
if [ -f "CHANGELOG.md" ]; then
# File exists: Prepend new changes (git-cliff intelligently handles headers).
npx git-cliff --config .change-log-config/src/cliff.toml --verbose --latest --prepend CHANGELOG.md
else
# File missing: Create new with full history and header.
npx git-cliff --config .change-log-config/src/cliff.toml --verbose --output CHANGELOG.md
fi

- name: Commit and Push
run: |
git add CHANGELOG.md
git commit -m "release: ${{ env.TAG_NAME }}"
git push origin release/${{ env.TAG_NAME }}

- name: Create Pull Request
env:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: |
gh pr create \
--title "release: ${{ env.TAG_NAME }}" \
--body-file pr_body_cleaned.md \
--base master \
--head release/${{ env.TAG_NAME }}
41 changes: 41 additions & 0 deletions .github/workflows/reusable-publish-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Publish Release

on:
workflow_call:
secrets:
ACCESS_TOKEN:
required: true

jobs:
publish-release:
if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.title, 'release:')
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Extract Tag Name
id: extract_tag
run: |
TITLE="${{ github.event.pull_request.title }}"
TAG_NAME=$(echo "$TITLE" | sed 's/release: //')
echo "TAG_NAME=$TAG_NAME" >> $GITHUB_ENV
VERSION_TITLE=${TAG_NAME#v}
echo "VERSION_TITLE=$VERSION_TITLE" >> $GITHUB_ENV

- name: Create Release Body File
env:
PR_BODY: ${{ github.event.pull_request.body }}
run: echo "$PR_BODY" > release_body.md

- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: |
gh release create ${{ env.TAG_NAME }} \
--title "${{ env.VERSION_TITLE }}" \
--notes-file release_body.md \
--verify-tag
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Changelog

All notable changes to this project will be documented in this file.

# [1.0.0] (2026-03-20)
### Bug Fixes

* move reusable workflows back to .github/workflows directory ([0b0676e](https://github.com/leoweyr/github-release-workflow/commit/0b0676e413f95b39d33c79d64ffc0259a3783206)) [@leoweyr](https://github.com/leoweyr)
* add missing reusable release workflows ([456d0c9](https://github.com/leoweyr/github-release-workflow/commit/456d0c9348aad3d41e1d4b61aca8f7cd50194261)) [@leoweyr](https://github.com/leoweyr)
* rename reserved GITHUB_TOKEN secret in reusable workflows ([8d2afaa](https://github.com/leoweyr/github-release-workflow/commit/8d2afaa30e97c3c735bfe39b1d822879d834d4de)) [@leoweyr](https://github.com/leoweyr)
* correct git-cliff config path to prevent fallback to default ([7aef3e8](https://github.com/leoweyr/github-release-workflow/commit/7aef3e84c53bacded51601db6dcab4b9e765634e)) [@leoweyr](https://github.com/leoweyr)


### Features

* add prepare release workflow ([4bec90f](https://github.com/leoweyr/github-release-workflow/commit/4bec90f7d44eda66efce0e48bec8079a5c98430c)) [@leoweyr](https://github.com/leoweyr)
* add publish release workflow ([20daca8](https://github.com/leoweyr/github-release-workflow/commit/20daca810acd33ee6071d7e5668fca95e203e797)) [@leoweyr](https://github.com/leoweyr)
* add user-facing workflows ([047bf99](https://github.com/leoweyr/github-release-workflow/commit/047bf996a00bb3fae423b17cb3d31a9392184b65)) [@leoweyr](https://github.com/leoweyr)
* add change log config ([4b667a0](https://github.com/leoweyr/github-release-workflow/commit/4b667a058ca7d14aa9960b7834262f5d7ee43a15)) [@leoweyr](https://github.com/leoweyr)


### Documentation

* update readme with usage instructions ([7e15921](https://github.com/leoweyr/github-release-workflow/commit/7e15921622d59b01fa1f571a707ca4ffad7d5a94)) [@leoweyr](https://github.com/leoweyr)
* **readme:** add banner ([e81214e](https://github.com/leoweyr/github-release-workflow/commit/e81214ea480b1bbd1c63ea78cb7c4c32af085513)) [@leoweyr](https://github.com/leoweyr)


### Miscellaneous Tasks

* move reusable workflows to src ([e48851c](https://github.com/leoweyr/github-release-workflow/commit/e48851ca6f5f92f075fae900cfc1332b7a507a20)) [@leoweyr](https://github.com/leoweyr)
* add icon ([04e730f](https://github.com/leoweyr/github-release-workflow/commit/04e730fc0a68c554c8b40f65ec949cdc4763ee73)) [@leoweyr](https://github.com/leoweyr)
* correct eye perspective in icon ([2ad0a73](https://github.com/leoweyr/github-release-workflow/commit/2ad0a7312fc8b75b7945679a71845ca68efbe43b)) [@leoweyr](https://github.com/leoweyr)



<!-- Generated by git-cliff. -->
39 changes: 37 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
# GitHub Release Workflow
![github-release-workflow](https://socialify.git.ci/leoweyr/github-release-workflow/image?description=1&font=KoHo&forks=1&issues=1&logo=https%3A%2F%2Fraw.githubusercontent.com%2Fleoweyr%2Fgithub-release-workflow%2Frefs%2Fheads%2Fdevelop%2Fassets%2Ficon.svg&name=1&owner=1&pattern=Formal+Invitation&pulls=1&stargazers=1&theme=Light)

Streamline your software delivery with a production-ready engineering workflow. Automated semantic versioning, changelog generation (via git-cliff), and GitHub release publishing.
> [!IMPORTANT]
> To ensure changelogs are generated correctly, all git commit messages must follow the **[Conventional Commits](https://www.conventionalcommits.org/)** specification.
>
> Also, you must go to your repository **Settings > Actions > General > Workflow permissions** and enable **"Allow GitHub Actions to create and approve pull requests"**, otherwise the automated release process will fail.

## 🚀 Instant Magic for Your Repository!!!

Add professional release automation to your personal project with a single step:

**Copy the `prepare-release.yml` and `publish-release.yml` files from `.github/workflows` into your project's `.github/workflows` directory.**

✨ That's it! Your repository is now enchanted.

## ⚙ How It Works

This workflow streamlines your release process into a few simple steps:

1. **Tag Your Release**: On your development branch (separate from `master` or `main`), create a git tag with a `v` prefix (e.g., `v1.0.0`).
```bash
git tag v1.0.0
```

2. **Push the Tag**: Push the tag to GitHub.
```bash
git push origin v1.0.0
```

3. **Automated Magic**: GitHub Actions will automatically:
* Generate a changelog based on your conventional commits.
* Create a specific release branch.
* Open a Pull Request to your default branch (e.g., `master`).

4. **Review and Merge**: Review the Pull Request created by the bot.
* **Do not modify the Pull Request title or body**, as they are used for the release metadata.
* Merge the Pull Request.
* The workflow will automatically create a GitHub Release for you.
89 changes: 89 additions & 0 deletions assets/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading