diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bed6591..2eabce3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,14 +38,32 @@ jobs: steps: - uses: actions/checkout@v7 - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + # Don't let the action put `-D warnings` in RUSTFLAGS. cargo-hyperlight + # builds third-party crates (e.g. hyperlight-guest-capi and its + # dependencies) by manifest path, so cargo treats them as local crates + # and does not apply `--cap-lints allow`. A warning in any of them would + # then fail the build. Lints are enforced by the `check` job instead. + rustflags: "" - uses: Swatinem/rust-cache@v2 - uses: extractions/setup-just@v4 - name: Enable kvm if: runner.os == 'Linux' && runner.arch == 'X64' && matrix.environment == 'GH' + shell: bash run: | - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules - sudo udevadm control --reload-rules - sudo udevadm trigger --name-match=kvm + # Make /dev/kvm accessible to the unprivileged runner user. + # On GitHub-hosted runners the device node is managed by udev, so install + # a rule and re-trigger it. Containerised runners (e.g. `act`) have no + # udev daemon, in which case fall back to setting the mode directly. + if sudo udevadm control --ping > /dev/null 2>&1; then + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + else + echo "udev is not running, setting the mode of /dev/kvm directly" + sudo chmod 666 /dev/kvm + fi + ls -l /dev/kvm - name: Install cargo-hyperlight shell: bash run: just install @@ -85,6 +103,9 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: components: rustfmt, clippy + # See the comment in the `run-tests` job. `just fmt` and `just clippy` + # pass `-D warnings` explicitly where it is wanted. + rustflags: "" - uses: extractions/setup-just@v4 - name: Setup nightly toolchain shell: bash diff --git a/docs/RELEASE.md b/docs/RELEASE.md new file mode 100644 index 0000000..49385e8 --- /dev/null +++ b/docs/RELEASE.md @@ -0,0 +1,105 @@ +# Releasing `cargo-hyperlight` + +Releases are fully automated by the [`publish`](../.github/workflows/publish.yml) workflow. +Pushing a tag of the form `vX.Y.Z` to `hyperlight-dev/cargo-hyperlight` will: + +1. Run the full [CI](../.github/workflows/ci.yml) suite (tests, spell check, lint). +2. Validate that the tag version matches the `version` field in [`Cargo.toml`](../Cargo.toml). +3. Publish the crate to [crates.io](https://crates.io/crates/cargo-hyperlight). +4. Create a GitHub Release with auto-generated release notes. + +The crates.io publish uses trusted publishing via +[`rust-lang/crates-io-auth-action`](https://github.com/rust-lang/crates-io-auth-action), +so no long-lived registry token is needed. + +## Prerequisites + +- Write access to `hyperlight-dev/cargo-hyperlight` (to push tags). +- `main` is green in CI. +- All changes intended for the release are already merged into `main`. + +## Steps + +### 1. Bump the crate version + +Open a pull request against `main` that bumps `version` in [`Cargo.toml`](../Cargo.toml). + +```toml +[package] +name = "cargo-hyperlight" +version = "X.Y.Z" +``` + +Then refresh the lockfile and sanity-check the build: + +```sh +cargo check +just fmt +just clippy +just test +``` + +Make sure `Cargo.lock` is included in the commit, since the version bump changes it. + +Get the pull request reviewed and merged. + +### 2. Verify the release candidate + +Once the version bump is merged, confirm CI on `main` is green and that the +package builds exactly as it will be published: + +```sh +git switch main +git pull upstream main +cargo publish --dry-run +``` + +### 3. Tag and push + +Tag the merge commit on `main` and push the tag to the upstream repository: + +```sh +git tag -a vX.Y.Z -m "vX.Y.Z" +git push upstream vX.Y.Z +``` + +> The tag **must** be `v` followed by the exact `Cargo.toml` version +> (for example `v0.1.14`). The workflow only triggers on tags matching +> `v[0-9]+.[0-9]+.[0-9]+`, and the `validate` job fails if the tag and the +> manifest version disagree. + +### 4. Watch the workflow + +Follow the run under the repository's **Actions** tab (or with +`gh run watch`). When it finishes, verify: + +- The new version appears on . +- A GitHub Release for `vX.Y.Z` was created with generated notes. +- `cargo install cargo-hyperlight` picks up the new version. + +## Troubleshooting + +**The workflow did not start.** +The tag does not match `v[0-9]+.[0-9]+.[0-9]+`. Pre-release suffixes such as +`v1.0.0-rc1` are not supported by the trigger. + +**`validate` failed with a version mismatch.** +The tag and `Cargo.toml` disagree. Delete the tag, fix the version, and retag: + +```sh +git push upstream :refs/tags/vX.Y.Z +git tag -d vX.Y.Z +``` + +**`publish` failed after CI passed.** +crates.io versions are immutable and cannot be re-published. If the upload +partially succeeded, bump to the next patch version and start over. If it +failed before upload (for example a transient registry error), re-running the +failed jobs from the Actions UI is safe. + +**The GitHub Release is missing but the crate published.** +Only the `release` job failed. Create the release manually: + +```sh +gh release create vX.Y.Z --title vX.Y.Z --generate-notes +``` diff --git a/rust-toolchain.toml b/rust-toolchain.toml index f8d7cf0..85901a6 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,7 @@ [toolchain] -channel = "1.89.0" +# Pinned to 1.94.0: rustc 1.95+ dropped support for custom target specs passed +# as `--target .json`, which we rely on to build the +# `x86_64-hyperlight-none` target and its sysroot. +channel = "1.94.0" profile = "default" components = ["rustfmt", "clippy"]