# Release Checklist
Use this checklist for every tagged release. A failed pre-publish check
blocks publication. A failed post-publish check requires a hotfix,
yank, or release-note correction before announcing the release.
Set these variables first:
```bash
export VERSION=0.1.2
export SAMPLE=/absolute/path/to/racbasicsamplefamily-2024.rfa
```
## Pre-Publish Gates
Run the normal source checks on the release commit:
```bash
cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo build --all-targets
tools/ci/verify-real-files.sh --profile ci # real-file, CLI, contract checks; no unit tests
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features -p rvt
```
Verify the crate can install and the CLIs run on a sample:
```bash
rm -rf /tmp/rvt-release-install
cargo install --path . --locked --root /tmp/rvt-release-install
/tmp/rvt-release-install/bin/rvt-inspect --version
/tmp/rvt-release-install/bin/rvt-info "$SAMPLE"
/tmp/rvt-release-install/bin/rvt-inspect "$SAMPLE" --json > /tmp/rvt.inspect.json
/tmp/rvt-release-install/bin/rvt-ifc "$SAMPLE" \
-o /tmp/rvt.ifc \
--diagnostics /tmp/rvt.diagnostics.json
test -s /tmp/rvt.inspect.json
test -s /tmp/rvt.ifc
test -s /tmp/rvt.diagnostics.json
```
Build and import the Python wheel locally:
```bash
rm -rf dist /tmp/rvt-wheel-smoke
maturin build --release --manifest-path rvt-py/Cargo.toml --out dist
python -m venv /tmp/rvt-wheel-smoke
. /tmp/rvt-wheel-smoke/bin/activate
python -m pip install --upgrade pip
python -m pip install dist/rvt-*.whl
python - <<'PY'
import json
import os
import rvt
sample = os.environ["SAMPLE"]
f = rvt.RevitFile(sample)
diag = json.loads(f.export_diagnostics_json())
print("rvt", rvt.__version__)
print("version", f.version)
print("confidence", diag["confidence"]["level"])
PY
deactivate
```
Build and load the viewer artifact:
```bash
wasm-pack build --target web --out-dir viewer/pkg -- --features wasm --no-default-features
cd viewer
pnpm install --frozen-lockfile
pnpm exec playwright install --with-deps chromium
pnpm run build
RVT_VIEWER_SAMPLE="$SAMPLE" pnpm run test:network
cd ..
```
The tag publish workflow repeats the release-critical checks:
- source crate install + CLI sample smoke;
- wheel install/import on Linux, macOS, and Windows;
- docs build with warnings denied;
- viewer build + browser sample load;
- crates.io publish;
- PyPI/TestPyPI publish.
## Tag And Publish
Confirm `Cargo.toml`, `rvt-py/Cargo.toml`, and Python metadata agree on
the release version, then tag:
```bash
git status --short
git tag "v${VERSION}"
git push origin "v${VERSION}"
```
For TestPyPI dry runs, dispatch `Publish (crates.io + PyPI)` manually
with `test-pypi=true`. The crates.io publish job is skipped for manual
TestPyPI runs.
## Post-Publish Verification
Verify crates.io from a clean shell **only if `cargo publish` succeeded
for this tag**. As of `v0.1.2` the crate name `rvt` was **not** on
crates.io (API: crate does not exist; docs.rs 404). If publish was
skipped or rejected, record `crates.io: NOT PUBLISHED` in the release
notes and do not claim docs.rs:
```bash
rm -rf /tmp/rvt-crates-smoke
cargo install rvt --version "$VERSION" --locked --root /tmp/rvt-crates-smoke
/tmp/rvt-crates-smoke/bin/rvt-inspect --version
/tmp/rvt-crates-smoke/bin/rvt-info "$SAMPLE"
```
Verify the prebuilt binaries the **Release binaries** job attached to the
GitHub Release (five archives plus `SHA256SUMS`; the job itself already
smoke-tested four of them on native runners):
```bash
rm -rf /tmp/rvt-bin-smoke && mkdir -p /tmp/rvt-bin-smoke && cd /tmp/rvt-bin-smoke
gh release download "v${VERSION}" --repo DrunkOnJava/rvt-rs
test "$(ls rvt-rs-v${VERSION}-* | wc -l)" -eq 5
shasum -a 256 -c SHA256SUMS
tar -xzf "rvt-rs-v${VERSION}-aarch64-apple-darwin.tar.gz" # or your platform's archive
"./rvt-rs-v${VERSION}-aarch64-apple-darwin/rvt-info" "$SAMPLE"
cd -
```
Verify PyPI on every supported OS family. On each machine (`0.1.2` is
known-good on PyPI):
```bash
python -m venv /tmp/rvt-pypi-smoke
. /tmp/rvt-pypi-smoke/bin/activate
python -m pip install --upgrade pip
python -m pip install "rvt==${VERSION}"
python - <<'PY'
import json
import os
import rvt
sample = os.environ["SAMPLE"]
f = rvt.RevitFile(sample)
diag = json.loads(f.export_diagnostics_json())
print("rvt", rvt.__version__)
print("version", f.version)
print("confidence", diag["confidence"]["level"])
PY
deactivate
```
Verify docs.rs **only after crates.io publish** (otherwise expect 404):
```bash
python -m webbrowser "https://docs.rs/rvt/${VERSION}/rvt/"
```
Verify the hosted viewer:
1. Open <https://drunkonjava.github.io/rvt-rs/>.
2. Drop the same `$SAMPLE`.
3. Confirm the status panel reaches `loaded`.
4. Download diagnostics and confirm the confidence level matches the
CLI/Python smoke output.
## Release Notes Evidence
Paste a short evidence block into the release notes:
```text
Release verification:
- CLI sample smoke: PASS on SAMPLE_NAME
- Viewer sample load: PASS
- docs.rs page: PASS | N/A (crate not on crates.io)
- Publish workflow run: URL
```
If any required line is not `PASS` (or an honest `NOT PUBLISHED` /
`N/A` where crates.io was intentionally skipped), do not announce the
release. Open a hotfix issue, link the failing workflow/log, and decide
whether to yank the artifact or publish a corrected patch release.