diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index cfa748f0..f7fe1f52 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,3 +8,6 @@ * [ ] Create a file in `src/towncrier/newsfragments/`. Describe your change and include important information. Your change will be included in the public release notes. * [ ] Make sure all GitHub Actions checks are green (they are automatically checking all of the above). +* [ ] Ensure `docs/tutorial.rst` is still up-to-date. +* [ ] If you add new **CLI arguments** (or change the meaning of existing ones), make sure `docs/cli.rst` reflects those changes. +* [ ] If you add new **configuration options** (or change the meaning of existing ones), make sure `docs/configuration.rst` reflects those changes. diff --git a/LICENSE b/LICENSE index 8e558858..72912bfa 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-2016, Amber Brown, meejah +Copyright (c) 2015, Amber Brown and the towncrier contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/README.rst b/README.rst index 3dea1829..5a0ae224 100644 --- a/README.rst +++ b/README.rst @@ -1,20 +1,26 @@ Hear ye, hear ye, says the ``towncrier`` ======================================== -.. image:: https://img.shields.io/github/workflow/status/twisted/towncrier/CI/trunk - :alt: GitHub Actions - :target: https://github.com/twisted/towncrier/actions?query=branch%3Atrunk +.. image:: https://img.shields.io/badge/Docs-Read%20The%20Docs-black + :alt: Documentation + :target: https://towncrier.readthedocs.io/ -.. image:: https://img.shields.io/codecov/c/github/twisted/towncrier/trunk - :alt: Codecov - :target: https://app.codecov.io/gh/twisted/towncrier/branch/trunk +.. image:: https://img.shields.io/badge/license-MIT-C06524 + :alt: License: MIT + :target: https://github.com/twisted/towncrier/blob/trunk/LICENSE +.. image:: https://img.shields.io/pypi/v/towncrier + :alt: PyPI release + :target: https://pypi.org/project/towncrier/ -``towncrier`` is a utility to produce useful, summarised news files for your project. -Rather than reading the Git history as some newer tools to produce it, or having one single file which developers all write to, ``towncrier`` reads "news fragments" which contain information `useful to end users`. +``towncrier`` is a utility to produce useful, summarized news files (also known as changelogs) for your project. + +Rather than reading the Git history, or having one single file which developers all write to and produce merge conflicts, ``towncrier`` reads "news fragments" which contain information useful to **end users**. Used by `Twisted `_, `pytest `_, `pip `_, `BuildBot `_, and `attrs `_, among others. +While the command line tool ``towncrier`` works on Python 3.7+ only, as long as you don't use any Python-specific affordances (like auto-detection of the project version), it is usable with **any project type** on **any platform**. + Philosophy ---------- @@ -22,182 +28,18 @@ Philosophy ``towncrier`` delivers the news which is convenient to those that hear it, not those that write it. That is, by duplicating what has changed from the "developer log" (which may contain complex information about the original issue, how it was fixed, who authored the fix, and who reviewed the fix) into a "news fragment" (a small file containing just enough information to be useful to end users), ``towncrier`` can produce a digest of the changes which is valuable to those who may wish to use the software. -These fragments are also commonly called "topfiles" or "newsfiles" in Twisted parlance. +These fragments are also commonly called "topfiles" or "newsfiles". ``towncrier`` works best in a development system where all merges involve closing a ticket. +To get started, check out our `tutorial `_! -Quick Start ------------ - -Install from PyPI:: - - python3 -m pip install towncrier - -.. note:: - - ``towncrier``, as a command line tool, works on Python 3.7+ only. - It is usable by projects written in other languages, provided you specify the project version either in the configuration file or on the command line. - For Python-compatible projects, the version can be discovered automatically. - -In your project root, add a ``towncrier.toml`` or a ``pyproject.toml`` file (if both files exist, the first will take precedence). -You can configure your project in two ways. -To configure it via an explicit directory, add: - -.. code-block:: toml - - [tool.towncrier] - directory = "changes" - -Alternatively, to configure it relative to a (Python) package directory, add: - -.. code-block:: toml - - [tool.towncrier] - package = "mypackage" - package_dir = "src" - filename = "NEWS.rst" - -.. note:: - - ``towncrier`` will also look in ``pyproject.toml`` for configuration if ``towncrier.toml`` is not found. - -For the latter, news fragments (see "News Fragments" below) should be in a ``newsfragments`` directory under your package. -Using the above example, your news fragments would be ``src/myproject/newsfragments/``). - -.. tip:: - - To prevent git from removing the ``newsfragments`` directory, make a ``.gitignore`` file in it with:: - - !.gitignore - - This will keep the folder around, but otherwise "empty". - -``towncrier`` needs to know what version your project is, and there are three ways you can give it: - -- For Python-compatible projects, a ``__version__`` in the top level package. - This can be either a string literal, a tuple, or an `Incremental `_ version. - -- Manually passing ``--version=`` when interacting with ``towncrier``. - -- Definining a ``version`` option in a configuration file: - -.. code-block:: ini - - [tool.towncrier] - # ... - version = "1.2.3" # project version if maintained separately - -To create a new news fragment, use the ``towncrier create`` command. -For example:: - - towncrier create 123.feature - -If a news fragment is not tied to an issue, use `+` as the basename (a random hash will be added to the filename to keep it unique): - - towncrier create +.feature - -To produce a draft of the news file, run:: - - towncrier build --draft - -To produce the news file for real, run:: - - towncrier build - -This command will remove the news files (with ``git rm``) and append the built news to the filename specified by the ``filename`` configuration option, and then stage the news file changes (with ``git add``). -It leaves committing the changes up to the user. - -If you wish to have content at the top of the news file (for example, to say where you can find the tickets), put your text above a rST comment that says:: - - .. towncrier release notes start - -``towncrier`` will then put the version notes after this comment, and leave your existing content that was above it where it is. - - -News Fragments --------------- - -``towncrier`` has a few standard types of news fragments, signified by the file extension. -These are: - -- ``.feature``: Signifying a new feature. -- ``.bugfix``: Signifying a bug fix. -- ``.doc``: Signifying a documentation improvement. -- ``.removal``: Signifying a deprecation or removal of public API. -- ``.misc``: A ticket has been closed, but it is not of interest to users. - -The start of the filename is the ticket number, and the content is what will end up in the news file. -For example, if ticket #850 is about adding a new widget, the filename would be ``myproject/newsfragments/850.feature`` and the content would be ``myproject.widget has been added``. - - -Further Options ---------------- - -Towncrier has the following global options, which can be specified in the toml file: - -.. code-block:: toml - - [tool.towncrier] - package = "" - package_dir = "." - single_file = true # if false, filename is formatted like `title_format`. - filename = "NEWS.rst" - directory = "directory/of/news/fragments" - version = "1.2.3" # project version if maintained separately - name = "arbitrary project name" - template = "path/to/template.rst" - start_string = "Text used to detect where to add the generated content in the middle of a file. Generated content added after this text. Newline auto added." - title_format = "{name} {version} ({project_date})" # or false if template includes title - issue_format = "format string for {issue} (issue is the first part of fragment name)" - underlines = "=-~" - wrap = false # Wrap text to 79 characters - all_bullets = true # make all fragments bullet points - orphan_prefix = "+" # Prefix for orphan news fragment files, set to "" to disable. - -If ``single_file`` is set to ``true`` or unspecified, all changes will be written to a single -fixed newsfile, whose name is literally fixed as the ``filename`` option. In each run of ``towncrier build``, -content of new changes will append at the top of old content, and after ``start_string`` if the -``start_string`` already appears in the newsfile. If the corresponding ``top_line``, which is formatted -as the option 'title_format', already exists in newsfile, ``ValueError`` will be raised to remind -you "already produced newsfiles for this version". - -If ``single_file`` is set to ``false`` instead, each versioned ``towncrier build`` will generate a -separate newsfile, whose name is formatted as the pattern given by option ``filename``. -For example, if ``filename="{version}-notes.rst"``, then the release note with version "7.8.9" will -be written to the file "7.8.9-notes.rst". If the newsfile already exists, its content -will be overwriten with new release note, without throwing a ``ValueError`` warning. - -If ``title_format`` is unspecified or an empty string, the default format will be used. -If set to ``false``, no title will be created. -This can be useful if the specified template creates the title itself. - -Furthermore, you can customize each of your own fragment types using: - -.. code-block:: toml - - [tool.towncrier] - # To add custom fragment types, with default setting, just add an empty section. - [tool.towncrier.fragment.feat] - [tool.towncrier.fragment.fix] - - # Custom fragment types can have custom attributes - # that are used when rendering the result based on the template. - [tool.towncrier.fragment.chore] - name = "Other Tasks" - showcontent = false - - - -Automatic pull request checks ------------------------------ - -To check if a feature branch adds at least one news fragment, run:: - - towncrier check - -By default this compares the current branch against ``origin/main``. You can use ``--compare-with`` if the trunk is named differently:: +.. links - towncrier check --compare-with origin/master +Project Links +------------- -The check is automatically skipped when the main news file is modified inside the branch as this signals a release branch that is expected to not have news fragments. +- **PyPI**: https://pypi.org/project/towncrier/ +- **Documentation**: https://towncrier.readthedocs.io/ +- **News**: https://github.com/twisted/towncrier/blob/trunk/NEWS.rst +- **License**: `MIT `_ diff --git a/RELEASE.rst b/RELEASE.rst index 54485ade..6a4e9918 100644 --- a/RELEASE.rst +++ b/RELEASE.rst @@ -1,5 +1,5 @@ -Releasing -========= +Release Process +=============== .. note:: Commands are written with Linux in mind and a ``venv`` located in ``venv/``. diff --git a/docs/cli.rst b/docs/cli.rst new file mode 100644 index 00000000..c7c621a4 --- /dev/null +++ b/docs/cli.rst @@ -0,0 +1,87 @@ +Command Line Reference +====================== + +The following options can be passed to all of the commands that explained below: + +.. option:: --config FILE_PATH + + Pass a custom config file at ``FILE_PATH``. + + Default: ``towncrier.toml`` or ``pyproject.toml`` file. + If both files exist, the first will take precedence + +.. option:: --dir PATH + + Build fragment in ``PATH``. + + Default: current directory. + + +``towncrier build`` +------------------- + +Build the combined news file from news fragments. +``build`` is also assumed if no command is passed. + +.. option:: --draft + + Only render news fragments to standard output. + Don't write to files, don't check versions. + +.. option:: --name NAME + + Use `NAME` as project name in the news file. + Can be configured. + +.. option:: --version VERSION + + Use ``VERSION`` in the rendered news file. + Can be configured or guessed (default). + +.. option:: --date DATE + + The date in `ISO format `_ to use in the news file. + + Default: today's date + +.. option:: --yes + + Do not ask for confirmations. + Useful for automated tasks. + + +``towncrier create`` +-------------------- + +Create a news fragment in the directory that ``towncrier`` is configured to look for fragments:: + + $ towncrier create 123.bugfix.rst + +``towncrier create`` will enforce that the passed type (e.g. ``bugfix``) is valid. + +.. option:: --content, -c CONTENT + + A string to use for content. + Default: an instructive placeholder. + +.. option:: --edit + + Create file and start `$EDITOR` to edit it right away.` + + +``towncrier check`` +------------------- + +To check if a feature branch adds at least one news fragment, run:: + + $ towncrier check + +The check is automatically skipped when the main news file is modified inside the branch as this signals a release branch that is expected to not have news fragments. + +By default, ``towncrier`` compares the current branch against ``origin/main`` (and falls back to ``origin/master`` with a warning if it exists, *for now*). + +.. option:: --compare-with REMOTE-BRANCH + + Use ``REMOTE-BRANCH`` instead of ``origin/main``:: + + $ towncrier check --compare-with origin/trunk diff --git a/docs/conf.py b/docs/conf.py index 62092d11..66ee6254 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -84,7 +84,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = "alabaster" +html_theme = "furo" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -97,21 +97,6 @@ # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = [] -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# This is required for the alabaster theme -# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars -html_sidebars = { - "**": [ - "about.html", - "navigation.html", - "relations.html", # needs 'show_related': True theme option to display - "searchbox.html", - "donate.html", - ] -} - # -- Options for HTMLHelp output ------------------------------------------ diff --git a/docs/configuration.rst b/docs/configuration.rst index 4cd86773..06bfb6ec 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1,97 +1,96 @@ Configuration Reference ======================= -``towncrier`` has many knobs and switches you can use, to customise it to your project's needs. +``towncrier`` has many knobs and switches you can use, to customize it to your project's needs. The setup in the `Quick Start `_ doesn't touch on many, but this document will detail each of these options for you! -For how to perform common customisation tasks, see `Customisation `_. +For how to perform common customization tasks, see `Customization `_. ``[tool.towncrier]`` -------------------- All configuration for ``towncrier`` sits inside ``pyproject.toml``, under the ``tool.towncrier`` namespace. -Please see `the TOML GitHub repo `_ for how to write TOML. +Please see https://toml.io/ for how to write TOML. + Top level keys ~~~~~~~~~~~~~~ +- ``directory`` -- If you are not storing your news fragments in your Python package, or aren't using Python, this is the path to where your newsfragments will be put. +- ``newsfile`` -- The filename of your news file. ``NEWS.rst`` by default. - ``package`` -- The package name of your project. (Python projects only) - ``package_dir`` -- The folder your package lives. ``./`` by default, some projects might need to use ``src``. (Python projects only) -- ``newsfile`` -- The filename of your news file. ``NEWS.rst`` by default. -- ``fragment_directory`` -- If you are not storing your newsfragments in your Python package, or aren't using Python, this is the path to where your newsfragments will be put. -- ``template`` -- Path to an alternate template for generating the newsfile, if you have one. -- ``start_line`` -- The magic string that ``towncrier`` looks for when considering where the release notes should start. ``.. towncrier release notes start`` by default. -- ``title_format`` -- A format string for the title of your project. ``{name} {version} ({project_date})`` by default. -- ``issue_format`` -- A format string for rendering the issue/ticket number in newsfiles. ``#{issue}`` by default. -- ``underlines`` -- The characters used for underlining headers. ``["=", "-", "~"]`` by default. +- ``template`` -- Path to an alternate template for generating the news file, if you have one. +- ``start_line`` -- The magic string that ``towncrier`` looks for when considering where the release notes should start. + ``.. towncrier release notes start`` by default. +- ``title_format`` -- A format string for the title of your project. + ``{name} {version} ({project_date})`` by default. +- ``issue_format`` -- A format string for rendering the issue/ticket number in newsfiles. + ``#{issue}`` by default. +- ``underlines`` -- The characters used for underlining headers. + ``["=", "-", "~"]`` by default. + Custom fragment types --------------------- -``Towncrier`` allows defining custom fragment types. Custom fragment types -will be used instead ``towncrier`` default ones, they are not combined. +``towncrier`` allows defining custom fragment types. +Custom fragment types will be used instead ``towncrier`` default ones, they are not combined. Users can configure each of their own custom fragment types by adding tables to the pyproject.toml named ``[tool.towncrier.fragment.]``. These tables may include the following optional keys: - * ``name``: The description of the fragment type, as it must be included - in the news file. If omitted, it defaults to its fragment type, - but capitalized. - * ``showcontent``: Whether if the fragment contents should be included in the - news file. If omitted, it defaults to ``true`` - - - -For example, if you want your custom fragment types to be -``["feat", "fix", "chore",]`` and you want all -of them to use the default configuration except ``"chore"`` you can do it as -follows: + * ``name``: The description of the fragment type, as it must be included in the news file. + If omitted, it defaults to its fragment type, but capitalized. + * ``showcontent``: Whether if the fragment contents should be included in the news file. If omitted, it defaults to ``true`` +For example, if you want your custom fragment types to be ``["feat", "fix", "chore",]`` and you want all of them to use the default configuration except ``"chore"`` you can do it as follows: .. code-block:: toml + [tool.towncrier] - [tool.towncrier] + [tool.towncrier.fragment.feat] + [tool.towncrier.fragment.fix] + [tool.towncrier.fragment.chore] + name = "Other Tasks" + showcontent = false - [tool.towncrier.fragment.feat] - [tool.towncrier.fragment.fix] - [tool.towncrier.fragment.chore] - name = "Other Tasks" - showcontent = false +All Options +----------- -DEPRECATED: Defining custom fragment types with an array of toml tables -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Users can create their own custom fragment types by adding an array of -tables to the pyproject.toml named ``[[tool.towncrier.type]]``. - -If still using this way to configure custom fragment types, -please notice that ``fragment_types`` must be empty or not provided. - -Each custom type (``[[tool.towncrier.type]]``) has the following -mandatory keys: - -* ``directory``: The type of the fragment. -* ``name``: The description of the fragment type, as it must be included - in the news file. -* ``showcontent``: Whether if the fragment contents should be included in the - news file. - - - -For example: +``towncrier`` has the following global options, which can be specified in the toml file: .. code-block:: toml - [tool.towncrier] - [[tool.towncrier.type]] - directory = "deprecation" - name = "Deprecations" - showcontent = true - - [[tool.towncrier.type]] - directory = "chore" - name = "Other Tasks" - showcontent = false + [tool.towncrier] + package = "" + package_dir = "." + single_file = true # if false, filename is formatted like `title_format`. + filename = "NEWS.rst" + directory = "directory/of/news/fragments" + version = "1.2.3" # project version if maintained separately + name = "arbitrary project name" + template = "path/to/template.rst" + start_string = "Text used to detect where to add the generated content in the middle of a file. Generated content added after this text. Newline auto added." + title_format = "{name} {version} ({project_date})" # or false if template includes title + issue_format = "format string for {issue} (issue is the first part of fragment name)" + underlines = "=-~" + wrap = false # Wrap text to 79 characters + all_bullets = true # make all fragments bullet points + orphan_prefix = "+" # Prefix for orphan news fragment files, set to "" to disable. + +If ``single_file`` is set to ``true`` or unspecified, all changes will be written to a single fixed newsfile, whose name is literally fixed as the ``filename`` option. +In each run of ``towncrier build``, content of new changes will append at the top of old content, and after ``start_string`` if the ``start_string`` already appears in the newsfile. +If the corresponding ``top_line``, which is formatted as the option 'title_format', already exists in newsfile, ``ValueError`` will be raised to remind you "already produced newsfiles for this version". + +If ``single_file`` is set to ``false`` instead, each versioned ``towncrier build`` will generate a separate newsfile, whose name is formatted as the pattern given by option ``filename``. +For example, if ``filename="{version}-notes.rst"``, then the release note with version "7.8.9" will be written to the file "7.8.9-notes.rst". +If the newsfile already exists, its content will be overwritten with new release note, without throwing a ``ValueError`` warning. + +If ``title_format`` is unspecified or an empty string, the default format will be used. +If set to ``false``, no title will be created. +This can be useful if the specified template creates the title itself. diff --git a/docs/contributing.rst b/docs/contributing.rst new file mode 100644 index 00000000..e582053e --- /dev/null +++ b/docs/contributing.rst @@ -0,0 +1 @@ +.. include:: ../CONTRIBUTING.rst diff --git a/docs/customisation/index.rst b/docs/customisation/index.rst deleted file mode 100644 index 189bffa6..00000000 --- a/docs/customisation/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -Customising ``towncrier`` -========================= - -``towncrier`` can be customised to suit your project's needs. -These pages should describe common customisation tasks, while if you want a reference, see `Configuration <../configuration.html>`_. - -.. toctree:: - :maxdepth: 2 - - newsfile diff --git a/docs/customization/index.rst b/docs/customization/index.rst new file mode 100644 index 00000000..4fc689cc --- /dev/null +++ b/docs/customization/index.rst @@ -0,0 +1,10 @@ +Customizing ``towncrier`` +========================= + +``towncrier`` can be customized to suit your project's needs. +These pages should describe common customization tasks, while if you want a reference, see `Configuration <../configuration.html>`_. + +.. toctree:: + :maxdepth: 2 + + newsfile diff --git a/docs/customisation/newsfile.rst b/docs/customization/newsfile.rst similarity index 96% rename from docs/customisation/newsfile.rst rename to docs/customization/newsfile.rst index 6fe4e76a..dc5a7935 100644 --- a/docs/customisation/newsfile.rst +++ b/docs/customization/newsfile.rst @@ -1,4 +1,4 @@ -Customising the News File Output +Customizing the News File Output ================================ Adding Content Above ``towncrier`` diff --git a/docs/index.rst b/docs/index.rst index d58935db..75c1b959 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,9 +1,38 @@ .. include:: ../README.rst + :end-before: To get started, + + +Documentation +------------- + +Narrative +~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + tutorial + + +Reference +~~~~~~~~~ .. toctree:: :maxdepth: 2 - quickstart - customisation/index + cli configuration + customization/index + + +Development +~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + contributing release + +.. include:: ../README.rst + :start-after: .. links diff --git a/docs/quickstart.rst b/docs/quickstart.rst deleted file mode 100644 index 75b267ed..00000000 --- a/docs/quickstart.rst +++ /dev/null @@ -1,141 +0,0 @@ -Quick Start -=========== - -This guide assumes you have a Python project that you wish to use ``towncrier`` on, to generate its news files/changelogs. -It will cover setting up your project with a basic configuration, which you can then feel free to `customise `_. - -Configuration -------------- - -``towncrier`` keeps its config in the `PEP-518 `_ ``pyproject.toml`` file. - -The most basic configuration is annotated below:: - - [tool.towncrier] - # The name of your Python package - package = "myproject" - # The path to your Python package. - # If your package lives in 'src/myproject/', it must be 'src', - # but if you don't keep your code in a 'src' dir, remove the - # config option - package_dir = "src" - # Where you want your news files to come out. This can be .rst - # or .md, towncrier's default template works with both. - filename = "NEWS.rst" - -By default, ``towncrier`` will look for news fragments inside your Python package, in a directory named ``newsfragments``. -With this example project, it will look in ``src/myproject/newsfragments/`` for them. - -Create this folder:: - - $ mkdir src/myproject/newsfragments/ - # This makes sure that Git will never delete the empty folder - $ echo '!.gitignore' > src/myproject/newsfragments/.gitignore - -The ``.gitignore`` will remain and keep Git from not tracking the directory. - - -Detecting Dates & Versions --------------------------- - -``towncrier`` needs to know what version your project is, and there are two ways you can give it: - -- For Python 2/3 compatible projects, a ``__version__`` in the top level package. - This can be either a string literal, a tuple, or an `Incremental `_ version. -- Manually passing ``--version=`` when interacting with ``towncrier``. - -As an example, if your package didn't have a ``__version__``, you could manually specify it when calling ``towncrier`` on the command line with the ``--version`` flag:: - - $ towncrier --version=1.2.3post4 - -``towncrier`` will also include the date (in ``YYYY-MM-DD`` format) when generating news files. -You can change this with the ``--date`` flag:: - - $ towncrier --date=2018-01-01 - - -Creating News Fragments ------------------------ - -``towncrier`` news fragments are categorised according to their 'type'. -There are five default types, but you can configure them freely (see `Configuration `_ for details). - -The five default types are: - -- ``feature``: Signifying a new feature. -- ``bugfix``: Signifying a bug fix. -- ``doc``: Signifying a documentation improvement. -- ``removal``: Signifying a deprecation or removal of public API. -- ``misc``: A ticket has been closed, but it is not of interest to users. - -When you create a news fragment, the filename consists of the ticket ID (or some other unique identifier) as well as the 'type'. -We can create some example news files to demonstrate:: - - $ echo 'Fixed a thing!' > src/myproject/newsfragments/1234.bugfix - $ echo 'Can also be `rst` as well!' > src/myproject/newsfragments/3456.doc.rst - $ echo 'The final part is ignored, so set it to whatever you want.' > src/myproject/newsfragments/8765.removal.txt - $ echo 'misc is special, and does not put the contents of the file in the newsfile.' > src/myproject/newsfragments/1.misc - -For orphan news fragments (those that don't need to be linked to any ticket ID or other identifier), start the file name with ``+``. -The content will still be included in the release notes, at the end of the category corresponding to the file extension:: - - $ echo 'Fixed an unreported thing!' > src/myproject/newsfragments/+anything.bugfix - -We can then see our news fragments compiled by running ``towncrier`` in draft mode:: - - $ towncrier --draft - -You should get an output similar to this:: - - $ towncrier --draft - Loading template... - Finding news fragments... - Rendering news fragments... - Draft only -- nothing has been written. - What is seen below is what would be written. - - myproject 1.0.2 (2017-08-21) - ============================ - - - Bugfixes - -------- - - - Fixed a thing! (#1234) - - Fixed an unreported thing! - - - Improved Documentation - ---------------------- - - - Can also be `rst` as well! (#3456) - - - Deprecations and Removals - ------------------------- - - - The final part is ignored, so set it to whatever you want. (#8765) - - - Misc - ---- - - - #1 - - -Producing News Files In Production ----------------------------------- - -To produce the news file for real, run:: - - $ towncrier - -This command will remove the news files (with ``git rm``) and append the built news to the filename specified in ``pyproject.toml``, and then stage the news file changes (with ``git add``). -It leaves committing the changes up to the user. - - -Finale ------- - -You should now have everything you need to get started with ``towncrier``! -Please see `Customising `_ for some common customisation tasks, or `Configuration `_ for the full configuration specification. diff --git a/docs/release.rst b/docs/release.rst index c6bb2ec2..c6238df9 100644 --- a/docs/release.rst +++ b/docs/release.rst @@ -1,4 +1 @@ -Release process -=============== - .. include:: ../RELEASE.rst diff --git a/docs/tutorial.rst b/docs/tutorial.rst new file mode 100644 index 00000000..7b893b1d --- /dev/null +++ b/docs/tutorial.rst @@ -0,0 +1,169 @@ +Tutorial +======== + +This tutorial assumes you have a Python project with a *reStructuredText* (rst) news file (also known as changelog) file that you wish to use ``towncrier`` on, to generate its news file. +It will cover setting up your project with a basic configuration, which you can then feel free to `customize `_. + +Install from PyPI:: + + python3 -m pip install towncrier + + +Configuration +------------- + +``towncrier`` keeps its config in the `PEP-518 `_ ``pyproject.toml`` or a ``towncrier.toml`` file. +If the latter exists, it takes precedence. + +The most basic configuration is just telling ``towncrier`` where to look for news fragments:: + + [tool.towncrier] + directory = "changes" + +Which will look into "./changes" for news fragments and write them into "./NEWS.rst". + +If you're working on a Python project, you can also specify a package:: + + [tool.towncrier] + # The name of your Python package + package = "myproject" + # The path to your Python package. + # If your package lives in 'src/myproject/', it must be 'src', + # but if you don't keep your code in a 'src' dir, remove the + # config option + package_dir = "src" + # Where you want your news files to come out. This can be .rst + # or .md, towncrier's default template works with both. + filename = "NEWS.rst" + +By default, ``towncrier`` will look for news fragments inside your Python package, in a directory named ``newsfragments``. +With this example project, it will look in ``src/myproject/newsfragments/`` for them. + +Create this folder:: + + $ mkdir src/myproject/newsfragments/ + # This makes sure that Git will never delete the empty folder + $ echo '!.gitignore' > src/myproject/newsfragments/.gitignore + +The ``.gitignore`` will remain and keep Git from not tracking the directory. + + +Detecting Dates & Versions +-------------------------- + +``towncrier`` needs to know what version your project is, and there are two ways you can give it: + +- For Python 2/3-compatible projects, a ``__version__`` in the top level package. + This can be either a string literal, a tuple, or an `Incremental `_ version. +- Manually passing ``--version=`` when interacting with ``towncrier``. + +As an example, if your package doesn't have a ``__version__``, you can manually specify it when calling ``towncrier`` on the command line with the ``--version`` flag:: + + $ towncrier build --version=1.2.3post4 + +``towncrier`` will also include the current date (in ``YYYY-MM-DD`` format) when generating news files. +You can change this with the ``--date`` flag:: + + $ towncrier build --date=2018-01-01 + + +Creating News Fragments +----------------------- + +``towncrier`` news fragments are categorised according to their 'type'. +There are five default types, but you can configure them freely (see `Configuration `_ for details). + +The five default types are: + +.. Keep in-sync with DefaultFragmentTypesLoader. + +- ``feature``: Signifying a new feature. +- ``bugfix``: Signifying a bug fix. +- ``doc``: Signifying a documentation improvement. +- ``removal``: Signifying a deprecation or removal of public API. +- ``misc``: A ticket has been closed, but it is not of interest to users. + +When you create a news fragment, the filename consists of the ticket ID (or some other unique identifier) as well as the 'type'. +``towncrier`` does not care about the fragment's suffix. + +You can create those fragments either by hand, or using the ``towncrier create`` command. +Let's create some example news fragments to demonstrate:: + + $ echo 'Fixed a thing!' > src/myproject/newsfragments/1234.bugfix + $ towncrier create --content 'Can also be ``rst`` as well!' 3456.doc.rst + # You can associate multiple ticket numbers with a news fragment by giving them the same contents. + $ towncrier create --content 'Can also be ``rst`` as well!' 7890.doc.rst + $ echo 'The final part is ignored, so set it to whatever you want.' > src/myproject/newsfragments/8765.removal.txt + $ echo 'misc is special, and does not put the contents of the file in the newsfile.' > src/myproject/newsfragments/1.misc + $ towncrier create --edit 2.misc.rst # starts an editor + $ towncrier create -c "Orphan fragments have no ticket ID." +random.bugfix.rst + +For orphan news fragments (those that don't need to be linked to any ticket ID or other identifier), start the file name with ``+``. +The content will still be included in the release notes, at the end of the category corresponding to the file extension:: + + $ echo 'Fixed an unreported thing!' > src/myproject/newsfragments/+anything.bugfix + +.. The --date is the date of towncrier's first release (15.0.0). + +We can then see our news fragments compiled by running ``towncrier`` in draft mode:: + + $ towncrier build --draft --name myproject --version 1.0.2 --date 2015-12-27 + +You should get an output similar to this:: + + Loading template... + Finding news fragments... + Rendering news fragments... + Draft only -- nothing has been written. + What is seen below is what would be written. + + myproject 1.0.2 (2015-12-27) + ============================ + + Bugfixes + -------- + + - Fixed a thing! (#1234) + - Orphan fragments have no ticket ID. + + + Improved Documentation + ---------------------- + + - Can also be ``rst``` as well! (#3456, #7890) + + + Deprecations and Removals + ------------------------- + + - The final part is ignored, so set it to whatever you want. (#8765) + + + Misc + ---- + + - #1, #2 + + +Producing News Files In Production +---------------------------------- + +To produce the news file for real, run:: + + $ towncrier + +This command will remove the news files (with ``git rm``) and append the built news to the filename specified in ``pyproject.toml``, and then stage the news file changes (with ``git add``). +It leaves committing the changes up to the user. + +If you wish to have content at the top of the news file (for example, to say where you can find the tickets), put your text above a rST comment that says:: + + .. towncrier release notes start + +``towncrier`` will then put the version notes after this comment, and leave your existing content that was above it where it is. + + +Finale +------ + +You should now have everything you need to get started with ``towncrier``! +Please see `Customizing `_ for some common c tasks, or `Configuration `_ for the full configuration specification. diff --git a/setup.py b/setup.py index a55a7598..4800f3f5 100644 --- a/setup.py +++ b/setup.py @@ -50,6 +50,7 @@ "dev": [ "packaging", "sphinx >= 5", + "furo", "twisted", ], }, diff --git a/src/towncrier/_settings/fragment_types.py b/src/towncrier/_settings/fragment_types.py index a9b83676..d370986d 100644 --- a/src/towncrier/_settings/fragment_types.py +++ b/src/towncrier/_settings/fragment_types.py @@ -38,6 +38,7 @@ class DefaultFragmentTypesLoader(BaseFragmentTypesLoader): _default_types = clt.OrderedDict( [ + # Keep in-sync with docs/tutorial.rst. ("feature", {"name": "Features", "showcontent": True}), ("bugfix", {"name": "Bugfixes", "showcontent": True}), ("doc", {"name": "Improved Documentation", "showcontent": True}),