build: fixed tl versioning + changelog generation
This commit is contained in:
parent
f525c12f83
commit
ec1154fdef
6 changed files with 122 additions and 23 deletions
8
.github/workflows/release.yaml
vendored
8
.github/workflows/release.yaml
vendored
|
@ -48,6 +48,9 @@ jobs:
|
|||
- name: Find packages to publish
|
||||
id: find
|
||||
run: node scripts/find-updated-packages.js ${{ inputs.kind }} ${{ inputs.packages }}
|
||||
- name: Generate changelog
|
||||
id: changelog
|
||||
run: node scripts/generate-changelog.js ${{ steps.find.outputs.modified }}
|
||||
- name: Bump versions
|
||||
id: bump
|
||||
run: node scripts/bump-version.js ${{ inputs.kind }} ${{ steps.find.outputs.modified }}
|
||||
|
@ -55,7 +58,7 @@ jobs:
|
|||
run: |
|
||||
git commit -am "v${{ steps.bump.outputs.version }}"
|
||||
git push
|
||||
- name: Build pacakges and publish to NPM
|
||||
- name: Build packages and publish to NPM
|
||||
id: build
|
||||
env:
|
||||
GH_RELEASE: 1
|
||||
|
@ -66,6 +69,7 @@ jobs:
|
|||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: v${{ steps.bump.outputs.version }}
|
||||
name: v${{ steps.bump.outputs.version }}
|
||||
artifacts: ${{ steps.build.outputs.tarballs }}}
|
||||
artifacts: ${{ steps.build.outputs.tarballs }}
|
||||
body: ${{ steps.changelog.outputs.changelog }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@mtcute/tl",
|
||||
"version": "0.1.0",
|
||||
"version": "166.0.0",
|
||||
"description": "TL schema used for mtcute",
|
||||
"main": "index.js",
|
||||
"author": "Alina Sireneva <alina@tei.su>",
|
||||
|
|
|
@ -29,6 +29,7 @@ function bumpVersions(packages, kind) {
|
|||
console.log('[i] Bumping versions to %s', nextVersion)
|
||||
|
||||
for (const pkg of packages) {
|
||||
if (pkg === 'tl') continue // own versioning
|
||||
const pkgJson = pkgJsons.find((it) => it.name === `@mtcute/${pkg}`)
|
||||
|
||||
if (!pkgJson) {
|
||||
|
|
|
@ -2,25 +2,7 @@ const cp = require('child_process')
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const { listPackages } = require('./publish')
|
||||
|
||||
function getLatestTag() {
|
||||
try {
|
||||
const res = cp.execSync('git describe --abbrev=0 --tags', { encoding: 'utf8', stdio: 'pipe' }).trim()
|
||||
|
||||
return res
|
||||
} catch (e) {
|
||||
if (e.stderr.match(/^fatal: (No names found|No tags can describe)/i)) {
|
||||
// no tags found, let's just return the first commit
|
||||
return cp.execSync('git rev-list --max-parents=0 HEAD', { encoding: 'utf8' }).trim()
|
||||
}
|
||||
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
function findChangedFilesSince(tag, until = 'HEAD') {
|
||||
return cp.execSync(`git diff --name-only ${tag} ${until}`, { encoding: 'utf8', stdio: 'pipe' }).trim().split('\n')
|
||||
}
|
||||
const { getLatestTag, findChangedFilesSince } = require('./git-utils')
|
||||
|
||||
getTsconfigFiles.cache = {}
|
||||
|
||||
|
@ -46,9 +28,11 @@ function isMeaningfulChange(pkg, path) {
|
|||
if (getTsconfigFiles(pkg).indexOf(path) > -1) return true
|
||||
|
||||
// some magic heuristics stuff
|
||||
if (path.match(/\.md$/i)) return false
|
||||
if (path.match(/\.(md|\.test\.ts)$/i)) return false
|
||||
if (path.match(/^\/(scripts|dist|tests|private)/i)) return false
|
||||
|
||||
console.log('[i] %s: %s is a meaningful change', pkg, path)
|
||||
|
||||
// to be safe
|
||||
return true
|
||||
}
|
||||
|
|
60
scripts/generate-changelog.js
Normal file
60
scripts/generate-changelog.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
const fs = require('fs')
|
||||
const { getLatestTag, getCommitsSince, parseConventionalCommit, findChangedFilesSince } = require('./git-utils')
|
||||
|
||||
function generateChangelog(onlyPackages) {
|
||||
const byPackage = {}
|
||||
|
||||
for (const commit of getCommitsSince(getLatestTag())) {
|
||||
const parsed = parseConventionalCommit(commit.msg)
|
||||
|
||||
if (!parsed) {
|
||||
console.warn('[warn] Failed to parse commit message: %s', commit.msg)
|
||||
continue
|
||||
}
|
||||
|
||||
const { type, breaking } = parsed
|
||||
|
||||
if (!type || ['chore', 'ci', 'docs', 'test'].includes(type)) continue
|
||||
|
||||
const changed = findChangedFilesSince(`${commit.hash}~1`, commit.hash)
|
||||
|
||||
const line = `- ${commit.hash}: ${breaking ? '**❗ BREAKING** ' : ''}${commit.msg}`
|
||||
|
||||
for (const file of changed) {
|
||||
if (!file.startsWith('packages/')) continue
|
||||
const pkg = file.split('/')[1]
|
||||
if (onlyPackages && !onlyPackages.includes(pkg)) continue
|
||||
|
||||
if (!byPackage[pkg]) byPackage[pkg] = {}
|
||||
byPackage[pkg][commit.hash] = line
|
||||
// console.log('including %s in %s because of %s', commit.hash, pkg, file)
|
||||
}
|
||||
}
|
||||
|
||||
let ret = ''
|
||||
|
||||
for (const [pkg, lines] of Object.entries(byPackage)) {
|
||||
ret += `### ${pkg}\n`
|
||||
ret += Object.values(lines).join('\n')
|
||||
ret += '\n\n'
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
let onlyPackages = null
|
||||
|
||||
if (process.argv[2]) {
|
||||
onlyPackages = process.argv[2].split(',')
|
||||
}
|
||||
|
||||
const res = generateChangelog(onlyPackages)
|
||||
|
||||
if (process.env.CI && process.env.GITHUB_OUTPUT) {
|
||||
const delim = `---${require('crypto').randomUUID()}---${require('os').EOL}`
|
||||
fs.appendFileSync(process.env.GITHUB_OUTPUT, `changelog<<${delim}${res}${delim}`)
|
||||
} else {
|
||||
console.log(res)
|
||||
}
|
||||
}
|
50
scripts/git-utils.js
Normal file
50
scripts/git-utils.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
const cp = require('child_process')
|
||||
|
||||
function getLatestTag() {
|
||||
try {
|
||||
const res = cp.execSync('git describe --abbrev=0 --tags', { encoding: 'utf8', stdio: 'pipe' }).trim()
|
||||
|
||||
return res
|
||||
} catch (e) {
|
||||
if (e.stderr.match(/^fatal: (No names found|No tags can describe)/i)) {
|
||||
// no tags found, let's just return the first commit
|
||||
return cp.execSync('git rev-list --max-parents=0 HEAD', { encoding: 'utf8' }).trim()
|
||||
}
|
||||
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
function findChangedFilesSince(tag, until = 'HEAD') {
|
||||
return cp.execSync(`git diff --name-only ${tag} ${until}`, { encoding: 'utf8', stdio: 'pipe' }).trim().split('\n')
|
||||
}
|
||||
|
||||
function getCommitsSince(tag, until = 'HEAD') {
|
||||
return cp
|
||||
.execSync(`git log --pretty="format:%H %s" ${tag}..${until}`, { encoding: 'utf8', stdio: 'pipe' })
|
||||
.trim()
|
||||
.split('\n')
|
||||
.reverse()
|
||||
.map((it) => {
|
||||
const [hash, ...msg] = it.split(' ')
|
||||
|
||||
return { hash, msg: msg.join(' ') }
|
||||
})
|
||||
}
|
||||
|
||||
function parseConventionalCommit(msg) {
|
||||
const match = msg.match(/^(\w+)(?:\(([^)]+)\))?(!?): (.+)$/)
|
||||
|
||||
if (!match) return null
|
||||
|
||||
const [, type, scope, breaking, subject] = match
|
||||
|
||||
return { type, scope, breaking: Boolean(breaking), subject }
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getLatestTag,
|
||||
findChangedFilesSince,
|
||||
getCommitsSince,
|
||||
parseConventionalCommit,
|
||||
}
|
Loading…
Reference in a new issue