Skip to content
Merged
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
41 changes: 24 additions & 17 deletions scripts/create-github-release.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@ import { tmpdir } from 'node:os'
const rootDir = path.join(import.meta.dirname, '..')
const ghToken = process.env.GH_TOKEN || process.env.GITHUB_TOKEN

// Get the previous release commit to diff against
const lastReleaseHash = execSync(
'git log --oneline --grep="ci: changeset release" -n 1 --format=%H HEAD~1',
// Get the previous release commit to diff against.
// This script runs right after the "ci: changeset release" commit is pushed,
// so HEAD is the release commit. We want commits between the previous release
// and this one (exclusive of both release commits).
const releaseLogs = execSync(
'git log --oneline --grep="ci: changeset release" --format=%H',
)
.toString()
.trim()
.split('\n')
.filter(Boolean)

const rangeFrom = lastReleaseHash || 'HEAD~1'
// Current release commit is releaseLogs[0] (HEAD), previous is releaseLogs[1]
const currentRelease = releaseLogs[0] || 'HEAD'
const previousRelease = releaseLogs[1]
const rangeFrom = previousRelease || `${currentRelease}~1`

// Get commits since last release (include author email for username lookup)
// Get commits between previous release and current release (exclude both)
const rawLog = execSync(
`git log ${rangeFrom}..HEAD~1 --pretty=format:"%h %ae %s" --no-merges`,
`git log ${rangeFrom}..${currentRelease} --pretty=format:"%h %ae %s" --no-merges`,
)
.toString()
.trim()
Expand Down Expand Up @@ -49,26 +57,24 @@ async function resolveUsername(email) {
}
}

// Group commits by type
// Group commits by conventional commit type
const groups = {}
for (const line of commits) {
// Format: "<hash> <email> <type>(<scope>): <subject>" or "<hash> <email> <type>: <subject>"
const match = line.match(/^(\w+)\s+(\S+)\s+(\w+)(?:\(([^)]+)\))?:\s*(.+)$/)
if (match) {
const [, hash, email, type, scope, subject] = match
const key = type.charAt(0).toUpperCase() + type.slice(1)
if (!groups[key]) groups[key] = []
groups[key].push({ hash, email, scope, subject })
} else {
// Non-conventional commits (merge commits, etc.) go to Other
if (!groups['Other']) groups['Other'] = []
const spaceIdx = line.indexOf(' ')
const rest = line.slice(spaceIdx + 1)
const spaceIdx2 = rest.indexOf(' ')
groups['Other'].push({
hash: line.slice(0, spaceIdx),
email: rest.slice(0, spaceIdx2),
scope: null,
subject: rest.slice(spaceIdx2 + 1),
})
const parts = line.split(' ')
const hash = parts[0]
const email = parts[1]
const subject = parts.slice(2).join(' ')
groups['Other'].push({ hash, email, scope: null, subject })
}
}

Expand Down Expand Up @@ -150,12 +156,13 @@ if (!tagExists) {
}

const prereleaseFlag = isPrerelease ? '--prerelease' : ''
const latestFlag = isPrerelease ? '' : ' --latest'
const tmpFile = path.join(tmpdir(), `release-notes-${tagName}.md`)
fs.writeFileSync(tmpFile, body)

try {
execSync(
`gh release create ${tagName} ${prereleaseFlag} --title "Release ${titleDate}" --notes-file ${tmpFile} --latest`,
`gh release create ${tagName} ${prereleaseFlag} --title "Release ${titleDate}" --notes-file ${tmpFile}${latestFlag}`,
{ stdio: 'inherit' },
)
console.info(`GitHub release ${tagName} created.`)
Expand Down
Loading