Skip to content

Commit

Permalink
Add changelog explanation
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsDrike committed Aug 5, 2024
1 parent 9d61a59 commit 87e35f6
Show file tree
Hide file tree
Showing 2 changed files with 214 additions and 73 deletions.
72 changes: 1 addition & 71 deletions changes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,74 +3,4 @@
This folder holds fragments of the changelog to be used in the next release, when the final changelog will be
generated.

For every pull request made to this project, the contributor is responsible for creating a file (fragment), with
a short description of what that PR changes.

These fragment files use the following format: `{pull_request_number}.{type}.md`,

Possible types are:
- **`feature`**: New feature that affects the public API.
- **`bugfix`**: A bugfix, which was affecting the public API.
- **`docs`**: Change to the documentation, or updates to public facing docstrings
- **`breaking`**: Signifying a breaking change of some part of the project's public API, which could cause issues for
end-users updating to this version. (Includes deprecation removals.)
- **`deprecation`**: Signifying a newly deprecated feature, scheduled for eventual removal.
- **`internal`** Fully internal change that doesn't affect the public API, but is significant enough to be mentioned,
likely because it affects project contributors. (Such as a new linter rule, change in code style, significant change
in internal API, ...)

For changes that do not fall under any of the above cases, please specify the lack of the changelog in the pull request
description, so that a maintainer can skip the job that checks for presence of this fragment file.

## Create fragments with commands

While you absolutely can simply create these files manually, it's a much better idea to use the `towncrier` library,
which can create the file for you in the proper place. With it, you can simply run `towncrier create
{pull_request}.{type}.md` after creating the pull request, edit the created file and commit the changes.

If the change is simple enough, you can even use the `-c`/`--content` flag and specify it directly, like: `towncrier
create 12.feature.md -c "Add dinosaurs!"`, or if you're used to terminal editors, there's also the `--edit` flag, which
opens the file with your `$EDITOR`.

## Preview changelog

