From 7d4dde44b21dfdeab66ec4d9739a93380bb5b70e Mon Sep 17 00:00:00 2001 From: mitchellhamilton Date: Tue, 10 Sep 2019 17:01:47 +1000 Subject: [PATCH] Sort changelog entries in PRs by highest bump type --- dist/index.js | 2 +- index.ts | 61 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/dist/index.js b/dist/index.js index e2bcc8b..41da21e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -985,5 +985,5 @@ function e(e){return Array.isArray(e)?e:[e]}const t=/^\s+$/,r=/^\\!/,i=/^\\#/,s= },{"array-union":"iMRL","glob":"R9Ja","fast-glob":"qwKf","dir-glob":"MgqK","./gitignore":"Rx5v"}],"kAcF":[function(require,module,exports) { "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var e=t(require("fs-extra")),a=t(require("path")),r=t(require("globby"));function t(e){return e&&e.__esModule?e:{default:e}}async function s(t={}){const s=t.cwd||process.cwd(),o=t.tools||["yarn","bolt"],n=await e.default.readFile(a.default.join(s,"package.json"),"utf-8").then(JSON.parse);let l;if(o.includes("yarn")&&n.workspaces?Array.isArray(n.workspaces)?l=n.workspaces:n.workspaces.packages&&(l=n.workspaces.packages):o.includes("bolt")&&n.bolt&&n.bolt.workspaces&&(l=n.bolt.workspaces),!l)return o.includes("root")?[{config:n,dir:s,name:n.name}]:null;const i=await(0,r.default)(l,{cwd:s,onlyDirectories:!0,absolute:!0,expandDirectories:!1});let c=[];const u=await Promise.all(i.sort().filter(r=>e.default.existsSync(a.default.join(r,"package.json"))).map(async r=>e.default.readFile(a.default.join(r,"package.json"),"utf8").then(e=>{const t=JSON.parse(e);return t.name||c.push(a.default.relative(s,a.default.join(r,"package.json"))),{config:t,name:t.name,dir:r}})));if(0!==c.length)throw c.sort(),new Error(`The following package.jsons are missing the "name" field:\n${c.join("\n")}`);return u}var o=s;exports.default=o; },{"fs-extra":"wFa+","globby":"e8e8"}],"7QCb":[function(require,module,exports) { -"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,a)}return n}function t(t){for(var a=1;a{o+=e.toString()},stderr:e=>{r+=e.toString()}}},a)),stdout:o,stderr:r}}function b(e,t){let n,a,o=c.default().use(u.default).parse(e),r=o.children;for(let i=0;i{let e=process.env.GITHUB_TOKEN;if(!e)return void r.setFailed("Please add the GITHUB_TOKEN to the changesets action");let n=`${s.context.repo.owner}/${s.context.repo.repo}`;const a=new s.GitHub(e);let o=a.repos.get(s.context.repo).then(e=>e.data.default_branch);console.log("setting git user"),await i.exec("git",["config","--global","user.name",'"github-actions[bot]"']),await i.exec("git",["config","--global","user.email",'"github-actions[bot]@users.noreply.github.com"']),console.log("setting GitHub credentials"),await l.default.writeFile(`${process.env.HOME}/.netrc`,`machine github.com\nlogin github-actions[bot]\npassword ${e}`);let c=await o;if(s.context.ref.replace("refs/heads/","")!==c)return void r.setFailed(`The changesets action should only run on ${c} but it's running on ${s.context.ref.replace("refs/heads/","")}, please change your GitHub actions config to only run the Changesets action on ${c}`);let u=l.default.readdirSync(`${process.cwd()}/.changeset`).some(e=>"config.js"!==e&&"README.md"!==e),d=r.getInput("publish");if(!u&&!d)return void console.log("No changesets found");if(!u&&d){console.log("No changesets found, attempting to publish any unpublished packages to npm");let e=await h.default({tools:["bolt","yarn","root"]});if(!e)return r.setFailed("Could not find workspaces");let n=new Map(e.map(e=>[e.name,e]));l.default.writeFileSync(`${process.env.HOME}/.npmrc`,`//registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN}`);let[o,...u]=d.split(/\s+/),g=await f(o,u);await i.exec("git",["push","origin",`HEAD:${c}`,"--follow-tags"]);let m=/New tag:\s+(@[^\/]+\/[^@]+|[^\/]+)@([^\s]+)/,w=[];for(let t of g.stdout.split("\n")){let e=t.match(m);if(null===e)continue;let a=e[1],o=n.get(a);if(void 0===o)return r.setFailed("Workspace not found for "+a+". This is probably a bug in the action, please open an issue");w.push(o)}return void(await Promise.all(w.map(async e=>{try{let o=p.default.join(e.dir,"CHANGELOG.md"),i=b(await l.default.readFile(o,"utf8"),e.config.version);if(!i)return r.setFailed(`Could not find changelog entry for ${e.name}@${e.config.version}`);await a.repos.createRelease(t({tag_name:`${e.name}@${e.config.version}`,body:i,prerelease:e.config.version.includes("-")},s.context.repo))}catch(n){if("ENOENT"!==n.code)throw n}})))}let{stderr:g}=await f("git",["checkout","changeset-release"],{ignoreReturnCode:!0}),m=!g.toString().includes("Switched to a new branch 'changeset-release'");m&&await i.exec("git",["checkout","-b","changeset-release"]);let w=m;if(!w){console.log("checking if new changesets should be added");const e=(await f("git",["merge-base","changeset-release",s.context.sha])).stdout.trim();w=(await f("git",["diff","--name-only",`${e}...${s.context.sha}`])).stdout.trim().includes(".changeset"),console.log("checked if new changesets should be added "+w)}if(w){await i.exec("git",["reset","--hard",s.context.sha]);let e=await f("node",["./node_modules/.bin/changeset","bump"]),o=`repo:${n}+state:open+head:changeset-release+base:${c}`,r=a.search.issuesAndPullRequests({q:o}),u=(async()=>{let t=/Updated file (.+)/,n=[];for(let a of e.stdout.split("\n")){let e=a.match(t);null!==e&&n.push(e[1])}return`This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and ${d?"the packages will be published to npm automatically":"publish to npm yourself or [setup this action to publish automatically](https://github.com/changesets/action#with-publishing)"}. If you're not ready to do a release yet, that's fine, whenever you add more changesets to ${c}, this PR will be updated.\n\n# Releases\n`+(await Promise.all(n.map(async e=>{let[t,n]=await Promise.all([l.default.readJson(p.default.join(p.default.dirname(e),"package.json")),l.default.readFile(e,"utf8")]),a=b(n,t.version);return`## ${t.name}@${t.version}\n\n`+a}))).join("\n ")})();await i.exec("git",["add","."]),await i.exec("git",["commit","-m","Version Packages"]),await i.exec("git",["push","origin","changeset-release","--force"]);let g=await r;console.log(JSON.stringify(g.data,null,2)),0===g.data.items.length?(console.log("creating pull request"),await a.pulls.create(t({base:c,head:"changeset-release",title:"Version Packages",body:await u},s.context.repo))):(a.pulls.update(t({pull_number:g.data.items[0].number,body:await u},s.context.repo)),console.log("pull request found"))}else console.log("no new changesets")})().catch(e=>{console.error(e),r.setFailed(e.message)}); +"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,a)}return n}function t(t){for(var a=1;a{o+=e.toString()},stderr:e=>{i+=e.toString()}}},a)),stdout:o,stderr:i}}var m;function b(e,t){let n,a,o=c.default().use(u.default).parse(e),i=m.dep,r=o.children;for(let s=0;s{let e=process.env.GITHUB_TOKEN;if(!e)return void i.setFailed("Please add the GITHUB_TOKEN to the changesets action");let n=`${s.context.repo.owner}/${s.context.repo.repo}`;const a=new s.GitHub(e);let o=a.repos.get(s.context.repo).then(e=>e.data.default_branch);console.log("setting git user"),await r.exec("git",["config","--global","user.name",'"github-actions[bot]"']),await r.exec("git",["config","--global","user.email",'"github-actions[bot]@users.noreply.github.com"']),console.log("setting GitHub credentials"),await l.default.writeFile(`${process.env.HOME}/.netrc`,`machine github.com\nlogin github-actions[bot]\npassword ${e}`);let c=await o;if(s.context.ref.replace("refs/heads/","")!==c)return void i.setFailed(`The changesets action should only run on ${c} but it's running on ${s.context.ref.replace("refs/heads/","")}, please change your GitHub actions config to only run the Changesets action on ${c}`);let u=l.default.readdirSync(`${process.cwd()}/.changeset`).some(e=>"config.js"!==e&&"README.md"!==e),d=i.getInput("publish");if(!u&&!d)return void console.log("No changesets found");if(!u&&d){console.log("No changesets found, attempting to publish any unpublished packages to npm");let e=await g.default({tools:["bolt","yarn","root"]});if(!e)return i.setFailed("Could not find workspaces");let n=new Map(e.map(e=>[e.name,e]));l.default.writeFileSync(`${process.env.HOME}/.npmrc`,`//registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN}`);let[o,...u]=d.split(/\s+/),h=await f(o,u);await r.exec("git",["push","origin",`HEAD:${c}`,"--follow-tags"]);let m=/New tag:\s+(@[^\/]+\/[^@]+|[^\/]+)@([^\s]+)/,w=[];for(let t of h.stdout.split("\n")){let e=t.match(m);if(null===e)continue;let a=e[1],o=n.get(a);if(void 0===o)return i.setFailed("Workspace not found for "+a+". This is probably a bug in the action, please open an issue");w.push(o)}return void(await Promise.all(w.map(async e=>{try{let o=p.default.join(e.dir,"CHANGELOG.md"),r=b(await l.default.readFile(o,"utf8"),e.config.version);if(!r)return i.setFailed(`Could not find changelog entry for ${e.name}@${e.config.version}`);await a.repos.createRelease(t({tag_name:`${e.name}@${e.config.version}`,body:r.content,prerelease:e.config.version.includes("-")},s.context.repo))}catch(n){if("ENOENT"!==n.code)throw n}})))}let{stderr:h}=await f("git",["checkout","changeset-release"],{ignoreReturnCode:!0}),m=!h.toString().includes("Switched to a new branch 'changeset-release'");m&&await r.exec("git",["checkout","-b","changeset-release"]);let w=m;if(!w){console.log("checking if new changesets should be added");const e=(await f("git",["merge-base","changeset-release",s.context.sha])).stdout.trim();w=(await f("git",["diff","--name-only",`${e}...${s.context.sha}`])).stdout.trim().includes(".changeset"),console.log("checked if new changesets should be added "+w)}if(w){await r.exec("git",["reset","--hard",s.context.sha]);let e=await f("node",["./node_modules/.bin/changeset","bump"]),o=`repo:${n}+state:open+head:changeset-release+base:${c}`,i=a.search.issuesAndPullRequests({q:o}),u=(async()=>{let t=/Updated file (.+)/,n=[];for(let a of e.stdout.split("\n")){let e=a.match(t);null!==e&&n.push(e[1])}return`This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and ${d?"the packages will be published to npm automatically":"publish to npm yourself or [setup this action to publish automatically](https://github.com/changesets/action#with-publishing)"}. If you're not ready to do a release yet, that's fine, whenever you add more changesets to ${c}, this PR will be updated.\n\n# Releases\n`+(await Promise.all(n.map(async e=>{let[t,n]=await Promise.all([l.default.readJson(p.default.join(p.default.dirname(e),"package.json")),l.default.readFile(e,"utf8")]),a=b(n,t.version);return{highestLevel:a.highestLevel,content:`## ${t.name}@${t.version}\n\n`+a.content}}))).sort((e,t)=>t.highestLevel-e.highestLevel).map(e=>e.content).join("\n ")})();await r.exec("git",["add","."]),await r.exec("git",["commit","-m","Version Packages"]),await r.exec("git",["push","origin","changeset-release","--force"]);let h=await i;console.log(JSON.stringify(h.data,null,2)),0===h.data.items.length?(console.log("creating pull request"),await a.pulls.create(t({base:c,head:"changeset-release",title:"Version Packages",body:await u},s.context.repo))):(a.pulls.update(t({pull_number:h.data.items[0].number,body:await u},s.context.repo)),console.log("pull request found"))}else console.log("no new changesets")})().catch(e=>{console.error(e),i.setFailed(e.message)}),function(e){e[e.dep=0]="dep",e[e.patch=1]="patch",e[e.minor=2]="minor",e[e.major=3]="major"}(m||(m={})); },{"@actions/core":"4FTV","@actions/exec":"utFe","@actions/github":"8Dol","fs-extra":"JTJ9","unified":"EJQW","remark-parse":"+8Y3","remark-stringify":"eCnT","mdast-util-to-string":"ljHw","get-workspaces":"kAcF"}]},{},["7QCb"], null) \ No newline at end of file diff --git a/index.ts b/index.ts index 33e76e5..64bb77c 100644 --- a/index.ts +++ b/index.ts @@ -163,7 +163,7 @@ async function execWithOutput( await octokit.repos.createRelease({ tag_name: `${workspace.name}@${workspace.config.version}`, - body: changelogEntry, + body: changelogEntry.content, prerelease: workspace.config.version.includes("-"), ...github.context.repo }); @@ -251,11 +251,17 @@ async function execWithOutput( changelogContents, pkgJsonContent.version ); - return ( - `## ${pkgJsonContent.name}@${pkgJsonContent.version}\n\n` + entry - ); + return { + highestLevel: entry.highestLevel, + content: + `## ${pkgJsonContent.name}@${pkgJsonContent.version}\n\n` + + entry.content + }; }) - )).join("\n ") + )) + .sort((a, b) => b.highestLevel - a.highestLevel) + .map(x => x.content) + .join("\n ") ); })(); await exec("git", ["add", "."]); @@ -288,11 +294,20 @@ async function execWithOutput( core.setFailed(err.message); }); +enum BumpLevels { + dep = 0, + patch = 1, + minor = 2, + major = 3 +} + function getChangelogEntry(changelog: string, version: string) { let ast = unified() .use(remarkParse) .parse(changelog); + let highestLevel = BumpLevels.dep; + let nodes = ast.children as Array; let headingStartInfo: | { @@ -304,24 +319,29 @@ function getChangelogEntry(changelog: string, version: string) { for (let i = 0; i < nodes.length; i++) { let node = nodes[i]; - if ( - headingStartInfo === undefined && - node.type === "heading" && - mdastToString(node) === version - ) { - headingStartInfo = { - index: i, - depth: node.depth - }; - continue; + if (node.type === "heading") { + let stringified: string = mdastToString(node); + let match = stringified.toLowerCase().match(/(major|minor|patch)/); + if (match !== null) { + let level = BumpLevels[match[0] as "major" | "minor" | "patch"]; + highestLevel = Math.max(level, highestLevel); + } + if (headingStartInfo === undefined && stringified === version) { + headingStartInfo = { + index: i, + depth: node.depth + }; + continue; + } } + if ( + endIndex === undefined && headingStartInfo !== undefined && node.type === "heading" && headingStartInfo.depth === node.depth ) { endIndex = i; - break; } } if (headingStartInfo) { @@ -330,7 +350,10 @@ function getChangelogEntry(changelog: string, version: string) { endIndex ); } - return unified() - .use(remarkStringify) - .stringify(ast); + return { + content: unified() + .use(remarkStringify) + .stringify(ast), + highestLevel: highestLevel + }; }