Skip to content
Draft
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
158 changes: 158 additions & 0 deletions .github/semantic-release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# Semantic Release Configuration

This repository uses a custom semantic release configuration to provide enhanced changelog generation and GitHub interaction.

## Features

### πŸ“– Enhanced Changelog

The changelog automatically categorizes commits with emojis and includes contributor information:

- ✨ **Features** - New functionality (`feat` commits)
- 🩹 **Fixes** - Bug fixes (`fix` commits)
- πŸ“š **Documentation** - Documentation updates (`docs` commits)
- πŸ› οΈ **Internals** - Internal changes (`refactor`, `style`, `test`, `build`, `ci`, `chore` commits)
- ⚑ **Performance** - Performance improvements (`perf` commits)
- ↩️ **Reverts** - Reverted changes (`revert` commits)
- ⚠️ **BREAKING CHANGES** - Breaking changes (commits with `BREAKING CHANGE` footer)

Each commit entry includes:

- Scope (if provided)
- Commit message with linked issues and usernames
- Commit hash link
- Author attribution (@username)

### πŸ’¬ Custom GitHub Comments

#### Issue Comments

**For Pre-releases:**

```
πŸŽ‰ This issue is included in version X.X.X-next.X which is now available for testing! πŸ§ͺ

πŸ“¦ NPM: [email protected]
πŸ“– GitHub Release: X.X.X-next.X

@username Can you check if everything works as expected in your project with this new version? Any feedback is welcome.

<small>This change will be included in the next regular release.</small>
```

**For Regular Releases:**

```
πŸŽ‰ This issue is included in version X.X.X which is now available! πŸš€

πŸ“¦ NPM: [email protected]
πŸ“– GitHub Release: X.X.X
```

#### Pull Request Comments

**For Pre-releases:**

```
πŸŽ‰ This PR is included in version X.X.X-next.X which is now available for testing! πŸ§ͺ

πŸ“¦ NPM: [email protected]
πŸ“– GitHub Release: X.X.X-next.X

@username Thank you for your contribution!

<small>This change will be included in the next regular release.</small>
```

**For Regular Releases:**

```
πŸŽ‰ This PR is included in version X.X.X which is now available! πŸš€

πŸ“¦ NPM: [email protected]
πŸ“– GitHub Release: X.X.X

Thank you for your contribution!
```

### πŸ“š Documentation

Added comprehensive documentation in `.github/semantic-release.md` explaining:

- How the new changelog categories work
- Examples of issue and PR comment templates
- Configuration file structure
- Commit types and their release impact

### πŸ’» Example Changelog Entry

Here's an example of how a changelog entry would look for a release like [PR #48](https://github.com/pawcoding/astro-loader-pocketbase/pull/48):

```markdown
## 2.7.1 (2025-08-10)

### 🩹 Fixes

- Cleanup entries correctly when using `idField` configuration option ([a1b2c3d](https://github.com/pawcoding/astro-loader-pocketbase/commit/a1b2c3d)) by @pawcoding

### πŸ› οΈ Internals

- Replace `eslint` with `oxlint` to make linting tasks even faster ([d4e5f6g](https://github.com/pawcoding/astro-loader-pocketbase/commit/d4e5f6g)) by @pawcoding
- Setup for Copilot and other agents ([h7i8j9k](https://github.com/pawcoding/astro-loader-pocketbase/commit/h7i8j9k)) by @pawcoding
- Add GitHub issue templates for better bug reporting and feature requests ([l0m1n2o](https://github.com/pawcoding/astro-loader-pocketbase/commit/l0m1n2o)) by @pawcoding
- Update dependencies to latest versions ([p3q4r5s](https://github.com/pawcoding/astro-loader-pocketbase/commit/p3q4r5s)) by @pawcoding

[2.7.1](https://github.com/pawcoding/astro-loader-pocketbase/compare/2.7.0...2.7.1) (5 commits)
```

## Configuration Files

### `release.config.cjs`

Main configuration file that sets up:

- Commit analysis rules
- Release notes generation with custom templates
- Changelog generation
- NPM publishing
- Git asset updates
- GitHub releases and comments

### `.semantic-release/templates/`

Custom Handlebars templates for changelog generation:

- `template.hbs` - Main changelog template with emoji categories
- `header.hbs` - Release header format
- `commit.hbs` - Individual commit entry format with contributor attribution
- `footer.hbs` - Release footer with links and commit count

## Release Branches

- **`master`** - Stable releases (latest)
- **`next`** - Pre-releases for testing (next channel)

## Commit Types and Release Impact

| Type | Description | Release | Changelog Section |
| ---------- | ---------------------------- | ------- | ----------------- |
| `feat` | New feature | Minor | ✨ Features |
| `fix` | Bug fix | Patch | 🩹 Fixes |
| `docs` | Documentation (README scope) | Patch | πŸ“š Documentation |
| `docs` | Other documentation | None | πŸ“š Documentation |
| `refactor` | Code refactoring | Patch | πŸ› οΈ Internals |
| `style` | Code style changes | Patch | πŸ› οΈ Internals |
| `test` | Adding/updating tests | None | πŸ› οΈ Internals |
| `build` | Build system (deps scope) | Patch | πŸ› οΈ Internals |
| `build` | Other build changes | None | πŸ› οΈ Internals |
| `ci` | CI configuration | None | πŸ› οΈ Internals |
| `chore` | Maintenance tasks | None | πŸ› οΈ Internals |
| `perf` | Performance improvements | Patch | ⚑ Performance |

## Breaking Changes

Commits with `BREAKING CHANGE` or `BREAKING CHANGES` in the footer will:

