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
51 changes: 29 additions & 22 deletions .changeset/changelog.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ export default {
/** @type string[] */
const usersFromSummary = [];

// Parse summary to extract scope and description
const summary = changeset.summary;

// Remove PR, commit, author/user lines from summary
const replacedChangelog = changeset.summary
const replacedChangelog = summary
.replace(/^\s*(?:pr|pull|pull\s+request):\s*#?(\d+)/im, (_, pr) => {
const num = Number(pr);
if (!Number.isNaN(num)) {
Expand All @@ -49,6 +52,24 @@ export default {
})
.trim();

// Detect scope from **scope**: format
const scopeMatch = replacedChangelog.match(/^\*\*([^:]+)\*\*:?\s*(.*)$/);
const scope = scopeMatch ? scopeMatch[1] : null;
const description = scopeMatch ? scopeMatch[2] : replacedChangelog;

// Detect breaking changes (explicit BREAKING or major version) - for future use
const explicitBreaking =
/^BREAKING[:\s]/i.test(replacedChangelog) || /\bBREAKING CHANGE\b/i.test(replacedChangelog);
void explicitBreaking;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The explicitBreaking variable is computed and then immediately voided. If this is intentional placeholder code for future use, it should be removed to avoid dead code. If it's meant to be used, it never feeds into the formatted output.


// Build formatted entry
const entryParts = [];
if (scope) {
entryParts.push(`**${scope}**: ${description}`);
} else {
entryParts.push(description);
}

const links = await (async () => {
if (prFromSummary !== undefined) {
let { links } = await getInfoFromPullRequest({
Expand Down Expand Up @@ -81,27 +102,13 @@ export default {
};
})();

const users = usersFromSummary.length
? usersFromSummary
.map((userFromSummary) => `[@${userFromSummary}](https://github.com/${userFromSummary})`)
.join(', ')
: links.user;

const metadata = [
links.pull === null ? '' : ` (${links.pull})`,
links.commit === null ? '' : ` (${links.commit})`,
users === null ? '' : ` by ${users}`,
].join('');

// Split summary into first line and the rest
const [firstLine, ...rest] = replacedChangelog.split('\n');
const restSummary = rest.join('\n').trim();

// No code block conversion: preserve original triple backtick code blocks and indentation
let releaseLine = `\n- ${firstLine}${metadata}`;
if (restSummary) {
releaseLine += '\n\n' + restSummary;
// Add PR link at end
if (links.pull) {
entryParts.push(`(${links.pull})`);
} else if (prFromSummary !== undefined) {
entryParts.push(`([#${prFromSummary}](https://github.com/${repo}/pull/${prFromSummary}))`);
}
return releaseLine;

return `\n- ${entryParts.join(' ')}`;
},
};
2 changes: 1 addition & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
"access": "public",
"baseBranch": "main",
"changelog": "./changelog.js",
"changelog": ["./changelog.js", { "repo": "hey-api/openapi-ts" }],
"commit": false,
"fixed": [],
"ignore": [],
Expand Down
21 changes: 20 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,32 @@ jobs:
uses: changesets/action@v1.7.0
with:
commit: 'ci: release'
createGithubReleases: false
publish: pnpm changeset publish
title: 'ci: release'
version: pnpm changeset version
version: pnpm changeset version && pnpm changelog:assemble
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
NPM_CONFIG_PROVENANCE: true

- name: Generate Release Tag
id: tag
run: echo "tag=$(pnpm changelog:release:tag)" >> $GITHUB_OUTPUT
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tag step runs after the changesets publish step. At that point, changesets has already created and pushed package-scoped tags (e.g. @hey-api/openapi-ts@0.95.0). But generateReleaseTag() generates a date-based tag (e.g. 2026-04-06.1) that is never created via git tag or pushed — the workflow only uses it as a label for the GitHub Release. The softprops/action-gh-release action will attempt to create a release for a tag that doesn't exist on the remote, which may fail or auto-create a tag at HEAD (not necessarily the release commit).


- name: Generate Release Notes
id: notes
run: pnpm changelog:release:notes > release-notes.md

- name: Create GitHub Release
uses: softprops/action-gh-release@v2.6.1
with:
body_path: release-notes.md
generate_release_notes: false
name: Release ${{ steps.tag.outputs.tag }}
tag_name: ${{ steps.tag.outputs.tag }}
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}

- name: Get current branch
run: echo "CURRENT_BRANCH=$(git branch --show-current)" >> $GITHUB_ENV

Expand Down
Loading
Loading