changesets 0.4.0

A library for parsing and creating changeset files
Documentation
# Changesets

A Rust crate implementing [Changesets]. If you want a CLI which supports this format, check out [Knope].

## What can this do?

This crate programmatically works with [changesets], and only concerns itself with the [changeset][changesets] formats and conventions. It specifically _does not_ parse Markdown, bodies of changes are considered plain text.

Examples are not copy/pasted here, because it's hard to test them. So instead, here are links to common tasks:

- [Create a change]https://github.com/knope-dev/changesets/blob/61a3f4887e23af02542da66428d4364ee6025f00/tests/change.rs#L5
- [Load a change]https://github.com/knope-dev/changesets/blob/61a3f4887e23af02542da66428d4364ee6025f00/tests/change.rs#LL46C6-L46C6
- [Load a changeset]https://github.com/knope-dev/changesets/blob/61a3f4887e23af02542da66428d4364ee6025f00/tests/change_set.rs#L5

## What is a changeset?

Releasing a project requires two things at a minimum:

1. Setting a new version, preferably a [Semantic Version][semver].
2. Describing the changes in some sort of release notes, like a [changelog]https://keepachangelog.com.

The manual way to do this is to review all the changes since the last release, write a changelog, and decide on a new version. However, the longer you go between _making the change_ (e.g., merging a pull request) and _releasing the change_, the more likely you are to forget something. This is especially true if you have a lot of changes, or if you have a lot of projects.

Changesets are a way of tracking changes as they happen, then bundling them up into a release. For each change you create a Markdown file containing which packages the change effects, how it effects them (in [semver terms][semver], and a Markdown summary of that change. For example, you might merge a PR which has these two change files:

### `.changeset/new_feature_to_fix_bug.md`

```markdown
---
changesets: minor
knope: patch
---

Added a feature to `changesets` to fix a bug in `knope`.
```

### `.changeset/new_feature_for_knope.md`

```markdown
---
knope: minor
---

This is a feature for Knope in the same PR
```

When you release, the `knope` package would contain both summaries in its changelog (and bump the version based on the highest change type), and the `changesets` package would contain only the first summary in its changelog.

This works very similarly to [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/), but does not rely on Git. You can use this together _with_ conventional commits using a tool like [Knope].

## Terminology in this project

### Change

A single Markdown file (usually in the `.changeset` directory) describing a change to one or more packages. Note that this matches the original definition of [changesets]. A change contains a summary (in Markdown), a list of packages affected, and the ["change type"](#change-type) for each package. The file must be in a [very strict format](#change-file-format).

### Change summary

The Markdown description of a change. This is the body of the change file. It should be included in the generated changelog.

### Change type

A string describing which type of change this is. If it is one of `patch`, `minor`, or `major`, the version will be bumped accordingly. All other types of changes are equivalent to `patch` for versioning, but may have a different effect in the generation of the changelog.

### Package

A releasable unit of code. Examples include a Rust crate, a JavaScript package, a Go module. A change can affect multiple packages.

### Changeset

A _set_ of _changes_ which will be released together. Notably, this differs from the original definition of [changesets], which is does not have a term for the bundle of multiple changes. A changeset may affect any number of packages.

### Release

The part of a changeset that applies to a single package and determines how that package is released.

## Change file format

Change files are Markdown files whose names _must_ end with `.md`. The content of the file must be as follows:

1. A line containing `---` (three dashes) on its own line.
2. Any number of lines containing `package: change type` pairs where `package` defines a package that this change impacts and `change type` is a [change type]#change-type. One pair per line. The first `:` is used to determine the separation between package and change type, so the package name may not contain a `:`.
3. A line containing `---` (three dashes) on its own line.
4. The rest of the file can contain any valid Markdown text.

## Differences from the original changesets

1. The original is implemented in JavaScript, intended for use with Node.js. This is implemented in Rust, intended primarily for use by [Knope].
2. The original has four fixed changed types (`major`, `minor`, `patch`, and `none`). This has only the first three, and allows for custom change types (for more flexibility when building changelogs). There is no way to specify that a change does not impact the version, since releasing a package without increasing the version is typically not supported.
3. The original defines a single Markdown file as a "changeset" without any term to define the collection of change files (e.g., in the `.changeset` folder). This crate defines a "changeset" as the collection of change files in a directory (e.g., `.changeset` is a changeset). A single change file is called a "change".

## Questions?

If you have any questions, comments, or suggestions, please create a [discussion] (after checking for an existing one).

[semver]: https://semver.org/
[changesets]: https://github.com/changesets/changesets
[Knope]: https://github.com/knope-dev/knope
[discussion]: https://github.com/knope-dev/changesets/discussions