All skills
wshobson avatar

/changelog-automation

@be57c0b
by Seth Hobsonwshobson/agents40k stars
4,281

Automate changelog generation from commits, PRs, and releases following Keep a Changelog format. Use when setting up release workflows, generating release notes, or standardizing commit conventions.

Use this Skill: https://skilld.dev/gh/wshobson/agents/changelog-automation

This session only. Nothing lands on disk.

referencesdetails.md

≈2.7k tokens on demand. Your agent reads this file only when SKILL.md points to it.

changelog-automation — detailed patterns and worked examples

Unreleased

Added

  • New feature X

1.2.0 - 2024-01-15

Added

  • User profile avatars
  • Dark mode support

Changed

  • Improved loading performance by 40%

Deprecated

  • Old authentication API (use v2)

Removed

  • Legacy payment gateway

Fixed

  • Login timeout issue (#123)

Security

  • Updated dependencies for CVE-2024-1234

### 2. Conventional Commits

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]


| Type       | Description      | Changelog Section  |
| ---------- | ---------------- | ------------------ |
| `feat`     | New feature      | Added              |
| `fix`      | Bug fix          | Fixed              |
| `docs`     | Documentation    | (usually excluded) |
| `style`    | Formatting       | (usually excluded) |
| `refactor` | Code restructure | Changed            |
| `perf`     | Performance      | Changed            |
| `test`     | Tests            | (usually excluded) |
| `chore`    | Maintenance      | (usually excluded) |
| `ci`       | CI changes       | (usually excluded) |
| `build`    | Build system     | (usually excluded) |
| `revert`   | Revert commit    | Removed            |

### 3. Semantic Versioning

MAJOR.MINOR.PATCH

MAJOR: Breaking changes (feat! or BREAKING CHANGE) MINOR: New features (feat) PATCH: Bug fixes (fix)


## Implementation

### Method 1: Conventional Changelog (Node.js)

