Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI

on:
push:
branches: [dev, main]
branches: [main]
pull_request:
workflow_dispatch:

Expand Down
5 changes: 4 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@ http://127.0.0.1:1313/) and `docs-build` (`site/public/`, gitignored), and `demo
`site/demos/` with VHS). Releases (`docs/RELEASE.md`): `changelog`
(drafts the next CHANGELOG section with git-cliff), `release-check`
(crate contents, `cargo publish --dry-run`, PKGBUILD checks), `release-tag`
(pushes main and the `vX.Y.Z` tag), and for `packaging/aur/`: `aur-srcinfo`
(tags `vX.Y.Z` on main and pushes the tag), and for `packaging/aur/`: `aur-srcinfo`
and `aur-test` (makepkg + namcap from a `git archive` of HEAD).

CI, release and Pages workflows are in `.github/workflows/`; every action is
pinned to a commit SHA with its version in a comment.

## Conventions

- Branches: work on a `feat/`, `fix/`, `docs/` or `chore/` branch off main,
push it with `mise run push`, and open a PR to main. main only moves by
merged PRs; there is no `dev` branch.
- Library + thin binary: everything lives in `src/lib.rs` modules so tests can
reach it; `src/main.rs` only dispatches.
- sysfs readers take a root path (`/` or a fixture dir), never hard-code
Expand Down
20 changes: 11 additions & 9 deletions docs/RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ steps are at the end, ready but not part of a release yet.

## What the workflows do

- **CI** (`.github/workflows/ci.yml`), on pushes to `dev` and `main` and on
pull requests: rustfmt, clippy `-D warnings`, the tests (insta snapshots
- **CI** (`.github/workflows/ci.yml`), on pushes to `main` and on pull
requests: rustfmt, clippy `-D warnings`, the tests (insta snapshots
fail instead of updating), a build with the MSRV from Cargo.toml's
`rust-version`, and the docs site with the pinned hugo.
- **Release** (`release.yml`), on a `v*` tag: fails unless the tag is
Expand Down Expand Up @@ -43,22 +43,24 @@ steps are at the end, ready but not part of a release yet.
mise run release-check # version + CHANGELOG, crate contents, PKGBUILDs
```

Commit (`Release X.Y.Z`) on local main.
4. **Fast-forward GitHub main, tag and push the tag:**
Commit (`Release X.Y.Z`) on a `release/X.Y.Z` branch, push it
(`mise run push`) and open a PR to main. When CI is green, merge it and
pull main locally.
4. **Tag and push the tag:**

```sh
mise run release-tag
```

On a clean main, it pushes main to GitHub `main` and `dev`, creates the
annotated tag `vX.Y.Z` and pushes it. Pushes go over SSH and retry up to
3 times, since the security key needs a touch. By hand, that's
`git push origin main:main main:dev`, then
On a clean main that matches GitHub main, it creates the annotated tag
`vX.Y.Z` and pushes it. Nothing pushes main itself: it only moves by
merged PRs. The push goes over SSH and retries up to 3 times, since the
security key needs a touch. By hand, that's
`git tag -a vX.Y.Z -m "plugii X.Y.Z"` and
`git push origin refs/tags/vX.Y.Z`.
5. **Wait for the Release workflow** (Actions tab, or `gh run watch`).
When it's green, check the release page: two tarballs, two `.sha256`,
and the notes. If it fails before publishing, fix it on main, delete the
and the notes. If it fails before publishing, fix it through a PR, delete the
tag locally and on GitHub (`git push origin :refs/tags/vX.Y.Z`), and
tag again.
6. **Check the site**: the Pages workflow runs when main's push touched
Expand Down
16 changes: 11 additions & 5 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,17 @@ description = "Update Cargo.lock within semver, then run the gates"
run = ["cargo update", { task = "check" }]

[tasks.push]
description = "Run the gates and push main to GitHub dev (retries for the security key)"
description = "Run the gates and push the current branch to GitHub, for a PR (retries for the security key)"
run = '''
set -e
[ "$(git branch --show-current)" = main ] || { echo "not on main"; exit 1; }
branch=$(git branch --show-current)
case "$branch" in
main|"") echo "on ${branch:-a detached HEAD}: work on a feat/, fix/, docs/ or chore/ branch"; exit 1 ;;
esac
[ -z "$(git status --porcelain)" ] || { echo "working tree not clean"; exit 1; }
mise run check
for i in 1 2 3; do
git push origin main:dev && exit 0
git push -u origin "$branch" && exit 0
echo "push failed (touch the security key?), retry $i/3"
done
exit 1
Expand Down Expand Up @@ -160,7 +163,7 @@ echo "built in $dir"
'''

[tasks.release-tag]
description = "Fast-forward GitHub main and dev to main, then tag v<version> and push the tag (retries for the security key)"
description = "Tag v<version> on main once it matches GitHub main, and push the tag (retries for the security key)"
run = '''
set -euo pipefail
[ "$(git branch --show-current)" = main ] || { echo "not on main"; exit 1; }
Expand All @@ -181,7 +184,10 @@ push() {
done
return 1
}
push main:main main:dev
git fetch -q origin main
[ "$(git rev-parse main)" = "$(git rev-parse origin/main)" ] || {
echo "local main isn't GitHub main: merge the release PR, then pull"; exit 1
}
git tag -a "$tag" -m "plugii $version"
push "refs/tags/$tag"
echo "pushed $tag: the Release workflow builds and publishes it"
Expand Down