To preview the latest changelog, run `towncrier build --draft --version [version number]`. (For version number, you can
pretty much enter anything as this is just for a draft version. For true builds, this would be the next version number,
so for example, if the current version is 1.0.2, next one will be one either 1.0.3, or 1.1.0, or 2.0.0. But for drafts,
you can also just enter something like `next` for the version, as it's just for your own private preview.)

To make this a bit easier, there is a taskipy task running the command above, so you can just use `poetry run task
changelog-preview` to see the changelog, if you don't like remembering new commands.

## Multiple fragments in single PR

If necessary, multiple fragment files can be created per pull-request, with different change types, if the PR covers
multiple areas. For example for PR #13 that both introduces a feature, and changes the documentation, can add
2 fragment files: `13.feature.md` and `13.docs.md`.

Additionally, if a single PR is addressing multiple unrelated topics in the same category, and needs to make multiple
distinct changelog entries, an optional counter value can be added at the end of the file name (needs to be an
integer). So for example PR #25 which makes 2 distinct internal changes can add these fragment files:
`25.internal.1.md` and `25.internal.2.md`. (The numbers in this counter position will not be shown in the final
changelog and are merely here for separation of the individual fragments.)

However if the changes are related to some bigger overarching goal, you can also just use a single fragment file with
the following format:

```markdown
Update changelog
- Rename `documentation` category to shorter: `docs`
- Add `internal` category for changes unrelated to public API, but potentially relevant to contributors
- Add github workflow enforcing presence of a new changelog fragment file for each PR
- For insignificant PRs which don't require any changelog entry, a maintainer can add `skip-fragment-check` label.
```

That said, if you end up making multiple distinct changelog fragments like this, it's a sign that your PR is probably
too big, and you should split it up into multiple PRs instead. Making huge PRs that address several unrelated topics at
once is generally a bad practice, and should be avoided. If you go overboard, your PR might even end up getting closed
for being too big, and you'll be required to split it up.

## Footnotes

- See <https://keepachangelog.com> for more info about why and how to properly maintain a changelog
- For more info about `towncrier`, check out it's [documentation](https://towncrier.readthedocs.io/en/latest/tutorial.html)
To learn more about changelog fragments, see our [documentation](https://py-mine.github.io/mcproto/latest/installation/changelog/)
215 changes: 213 additions & 2 deletions docs/contributing/guides/changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,214 @@
!!! bug "Work In Progress"
# Changelog fragments

This page is still being written. The content below (if any) may change.
Our project contains a changelog which tracks all notable changes for easy and quick reference to both users and our
contributors.

To maintain our changelog, we're using [`towncrier`](https://towncrier.readthedocs.io/en/stable/), which allows us to
create **fragment files**, which each contains a single changelog entry. Once a new release is created, all of
these fragments will be used to create a changelog for that new release.

We generally require every pull request to to include a new changelog fragment, summarizing what it does.

!!! note

If you think your change shouldn't require a changelog entry (it's a small / simple change that isn't worth
noting), ask us to add the `skip-fragment-check` label to your PR, which will disable the automated check that
enforces a presence of the changelog fragment.

## Structure of a fragment file

The fragment files are stored in the `changes/` directory in our project. These files follow the following naming
format: `{pull_request_number.type}.md`.

Possible fragment types are:

- **`feature`**: New feature that affects the public API.
- **`bugfix`**: A bugfix, which was affecting the public API.
- **`docs`**: Change to the documentation, or updates to public facing docstrings
- **`breaking`**: Signifying a breaking change of some part of the project's public API, which could cause issues for
end-users updating to this version. (Includes deprecation removals.)
- **`deprecation`**: Signifying a newly deprecated feature, scheduled for eventual removal.
- **`internal`** Fully internal change that doesn't affect the public API, but is significant enough to be mentioned,
likely because it affects project contributors. (Such as a new linter rule, change in code style, significant change
in internal API, ...)

## Create fragments with commands

While you can absolutely create these files manually, it's often a lot more convenient to use the `towncrier` CLI,
which can create the file for you in the proper place automatically. With it, you can simply run:

```bash
towncrier create {pull_request_number}.{type}.md
```

After you ran the command, a new file will appear in the `changes/` directory. You can now open it and describe your
change inside of it.

If the change is simple enough, you can even use the `-c` / `--content` flag to specify it directly, like:

```bash
towncrier create 12.feature.md -c "Add dinosaurs!"
```

!!! tip "Terminal editors"

If you're used to terminal editors, there's also an `--edit` flag, which will open the file with your
`$EDITOR`. (I would recommend `neovim`, but if you find it too complex, `nano` also works well)

## Multiple fragments in a single PR

If necessary, multiple fragment files can be created per pull-request, with different change types, if the PR covers
multiple areas. For example for PR #13 that both introduces a feature, and changes the documentation, can add 2
fragment files: `13.feature.md` and `13.docs.md`.

Additionally, if a single PR is addressing multiple unrelated topics in the same category, and needs to make multiple
distinct changelog entries, an optional counter value can be added at the end of the file name (needs to be an
integer). So for example PR #25 which makes 2 distinct internal changes can add these fragment files:
`25.internal.1.md` and `25.internal.2.md`. (The numbers in this counter position will not be shown in the final
changelog and are merely here for separation of the individual fragments.)

However if the changes are related to some bigger overarching goal, you can also just use a single fragment file with
the following format:

```markdown title="changes/25.internal.md"
Update towncrier categories

- Rename `documentation` category to shorter: `docs`
- Add `internal` category for changes unrelated to public API, but potentially relevant to contributors
- Add github workflow enforcing presence of a new changelog fragment file for each PR
- For insignificant PRs which don't require any changelog entry, a maintainer can add `skip-fragment-check` label.
```

!!! warning

While possible, if you end up making multiple distinct changelog fragments like this, it's a sign that your PR
might be too big, and you should split it up into multiple PRs instead. Making huge PRs that address several
unrelated topics at once is generally a bad practice, and should be avoided. If you go overboard, your PR might
even end up getting closed for being too big, and you'll be required to split it up.

## Preview changelog

To preview the latest changelog, run `towncrier build --draft --version latest`.

??? note "Meaning of the version value"

The `--version` attribute usually takes the version number of the project, to which these changes apply. However,
since we just want to preview the changes, it doesn't really matter for us, so we can just pass `latest` or
whatever else you wish.

For actual builds, the version is automatically obtained and this command is executed in our release CI workflow.

This version will be used in the first line of the changelog (the header).

??? note "Meaning of --draft flag"

The `--draft` flag will make sure that towncrier will only show you the contents of the next changelog version
entry, but won't actually add that generated content to our `CHANGELOG.md` file, while consuming (removing) the
changelog fragments.

You will never need to run `towncrier` without the `--draft` flag, as our CI workflows for project releasing handle
that automatically.

To make this a bit easier, there is a taskipy task running the command above, so you can just use `poetry run task
changelog-preview` to see the changelog, if you don't like remembering new commands.

## Fragment contents

Fragment files follow the same markdown syntax as our documentation.

The contents of a fragment file should describe the change that you've made in a quick and general way. That said, the
change descriptions can be a bit more verbose than just the PR title, but only if it's necessary. Keep in mind that
these changes will be shown to the end users of the library, so try to explain your change in a way that a
non-contributor would understand.

!!! tip

If your change needs some more in-depth explanations, perhaps with code examples and reasoning for why such a
change was made, use the PR body (description) for this purpose. Each changelog entry will contain a link to the
corresponding pull request, so if someone is interested in any additional details about a change, they can always
look there.

### Examples of good changlog fragment files

:material-check:{ style="color: #4DB6AC" } **Clear and descriptive**

```markdown title="changes/171.feature.md"
Add `Account.check` function, to verify that the access token in use is valid, and the data the Account instance has
matches the data minecraft API has.
```

```markdown title="changes/179.docs.md"
Enforce presence of docstrings everywhere with pydocstyle. This also adds docstring to all functions and classes that
didn't already have one. Minor improvements for consistency were also made to some existing docstrings.
```

:material-check:{ style="color: #4DB6AC" } **Slightly on the longer side, but it's justified** (sometimes, it's
important to explain the issue that this fixes, so that users know that it was there)