```bash
# Install tools
npm install -D @commitlint/cli @commitlint/config-conventional
npm install -D husky
npm install -D standard-version
# or
npm install -D semantic-release

# Setup commitlint
cat > commitlint.config.js << 'EOF'
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [
      2,
      'always',
      [
        'feat',
        'fix',
        'docs',
        'style',
        'refactor',
        'perf',
        'test',
        'chore',
        'ci',
        'build',
        'revert',
      ],
    ],
    'subject-case': [2, 'never', ['start-case', 'pascal-case', 'upper-case']],
    'subject-max-length': [2, 'always', 72],
  },
};
EOF

# Setup husky
npx husky init
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg

Method 2: standard-version Configuration

// .versionrc.js
module.exports = {
  types: [
    { type: "feat", section: "Features" },
    { type: "fix", section: "Bug Fixes" },
    { type: "perf", section: "Performance Improvements" },
    { type: "revert", section: "Reverts" },
    { type: "docs", section: "Documentation", hidden: true },
    { type: "style", section: "Styles", hidden: true },
    { type: "chore", section: "Miscellaneous", hidden: true },
    { type: "refactor", section: "Code Refactoring", hidden: true },
    { type: "test", section: "Tests", hidden: true },
    { type: "build", section: "Build System", hidden: true },
    { type: "ci", section: "CI/CD", hidden: true },
  ],
  commitUrlFormat: "{{host}}/{{owner}}/{{repository}}/commit/{{hash}}",
  compareUrlFormat:
    "{{host}}/{{owner}}/{{repository}}/compare/{{previousTag}}...{{currentTag}}",
  issueUrlFormat: "{{host}}/{{owner}}/{{repository}}/issues/{{id}}",
  userUrlFormat: "{{host}}/{{user}}",
  releaseCommitMessageFormat: "chore(release): {{currentTag}}",
  scripts: {
    prebump: 'echo "Running prebump"',
    postbump: 'echo "Running postbump"',
    prechangelog: 'echo "Running prechangelog"',
    postchangelog: 'echo "Running postchangelog"',
  },
};
// package.json scripts
{
  "scripts": {
    "release": "standard-version",
    "release:minor": "standard-version --release-as minor",
    "release:major": "standard-version --release-as major",
    "release:patch": "standard-version --release-as patch",
    "release:dry": "standard-version --dry-run"
  }
}

Method 3: semantic-release (Full Automation)

// release.config.js
module.exports = {
  branches: [
    "main",
    { name: "beta", prerelease: true },
    { name: "alpha", prerelease: true },
  ],
  plugins: [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    [
      "@semantic-release/changelog",
      {
        changelogFile: "CHANGELOG.md",
      },
    ],
    [
      "@semantic-release/npm",
      {
        npmPublish: true,
      },
    ],
    [
      "@semantic-release/github",
      {
        assets: ["dist/**/*.js", "dist/**/*.css"],
      },
    ],
    [
      "@semantic-release/git",
      {
        assets: ["CHANGELOG.md", "package.json"],
        message:
          "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}",
      },
    ],
  ],
};

Method 4: GitHub Actions Workflow

# .github/workflows/release.yml
name: Release

on:
  push:
    branches: [main]
  workflow_dispatch:
    inputs:
      release_type:
        description: "Release type"
        required: true
        default: "patch"
        type: choice
        options:
          - patch
          - minor
          - major

permissions:
  contents: write
  pull-requests: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ secrets.GITHUB_TOKEN }}

      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - run: npm ci

      - name: Configure Git
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

      - name: Run semantic-release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: npx semantic-release

  # Alternative: manual release with standard-version
  manual-release:
    if: github.event_name == 'workflow_dispatch'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-node@v4
        with:
          node-version: "20"

      - run: npm ci

      - name: Configure Git
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

      - name: Bump version and generate changelog
        run: npx standard-version --release-as ${{ inputs.release_type }}

      - name: Push changes
        run: git push --follow-tags origin main

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v1
        with:
          tag_name: ${{ steps.version.outputs.tag }}
          body_path: RELEASE_NOTES.md
          generate_release_notes: true

Method 5: git-cliff (Rust-based, Fast)

# cliff.toml
[changelog]
header = """
# Changelog

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

"""
body = """
{% if version %}\
    ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
    ## [Unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
    ### {{ group | upper_first }}
    {% for commit in commits %}
        - {% if commit.scope %}**{{ commit.scope }}:** {% endif %}\
            {{ commit.message | upper_first }}\
            {% if commit.github.pr_number %} ([#{{ commit.github.pr_number }}](https://github.com/owner/repo/pull/{{ commit.github.pr_number }})){% endif %}\
    {% endfor %}
{% endfor %}
"""
footer = """
{% for release in releases -%}
    {% if release.version -%}
        {% if release.previous.version -%}
            [{{ release.version | trim_start_matches(pat="v") }}]: \
                https://github.com/owner/repo/compare/{{ release.previous.version }}...{{ release.version }}
        {% endif -%}
    {% else -%}
        [unreleased]: https://github.com/owner/repo/compare/{{ release.previous.version }}...HEAD
    {% endif -%}
{% endfor %}
"""
trim = true

[git]
conventional_commits = true
filter_unconventional = true
split_commits = false
commit_parsers = [
    { message = "^feat", group = "Features" },
    { message = "^fix", group = "Bug Fixes" },
    { message = "^doc", group = "Documentation" },
    { message = "^perf", group = "Performance" },
    { message = "^refactor", group = "Refactoring" },
    { message = "^style", group = "Styling" },
    { message = "^test", group = "Testing" },
    { message = "^chore\\(release\\)", skip = true },
    { message = "^chore", group = "Miscellaneous" },
]
filter_commits = false
tag_pattern = "v[0-9]*"
skip_tags = ""
ignore_tags = ""
topo_order = false
sort_commits = "oldest"

[github]
owner = "owner"
repo = "repo"
# Generate changelog
git cliff -o CHANGELOG.md

# Generate for specific range
git cliff v1.0.0..v2.0.0 -o RELEASE_NOTES.md

# Preview without writing
git cliff --unreleased --dry-run

Method 6: Python (commitizen)

# pyproject.toml
[tool.commitizen]
name = "cz_conventional_commits"
version = "1.0.0"
version_files = [
    "pyproject.toml:version",
    "src/__init__.py:__version__",
]
tag_format = "v$version"
update_changelog_on_bump = true
changelog_incremental = true
changelog_start_rev = "v0.1.0"

[tool.commitizen.customize]
message_template = "{{change_type}}{% if scope %}({{scope}}){% endif %}: {{message}}"
schema = "<type>(<scope>): <subject>"
schema_pattern = "^(feat|fix|docs|style|refactor|perf|test|chore)(\\(\\w+\\))?:\\s.*"
bump_pattern = "^(feat|fix|perf|refactor)"
bump_map = {"feat" = "MINOR", "fix" = "PATCH", "perf" = "PATCH", "refactor" = "PATCH"}
# Install
pip install commitizen

# Create commit interactively
cz commit

# Bump version and update changelog
cz bump --changelog

# Check commits
cz check --rev-range HEAD~5..HEAD

Release Notes Templates

GitHub Release Template

## What's Changed

### 🚀 Features

{{ range .Features }}

- {{ .Title }} by @{{ .Author }} in #{{ .PR }}
  {{ end }}

### 🐛 Bug Fixes

{{ range .Fixes }}

- {{ .Title }} by @{{ .Author }} in #{{ .PR }}
  {{ end }}

### 📚 Documentation

{{ range .Docs }}

- {{ .Title }} by @{{ .Author }} in #{{ .PR }}
  {{ end }}

### 🔧 Maintenance

{{ range .Chores }}

- {{ .Title }} by @{{ .Author }} in #{{ .PR }}
  {{ end }}

## New Contributors

{{ range .NewContributors }}

- @{{ .Username }} made their first contribution in #{{ .PR }}
  {{ end }}

**Full Changelog**: https://github.com/owner/repo/compare/v{{ .Previous }}...v{{ .Current }}

Internal Release Notes

# Release v2.1.0 - January 15, 2024

Source: SKILL.md on GitHub

No alerts16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    No security risks were detected. The skill provides standard documentation, templates, and configurations for automating software changelogs and release notes using well-known ecosystem tools.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    1/1 file flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at be57c0b. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 days ago.

Activeupdated 4 months ago
  • Git/VCS
  • changelog
  • conventional-commits
  • release-notes
  • semantic-versioning
  • keep-a-changelog
  • release-automation
  • version-management

README badge

README badge for wshobson/agents/changelog-automation

Automates changelog generation from git commits and releases following Keep a Changelog format and Conventional Commits conventions. Use this skill to implement standardized release workflows, generate release notes from commit history, and manage semantic versioning across projects.

Generated from the current SKILL.md.

Does this skill support Conventional Commits?
Yes. The skill is built around Conventional Commits format, using commit message patterns like `feat:`, `fix:`, and `!` for breaking changes to enable automated changelog generation.
What changelog format does this skill target?
Keep a Changelog format, which organizes changes by version with sections for features, bug fixes, breaking changes, and known issues.
Can this integrate with GitHub or GitLab releases?
Yes. The skill covers generating GitHub/GitLab release notes as part of the release workflow automation.
Does this handle semantic versioning?
The skill addresses semantic versioning as part of version management, using commit types (feat, fix, breaking change) to determine version bumps.
What tools or CI systems does this skill require?
The skill documents patterns and best practices but does not specify particular tools. It assumes commitlint for validation and mentions implementing workflows in CI pipelines.

Generated from the current SKILL.md. These answers refresh after source changes.