Skip to content

Commit

Permalink
(feat: website) Add new "Changelog" page
Browse files Browse the repository at this point in the history
You can now see all updates to SaaS Manual on the Changelog page: https://saasmanual.com/changelog.
The Changelog is generated from merge commits to the SaaS Manual website repository. 🎉
  • Loading branch information
nonken committed Jan 3, 2021
1 parent a1ede1a commit f8d65e0
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 5 deletions.
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import wikipedia from './src/lib/wikipedia';
import embedImage from './src/lib/embed-image';
import seo from './src/lib/seo';
import embedSource from './src/lib/embed-source';
import changelog from './src/lib/changelog';

(new Generator)
.templates('./src/template')
Expand All @@ -26,6 +27,7 @@ import embedSource from './src/lib/embed-source';
.use(config)
.use(meta)
.use(sitemap)
.use(changelog)
.use(seo)
.useRemarkPlugin((ctx) => { return directive; })
.useRemarkPlugin((ctx) => { return toc; })
Expand Down
6 changes: 6 additions & 0 deletions src/content/changelog/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
draft: true
keywords: homepage
layout: changelog.njk
title: SaaS Manual Changelog
---
5 changes: 0 additions & 5 deletions src/content/changelog/sha/index.md

This file was deleted.

79 changes: 79 additions & 0 deletions src/lib/changelog/helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
const propertyDelimiter = '@part@';
const commitDelimiter = '@commit-delimiter@';
const RE_SUBJECT = /^\((feat|fix|chore)\:\s?(.+)\)\s?(.+)/
const formats = [{
placeholder: '%h',
property: 'sha'
}, {
placeholder: '%an',
property: 'authorName'
}, {
placeholder: '%ae',
property: 'authorEmail'
}, {
placeholder: '%cD',
property: 'dateTime'
}, {
placeholder: '%s',
property: 'subject',
formatter: (line) => {
const match = RE_SUBJECT.exec(line);

if (!match) return;

return {
type: match[1],
module: match[2],
title: match[3]
}
}
}, {
placeholder: '%b',
property: 'body'
}];

const gitFormat = `--format=${formats.map(item => item.placeholder).join(propertyDelimiter)}${commitDelimiter}`;

async function* chunksToCommits(chunks) {
let previous = '';
for await (const chunk of chunks) {
previous += chunk;
let eolIndex;
while ((eolIndex = previous.indexOf(commitDelimiter)) >= 0) {
const line = previous.slice(0, eolIndex + commitDelimiter.length);
yield line;
previous = previous.slice(eolIndex + commitDelimiter.length);
}
}
if (previous.length > 0) {
yield previous;
}
}

const RE_COMMIT = new RegExp(`${commitDelimiter}`);
function cleanCommit(commit) {
const matchCommit = RE_COMMIT.exec(commit);
if (matchCommit) commit = commit.slice(0, matchCommit.index);
return commit.trim();
}

async function parseCommits(readable) {
const commits = [];
for await (const commit of chunksToCommits(readable)) {
const cleanedCommit = cleanCommit(commit);
const parts = cleanedCommit.split(propertyDelimiter);

commits.push(formats.reduce((commit, format, index) => {
commit[format.property] = format.formatter ? format.formatter(parts[index]) : parts[index];
return commit;
}, {}));
}
return commits;
}

export {
cleanCommit,
chunksToCommits,
parseCommits,
gitFormat
}
25 changes: 25 additions & 0 deletions src/lib/changelog/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

const { parseCommits, gitFormat } = require('./helper');
const { spawn } = require('child_process');


async function changelog(generator) {
const source = spawn('git', ['log', gitFormat]);

source.on('error', function (err) {
console.log(`Something went wrong: ${err}`);
});

const commits = await parseCommits(source.stdout);

for (const file in generator.ctx) {
const props = generator.ctx[file];
props.data.changelog = commits;
}

return this;
}