- Trigger a major release
- Be listed in a special "⚠️ BREAKING CHANGES" section
- Include migration information from the commit footer
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ pnpm-debug.log*
.prettierignore
.gitignore
.nvmrc

# semantic-release templates (handlebars)
.semantic-release/templates/
24 changes: 24 additions & 0 deletions .semantic-release/templates/commit.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
*
{{#if commit.scope}}**{{commit.scope}}:** {{/if}}{{#if
commit.subject
}}{{commit.subject}}{{else}}{{commit.header}}{{/if}}

{{~! commit link }}
{{#if @root.linkReferences~}}
([{{hash}}]({{@root.repository}}/{{@root.commit}}/{{hash}}))
{{~else}}
{{~#if @root.repository}}
([{{hash}}]({{@root.repository}}/{{@root.commit}}/{{hash}}))
{{~/if}}
{{~/if}}

{{~! commit references }}
{{~#if references~}}
{{~#each references}}
{{#if
@root.linkReferences
}}([{{this.issue}}]({{@root.repository}}/{{@root.issue}}/{{this.issue}})){{else}}{{this.issue}}{{/if}}{{/each}}
{{~/if}}

{{~! commit author }}
{{~#if commit.author.name}} by @{{commit.author.name}}{{/if}}
35 changes: 35 additions & 0 deletions .semantic-release/templates/footer.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{{#if host}}
{{~! release link }}
{{~#if linkCompare}}
{{~#if previousTag}}
{{~#if currentTag}}
[{{currentTag}}]({{host}}/{{owner}}/{{repository}}/{{compareUrlFormat}}/{{previousTag}}...{{currentTag}})
{{~else}}
{{~currentTag}}
{{~/if}}
{{~else}}
{{~#if currentTag}}
{{~currentTag}}
{{~/if}}
{{~/if}}
{{~else}}
{{~#if currentTag}}
{{~currentTag}}
{{~/if}}
{{~/if}}

{{~! commit range }}
{{~#if commitsUrl}}
{{~#if previousTag}}
([{{shortHash}}.{{previousTag}}]({{host}}/{{owner}}/{{repository}}/{{commitsUrlFormat}}/{{previousTag}}..{{currentTag}}))
{{~else}}
([{{shortHash}}]({{host}}/{{owner}}/{{repository}}/{{commitsUrlFormat}}/{{currentTag}}))
{{~/if}}
{{~/if}}

{{~! commit count }}
{{~#if (gt commits.length 0)}}
({{commits.length}}
commit{{#unless (eq commits.length 1)}}s{{/unless}})
{{~/if}}
{{~/if}}
4 changes: 4 additions & 0 deletions .semantic-release/templates/header.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{{#if version~}}
##
{{#if title}}{{title}}{{else}}{{version}}{{/if}}{{#if date}} ({{date}}){{/if}}
{{~/if}}
40 changes: 40 additions & 0 deletions .semantic-release/templates/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{{> header}}

{{#each commitGroups}}

{{#if title}}
{{#if (eq title 'Features')}}
### ✨ Features
{{else if (eq title 'Bug Fixes')}}
### 🩹 Fixes
{{else if (eq title 'Documentation')}}
### πŸ“š Documentation
{{else if (eq title 'Internals')}}
### πŸ› οΈ Internals
{{else if (eq title 'Performance Improvements')}}
### ⚑ Performance
{{else if (eq title 'Reverts')}}
### ↩️ Reverts
{{else}}
### {{title}}
{{/if}}

{{/if}}
{{#each commits}}
{{> commit root=@root}}
{{/each}}

{{/each}}

{{#if noteGroups}}
{{#each noteGroups}}

### ⚠️ BREAKING CHANGES

{{#each notes}}
* {{#if commit.scope}}**{{commit.scope}}:** {{/if}}{{text}}
{{/each}}
{{/each}}

{{/if}}
{{> footer}}
78 changes: 78 additions & 0 deletions .semantic-release/utils/transform-commit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Transform function for semantic-release commit processing
* Categorizes commits and processes issue/PR links
*/
function transformCommit(commit, context) {
const issues = [];

commit.notes.forEach((note) => {
note.title = "BREAKING CHANGES";
});

// Group different commit types under appropriate categories
if (commit.type === "feat") {
commit.type = "Features";
} else if (commit.type === "fix") {
commit.type = "Bug Fixes";
} else if (commit.type === "docs") {
commit.type = "Documentation";
} else if (
["style", "refactor", "test", "build", "ci", "chore"].includes(commit.type)
) {
commit.type = "Internals";
} else if (commit.type === "perf") {
commit.type = "Performance Improvements";
} else if (commit.revert) {
commit.type = "Reverts";
} else {
return;
}

if (commit.scope === "*") {
commit.scope = "";
}

if (typeof commit.hash === "string") {
commit.shortHash = commit.hash.substring(0, 7);
}

if (typeof commit.subject === "string") {
let url = context.repository
? `${context.host}/${context.owner}/${context.repository}`
: context.repoUrl;
if (url) {
url = `${url}/issues/`;
// Issue URLs.
commit.subject = commit.subject.replace(/#([0-9]+)/g, (_, issue) => {
issues.push(issue);
return `[#${issue}](${url}${issue})`;
});
}
if (context.host) {
// User URLs.
commit.subject = commit.subject.replace(
/\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g,
(_, username) => {
if (username.includes("/")) {
return `@${username}`;
}

return `[@${username}](${context.host}/${username})`;
}
);
}
}

// remove references that already appear in the subject
commit.references = commit.references.filter((reference) => {
if (issues.indexOf(reference.issue) === -1) {
return true;
}

return false;
});

return commit;
}

module.exports = { transformCommit };
Loading