Skip to content

Merge branch 'main' of https://github.com/kirti/github-actions-node-p… #2

Merge branch 'main' of https://github.com/kirti/github-actions-node-p…

Merge branch 'main' of https://github.com/kirti/github-actions-node-p… #2

name: Release Automation
on:
push:
branches: [ main, master ]
paths-ignore:
- '**.md'
- '.github/workflows/**'
workflow_dispatch:
inputs:
release_type:
description: 'Release type (patch, minor, major)'
required: true
default: 'patch'
type: choice
options: [patch, minor, major]
permissions:
contents: write
pull-requests: write
jobs:
release:
runs-on: ubuntu-latest
# Only run if commit message signals a release
if: |
contains(github.event.head_commit.message, 'feat:') ||
contains(github.event.head_commit.message, 'fix:') ||
contains(github.event.head_commit.message, 'release:') ||
github.event_name == 'workflow_dispatch'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for changelog generation
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Install dependencies
run: npm ci
- name: Run tests before release
run: npm test -- --passWithNoTests --watchAll=false
- name: Build
run: npm run build
- name: Determine release type
id: release-type
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "type=${{ github.event.inputs.release_type }}" >> $GITHUB_OUTPUT
else
# Auto-detect from commit message
MSG="${{ github.event.head_commit.message }}"
if echo "$MSG" | grep -q "BREAKING CHANGE\|major:"; then
echo "type=major" >> $GITHUB_OUTPUT
elif echo "$MSG" | grep -q "feat:"; then
echo "type=minor" >> $GITHUB_OUTPUT
else
echo "type=patch" >> $GITHUB_OUTPUT
fi
fi
- name: Bump version
id: version
run: |
npm version ${{ steps.release-type.outputs.type }} --no-git-tag-version
NEW_VERSION=$(node -p "require('./package.json').version")
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "New version: $NEW_VERSION"
- name: Generate changelog
id: changelog
run: |
# Get commits since last tag
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -z "$LAST_TAG" ]; then
COMMITS=$(git log --pretty=format:"- %s (%h)" -20)
else
COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"- %s (%h)")
fi
# Categorize commits
FEATURES=$(echo "$COMMITS" | grep "^- feat:" || echo "")
FIXES=$(echo "$COMMITS" | grep "^- fix:" || echo "")
OTHER=$(echo "$COMMITS" | grep -v "^- feat:\|^- fix:" || echo "")
CHANGELOG="## What's Changed in v${{ steps.version.outputs.version }}"
if [ -n "$FEATURES" ]; then
CHANGELOG="$CHANGELOG\n\n### ✨ New Features\n$FEATURES"
fi
if [ -n "$FIXES" ]; then
CHANGELOG="$CHANGELOG\n\n### 🐛 Bug Fixes\n$FIXES"
fi
if [ -n "$OTHER" ]; then
CHANGELOG="$CHANGELOG\n\n### 🔧 Other Changes\n$OTHER"
fi
echo "changelog<<EOF" >> $GITHUB_OUTPUT
echo -e "$CHANGELOG" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Commit version bump
run: |
git add package.json package-lock.json
git commit -m "chore: release v${{ steps.version.outputs.version }} [skip ci]"
git tag "v${{ steps.version.outputs.version }}"
git push origin HEAD --tags
- name: Create GitHub Release
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: `v${{ steps.version.outputs.version }}`,
name: `v${{ steps.version.outputs.version }}`,
body: `${{ steps.changelog.outputs.changelog }}`,
draft: false,
prerelease: false
});
- name: Summary
run: |
echo "## 🚀 Released v${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "Type: ${{ steps.release-type.outputs.type }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "${{ steps.changelog.outputs.changelog }}" >> $GITHUB_STEP_SUMMARY