build: fixed tl versioning + changelog generation

This commit is contained in:
alina 🌸 2023-11-12 19:19:02 +03:00
parent f525c12f83
commit ec1154fdef
Signed by: teidesu
SSH key fingerprint: SHA256:uNeCpw6aTSU4aIObXLvHfLkDa82HWH9EiOj9AXOIRpI
6 changed files with 122 additions and 23 deletions

View file

@ -48,6 +48,9 @@ jobs:
- name: Find packages to publish - name: Find packages to publish
id: find id: find
run: node scripts/find-updated-packages.js ${{ inputs.kind }} ${{ inputs.packages }} 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 - name: Bump versions
id: bump id: bump
run: node scripts/bump-version.js ${{ inputs.kind }} ${{ steps.find.outputs.modified }} run: node scripts/bump-version.js ${{ inputs.kind }} ${{ steps.find.outputs.modified }}
@ -55,7 +58,7 @@ jobs:
run: | run: |
git commit -am "v${{ steps.bump.outputs.version }}" git commit -am "v${{ steps.bump.outputs.version }}"
git push git push
- name: Build pacakges and publish to NPM - name: Build packages and publish to NPM
id: build id: build
env: env:
GH_RELEASE: 1 GH_RELEASE: 1
@ -66,6 +69,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
tag: v${{ steps.bump.outputs.version }} tag: v${{ steps.bump.outputs.version }}
name: 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 draft: false
prerelease: false prerelease: false

View file

@ -1,6 +1,6 @@
{ {
"name": "@mtcute/tl", "name": "@mtcute/tl",
"version": "0.1.0", "version": "166.0.0",
"description": "TL schema used for mtcute", "description": "TL schema used for mtcute",
"main": "index.js", "main": "index.js",
"author": "Alina Sireneva <alina@tei.su>", "author": "Alina Sireneva <alina@tei.su>",

View file

@ -29,6 +29,7 @@ function bumpVersions(packages, kind) {
console.log('[i] Bumping versions to %s', nextVersion) console.log('[i] Bumping versions to %s', nextVersion)
for (const pkg of packages) { for (const pkg of packages) {
if (pkg === 'tl') continue // own versioning
const pkgJson = pkgJsons.find((it) => it.name === `@mtcute/${pkg}`) const pkgJson = pkgJsons.find((it) => it.name === `@mtcute/${pkg}`)
if (!pkgJson) { if (!pkgJson) {

View file

@ -2,25 +2,7 @@ const cp = require('child_process')
const fs = require('fs') const fs = require('fs')
const path = require('path') const path = require('path')
const { listPackages } = require('./publish') const { listPackages } = require('./publish')
const { getLatestTag, findChangedFilesSince } = require('./git-utils')
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')
}
getTsconfigFiles.cache = {} getTsconfigFiles.cache = {}
@ -46,9 +28,11 @@ function isMeaningfulChange(pkg, path) {
if (getTsconfigFiles(pkg).indexOf(path) > -1) return true if (getTsconfigFiles(pkg).indexOf(path) > -1) return true
// some magic heuristics stuff // 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 if (path.match(/^\/(scripts|dist|tests|private)/i)) return false
console.log('[i] %s: %s is a meaningful change', pkg, path)
// to be safe // to be safe
return true return true
} }

View 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
View 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,
}