```markdown title="changes/330.bugfix.md"
Fix behavior of the `mcproto.utils.deprecation` module, which was incorrectly always using a fallback version, assuming
mcproto is at version 0.0.0. This then could've meant that using a deprecated feature that is past the specified
deprecation (removal) version still only resulted in a deprecation warning, as opposed to a full runtime error.
```

:material-check:{ style="color: #4DB6AC" } **With an extra note about the breaking change** (adding some extra
description isn't always bad, especially for explaining how a breaking change affects existing code)

```markdown title="changes/130.breaking.md"
Renamed "shared_key" field to "shared_secret" in `LoginEncryptionPacket`, following the official terminology.

This is a breaking change as `LoginEncryptionPacket`'s `__init__` method now uses "shared_secret" keyword only
argument, not "shared_key". Every initialization call to this packet needs to be updated.
```

:material-check:{ style="color: #4DB6AC" } **With a list of subchanges that were made** (be careful with this one
though, make sure you don't over-do it)

```markdown title="changes/129.feature.md"
Added a system for handling Minecraft authentication

- Yggdrasil system for unmigrated i.e. non-Microsoft accounts (supportng Minecraft accounts, and the really old
Mojang accounts)
- Microsoft OAuth2 system (Xbox live) for migrated i.e. Microsoft accounts
```

### Examples of bad changelog fragment files

:material-close:{ style="color: #EF5350" } **Unclear** (but what does this class do?)

```markdown title="changes/123.feature.md"
Update `Buffer` class.
```

:material-close:{ style="color: #EF5350" } **Bad category** (this is a feature, not a bugfix)

```markdown title="changes/161.bugfix.md"
Add support for encryption. Connection classes now have `enable_encryption` method, and some encryption related functions
were added into a new mcproto.encryption module.
```

:material-close:{ style="color: #EF5350" } **Way too long** (this should've been the PR description)

```markdown title="changes/161.bugfix.md"
Introduce support for encryption handling.

Most servers (even offline ones) usually send an EncryptionRequest packet during the LOGIN state, with a public
(RSA) key that the client is expected to use to encrypt a randomly generated shared secret, to send back to the
server in EncryptionResponse packet. After that, all further communication is encrypted with this shared secret.

The encryption used is a AES/CFB8 stream cipher. That means the encrypted ciphertext will have the same amount
of bytes as the original plaintext, allowing us to still trust our reader/writer methods that rely on reading
specific amounts of bytes, even if their content don't make sense.

This directly uses the base connection classes and adds enable_encryption method to them, which after getting
called will automatically encrypt/decrypt any incomming/outcomming data.

This additionally also changes the LoginEncryptionRequest packet class, and makes the public key attribute
actually hold an RSA public key (from the cryptography library), instead of just the received bytes. This is
then much more useful to work with later on. This is a breaking change.
```

## Footnotes

- See <https://keepachangelog.com> for more info about why and how to properly maintain a changelog
- For more info about `towncrier`, check out it's [documentation](https://towncrier.readthedocs.io/en/latest/tutorial.html)

0 comments on commit 87e35f6

Please sign in to comment.