Skip to content

Commit 0d7e3ab

Browse files
committed
docs: add skill for publishing torrust-linting to crates.io
- Add skills/publish-rust-crate/SKILL.md with the full release process - Add MSRV to project-words.txt - Auto-format Cargo.toml (taplo spacing)
1 parent 9c4297c commit 0d7e3ab

3 files changed

Lines changed: 304 additions & 6 deletions

File tree

Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ edition = "2021"
55
rust-version = "1.85"
66
default-run = "linter"
77
description = "Linting utilities for Torrust projects"
8-
authors = ["Torrust Organization <https://torrust.com>"]
8+
authors = [ "Torrust Organization <https://torrust.com>" ]
99
documentation = "https://docs.rs/torrust-linting"
1010
homepage = "https://torrust.com"
1111
repository = "https://github.com/torrust/torrust-linting"
1212
license = "MIT"
1313
readme = "README.md"
14-
keywords = ["torrust", "linting", "cli"]
15-
categories = ["development-tools", "command-line-utilities"]
16-
include = ["/src", "/examples", "LICENSE", "README.md"]
14+
keywords = [ "torrust", "linting", "cli" ]
15+
categories = [ "development-tools", "command-line-utilities" ]
16+
include = [ "/src", "/examples", "LICENSE", "README.md" ]
1717

1818
[lib]
1919
name = "torrust_linting"
@@ -25,6 +25,6 @@ path = "src/bin/linter.rs"
2525

2626
[dependencies]
2727
anyhow = "1.0"
28-
clap = { version = "4.0", features = ["derive"] }
28+
clap = { version = "4.0", features = [ "derive" ] }
2929
tracing = "0.1"
30-
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
30+
tracing-subscriber = { version = "0.3", features = [ "env-filter" ] }

project-words.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ clippy
22
cspell
33
dtolnay
44
markdownlint
5+
MSRV
56
noconfirm
67
pacman
78
rustfmt

