From 9287fb0c722106b1f925f49f3f9d4b46c5c64205 Mon Sep 17 00:00:00 2001 From: Rodrigo Dlugokenski Date: Sat, 17 Oct 2026 13:05:28 -0300 Subject: [PATCH 1/2] Use feature branches and PRs instead of a dev branch `mise run push` now runs the gates and pushes the current branch under its own name (it refuses main), for a PR to main. CI runs on pushes to main and on pull requests. A release goes in as a `release/X.Y.Z` PR too: `release-tag` only tags, once local main matches GitHub main, so nothing pushes main directly. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 2 +- CLAUDE.md | 3 +++ docs/RELEASE.md | 20 +++++++++++--------- mise.toml | 16 +++++++++++----- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d82f691..234424a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: push: - branches: [dev, main] + branches: [main] pull_request: workflow_dispatch: diff --git a/CLAUDE.md b/CLAUDE.md index 842e3e7..7d78829 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -30,6 +30,9 @@ 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 diff --git a/docs/RELEASE.md b/docs/RELEASE.md index a36d87d..b9d6afd 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -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 @@ -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 diff --git a/mise.toml b/mise.toml index a16f3a8..959053c 100644 --- a/mise.toml +++ b/mise.toml @@ -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/ or docs/ 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 @@ -160,7 +163,7 @@ echo "built in $dir" ''' [tasks.release-tag] -description = "Fast-forward GitHub main and dev to main, then tag v and push the tag (retries for the security key)" +description = "Tag v 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; } @@ -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" From 526d15eba242162cffdc3f0a2db9d485f9e7fce0 Mon Sep 17 00:00:00 2001 From: Rodrigo Dlugokenski Date: Sun, 25 Oct 2026 08:00:01 -0300 Subject: [PATCH 2/2] Name chore/ branches in push's refusal, and release-tag's new job in CLAUDE.md Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 2 +- mise.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 7d78829..bdd3765 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,7 +22,7 @@ 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 diff --git a/mise.toml b/mise.toml index 959053c..4194477 100644 --- a/mise.toml +++ b/mise.toml @@ -66,7 +66,7 @@ run = ''' set -e branch=$(git branch --show-current) case "$branch" in - main|"") echo "on ${branch:-a detached HEAD}: work on a feat/, fix/ or docs/ branch"; exit 1 ;; + 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