UNPKG

relion

Version:

🔖 Modern Release Workflow Helper

5 lines • 3.64 kB
import{readFileSync as e,writeFileSync as t}from"node:fs";import{execSync as n,spawnSync as r}from"node:child_process";import{createInterface as i}from"node:readline";import a from"semver";const o=e=>n(`git log ${e?`${e}..`:``} --format="%h %B---" .`,{encoding:`utf8`}).trim().split(`---`).filter(Boolean).map(e=>/^(.+?) (.+)/s.exec(e.trim())).map(e=>({hash:e?.[1]??``,message:e?.[2].trim()??``})),s=(e,t=[])=>e.filter(e=>t.some(t=>t instanceof RegExp?t.test(e.message):u(t).test(e.message))),c=(e,t)=>{let n=e.some(e=>e.message.includes(`BREAKING CHANGE`))?t.startsWith(`0.`)?`minor`:`major`:e.some(e=>/feat(\(.*?\))?:/.test(e.message))?`minor`:`patch`;return a.inc(t,n)??(()=>{throw Error(`Failed to increment version '${t}' with release type '${n}'`)})()},l=async()=>{let e=i({input:process.stdin,output:process.stdout});return await new Promise(t=>{e.question(`Press Enter to continue ('s' to skip): `,n=>{e.close(),t(n.trim()!==`s`)})})},u=e=>{let t=/^\/(.+)\/(\w*)$/.exec(e);return t?new RegExp(t[1],t[2]):new RegExp(e)},d=[`context`,`bump`,`commit`,`tag`],f={file:`package.json`,pattern:/(version.*?)\d[\w.+-]*/,replacement:`$1{{newVersion}}`},p={flow:[],newVersion:``,bumpFiles:[`package.json`],contextFile:`RELEASE.md`,commitMessage:`chore(release): {{tag}}`,tagPrefix:`v`,commitFilters:[/^feat|^fix|^perf|^style|^docs/,`BREAKING CHANGE`],dryRun:!1},m=async(e,n,r,i,a)=>{if(console.log(`\nAbout to write context to '${e.contextFile}'`),!await l()||e.dryRun)return;let o=``,s=`---\nversion: ${e.newVersion}\ntag: ${i}\ndate: ${new Date().toLocaleString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})}\nprevTag: ${r}\nrepoURL: ${a} --- `;o+=s+` `;let c=n.map(e=>`[${e.hash}] ${e.message}`).join(`\n${`-`.repeat(30)}\n`);o+=`## Commit Log\n\n\`\`\`\n${c}\n\`\`\``,t(e.contextFile,o,`utf8`)},h=async n=>{let r=n.bumpFiles.map(e=>typeof e==`string`?{...f,file:e}:e);console.log(`\nAbout to bump versions in files: ${r.map(e=>[e.file].flat()).flat().join(`, `)}`),await l()&&r.forEach(r=>{typeof r.pattern==`string`&&(r.pattern=u(r.pattern)),[r.file].flat().forEach(i=>{let a=e(i,`utf8`).replace(r.pattern,r.replacement.replace(`{{newVersion}}`,n.newVersion));n.dryRun||t(i,a,`utf8`)})})},g=async e=>{let t=`git commit -m "${e.commitMessage}"`;console.log(`\nAbout to commit changes: '${t}'`),await l()&&(e.dryRun||n(t,{stdio:`inherit`}))},_=async(e,t,r)=>{let i=`git tag ${r} -m "${e.commitMessage}"`,a=RegExp(`^${e.commitMessage.replace(r,t).replace(/[()]/g,`\\$&`)}$`),o=n(`git log -1 --format=%s`,{encoding:`utf8`}).trim(),s=``;a.test(o)&&(s+=` Latest commit is a release commit. Reusing the latest tag.`,i=`git tag ${t} -m "${o}" -f`),s+=`\nAbout to create a tag: '${i}'`,console.log(s),await l()&&(e.dryRun||n(i,{stdio:`inherit`}))};var v=async t=>{let n=JSON.parse(e(`package.json`,`utf8`)),i={...p,...n.relion,...t};console.log(`-`.repeat(30));let a=n.version;console.log(`Current version: ${a}`);let l=r(`git`,[`describe`,`--match`,`${i.tagPrefix}[0-9]*.[0-9]*.[0-9]*`,`--abbrev=0`],{encoding:`utf8`}).stdout.trim();console.log(`Current tag: ${l}`);let u=s(o(l),i.commitFilters);console.log(`Filtered commits: ${u.length}`),i.newVersion||=c(u,a),console.log(`New version: ${i.newVersion}`);let f=`${i.tagPrefix}${i.newVersion}`;console.log(`New tag: ${f}`),i.commitMessage=i.commitMessage.replace(`{{tag}}`,f),console.log(`Commit message: '${i.commitMessage}'`);let v=n.repository;console.log(`Repo URL: ${v}`),console.log(`-`.repeat(30));for(let e of d.filter(e=>i.flow.includes(e)))await{context:()=>m(i,u,l,f,v),bump:()=>h(i),commit:()=>g(i),tag:()=>_(i,l,f)}[e]()};const y=e=>e;export{v as default,y as defineConfig};