export {
changelog as default
}
62 changes: 62 additions & 0 deletions src/template/changelog.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="en">
<head>
{% include './include/head.njk' %}
</head>
<body>
{% include './include/navigation.njk' %}
<div class="max-w-7xl mx-auto px-4 sm:px-6 mt-24 pb-24">
<div class="text-center">
<h2 class="text-3xl tracking-tight font-extrabold text-gray-900 sm:text-4xl">
{{title}}
</h2>
<p class="mt-3 max-w-2xl mx-auto text-xl text-gray-500 sm:mt-4">
Checkout the latest updates to SaaS Manual:
</p>
</div>
<div class="flex flex-col mt-12 px-4 md:px-0">
<div class="flow-root">
<ul class="-mb-8">
{% for item in changelog %}
{% if item.subject %}
<li>
<div class="relative pb-8">
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200" aria-hidden="true"></span>
<div class="relative flex space-x-3">
<div>
{% if item.subject.type === 'fix' %}
<span class="h-8 w-8 rounded-full bg-gray-500 flex items-center justify-center ring-8 ring-white">
<svg class="h-4 w-4 text-white" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="tools" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M501.1 395.7L384 278.6c-23.1-23.1-57.6-27.6-85.4-13.9L192 158.1V96L64 0 0 64l96 128h62.1l106.6 106.6c-13.6 27.8-9.2 62.3 13.9 85.4l117.1 117.1c14.6 14.6 38.2 14.6 52.7 0l52.7-52.7c14.5-14.6 14.5-38.2 0-52.7zM331.7 225c28.3 0 54.9 11 74.9 31l19.4 19.4c15.8-6.9 30.8-16.5 43.8-29.5 37.1-37.1 49.7-89.3 37.9-136.7-2.2-9-13.5-12.1-20.1-5.5l-74.4 74.4-67.9-11.3L334 98.9l74.4-74.4c6.6-6.6 3.4-17.9-5.7-20.2-47.4-11.7-99.6.9-136.6 37.9-28.5 28.5-41.9 66.1-41.2 103.6l82.1 82.1c8.1-1.9 16.5-2.9 24.7-2.9zm-103.9 82l-56.7-56.7L18.7 402.8c-25 25-25 65.5 0 90.5s65.5 25 90.5 0l123.6-123.6c-7.6-19.9-9.9-41.6-5-62.7zM64 472c-13.2 0-24-10.8-24-24 0-13.3 10.7-24 24-24s24 10.7 24 24c0 13.2-10.7 24-24 24z"></path></svg>
</span>
{% elif item.subject.type === 'feat' %}
<span class="h-8 w-8 rounded-full bg-green-500 flex items-center justify-center ring-8 ring-white">
<svg class="h-4 w-4 text-white" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="lightbulb-on" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M240.06,454.34A32,32,0,0,0,245.42,472l17.1,25.69c5.23,7.91,17.17,14.28,26.64,14.28h61.7c9.47,0,21.41-6.37,26.64-14.28L394.59,472A37.47,37.47,0,0,0,400,454.34L400,416H240ZM319.45,0C217.44.31,144,83,144,176a175,175,0,0,0,43.56,115.78c16.52,18.85,42.36,58.22,52.21,91.44,0,.28.07.53.11.78H400.12c0-.25.07-.5.11-.78,9.85-33.22,35.69-72.59,52.21-91.44A175,175,0,0,0,496,176C496,78.63,416.91-.31,319.45,0ZM320,96a80.09,80.09,0,0,0-80,80,16,16,0,0,1-32,0A112.12,112.12,0,0,1,320,64a16,16,0,0,1,0,32ZM112,192a24,24,0,0,0-24-24H24a24,24,0,0,0,0,48H88A24,24,0,0,0,112,192Zm504-24H552a24,24,0,0,0,0,48h64a24,24,0,0,0,0-48ZM131.08,55.22l-55.42-32a24,24,0,1,0-24,41.56l55.42,32a24,24,0,1,0,24-41.56Zm457.26,264-55.42-32a24,24,0,1,0-24,41.56l55.42,32a24,24,0,0,0,24-41.56Zm-481.26-32-55.42,32a24,24,0,1,0,24,41.56l55.42-32a24,24,0,0,0-24-41.56ZM520.94,100a23.8,23.8,0,0,0,12-3.22l55.42-32a24,24,0,0,0-24-41.56l-55.42,32a24,24,0,0,0,12,44.78Z"></path></svg>
</span>
{% else %}
<span class="h-8 w-8 rounded-full bg-gray-500 flex items-center justify-center ring-8 ring-white">
<svg class="h-4 w-4 text-white" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="broom" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M256.47 216.77l86.73 109.18s-16.6 102.36-76.57 150.12C206.66 523.85 0 510.19 0 510.19s3.8-23.14 11-55.43l94.62-112.17c3.97-4.7-.87-11.62-6.65-9.5l-60.4 22.09c14.44-41.66 32.72-80.04 54.6-97.47 59.97-47.76 163.3-40.94 163.3-40.94zM636.53 31.03l-19.86-25c-5.49-6.9-15.52-8.05-22.41-2.56l-232.48 177.8-34.14-42.97c-5.09-6.41-15.14-5.21-18.59 2.21l-25.33 54.55 86.73 109.18 58.8-12.45c8-1.69 11.42-11.2 6.34-17.6l-34.09-42.92 232.48-177.8c6.89-5.48 8.04-15.53 2.55-22.44z"></path></svg>
</span>
{% endif %}
</div>
<div class="min-w-0 flex-1 pt-1 flex justify-between space-x-4">
<div>
<h2 class="text-gray-800">{{ item.subject.title }}</h2>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
{{ item.subject.module }}
</span>
<pre class="font-sans text-sm text-gray-600 mt-2">{{item.body}}</pre>
</div>
<div class="text-right text-sm whitespace-nowrap text-gray-500">
<time datetime="2020-09-20">{{ item.dateTime }}</time>
</div>
</div>
</div>
</div>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
</div>
</body>
8 changes: 8 additions & 0 deletions src/template/include/navigation.njk
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@
<span>Books</span>
</a>
</div>
<div class="relative">
<a href="/changelog" class="group bg-white rounded-md text-gray-500 inline-flex items-center text-base font-medium hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<span>Changelog</span>
</a>
</div>
</nav>
<div class="hidden md:flex items-center justify-end md:flex-1 lg:w-0"></div>
</div>
Expand Down Expand Up @@ -147,6 +152,9 @@
<div class="px-2 pt-2 pb-3" role="none">
<a href="/books" class="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-50" role="menuitem">Books</a>
</div>
<div class="px-2 pt-2 pb-3" role="none">
<a href="/changelog" class="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-50" role="menuitem">Changelog</a>
</div>
</div>
</div>
</div>
Expand Down

0 comments on commit f8d65e0

Please sign in to comment.