[{"data":1,"prerenderedAt":222},["Reactive",2],{"search-api":3},[4,11,21,29,37,46,53,60,67,89,98,117,124,133,143,150,160,168,176,184,191,198,205,215],{"id":5,"path":6,"dir":7,"title":8,"description":7,"keywords":9,"body":10},"content:0.index.md","/","","Relno Docs",[],"    Relno made it easy to generate release notes.   Relno reads the commit history and generates release notes based on commit messages. Provide a template and expression syntax to customize your release notes.",{"id":12,"path":13,"dir":7,"title":14,"description":15,"keywords":16,"body":20},"content:1.get-started.md","/get-started","Get Started","How to get started with Relno by adding it to an existing project.",[17,18,19],"Prerequisites","Setup config file","Install Relno","  Get Started  How to get started with Relno by adding it to an existing project.  Prerequisites  Change your repository default pull request title format. You can find it in   Settings  ->   General  ->   Pull Requests  on GitHub repository page.     Relno use pull request title to generate release note. So you need to change your repository default pull request title format and make sure your pull request title follow   Conventional Commits .  Setup config file  Create a   relno.config.js  file in your project root directory.      module  .  exports   =   {\n       template:   \"template.rntmd\"  ,\n       prTypes: [\n           {\n           identifier:   \"breaking\"  ,\n           title:   \"⚠️ Breaking Changes\"  ,\n           filter  : (  _  ,   commit  )   =>\n               commit.message.  match  (  /  (  [  ^  ()\\n!]  +  )(?:  \\(  .  *  \\)  )  ?  !:   .  +   \\(  #  [1-9][0-9]  *  \\)  /  )   !==\n               null  ,\n           },\n           { identifier:   \"feat\"  , title:   \"🚀 Enhancements\"   },\n           { identifier:   \"fix\"  , title:   \"🩹 Fixes\"   },\n           { identifier:   \"docs\"  , title:   \"📖 Documentation\"   },\n           { identifier:   \"chore\"  , title:   \"🏡 Chore\"   },\n           { identifier:   \"refactor\"  , title:   \"💅 Refactors\"   },\n           { identifier:   \"test\"  , title:   \"✅ Tests\"   },\n       ],\n   };\n   template  is the template file path. We will use this file to generate the release note.   prTypes  is the pull request type configuration.   identifier  is the pull request type identifier.   title  is the pull request type title which would be generated. According above config, if you have a pull request with title   feat: add new feature , the generated title would be   🚀 Enhancements  Then, create a   template.rntmd  file in your project root directory.      ## 📝 Changelog\n   \n   [compare changes]({{ compareUrl }})\n   \n   \u003C!-- BEGIN breaking SECTION -->\n   \n   ### {{ title }}\n   \n   \u003C!-- BEGIN commits SECTION -->\n   \n   -   {{ prSubtype }}{{ generateIfNotEmpty(prSubtype, \": \") }}{{ toSentence(message) }} (#{{ prNumber }})\n   \u003C!-- END commits SECTION -->\n   \n   \u003C!-- END breaking SECTION -->\n   \u003C!-- BEGIN feat, fix, docs, chore, refactor, test SECTION -->\n   \n   ### {{ title }}\n   \n   \u003C!-- BEGIN commits SECTION -->\n   \n   -   {{ prSubtype }}{{ generateIfNotEmpty(prSubtype, \": \") }}{{ generateIf(prBreaking, \"⚠️ \") }}{{ toSentence(message) }} (#{{ prNumber }})\n   \u003C!-- END commits SECTION -->\n   \n   \u003C!-- END feat, fix, docs, chore, refactor, test SECTION -->\n   \u003C!-- Generate by Release Note -->\n  You might notice that there are some special syntax in the template file.   {{ }}  is the expression syntax. Relno would replace it with the specified variable or macro, even a string literal.   \u003C!-- BEGIN commits SECTION -->  and   \u003C!-- END commits SECTION -->  is the section syntax. Relno need this to know where the content should be inserted.  Install Relno  Now, you can add Relno to your release workflow, or just run it as a command line tool.  GitHub Action      name  :   Release\n   on  :\n       release  :\n       types  : [  published  ,   edited  ]\n   \n   jobs  :\n       release-note  :\n       runs-on  :   ubuntu-latest\n       steps  :\n       -   uses  :   actions/checkout@v3\n           with  :\n           fetch-depth  :   0\n       -   uses  :   ppodds/relno-action@v1\n           with  :\n           token  :   ${{ secrets.GITHUB_TOKEN }}\n  Create a new release, and you will get your beautiful release note. 🚀  Command Line Tool  You can install Relno globally or as a dev dependency.      npm   install   -g   relno-cli\n  After installation, you can run   relno-cli  in your project root directory.      npx   relno-cli   --help\n  A few examples is listed below.      npx   relno-cli   -f   v0.0.1   -t   v1.0.0   -m   compareUrl=https://github.com/ppodds/relno/compare/v0.0.1...v1.0.0\n   npx   relno-cli   -f   5351949  a32bebff9562ce5ba9078360b8fe38711   -t   d467be3275eaca3639a1b6825b705cfc83fe072d\n  html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":22,"path":23,"dir":24,"title":25,"description":7,"keywords":26,"body":28},"content:2.guide:1.basic-knowledge.md","/guide/basic-knowledge","guide","Basic Knowledge",[27],"How Do Relno work?","  Basic Knowledge  How Do Relno work?  Relno will read the commit message of pull request from the git log, and then generate a release note based on the configuration file. It   rely on   Conventional Commits , so you should follow the specification to write your commit message, or it will not work.   We will allow you to set how to parse the commit message in the future, but now we only support   Conventional Commits .",{"id":30,"path":31,"dir":32,"title":33,"description":34,"keywords":35,"body":36},"content:2.guide:2.configuration:1.introduction.md","/guide/configuration/introduction","configuration","Introduction","Relno will read the configuration file from the current working directory. The default file name is relno.config.js. You can also specify the file name by using the --config (or -c) option.",[],"  Introduction  Relno will read the configuration file from the current working directory. The default file name is   relno.config.js . You can also specify the file name by using the   --config  (or   -c ) option.",{"id":38,"path":39,"dir":32,"title":40,"description":7,"keywords":41,"body":45},"content:2.guide:2.configuration:2.options.md","/guide/configuration/options","Options",[42,43,44],"template","prTypes","plugins","  Options   template  type:   string  \nrequired: yes  The path to your template file.   prTypes  type:   { \"identifier\": string, \"title\": string, \"filter\"?: (prType: PRType, commit: Commit) => boolean; }[]  \nrequired: yes  Define which pull request should be included in the release note and how to generate the title.   filter  is useful when you want to set a condition to include the pull request.   prType  and   commit  is the parameter of the   filter  function. They can be used to check the pull request type and commit message. Allow you to write your custom filter logic.   plugins  type:   RelnoPlugin[] \nrequired: no  The plugins to be used in Relno.",{"id":47,"path":48,"dir":42,"title":49,"description":50,"keywords":51,"body":52},"content:2.guide:3.template:1.expression-syntax.md","/guide/template/expression-syntax","Expression Syntax","Relno provide a simple expression syntax to help you generate the release note.",[],"  Expression Syntax  Relno provide a simple expression syntax to help you generate the release note.  Syntax:   {{ expression }}  Examples:    {{ title }}\n{{ \"Hello World\" }}\n{{ toSentence(\"this is a sentence\") }}\n  You can use expression in your template file to generate the release note.  Expression could be:   string literal\n    \"Hello World\"   'Hello World'  variable (change in different context)\n    compareUrl  (in default context)   title  (in changes section)   message  (in commits section)  macro\n    toSentence(\"this is a sentence\")   toSentence(generateIfNotEmpty(notEmpty, \"this is a sentence\"))",{"id":54,"path":55,"dir":42,"title":56,"description":57,"keywords":58,"body":59},"content:2.guide:3.template:2.section-syntax.md","/guide/template/section-syntax","Section Syntax","You can use section tag to define a section in your template file.",[],"  Section Syntax  You can use section tag to define a section in your template file.  Begin Syntax:   \u003C!-- BEGIN section SECTION -->  End Syntax:   \u003C!-- END section SECTION -->  Examples:      \u003C!-- BEGIN test SECTION -->\n   This is a test section.\n   \u003C!-- END test SECTION -->\n  If you have the same template content in multiple sections, you can define it with the following syntax:      \u003C!-- BEGIN feat, refactor, test SECTION -->\n   The content in this section will be generated in feat, refactor and test sections.\n   \u003C!-- END feat, refactor, test SECTION -->\n  It is very useful when you have a lot of sections with the same content.   The begin tags and end tags must be identical.  Available sections:    default    PR type  (change to your defined PR type identifier)\n    commits    default  section is not a real section, it is the default context of the template file. In generate process, Relno will insert   default  section end tag at the end of the template file. As a result, you should never use   default  as a section name.  html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":61,"path":62,"dir":63,"title":33,"description":64,"keywords":65,"body":66},"content:2.guide:4.variables:1.introduction.md","/guide/variables/introduction","variables","Variables can be used in the expression in the template. If the variable is not defined in the context and you use it, it will throw an error. If Relno can't get the value of the variable, it will use an empty string instead.",[],"  Introduction  Variables can be used in the expression in the template. If the variable is not defined in the context and you use it, it will throw an error. If Relno can't get the value of the variable, it will use an empty string instead.  Currently, variables only has two types:   string  and   boolean .",{"id":68,"path":69,"dir":63,"title":70,"description":71,"keywords":72,"body":88},"content:2.guide:4.variables:2.default-context.md","/guide/variables/default-context","Default Context","The following variables are available in the default context. You can think these variable as metadata. In relno-cli, you can use --metadata (or -m) option to pass these variables.",[73,74,75,76,77,78,79,80,81,82,83,84,85,86,87],"authorLogin","authorName","authorEmail","createdAt","discussionUrl","htmlUrl","id","name","publishedAt","tagName","fromVersion","tarballUrl","targetCommitish","zipballUrl","compareUrl","  Default Context  The following variables are available in the default context. You can think these variable as metadata. In   relno-cli , you can use   --metadata  (or   -m ) option to pass these variables.   These variables are only available when you are using   relno-action . If you are using   relno-cli , you can pass these variables by using   --metadata  (or   -m ) option.   authorLogin  The release author's login (GitHub username).   authorName  The release author's name (could be set in GitHub profile). If the user has not set the name, it will be an empty string.   authorEmail  The release author's email. It will be an empty string most of the time.   createdAt  The release created time. It would provided as a UTC time. You can use   formatDate  macro to format it.   discussionUrl  The release discussion url. It will be an empty string if the release hasn't linked to any discussion.   htmlUrl  The release html url (GitHub release page).  e.g.   https://github.com/ppodds/relno/releases/tag/v0.0.1-alpha.1   id  The action id of the triggered workflow.   name  The release name. It could be an empty string.   publishedAt  The release published time. It would provided as a UTC time. You can use   formatDate  macro to format it.   tagName  The release tag name.   fromVersion  The version which the release is from.   tarballUrl  The release tarball url.   targetCommitish  The release target commitish.   zipballUrl  The release zipball url.   compareUrl  The release compare url.  e.g.   https://github.com/ppodds/relno/compare/v0.0.1-alpha.1...v0.0.1-alpha.2",{"id":90,"path":91,"dir":63,"title":92,"description":93,"keywords":94,"body":97},"content:2.guide:4.variables:3.prtype-context.md","/guide/variables/prtype-context","PR Type Context","The following variables are available in pr type context. They are injected into the context when you use prTypes option in the configuation file.",[95,96],"title","identifier","  PR Type Context  The following variables are available in pr type context. They are injected into the context when you use   prTypes  option in the configuation file.   title  Same as   title  which set in   prTypes .   identifier  Same as   identifier  which set in   prTypes .",{"id":99,"path":100,"dir":63,"title":101,"description":102,"keywords":103,"body":116},"content:2.guide:4.variables:4.commit-context.md","/guide/variables/commit-context","Commits Context","The following variables are available in commit context. These variables are from the commit message and commit information.",[104,105,106,107,108,109,110,111,74,75,112,113,114,115],"hash","parents","date","message","refs","body","commiterName","commiterEmail","prType","prSubtype","prBreaking","prNumber","  Commits Context  The following variables are available in commit context. These variables are from the commit message and commit information.   hash  The commit hash.   parents  The commit parents hash (separated by   \" \" ).   date  The commit date. It would provided as a UTC time. You can use   formatDate  macro to format it.   message  The commit message (without other information).  e.g.   docs: a test (#1)  =>   a test   refs  The commit refs (separated by   \" \" ).   body  The commit body.   commiterName  The commiter name. If you merge a pull request on GitHub,   commiterName  will be   GitHub .   commiterEmail  The commiter email. If you merge a pull request on GitHub,   commiterEmail  will be   noreply@github.com .   authorName  The author name (set in git config).   authorEmail  The author email (set in git config).   prType  The pull request type (extracted from commit message)  e.g.   docs: a test (#1)  =>   docs   prSubtype  The pull request subtype (extracted from commit message)  e.g.   docs(test): a test (#1)  =>   test   prBreaking  If the pull request is breaking change. It would be a   boolean  value, if you use it in template directly, it will be   true  or   false .  e.g.   feat!: breaking change (#1)  =>   true   prNumber  The pull request number (extracted from commit message).  e.g.   docs: a test (#1)  =>   1",{"id":118,"path":119,"dir":120,"title":33,"description":121,"keywords":122,"body":123},"content:2.guide:5.macros:1.introduction.md","/guide/macros/introduction","macros","Macros can be used in the expression in the template. It is a function that will be called when the expression is evaluated. You can use it just like a JavaScript function.",[],"  Introduction  Macros can be used in the expression in the template. It is a function that will be called when the expression is evaluated. You can use it just like a JavaScript function.",{"id":125,"path":126,"dir":120,"title":127,"description":7,"keywords":128,"body":132},"content:2.guide:5.macros:2.string-utils.md","/guide/macros/string-utils","String Utils",[129,130,131],"toSentence","toTitle","formatDate","  String Utils  toSentence  Signature:   toSentence(str: string)  Convert a string to a sentence.  Examples:      toSentence  (  \"this is a sentence\"  )\n   This is a sentence\n      toSentence  (  \"test\"  )\n   Test\n  toTitle  Signature:   toTitle(str: string)  Convert a string to a title.  Examples:      toTitle  (  \"this is a title\"  )\n   This Is  A Title\n      toTitle  (  \"test\"  )\n   Test\n  formatDate  Signature:   formatDate(dateStr: string, format: string)  Generate a formatted date string. Check out   date-and-time  to see the supported format string.  Examples:      // publishedAt = \"2022-01-01T00:00:00Z\"\n   formatDate  (publishedAt,   \"YYYY-MM-DD\"  )\n   2022-01-01\n  html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":134,"path":135,"dir":120,"title":136,"description":7,"keywords":137,"body":142},"content:2.guide:5.macros:3.condition.md","/guide/macros/condition","Condition",[138,139,140,141],"generateIfNotEmpty","generateIfEmpty","generateIfNot","generateIf","  Condition  generateIfNotEmpty  Signature:   generateIfNotEmpty(toBeCheck: string, content: string)  Generate content if the string is not empty.  Examples:      generateIfNotEmpty  (  \"\"  ,   \"test\"  )\n         generateIfNotEmpty  (  \"a\"  ,   \"test\"  )\n   test\n  generateIfEmpty  Signature:   generateIfEmpty(toBeCheck: string, content: string)  Generate content if the string is empty.  Examples:      generateIfEmpty  (  \"\"  ,   \"test\"  )\n   test\n      generateIfEmpty  (  \"a\"  ,   \"test\"  )\n     generateIfNot  Signature:   generateIfNot(condition: boolean, content: string)  Generate content if the condition is   false .  Examples:      generateIfNot  (  true  ,   \"test\"  )\n         generateIfNot  (  false  ,   \"test\"  )\n   test\n  generateIf  Signature:   generateIf(condition: string, content: string)  Generate content if the condition is   true .  Examples:      generateIf  (  true  ,   \"test\"  )\n   test\n      generateIf  (  false  ,   \"test\"  )\n     html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":144,"path":145,"dir":146,"title":33,"description":147,"keywords":148,"body":149},"content:2.guide:6.plugin:1.introduction.md","/guide/plugin/introduction","plugin","Relno provides a plugin system to extend the functionality of Relno. Plugin can access the Relno API and can be used to implement custom features. Plugin system provides high flexibility, and you can also publish your plugin to npm.",[],"  Introduction  Relno provides a plugin system to extend the functionality of Relno. Plugin can access the Relno API and can be used to implement custom features. Plugin system provides high flexibility, and you can also publish your plugin to npm.  A plugin can be added to Relno by adding it to the   plugins  option in configuration file.      const   {   MyPlugin   }   =   require  (  \"my-plugin\"  );\n   \n   module  .export   =   {\n       ...\n       plugins: [\n           // add your plugin here\n           MyPlugin\n       ]\n   };\n  html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":151,"path":152,"dir":146,"title":153,"description":154,"keywords":155,"body":159},"content:2.guide:6.plugin:2.write-plugin.md","/guide/plugin/write-plugin","Write Your Own Plugin","As we mentioned in the previous section, plugin can access the Relno API and can be used to implement custom features. In this section, we will learn how to write a plugin.",[156,157,158],"Plugin Structure","Register Lifecycle Hooks","Register Custom Sections","  Write Your Own Plugin  As we mentioned in the previous section, plugin can access the Relno API and can be used to implement custom features. In this section, we will learn how to write a plugin.  Plugin Structure  A Relno plugin is a function that registers lifecycle hooks and custom sections. The function will be called by Relno when building the generator. Relno provides a function to provide typechecking for the plugin. In the following example, we create a plugin and export it as   RelnoExamplePlugin .      import   {\n     defineRelnoPlugin,\n   }   from   \"relno\"  ;\n   \n   export   const   RelnoExamplePlugin   =   defineRelnoPlugin  (  async   (  generator  )   =>   {\n       // register lifecycle hooks and custom sections here\n       ...\n   });\n  Register Lifecycle Hooks  Relno provides a set of lifecycle hooks that can be used to customize the behavior of Relno. You can register a lifecycle hook by calling the   addHook  method of the generator.   addHook  method takes two parameters: the lifecycle hook and the callback function. The callback function will be called when the lifecycle hook is triggered. The callback function will be called with the generator and the context as parameters. The context contains the information that is relevant to the lifecycle hook. For this example, we register a   BeforeGenerate  hook. The   BeforeGenerate  hook is triggered before the generator starts to generate the release note. The context contains the commits that are included in the release note.      export   const   RelnoExamplePlugin   =   defineRelnoPlugin  (  async   (  generator  )   =>   {\n       generator.  addHook  (\n           Lifecycle.BeforeGenerate,\n           async   (  generator  :   Generator  ,   context  :   BeforeGenerateContext  )   =>   {\n               const   commits   =   context.commits;\n               // do something with the commits object\n           },\n       );\n   });\n  Register Custom Sections  Relno provides custom section support. You can register a custom section by calling the   addSection  method of the generator.   addSection  method needs a section object as parameter. The section object controll the rendering logic of the section. For this example, we register a custom section named   mySection  and render it simply. The   parse  method of the section object will be called when the generator starts to parse   mySection  section.   sectionNode  parameter is the AST node parsed by parser. The   parse  method should return a   SectionNode  object. You should parse the children of the   sectionNode  and return the result. Relno provides a   parseNode  method to parse a node recursively. If the node is a section node, it will parse the node recursively. If the node is a text node, it will render the node and the expression syntax will be evaluated. The following example pass a variable named   testVariable  to the   parseNode  method.      import   { Generator, Section, SectionNode, TemplateNodeType }   from   \"relno\"  ;\n   \n   class   MySection   extends   Section   {\n       public   constructor  () {\n           super  (  \"mySection\"  );\n       }\n   \n       public   async   parse  (\n           generator  :   Generator  ,\n           sectionNode  :   SectionNode  ,\n       )  :   Promise  \u003C  SectionNode  > {\n           const   result  :   SectionNode   =   {\n               type: TemplateNodeType.Section,\n               name: sectionNode.name,\n               tags: sectionNode.tags,\n               children: [],\n           };\n           for   (  const   child   of   sectionNode.children) {\n               result.children.  push  (\n                   await   generator.  parseNode  (generator, child, {\n                       // pass variables, the variables will be available in the section\n                       testVariable:   \"test\"  ,\n                   }),\n               );\n           }\n           return   result;\n       }\n   }\n   \n   export   const   RelnoExamplePlugin   =   defineRelnoPlugin  (  async   (  generator  )   =>   {\n       generator.  addSection  (  new   MySection  ());\n   });\n  html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":161,"path":162,"dir":146,"title":163,"description":164,"keywords":165,"body":167},"content:2.guide:6.plugin:3.contributors-plugin.md","/guide/plugin/contributors-plugin","Contributors Plugin","Relno provides an official plugin to generate a list of contributors. It is a good example to learn how to write a Relno plugin. If you are interested in writing a plugin, you can read the source code of it.",[166],"Contributors Section","  Contributors Plugin  Relno provides an official plugin to generate a list of contributors. It is a good example to learn how to write a Relno plugin. If you are interested in writing a plugin, you can read the source code of it.  Contributors Section  Contributors section can be used to generate a list of contributors. The following example shows how to use the contributors section.      \u003C!-- BEGIN contributors SECTION -->\n   -   {{ contributorName }}\n   \u003C!-- END contributors SECTION -->\n  Variables  The following variables are available in the contributors section.   contributorName  The name of the contributor. It is the name of the author of the commit.   contributorEmail  The email of the contributor. It is the email of the author of the commit.  html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":169,"path":170,"dir":171,"title":172,"description":173,"keywords":174,"body":175},"content:3.api:1.config:1.define-relno-config.md","/api/config/define-relno-config","config","defineRelnoConfig","Define the configuration for Relno. This function provides the typechecking for the configuration. If you want to use this function, you must install Relno as a dev dependency, and can only be run when node_modules is present. In CI environments, it is not useful because you need to install the dependencies first.",[],"   defineRelnoConfig  Define the configuration for Relno. This function provides the typechecking for the configuration. If you want to use this function, you must install Relno as a dev dependency, and can only be run when   node_modules  is present. In CI environments, it is not useful because you need to install the dependencies first.   Usage:      const   {   defineRelnoConfig   }   =   require  (  \"relno\"  );\n   \n   module  .export   =   defineRelnoConfig  ({\n       template:   \"template.rntmd\"  ,\n       ...\n   });\n  html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":177,"path":178,"dir":179,"title":180,"description":181,"keywords":182,"body":183},"content:3.api:2.generator:1.generate.md","/api/generator/generate","generator","generate","Generate a release note by the generator instance.",[],"   generate  Generate a release note by the generator instance.   Usage:      const   {   Generator   }   =   require  (  \"relno\"  );\n   \n   const   generator   =   new   Generator  ([], {\n       template:   \"\"  ,\n       prTypes: [],\n       metadata: {}   as   ReleaseMetadata  ,\n   });\n   const   result   =   await   generator.  generate  ();\n  html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":185,"path":186,"dir":179,"title":187,"description":188,"keywords":189,"body":190},"content:3.api:2.generator:2.add-section.md","/api/generator/add-section","addSection","Add a custom section to the generator instance.",[],"   addSection  Add a custom section to the generator instance.   Usage:      import   { Generator, Section, SectionNode, TemplateNodeType }   from   \"relno\"  ;\n   \n   class   MySection   extends   Section   {\n       public   constructor  () {\n           super  (  \"mySection\"  );\n       }\n   \n       public   async   parse  (\n           generator  :   Generator  ,\n           sectionNode  :   SectionNode  ,\n       )  :   Promise  \u003C  SectionNode  > {\n           const   result  :   SectionNode   =   {\n               type: TemplateNodeType.Section,\n               name: sectionNode.name,\n               tags: sectionNode.tags,\n               children: [],\n           };\n           for   (  const   child   of   sectionNode.children) {\n               result.children.  push  (\n                   await   generator.  parseNode  (generator, child, {}),\n               );\n           }\n           return   result;\n       }\n   }\n   \n   const   generator   =   new   Generator  ([], {\n       template:   \"\"  ,\n       prTypes: [],\n       metadata: {}   as   ReleaseMetadata  ,\n   });\n   generator.  addSection  (  new   MySection  ());\n   Learn more about   custom section .  html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":192,"path":193,"dir":179,"title":194,"description":195,"keywords":196,"body":197},"content:3.api:2.generator:4.add-hook.md","/api/generator/add-hook","addHook","Add a lifecycle hook to the generator instance.",[],"   addHook  Add a lifecycle hook to the generator instance.   Usage:      import   { Generator, BeforeGenerateContext }   from   \"relno\"  ;\n   \n   const   generator   =   new   Generator  ([], {\n       template:   \"\"  ,\n       prTypes: [],\n       metadata: {}   as   ReleaseMetadata  ,\n   });\n   generator.  addHook  (\n       Lifecycle.BeforeGenerate,\n       async   (  generator  :   Generator  ,   context  :   BeforeGenerateContext  )   =>   {\n           const   commits   =   context.commits;\n           // do something with the commits object\n       },\n   );\n   Learn more about   lifecycle hooks .  html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":199,"path":200,"dir":179,"title":201,"description":202,"keywords":203,"body":204},"content:3.api:2.generator:5.parse-node.md","/api/generator/parse-node","parseNode","Parse a node recursively. If the node is a section node, it will parse the node recursively. If the node is a text node, it will render the node and the expression syntax will be evaluated.",[],"   parseNode  Parse a node recursively. If the node is a section node, it will parse the node recursively. If the node is a text node, it will render the node and the expression syntax will be evaluated.   Learn more about   use cases .",{"id":206,"path":207,"dir":208,"title":209,"description":7,"keywords":210,"body":214},"content:3.api:3.advanced:1.lifecycle-hooks.md","/api/advanced/lifecycle-hooks","advanced","Lifecycle Hooks",[211,212,213],"BeforeGenerate","AfterGenerate","Generating","  Lifecycle Hooks   BeforeGenerate  Context Type     interface   BeforeGenerateContext   {\n       lifecycle  :   Lifecycle  .  BeforeGenerate  ;\n       commits  :   Commit  [];\n   }\n   AfterGenerate  Context Type     interface   AfterGenerateContext   {\n       lifecycle  :   Lifecycle  .  AfterGenerate  ;\n       commits  :   Commit  [];\n   }\n   Generating  Context Type     interface   GeneratingContext   {\n       lifecycle  :   Lifecycle  .  Generating  ;\n       sectionName  :   string  ;\n       variable  :   Variable  ;\n       result  :   SectionNode  ;\n   }\n  html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":216,"path":217,"dir":7,"title":218,"description":7,"keywords":219,"body":221},"content:4.faq.md","/faq","Frequently Asked Questions",[220],"How do relno-action know when to update the release note?","  Frequently Asked Questions  How do   relno-action  know when to update the release note?   relno-action  will check the release body to see if it contains   \u003C!-- Generate by Release Note --> . If it contains this comment, it will not update the release body. It means you can edit the release body manually after the release note is generated. This is useful when you want to add some extra information in the specify release.   If you want to update the release note, you need to remove the comment.  Action failed with   unknown revision or path not in the working tree  error  This error is caused by   actions/checkout  action. You need to add   fetch-depth: 0  to the   actions/checkout  action.   actions/checkout  will only fetch the commit which triggered the workflow by default. If you want to get the whole commit tree, you need to set   fetch-depth  manually. See   actions/checkout .      -   uses  :   actions/checkout@v3\n     with  :\n       fetch-depth  :   0\n  html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",1775071098204]