skills/publish-rust-crate/SKILL.md

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
---
2+
name: publish-rust-crate
3+
description: Publishes a new version of the torrust-linting crate to crates.io. Use this skill when the user asks to release a new version, publish the package, cut a release, bump the version, or prepare a crates.io release for this project.
4+
license: MIT
5+
compatibility: Requires Rust toolchain (cargo), git, and write access to crates.io and the GitHub remote at https://github.com/torrust/torrust-linting. Run inside the repository root.
6+
metadata:
7+
author: torrust
8+
version: "1.0"
9+
---
10+
11+
# Publishing `torrust-linting` to crates.io
12+
13+
This skill covers the full end-to-end process of releasing a new version of the
14+
`torrust-linting` crate to [crates.io](https://crates.io/crates/torrust-linting).
15+
16+
Repository: <https://github.com/torrust/torrust-linting>
17+
18+
---
19+
20+
## Overview
21+
22+
The release process consists of six sequential phases:
23+
24+
1. [Pre-release checklist](#1-pre-release-checklist)
25+
2. [Version bump](#2-version-bump)
26+
3. [Local validation](#3-local-validation)
27+
4. [Tag and commit](#4-tag-and-commit)
28+
5. [Publish to crates.io](#5-publish-to-cratesio)
29+
6. [Post-publish verification](#6-post-publish-verification)
30+
31+
---
32+
33+
## 1. Pre-release checklist
34+
35+
### 1.1 Verify `Cargo.toml` metadata
36+
37+
The `[package]` section must contain all of the following fields before publishing.
38+
The current state is already correct — verify nothing has regressed since the last release.
39+
40+
```toml
41+
[package]
42+
name = "torrust-linting"
43+
version = "0.1.0" # <-- bump this in §2
44+
edition = "2021"
45+
rust-version = "1.85"
46+
description = "Linting utilities for Torrust projects"
47+
authors = ["Torrust Organization <https://torrust.com>"]
48+
documentation = "https://docs.rs/torrust-linting"
49+
homepage = "https://torrust.com"
50+
repository = "https://github.com/torrust/torrust-linting"
51+
license = "MIT"
52+
readme = "README.md"
53+
keywords = ["torrust", "linting", "cli"]
54+
categories = ["development-tools", "command-line-utilities"]
55+
include = ["/src", "/examples", "LICENSE", "README.md"]
56+
```
57+
58+
Key things to check:
59+
60+
- `readme = "README.md"` is present — without it crates.io will not render the README on the crate page.
61+
- `license` is a valid SPDX identifier.
62+
- `keywords` has at most 5 entries, all lowercase.
63+
- `categories` entries are from the [crates.io category list](https://crates.io/categories).
64+
65+
### 1.2 Verify `README.md` dependency snippet
66+
67+
The "As a library dependency" section in `README.md` must show the crates.io form
68+
with the **new** version number — never the git source form.
69+
70+
**Correct:**
71+
72+
```toml
73+
[dependencies]
74+
torrust-linting = "0.2.0" # use the new version being released
75+
```
76+
77+
**Wrong (must not appear in a release):**
78+
79+
```toml
80+
[dependencies]
81+
torrust-linting = { git = "https://github.com/torrust/torrust-linting" }
82+
```
83+
84+
### 1.3 Verify `Cargo.lock` is committed
85+
86+
`torrust-linting` ships a binary, so `Cargo.lock` must be committed for reproducible builds.
87+
88+
```sh
89+
git status Cargo.lock # must show "nothing to commit"
90+
```
91+
92+
### 1.4 Inspect the package contents
93+
94+
Verify the `.crate` archive contains the right files and nothing unexpected:
95+
96+
```sh
97+
cargo package --list
98+
```
99+
100+
Expected output includes files under `src/`, `examples/`, `LICENSE`, `README.md`,
101+
and `Cargo.toml`. It must not include `target/`, secrets, or local config files.
102+
103+
---
104+
105+
## 2. Version bump
106+
107+
Edit `version` in `Cargo.toml` following [Semantic Versioning](https://semver.org/):
108+
109+
| Change type | Example |
110+
| -------------------------------- | ----------------- |
111+
| Backwards-compatible bug fix | `0.1.0``0.1.1` |
112+
| New backwards-compatible feature | `0.1.0``0.2.0` |
113+
| Breaking change in public API | `0.1.0``1.0.0` |
114+
115+
After bumping the version in `Cargo.toml`, also update the version string in the
116+
`README.md` dependency snippet (§1.2).
117+
118+
> **Note:** While still on `0.x.y`, a MINOR bump may contain breaking changes by
119+
> convention. Stabilize the public API before releasing `1.0.0`.
120+
121+
---
122+
123+
## 3. Local validation
124+
125+
Run every check locally before touching git, to avoid noisy CI failures.
126+
127+
### 3.1 Dry-run publish
128+
129+
Simulates packaging and upload without actually publishing anything:
130+
131+
```sh
132+
cargo publish --dry-run
133+
```
134+
135+
The last line of a successful dry run is:
136+
137+
```text
138+
warning: aborting upload due to dry run
139+
```
140+
141+
Any error before that line must be fixed before continuing.
142+
143+
### 3.2 Run all linters (mandatory CI gate)
144+
145+
`torrust-linting` uses its own binary as the CI gate. The linter **must exit 0**.
146+
The same check runs in `.github/workflows/linting.yml` and will reject any push that fails.
147+
148+
```sh
149+
cargo run
150+
```
151+
152+
This runs: `markdownlint`, `yamllint`, `taplo`, `cspell`, `cargo clippy`, `cargo fmt`, `shellcheck`.
153+
154+
Common fixes:
155+
156+
| Linter | Fix |
157+
| -------------- | --------------------------------------------------------------------------- |
158+
| `rustfmt` | `cargo fmt` |
159+
| `clippy` | Address the warning, or add `#[allow(...)]` with a justification comment |
160+
| `markdownlint` | Edit the offending Markdown file |
161+
| `yamllint` | Edit the offending YAML file |
162+
| `taplo` | `taplo fmt **/*.toml` |
163+
| `cspell` | Add the word to `project-words.txt` (one word per line, alphabetical order) |
164+
| `shellcheck` | Fix the script per shellcheck's suggestion |
165+
166+
---
167+
168+
## 4. Tag and commit
169+
170+
### 4.1 Commit the release preparation changes
171+
172+
Stage all files changed during §1–§3 in a single commit.
173+
Use [Conventional Commits](https://www.conventionalcommits.org/) format:
174+
175+
```sh
176+
git add Cargo.toml Cargo.lock README.md
177+
git commit -m "chore: release v0.2.0
178+
179+
- Bump version to 0.2.0
180+
- Update README dependency snippet to crates.io form"
181+
```
182+
183+
If preparing on a branch, name it `chore/release-v0.2.0` and open a PR to `main`.
184+
Tag only after the commit is on `main`.
185+
186+
### 4.2 Create an annotated git tag
187+
188+
The tag name must exactly match the version in `Cargo.toml` with a `v` prefix:
189+
190+
```sh
191+
git tag -a v0.2.0 -m "Release v0.2.0"
192+
```
193+
194+
Do not create the tag until the release commit is final — the tag should point
195+
to the exact commit that was published.
196+
197+
### 4.3 Push the commit and tag
198+
199+
```sh
200+
git push origin main
201+
git push origin v0.2.0
202+
```
203+
204+
---
205+
206+
## 5. Publish to crates.io
207+
208+
### 5.1 Authenticate (once per machine)
209+
210+
Generate a token at <https://crates.io/settings/tokens> with the `publish-new`
211+
and `publish-update` scopes:
212+
213+
```sh
214+
cargo login
215+
# paste your API token when prompted
216+
```
217+
218+
### 5.2 Publish
219+
220+
```sh
221+
cargo publish
222+
```
223+
224+
The command packages the crate, verifies it compiles from the packaged source,
225+
then uploads it. This takes up to 60 seconds.
226+
227+
> **Important:** Published versions cannot be deleted — only yanked. Yanking hides
228+
> a version from `cargo add` suggestions but does not break builds that already
229+
> pin that version. Double-check the dry run (§3.1) before running this.
230+
231+
---
232+
233+
## 6. Post-publish verification
234+
235+
### 6.1 Verify on crates.io
236+
237+
Open the crate page and confirm the new version is listed as latest, the README
238+
renders correctly, and all metadata is shown:
239+
240+
<https://crates.io/crates/torrust-linting/0.2.0>
241+
242+
### 6.2 Verify docs.rs built successfully
243+
244+
docs.rs automatically builds documentation after every publish. Check the build log:
245+
246+
<https://docs.rs/crate/torrust-linting/0.2.0/builds>
247+
248+
Build failures are not fatal for the release but should be fixed in a prompt patch release.
249+
250+
### 6.3 Create a GitHub Release
251+
252+
1. Go to <https://github.com/torrust/torrust-linting/releases/new>
253+
2. Select tag `v0.2.0`.
254+
3. Set the title to `v0.2.0`.
255+
4. Write release notes (use `git log` or the commit history as a source).
256+
5. Click **Publish release**.
257+
258+
### 6.4 Announce (optional)
259+
260+
- [Torrust GitHub Discussions](https://github.com/orgs/torrust/discussions)
261+
- The project's Discord or Matrix channel.
262+
263+
---
264+
265+
## Common mistakes to avoid
266+
267+
| Mistake | Consequence | Prevention |
268+
| ------------------------------------------------- | ------------------------------------------ | -------------------------------------------------- |
269+
| `readme = "README.md"` missing from `Cargo.toml` | crates.io page shows no documentation | Verify §1.1 before every release |
270+
| README still shows `git` dependency after publish | New users get the wrong source | Update README snippet in the release commit (§1.2) |
271+
| Skipping `cargo publish --dry-run` | Compile errors surface during live publish | Always run §3.1 first |
272+
| Skipping `cargo run` linter check | CI fails after push | Run linters locally before every commit (§3.2) |
273+
| Tagging before the release commit is on `main` | Tag points to wrong commit | Tag only after merge (§4.2) |
274+
| Forgetting `git push origin v0.2.0` | No GitHub Release can be created | Always push the tag explicitly (§4.3) |
275+
| MINOR bump omitted for a breaking change | Downstream consumers break | Follow Semantic Versioning (§2) |
276+
277+
---
278+
279+
## Quick-reference checklist
280+
281+
```text
282+
[ ] 1.1 Cargo.toml metadata looks correct (especially readme = "README.md")
283+
[ ] 1.2 README dependency snippet updated to new version number
284+
[ ] 1.3 Cargo.lock is committed
285+
[ ] 1.4 cargo package --list shows expected files
286+
[ ] 2 Version bumped in Cargo.toml
287+
[ ] 3.1 cargo publish --dry-run exits without error
288+
[ ] 3.2 cargo run (all linters) exits 0
289+
[ ] 4.1 Release preparation commit on main (conventional commit message)
290+
[ ] 4.2 Annotated git tag vX.Y.Z created on that commit
291+
[ ] 4.3 git push origin main && git push origin vX.Y.Z
292+
[ ] 5.1 Authenticated with crates.io (cargo login)
293+
[ ] 5.2 cargo publish completed successfully
294+
[ ] 6.1 New version visible on https://crates.io/crates/torrust-linting
295+
[ ] 6.2 docs.rs build passed at https://docs.rs/crate/torrust-linting/X.Y.Z/builds
296+
[ ] 6.3 GitHub Release created at https://github.com/torrust/torrust-linting/releases
297+
```

0 commit comments

Comments
 (0)