mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-08 05:43:53 +00:00
build(docs): introduce release script
This change introduces a new NPM run script to automatically generate the release changelog, as well as bump version numbers across the code-base and create the release tag. This script runs [Standard Version] to execute this, which is a tool designed around automating substantial parts of the release process. This can be done by running: npm run release -- [<standard-version args>] Standard Version expects the project to adhere to the [Semantic Versioning] convention which TF-A does not, so you may need to specify the version manually, e.g.: npm run release -- --release-as 2.6.0 Individual steps of the release process may also be skipped at-will, which may be necessary when, for example, tweaking the changelog: npm run release -- --skip.commit --skip.tag Standard Version is configured by the `.versionrc.js` file, which contains information about the Conventional Commits types and scopes used by the project, and how they map to the changelog. To maintain continuity with the existing changelog style - at least to the extent possible in the move from manual to automatic creation - a customized changelog template has been introduced, based on the Conventional Commits template provided by Standard Version. This template package extends the Conventional Commits template package by introducing support for parsing the Conventional Commits scopes into changelog sections, similarly to how they were previously organized. [Standard Version]: https://github.com/conventional-changelog/standard-version [Semantic Versioning]: https://semver.org Change-Id: I5bafa512daedc631baae951651c38c1c62046b0a Signed-off-by: Chris Kay <chris.kay@arm.com>
This commit is contained in:
parent
c76556a017
commit
c4e8edab21
17 changed files with 4259 additions and 4605 deletions
|
@ -11,6 +11,24 @@
|
|||
const cz = require("./.cz.json");
|
||||
const { "trailer-exists": trailerExists } = require("@commitlint/rules").default;
|
||||
|
||||
/*
|
||||
* Recursively fetch the project's supported scopes from the Commitizen configuration file. We use
|
||||
* permit only the blessed scope for each section to encourage developers to use a consistent scope
|
||||
* scheme.
|
||||
*/
|
||||
function getScopes(sections) {
|
||||
return sections.flatMap(section => {
|
||||
const scopes = section.scopes;
|
||||
const subscopes = getScopes(section.sections || []);
|
||||
|
||||
const scope = scopes ? [ scopes[0] ] : []; /* Only use the blessed scope */
|
||||
|
||||
return scope.concat(subscopes);
|
||||
})
|
||||
};
|
||||
|
||||
const scopes = getScopes(cz.sections); /* Contains every blessed scope */
|
||||
|
||||
module.exports = {
|
||||
extends: ["@commitlint/config-conventional"],
|
||||
plugins: [
|
||||
|
@ -27,5 +45,8 @@ module.exports = {
|
|||
|
||||
"change-id-exists": [1, "always", "Change-Id:"], /* Warning */
|
||||
"signed-off-by-exists": [1, "always", "Signed-off-by:"], /* Warning */
|
||||
|
||||
"scope-case": [2, "always", "kebab-case"], /* Error */
|
||||
"scope-enum": [1, "always", scopes] /* Warning */
|
||||
},
|
||||
};
|
||||
|
|
71
.cz.json
71
.cz.json
|
@ -1,5 +1,72 @@
|
|||
{
|
||||
"path": "./node_modules/cz-conventional-changelog",
|
||||
"maxHeaderWidth": 50,
|
||||
"maxLineWidth": 72
|
||||
}
|
||||
"maxLineWidth": 72,
|
||||
"types": [
|
||||
{
|
||||
"type": "feat",
|
||||
"title": "New Features",
|
||||
"description": "A new feature"
|
||||
},
|
||||
{
|
||||
"type": "fix",
|
||||
"title": "Resolved Issues",
|
||||
"description": "A bug fix"
|
||||
},
|
||||
{
|
||||
"type": "build",
|
||||
"title": "Build System",
|
||||
"description": "Changes that affect the build system or external dependencies",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"type": "ci",
|
||||
"title": "Continuous Integration",
|
||||
"description": "Changes to our CI configuration files and scripts",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"type": "docs",
|
||||
"title": "Build System",
|
||||
"description": "Documentation-only changes",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"type": "perf",
|
||||
"title": "Performance Improvements",
|
||||
"description": "A code change that improves performance",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"type": "refactor",
|
||||
"title": "Code Refactoring",
|
||||
"description": "A code change that neither fixes a bug nor adds a feature",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"type": "revert",
|
||||
"title": "Reverted Changes",
|
||||
"description": "Changes that revert a previous change",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"type": "style",
|
||||
"title": "Style",
|
||||
"description": "Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.)",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"type": "test",
|
||||
"title": "Tests",
|
||||
"description": "Adding missing tests or correcting existing tests",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"type": "chore",
|
||||
"title": "Miscellaneous",
|
||||
"description": "Any other change",
|
||||
"hidden": true
|
||||
}
|
||||
],
|
||||
"sections": []
|
||||
}
|
||||
|
|
66
.versionrc.js
Normal file
66
.versionrc.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* eslint-env es6 */
|
||||
|
||||
"use strict";
|
||||
|
||||
const cz = require("./.cz.json");
|
||||
|
||||
/*
|
||||
* Convert the Commitizen types array into the format accepted by the Conventional Changelog
|
||||
* Conventional Commits plugin (which our own plugin extends).
|
||||
*/
|
||||
const types = cz.types.map(type => {
|
||||
if (!type.hidden) {
|
||||
/*
|
||||
* Conventional Changelog prevents each section from appearing only if it has no designated
|
||||
* title, regardless of the value of the `hidden` flag.
|
||||
*/
|
||||
type.section = type.title;
|
||||
}
|
||||
|
||||
delete type.title;
|
||||
delete type.description;
|
||||
|
||||
return type;
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
"header": "# Change Log & Release Notes\n\nThis document contains a summary of the new features, changes, fixes and known\nissues in each release of Trusted Firmware-A.\n",
|
||||
"preset": {
|
||||
"name": "tf-a",
|
||||
"commitUrlFormat": "https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/{{hash}}",
|
||||
"compareUrlFormat": "https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/{{previousTag}}..{{currentTag}}",
|
||||
"userUrlFormat": "https://github.com/{{user}}",
|
||||
|
||||
"types": types,
|
||||
"sections": cz.sections,
|
||||
},
|
||||
"bumpFiles": [
|
||||
{
|
||||
"filename": "Makefile",
|
||||
"updater": {
|
||||
"readVersion": function (contents) {
|
||||
const major = contents.match(/^VERSION_MAJOR\s*:=\s*(\d+?)$/m)[1];
|
||||
const minor = contents.match(/^VERSION_MINOR\s*:=\s*(\d+?)$/m)[1];
|
||||
|
||||
return `${major}.${minor}.0`;
|
||||
},
|
||||
|
||||
"writeVersion": function (contents, version) {
|
||||
const major = version.split(".")[0];
|
||||
const minor = version.split(".")[1];
|
||||
|
||||
contents = contents.replace(/^(VERSION_MAJOR\s*:=\s*)(\d+?)$/m, `$1${major}`);
|
||||
contents = contents.replace(/^(VERSION_MINOR\s*:=\s*)(\d+?)$/m, `$1${minor}`);
|
||||
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
|
@ -747,6 +747,12 @@ Threat Model
|
|||
:|G|: `vwadekar`_
|
||||
:|F|: docs/threat_model/
|
||||
|
||||
Conventional Changelog Extensions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
:|M|: Chris Kay <chris.kay@arm.com>
|
||||
:|G|: `CJKay`_
|
||||
:|F|: tools/conventional-changelog-tf-a
|
||||
|
||||
.. _AlexeiFedorov: https://github.com/AlexeiFedorov
|
||||
.. _Andre-ARM: https://github.com/Andre-ARM
|
||||
.. _Anson-Huang: https://github.com/Anson-Huang
|
||||
|
|
3766
docs/change-log.md
Normal file
3766
docs/change-log.md
Normal file
File diff suppressed because it is too large
Load diff
4602
docs/change-log.rst
4602
docs/change-log.rst
File diff suppressed because it is too large
Load diff
24
package-lock.json
generated
24
package-lock.json
generated
|
@ -13,6 +13,7 @@
|
|||
"@commitlint/cli": "^14.1.0",
|
||||
"@commitlint/config-conventional": "^14.1.0",
|
||||
"commitizen": "^4.2.4",
|
||||
"conventional-changelog-tf-a": "file:tools/conventional-changelog-tf-a",
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"husky": "^7.0.4",
|
||||
"standard-version": "^9.3.2"
|
||||
|
@ -1075,6 +1076,10 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/conventional-changelog-tf-a": {
|
||||
"resolved": "tools/conventional-changelog-tf-a",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/conventional-changelog-writer": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz",
|
||||
|
@ -3813,6 +3818,16 @@
|
|||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"tools/conventional-changelog-tf-a": {
|
||||
"version": "1.0.0",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"conventional-changelog-conventionalcommits": "^4.6.1",
|
||||
"execa": "^5.1.1",
|
||||
"lodash": "^4.17.21",
|
||||
"q": "^1.5.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -4663,6 +4678,15 @@
|
|||
"integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==",
|
||||
"dev": true
|
||||
},
|
||||
"conventional-changelog-tf-a": {
|
||||
"version": "file:tools/conventional-changelog-tf-a",
|
||||
"requires": {
|
||||
"conventional-changelog-conventionalcommits": "^4.6.1",
|
||||
"execa": "^5.1.1",
|
||||
"lodash": "^4.17.21",
|
||||
"q": "^1.5.1"
|
||||
}
|
||||
},
|
||||
"conventional-changelog-writer": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz",
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
"license": "BSD-3-Clause",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"postinstall": "husky install"
|
||||
"postinstall": "husky install",
|
||||
"release": "standard-version -i docs/change-log.md"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^14.1.0",
|
||||
"@commitlint/config-conventional": "^14.1.0",
|
||||
"commitizen": "^4.2.4",
|
||||
"conventional-changelog-tf-a": "file:tools/conventional-changelog-tf-a",
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"husky": "^7.0.4",
|
||||
"standard-version": "^9.3.2"
|
||||
|
|
222
tools/conventional-changelog-tf-a/index.js
Normal file
222
tools/conventional-changelog-tf-a/index.js
Normal file
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* eslint-env es6 */
|
||||
|
||||
"use strict";
|
||||
|
||||
const Handlebars = require("handlebars");
|
||||
const Q = require("q");
|
||||
const _ = require("lodash");
|
||||
|
||||
const ccConventionalChangelog = require("conventional-changelog-conventionalcommits/conventional-changelog");
|
||||
const ccParserOpts = require("conventional-changelog-conventionalcommits/parser-opts");
|
||||
const ccRecommendedBumpOpts = require("conventional-changelog-conventionalcommits/conventional-recommended-bump");
|
||||
const ccWriterOpts = require("conventional-changelog-conventionalcommits/writer-opts");
|
||||
|
||||
const execa = require("execa");
|
||||
|
||||
const readFileSync = require("fs").readFileSync;
|
||||
const resolve = require("path").resolve;
|
||||
|
||||
/*
|
||||
* Register a Handlebars helper that lets us generate Markdown lists that can support multi-line
|
||||
* strings. This is driven by inconsistent formatting of breaking changes, which may be multiple
|
||||
* lines long and can terminate the list early unintentionally.
|
||||
*/
|
||||
Handlebars.registerHelper("tf-a-mdlist", function (indent, options) {
|
||||
const spaces = new Array(indent + 1).join(" ");
|
||||
const first = spaces + "- ";
|
||||
const nth = spaces + " ";
|
||||
|
||||
return first + options.fn(this).replace(/\n(?!\s*\n)/gm, `\n${nth}`).trim() + "\n";
|
||||
});
|
||||
|
||||
/*
|
||||
* Register a Handlebars helper that concatenates multiple variables. We use this to generate the
|
||||
* title for the section partials.
|
||||
*/
|
||||
Handlebars.registerHelper("tf-a-concat", function () {
|
||||
let argv = Array.prototype.slice.call(arguments, 0);
|
||||
|
||||
argv.pop();
|
||||
|
||||
return argv.join("");
|
||||
});
|
||||
|
||||
function writerOpts(config) {
|
||||
/*
|
||||
* Flatten the configuration's sections list. This helps us iterate over all of the sections
|
||||
* when we don't care about the hierarchy.
|
||||
*/
|
||||
|
||||
const flattenSections = function (sections) {
|
||||
return sections.flatMap(section => {
|
||||
const subsections = flattenSections(section.sections || []);
|
||||
|
||||
return [section].concat(subsections);
|
||||
})
|
||||
};
|
||||
|
||||
const flattenedSections = flattenSections(config.sections);
|
||||
|
||||
/*
|
||||
* Register a helper to return a restructured version of the note groups that includes notes
|
||||
* categorized by their section.
|
||||
*/
|
||||
Handlebars.registerHelper("tf-a-notes", function (noteGroups, options) {
|
||||
const generateTemplateData = function (sections, notes) {
|
||||
return (sections || []).flatMap(section => {
|
||||
const templateData = {
|
||||
title: section.title,
|
||||
sections: generateTemplateData(section.sections, notes),
|
||||
notes: notes.filter(note => section.scopes?.includes(note.commit.scope)),
|
||||
};
|
||||
|
||||
/*
|
||||
* Don't return a section if it contains no notes and no sub-sections.
|
||||
*/
|
||||
if ((templateData.sections.length == 0) && (templateData.notes.length == 0)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [templateData];
|
||||
});
|
||||
};
|
||||
|
||||
return noteGroups.map(noteGroup => {
|
||||
return {
|
||||
title: noteGroup.title,
|
||||
sections: generateTemplateData(config.sections, noteGroup.notes),
|
||||
notes: noteGroup.notes.filter(note =>
|
||||
!flattenedSections.some(section => section.scopes?.includes(note.commit.scope))),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
* Register a helper to return a restructured version of the commit groups that includes commits
|
||||
* categorized by their section.
|
||||
*/
|
||||
Handlebars.registerHelper("tf-a-commits", function (commitGroups, options) {
|
||||
const generateTemplateData = function (sections, commits) {
|
||||
return (sections || []).flatMap(section => {
|
||||
const templateData = {
|
||||
title: section.title,
|
||||
sections: generateTemplateData(section.sections, commits),
|
||||
commits: commits.filter(commit => section.scopes?.includes(commit.scope)),
|
||||
};
|
||||
|
||||
/*
|
||||
* Don't return a section if it contains no notes and no sub-sections.
|
||||
*/
|
||||
if ((templateData.sections.length == 0) && (templateData.commits.length == 0)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [templateData];
|
||||
});
|
||||
};
|
||||
|
||||
return commitGroups.map(commitGroup => {
|
||||
return {
|
||||
title: commitGroup.title,
|
||||
sections: generateTemplateData(config.sections, commitGroup.commits),
|
||||
commits: commitGroup.commits.filter(commit =>
|
||||
!flattenedSections.some(section => section.scopes?.includes(commit.scope))),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
const writerOpts = ccWriterOpts(config)
|
||||
.then(writerOpts => {
|
||||
const ccWriterOptsTransform = writerOpts.transform;
|
||||
|
||||
/*
|
||||
* These configuration properties can't be injected directly into the template because
|
||||
* they themselves are templates. Instead, we register them as partials, which allows
|
||||
* them to be evaluated as part of the templates they're used in.
|
||||
*/
|
||||
Handlebars.registerPartial("commitUrl", config.commitUrlFormat);
|
||||
Handlebars.registerPartial("compareUrl", config.compareUrlFormat);
|
||||
Handlebars.registerPartial("issueUrl", config.issueUrlFormat);
|
||||
|
||||
/*
|
||||
* Register the partials that allow us to recursively create changelog sections.
|
||||
*/
|
||||
|
||||
const notePartial = readFileSync(resolve(__dirname, "./templates/note.hbs"), "utf-8");
|
||||
const noteSectionPartial = readFileSync(resolve(__dirname, "./templates/note-section.hbs"), "utf-8");
|
||||
const commitSectionPartial = readFileSync(resolve(__dirname, "./templates/commit-section.hbs"), "utf-8");
|
||||
|
||||
Handlebars.registerPartial("tf-a-note", notePartial);
|
||||
Handlebars.registerPartial("tf-a-note-section", noteSectionPartial);
|
||||
Handlebars.registerPartial("tf-a-commit-section", commitSectionPartial);
|
||||
|
||||
/*
|
||||
* Override the base templates so that we can generate a changelog that looks at least
|
||||
* similar to the pre-Conventional Commits TF-A changelog.
|
||||
*/
|
||||
writerOpts.mainTemplate = readFileSync(resolve(__dirname, "./templates/template.hbs"), "utf-8");
|
||||
writerOpts.headerPartial = readFileSync(resolve(__dirname, "./templates/header.hbs"), "utf-8");
|
||||
writerOpts.commitPartial = readFileSync(resolve(__dirname, "./templates/commit.hbs"), "utf-8");
|
||||
writerOpts.footerPartial = readFileSync(resolve(__dirname, "./templates/footer.hbs"), "utf-8");
|
||||
|
||||
writerOpts.transform = function (commit, context) {
|
||||
/*
|
||||
* Fix up commit trailers, which for some reason are not correctly recognized and
|
||||
* end up showing up in the breaking changes.
|
||||
*/
|
||||
|
||||
commit.notes.forEach(note => {
|
||||
const trailers = execa.sync("git", ["interpret-trailers", "--parse"], {
|
||||
input: note.text
|
||||
}).stdout;
|
||||
|
||||
note.text = note.text.replace(trailers, "").trim();
|
||||
});
|
||||
|
||||
return ccWriterOptsTransform(commit, context);
|
||||
};
|
||||
|
||||
return writerOpts;
|
||||
});
|
||||
|
||||
return writerOpts;
|
||||
}
|
||||
|
||||
module.exports = function (parameter) {
|
||||
const config = parameter || {};
|
||||
|
||||
return Q.all([
|
||||
ccConventionalChangelog(config),
|
||||
ccParserOpts(config),
|
||||
ccRecommendedBumpOpts(config),
|
||||
writerOpts(config)
|
||||
]).spread((
|
||||
conventionalChangelog,
|
||||
parserOpts,
|
||||
recommendedBumpOpts,
|
||||
writerOpts
|
||||
) => {
|
||||
if (_.isFunction(parameter)) {
|
||||
return parameter(null, {
|
||||
gitRawCommitsOpts: { noMerges: null },
|
||||
conventionalChangelog,
|
||||
parserOpts,
|
||||
recommendedBumpOpts,
|
||||
writerOpts
|
||||
});
|
||||
} else {
|
||||
return {
|
||||
conventionalChangelog,
|
||||
parserOpts,
|
||||
recommendedBumpOpts,
|
||||
writerOpts
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
12
tools/conventional-changelog-tf-a/package.json
Normal file
12
tools/conventional-changelog-tf-a/package.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "conventional-changelog-tf-a",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"conventional-changelog-conventionalcommits": "^4.6.1",
|
||||
"execa": "^5.1.1",
|
||||
"lodash": "^4.17.21",
|
||||
"q": "^1.5.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{{#if title ~}}
|
||||
{{ header }}
|
||||
|
||||
{{#if commits.length ~}}
|
||||
{{#each commits ~}}
|
||||
{{#tf-a-mdlist 0}}{{> commit root=@root showScope=../topLevel }}{{/tf-a-mdlist ~}}
|
||||
{{/each}}
|
||||
|
||||
{{/if ~}}
|
||||
|
||||
{{#if sections.length ~}}
|
||||
{{#each sections ~}}
|
||||
{{#tf-a-mdlist 0}}{{> tf-a-commit-section root=@root header=(tf-a-concat "**" title "**") }}{{/tf-a-mdlist}}
|
||||
{{/each}}
|
||||
{{/if ~}}
|
||||
|
||||
{{/if}}
|
15
tools/conventional-changelog-tf-a/templates/commit.hbs
Normal file
15
tools/conventional-changelog-tf-a/templates/commit.hbs
Normal file
|
@ -0,0 +1,15 @@
|
|||
{{#if scope }}
|
||||
{{~#if showScope }}**{{ scope }}:** {{/if}}
|
||||
{{~/if}}
|
||||
|
||||
{{~#if subject }}
|
||||
{{~ subject }}
|
||||
{{~else}}
|
||||
{{~ header }}
|
||||
{{~/if}}
|
||||
|
||||
{{~#if hash }} {{#if @root.linkReferences ~}}
|
||||
([{{ shortHash }}]({{> commitUrl root=@root }}))
|
||||
{{~else}}
|
||||
{{~ shortHash }}
|
||||
{{~/if}}{{~/if}}
|
0
tools/conventional-changelog-tf-a/templates/footer.hbs
Normal file
0
tools/conventional-changelog-tf-a/templates/footer.hbs
Normal file
13
tools/conventional-changelog-tf-a/templates/header.hbs
Normal file
13
tools/conventional-changelog-tf-a/templates/header.hbs
Normal file
|
@ -0,0 +1,13 @@
|
|||
{{#if isPatch~}}
|
||||
###
|
||||
{{~else~}}
|
||||
##
|
||||
{{~/if}} {{#if @root.linkCompare~}}
|
||||
[{{version}}]({{> compareUrl root=@root}})
|
||||
{{~else}}
|
||||
{{~version}}
|
||||
{{~/if}}
|
||||
{{~#if title}} "{{title}}"
|
||||
{{~/if}}
|
||||
{{~#if date}} ({{date}})
|
||||
{{/if}}
|
13
tools/conventional-changelog-tf-a/templates/note-section.hbs
Normal file
13
tools/conventional-changelog-tf-a/templates/note-section.hbs
Normal file
|
@ -0,0 +1,13 @@
|
|||
{{ header }}
|
||||
|
||||
{{#if notes.length ~}}
|
||||
{{#each notes ~}}
|
||||
{{#tf-a-mdlist 0}}{{> tf-a-note root=@root showScope=../topLevel }}{{/tf-a-mdlist}}
|
||||
{{/each ~}}
|
||||
{{/if ~}}
|
||||
|
||||
{{#if sections.length ~}}
|
||||
{{#each sections ~}}
|
||||
{{#tf-a-mdlist 0}}{{> tf-a-note-section root=@root header=(tf-a-concat "**" title "**") }}{{/tf-a-mdlist}}
|
||||
{{/each~}}
|
||||
{{/if}}
|
3
tools/conventional-changelog-tf-a/templates/note.hbs
Normal file
3
tools/conventional-changelog-tf-a/templates/note.hbs
Normal file
|
@ -0,0 +1,3 @@
|
|||
{{ text }}
|
||||
|
||||
**See:** {{#with commit }}{{> commit root=@root showScope=../showScope }}{{/with}}
|
9
tools/conventional-changelog-tf-a/templates/template.hbs
Normal file
9
tools/conventional-changelog-tf-a/templates/template.hbs
Normal file
|
@ -0,0 +1,9 @@
|
|||
{{> header }}
|
||||
|
||||
{{#each (tf-a-notes noteGroups) ~}}
|
||||
{{> tf-a-note-section root=@root header=(tf-a-concat "### ⚠ " title) topLevel=true }}
|
||||
{{/each ~}}
|
||||
|
||||
{{#each (tf-a-commits commitGroups) ~}}
|
||||
{{> tf-a-commit-section root=@root header=(tf-a-concat "### " title) topLevel=true }}
|
||||
{{/each ~}}
|
Loading…
Add table
Reference in a new issue