diff --git a/.github/ISSUE_TEMPLATE/01_bug_report.yml b/.github/ISSUE_TEMPLATE/01_bug_report.yml index 58243e06..a7e62222 100644 --- a/.github/ISSUE_TEMPLATE/01_bug_report.yml +++ b/.github/ISSUE_TEMPLATE/01_bug_report.yml @@ -84,7 +84,7 @@ body: id: rustiq_version attributes: label: RustiQ version or commit - placeholder: v0.1.0-alpha.1 or commit SHA + placeholder: v0.1.0-beta.1 or commit SHA validations: required: true diff --git a/.github/workflows/release-smoke.yml b/.github/workflows/release-smoke.yml index dccfa305..89d93b60 100644 --- a/.github/workflows/release-smoke.yml +++ b/.github/workflows/release-smoke.yml @@ -1,6 +1,8 @@ name: Release artifact smoke test on: + pull_request: + branches: [main] workflow_dispatch: inputs: ref: @@ -12,6 +14,10 @@ on: permissions: contents: read +concurrency: + group: release-smoke-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: manual: uses: ./.github/workflows/build-release-manual.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1e6abc2f..bf96cdec 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -95,7 +95,7 @@ jobs: # Build and packages all the platform-specific things build-local-artifacts: - name: build-local-artifacts (${{ join(matrix.targets, ', ') }}) + name: Build platform artifacts # Let the initial task tell us to not run (currently very blunt) needs: - plan diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fd7d9f2..fc3391ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -The following capabilities are intended for the first public beta, `v0.1.0-beta.1`. +## [0.1.0-beta.1] - 2026-11-12 + ### Added @@ -58,4 +59,5 @@ The following capabilities are intended for the first public beta, `v0.1.0-beta. - The MP2 workspace budget does not bound total process memory; AO integral storage can still grow rapidly with basis size. -[Unreleased]: https://github.com/mveril/RustiQ/commits/main/ +[Unreleased]: https://github.com/mveril/RustiQ/compare/v0.1.0-beta.1...HEAD +[0.1.0-beta.1]: https://github.com/mveril/RustiQ/releases/tag/v0.1.0-beta.1 diff --git a/CITATION.cff b/CITATION.cff index 07cd686d..d25a8238 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -5,7 +5,9 @@ type: software authors: - family-names: Veril given-names: Mickael -version: 0.1.0-alpha.1 -license: MIT OR Apache-2.0 +version: 0.1.0-beta.2.dev +license: + - MIT + - Apache-2.0 repository-code: https://github.com/mveril/RustiQ -abstract: A Rust prototype for modern quantum chemistry software. +abstract: Experimental quantum chemistry software written in Rust, providing a reusable scientific library and CLI. RustiQ-authored code is available under MIT OR Apache-2.0. diff --git a/Cargo.lock b/Cargo.lock index c15a6222..27d3d587 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4675,7 +4675,7 @@ dependencies = [ [[package]] name = "rustiq-chem" -version = "0.1.0-alpha.1.dev" +version = "0.1.0-beta.2.dev" dependencies = [ "anstream", "anstyle", @@ -4719,7 +4719,7 @@ dependencies = [ [[package]] name = "rustiq-chem-core" -version = "0.1.0-alpha.1.dev" +version = "0.1.0-beta.2.dev" dependencies = [ "approx", "bounded-vec-deque", @@ -4727,6 +4727,7 @@ dependencies = [ "const_format", "delegate", "factorial", + "itertools 0.14.0", "mendeleev", "miette", "nalgebra", diff --git a/Cargo.toml b/Cargo.toml index 9f62cfb7..8d37c391 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,7 +67,7 @@ tokio = { version = "1", default-features = false } name = "rustiq-chem" description = "A modern command-line application for quantum chemistry, written in Rust" authors.workspace = true -version = "0.1.0-alpha.1.dev" +version = "0.1.0-beta.2.dev" edition.workspace = true license.workspace = true repository.workspace = true @@ -91,7 +91,7 @@ completions = ["dep:clap_complete", "dep:clap_complete_nushell", "dep:sysinfo"] [dependencies] bytesize.workspace = true -rustiq-core = { package = "rustiq-chem-core", path = "crates/rustiq-core", version = "0.1.0-alpha.1.dev", default-features = false } +rustiq-core = { package = "rustiq-chem-core", path = "crates/rustiq-core", version = "0.1.0-beta.2.dev", default-features = false } directories = "6" miette = { workspace = true, features = ["fancy"] } clap = { version = "4.6", features = ["cargo", "derive", "env"] } diff --git a/README.md b/README.md index 3a6bc891..8e5fd2a0 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,18 @@ and [the first H₂ calculation](https://mveril.github.io/RustiQ/getting-started Release archives contain the executable and licenses; obtain basis data and create calculation inputs as shown in those guides. +Once the beta is published, install it from crates.io with +`cargo install --locked rustiq-chem --version '=0.1.0-beta.1'`, or install the +tagged flake’s default package with +`nix profile install 'github:mveril/RustiQ/v0.1.0-beta.1'`. +See the installation guide for prerequisites and supported Nix platforms. + To build from source, install Git, Rust through [rustup](https://rustup.rs/), a C/C++ build toolchain, and CMake; see [manual setup](docs/src/development/manual-setup.md). Alternatively, enter `nix develop .#rust` after cloning: ```sh -git clone https://github.com/mveril/RustiQ.git +git clone --branch develop --single-branch https://github.com/mveril/RustiQ.git cd RustiQ cargo build --locked cargo run --locked -- basis import tests/data/sto-3g.json diff --git a/THIRD-PARTY-NOTICES.sha256 b/THIRD-PARTY-NOTICES.sha256 index 260cd661..20cff1fa 100644 --- a/THIRD-PARTY-NOTICES.sha256 +++ b/THIRD-PARTY-NOTICES.sha256 @@ -1 +1 @@ -2fbcaed6277c0ee1532734dbf6474fea1965985e94c34c8fe07ab9ea0dbaf992 THIRD-PARTY-NOTICES.txt +3f1859908faa6531c31671624f15e6339819bd08c6ba0e70bc6c9cd6305d12d9 THIRD-PARTY-NOTICES.txt diff --git a/THIRD-PARTY-NOTICES.txt b/THIRD-PARTY-NOTICES.txt index d065bf9f..107dec99 100644 --- a/THIRD-PARTY-NOTICES.txt +++ b/THIRD-PARTY-NOTICES.txt @@ -1,6 +1,6 @@ -Cargo.lock SHA-256: 7f274ca9e7f738d58ec0e46d03be9802569df0512ec91892f4ccd1edbd90ad02 -Notice inputs SHA-256: 23de7d7b750a771f73732580c0542ac4047e5afd0d13789e3ec333efed68208c -Corresponding source: https://github.com/mveril/RustiQ/releases/download/v0.1.0-alpha.1.dev/rustiq-corresponding-source.tar.gz +Cargo.lock SHA-256: 2a1954c2ec99b6e87db533afbdd2e3d57caaaec25452083c8310ff2f821730ac +Notice inputs SHA-256: 911b204bcfd6752d237e8ae735612b807bcbe52013a872b01f843c3897c6bc7b +Corresponding source: https://github.com/mveril/RustiQ/releases/download/v0.1.0-beta.2.dev/rustiq-corresponding-source.tar.gz RustiQ third-party licenses ========================== @@ -8220,8 +8220,8 @@ limitations under the License. Apache License 2.0 (Apache-2.0) Used by: - rustiq-chem 0.1.0-alpha.1.dev — https://github.com/mveril/RustiQ - rustiq-chem-core 0.1.0-alpha.1.dev — https://github.com/mveril/RustiQ + rustiq-chem 0.1.0-beta.2.dev — https://github.com/mveril/RustiQ + rustiq-chem-core 0.1.0-beta.2.dev — https://github.com/mveril/RustiQ Apache License Version 2.0, January 2004 diff --git a/crates/rustiq-core/Cargo.toml b/crates/rustiq-core/Cargo.toml index 48482916..152c0a57 100644 --- a/crates/rustiq-core/Cargo.toml +++ b/crates/rustiq-core/Cargo.toml @@ -2,7 +2,7 @@ name = "rustiq-chem-core" description = "A reusable Rust library for modern quantum chemistry software" authors.workspace = true -version = "0.1.0-alpha.1.dev" +version = "0.1.0-beta.2.dev" edition.workspace = true license.workspace = true repository.workspace = true @@ -28,6 +28,7 @@ online = ["dep:reqwest", "dep:tokio"] bench = [] [dependencies] +itertools = { version = "0.14", default-features = false } miette.workspace = true reqwest = { version = "0.13", default-features = false, optional = true, features = [ "json", @@ -48,7 +49,7 @@ bounded-vec-deque = "0.1.1" thiserror.workspace = true rand.workspace = true rand_chacha = "0.10" -petname = { version = "3.2", default-features = false } +petname = { version = "3.1", default-features = false } rand_distr = "0.6" special = { version = "0.14", default-features = false, features = ["std"] } factorial = "0.4.0" diff --git a/docs/src/development/docker-setup.md b/docs/src/development/docker-setup.md index 2b045483..a7d6372d 100644 --- a/docs/src/development/docker-setup.md +++ b/docs/src/development/docker-setup.md @@ -63,7 +63,7 @@ cross-architecture emulation into the comparison. Open a terminal on your computer and download the project: ```sh -git clone https://github.com/mveril/RustiQ.git +git clone --branch develop --single-branch https://github.com/mveril/RustiQ.git cd RustiQ ``` diff --git a/docs/src/development/manual-setup.md b/docs/src/development/manual-setup.md index d0ec5b66..7d8c90be 100644 --- a/docs/src/development/manual-setup.md +++ b/docs/src/development/manual-setup.md @@ -27,7 +27,7 @@ Install Git and Rust through [`rustup`](https://rustup.rs/), then use Cargo directly on Linux, macOS, or Windows: ```sh -git clone https://github.com/mveril/RustiQ.git +git clone --branch develop --single-branch https://github.com/mveril/RustiQ.git cd RustiQ rustup show cargo build --locked diff --git a/docs/src/development/nix-packages.md b/docs/src/development/nix-packages.md index 992060bb..fef796cd 100644 --- a/docs/src/development/nix-packages.md +++ b/docs/src/development/nix-packages.md @@ -2,7 +2,7 @@ The flake also exposes `legacyPackages..cpuTarget`, a function accepting an LLVM CPU name and returning a CPU-specific RustiQ package. See the -[installation guide](../getting-started/installation.md#install-with-nix) for +[Nix installation guide](../getting-started/installation-nix.md#optional-cpu-specific-build) for commands and portability considerations. The default package remains portable. The packages below are declared in [`flake.nix`](https://github.com/mveril/RustiQ/blob/main/flake.nix). All four @@ -96,7 +96,10 @@ The flake also exposes `nix build .#book` to build this manual, `nix build .#cargo-artifacts` for cached Cargo dependency artifacts, and `nix build .#pyscf-environment` for the base PySCF environment. These are build outputs rather than development shells. The default package is the RustiQ CLI -binary, available through `nix build`. Its online manual follows the Cargo +binary, available through `nix build` or explicitly through `nix build .#default`. +Install a tagged version with `nix profile install github:mveril/RustiQ/vVERSION`, +replacing `vVERSION` with a published tag. Both development and release revisions +use this default package. Its online manual follows the Cargo version: a `dev` prerelease identifier selects development documentation; other versions select the matching versioned manual. No release flag is needed. See [releasing](releasing.md#preparing-a-release). diff --git a/docs/src/development/nix-setup.md b/docs/src/development/nix-setup.md index 9061249e..00c8e01c 100644 --- a/docs/src/development/nix-setup.md +++ b/docs/src/development/nix-setup.md @@ -94,7 +94,7 @@ Install Nix with flakes enabled, clone the repository, and enter the development shell manually: ```sh -git clone https://github.com/mveril/RustiQ.git +git clone --branch develop --single-branch https://github.com/mveril/RustiQ.git cd RustiQ nix develop ``` @@ -144,7 +144,7 @@ nix build Install both Nix and `direnv`, enable the direnv hook for your shell, then run: ```sh -git clone https://github.com/mveril/RustiQ.git +git clone --branch develop --single-branch https://github.com/mveril/RustiQ.git cd RustiQ direnv allow ``` diff --git a/docs/src/development/releasing.md b/docs/src/development/releasing.md index 5013d9d5..20782557 100644 --- a/docs/src/development/releasing.md +++ b/docs/src/development/releasing.md @@ -33,13 +33,17 @@ out-of-date generated workflow. Keep the pin synchronized with the intended upload-artifact release when updating the workflow or cargo-dist. Preserve the custom `build-manual` job, the local-build dependency on it, and the download into `manual/html/` when regenerating the release workflow; generated defaults do -not contain this offline-manual integration. +not contain this offline-manual integration. Preserve the static local-build job +name, `Build platform artifacts`, so pull requests that skip artifact builds +display a readable name before the target matrix is expanded. ### Release rehearsal -Run **Actions → Release artifact smoke test → Run workflow** and select the -commit, branch, or tag to rehearse. The manually triggered workflow builds the -configured target archive with the pinned dist version on each target's native +The **Release artifact smoke test** workflow runs automatically on pull requests +targeting `main`, testing the prospective merge commit. To rehearse another +revision, run **Actions → Release artifact smoke test → Run workflow** and select +the commit, branch, or tag. New runs cancel older rehearsals for the same pull +request or selected workflow ref. The workflow builds the configured target archive with the pinned dist version on each target's native GitHub-hosted runner. It extracts that archive, verifies its dist-generated SHA-256 checksum, starts the packaged `rustiq` executable, checks `--help`, and runs the checked-in H2/STO-3G regression with a copied local basis fixture @@ -68,12 +72,12 @@ system installations. The rehearsal requires the combined `sha256.sum` generated dist build and verifies each tested archive against it. A checksum made during a rehearsal does not independently validate a published release. -The rehearsal has read-only repository permissions and only a -`workflow_dispatch` trigger. It does not run dist's `host` command, upload +The rehearsal has read-only repository permissions and supports `pull_request` +events targeting `main` and manual `workflow_dispatch` runs. It does not run dist's `host` command, upload release assets, create a GitHub Release, create tags, or publish crates. It complements `.github/workflows/release.yml`, whose dispatched release path builds -and publishes the release assets; ordinary pull requests continue to use the -generated plan-only check. +and publishes the release assets. Pull requests targeting `develop` continue +to use the generated plan-only check without the six-target rehearsal. Each executable archive includes `rustiq` (named `rustiq.exe` on Windows), the README, `LICENSE-MIT`, `LICENSE-APACHE`, `COPYING`, `DISTRIBUTION.md`, and @@ -268,7 +272,7 @@ if the Nixpkgs package differs: cargo install cargo-dist --version 0.34.0 --locked ``` -Development takes place on the default `develop` branch. Use a version ending +Development takes place on the `develop` branch. Use a version ending in `.dev`, keeping both crate versions and the internal dependency synchronized. Prepare a release on a `chore/*` task branch from `develop`: remove the development identifier, finalize the dated changelog, and update `Cargo.lock`. diff --git a/docs/src/getting-started/first-calculation.md b/docs/src/getting-started/first-calculation.md index 3ba87fca..3b969aa9 100644 --- a/docs/src/getting-started/first-calculation.md +++ b/docs/src/getting-started/first-calculation.md @@ -1,9 +1,10 @@ # First H₂ calculation -## Using only the release binary +## Using an installed release -Copy the following geometry into a file named `h2.xyz` in your working -directory. It is the same geometry used by the checked-in sample: +The following commands work after installing a release from a GitHub archive, +Cargo, or Nix. Copy the following geometry into a file named `h2.xyz` in your +working directory. It is the same geometry used by the checked-in sample: ```text {{#include ../../../samples/h2/molecule.xyz}} diff --git a/docs/src/getting-started/installation-nix.md b/docs/src/getting-started/installation-nix.md index a9709ea0..5860c286 100644 --- a/docs/src/getting-started/installation-nix.md +++ b/docs/src/getting-started/installation-nix.md @@ -1,5 +1,10 @@ # Installing with Nix +Nix is one of the three release installation channels, alongside a +[GitHub Releases archive](installation.md#install-a-prebuilt-release-binary) +and the [Cargo package](installation.md#install-with-cargo). This page covers +the Nix-specific choices. + Install [Nix](https://nixos.org/download/) and enable the `nix-command` and `flakes` experimental features. The flake supports x86-64 Linux, ARM64 Linux, and Apple Silicon macOS. On Windows, use Nix inside WSL2 to run the Linux @@ -12,6 +17,13 @@ nix profile install github:mveril/RustiQ rustiq --version ``` +The unqualified `github:mveril/RustiQ` reference follows GitHub's default +branch, `main`. That branch contains released versions only. To keep a fixed +version, use a release tag (for example, +`github:mveril/RustiQ/v0.1.0-beta.1`) or a commit revision instead. +An unqualified reference is captured only when a consuming configuration's +`flake.lock` is updated; a tag makes the selected release explicit. + ## Home Manager without a configuration flake If your Home Manager configuration uses `home.nix` directly, create a @@ -24,7 +36,7 @@ let in { home.packages = [ - (rustiq.legacyPackages.${pkgs.stdenv.hostPlatform.system}.cpuTarget "native") + rustiq.packages.${pkgs.stdenv.hostPlatform.system}.default ]; } ``` @@ -38,11 +50,11 @@ imports = [ ./rustiq.nix ]; Apply the configuration using your usual command. For Home Manager integrated as a NixOS module, run `sudo nixos-rebuild switch --impure`; for standalone Home Manager, run `home-manager switch --impure`. The unlocked GitHub reference -requires impure evaluation. Check `rustiq --version` afterward. The reference tracks the default branch -and is not pinned by a configuration `flake.lock`; use a revision in the URL -for a fixed version. See the [CPU-specific build](#optional-cpu-specific-build) -caveats before using `native`. To use the standard package, replace the entry -in `home.packages` with `rustiq.packages.${pkgs.stdenv.hostPlatform.system}.default`. +requires impure evaluation. Check `rustiq --version` afterward. The reference tracks +the release-only default branch, `main`, and is not pinned by a configuration +`flake.lock`; use a revision in the URL +for a fixed version. The standard package is portable across machines of the +same supported platform. ## Home Manager and NixOS @@ -97,8 +109,8 @@ specialArgs = { inherit inputs; }; ``` Merge this with any existing `specialArgs`. Create `rustiq.nix` beside your -`configuration.nix`. This complete NixOS module installs a RustiQ build -optimized for the build machine's CPU: +`configuration.nix`. This complete NixOS module installs the standard portable +RustiQ package: ```nix {{#include rustiq.nix}} @@ -114,13 +126,6 @@ Then import it in the existing `configuration.nix`, preserving any other imports ``` Alternatively, add `./rustiq.nix` to the `modules` list in `nixosSystem`. -See the CPU caveats below before using `native`. To use the standard package, -replace the expression inside the list with: - -```nix -inputs.rustiq.packages.${pkgs.stdenv.hostPlatform.system}.default -``` - From the configuration directory, apply it with `sudo nixos-rebuild switch --flake .#YOUR_HOST` and check `rustiq --version`. Replace `YOUR_HOST` with your NixOS configuration name. See the @@ -128,8 +133,9 @@ Replace `YOUR_HOST` with your NixOS configuration name. See the ## Optional CPU-specific build -The NixOS module above uses this expression. For Home Manager, you can also -replace the standard package entry in `home.packages` with it: +The examples above use the portable standard package. For NixOS or Home +Manager, replace that package expression with this one only when a build tied +to the build machine's CPU is appropriate: ```nix (inputs.rustiq.legacyPackages.${pkgs.stdenv.hostPlatform.system}.cpuTarget "native") @@ -162,6 +168,15 @@ nix build ./result/bin/rustiq --version ``` +For development, clone `develop` explicitly because the default branch is +release-only: + +```sh +git clone --branch develop --single-branch https://github.com/mveril/RustiQ.git +cd RustiQ +nix develop +``` + The package includes the offline manual and shell completions. Run `rustiq docs` after installing, or `./result/bin/rustiq docs` from the checkout. See the [manual instructions](installation.md#consult-the-manual) and the @@ -169,6 +184,6 @@ after installing, or `./result/bin/rustiq docs` from the checkout. See the The package enables online basis downloads but does not bundle sample inputs or basis sets. Download or import a basis before running a calculation; see -[make basis sets available](installation.md#make-basis-sets-available) and the +[obtaining a basis after installation](installation.md#after-installation-obtain-a-basis-and-run-a-calculation) and the [first calculation](first-calculation.md). For development shells, see [Nix setup](../development/nix-setup.md). diff --git a/docs/src/getting-started/installation.md b/docs/src/getting-started/installation.md index 4da57ce8..73f36987 100644 --- a/docs/src/getting-started/installation.md +++ b/docs/src/getting-started/installation.md @@ -1,14 +1,20 @@ # Installation -## Install with Nix +After a release promotion completes, RustiQ is distributed through a prebuilt +archive on GitHub Releases, the Cargo registry, and the Nix flake. The three +publications run independently, so use the channel where the release is listed. +They are all built from the same release tag. -See [installing with Nix](installation-nix.md) for the supported platforms, -profile installation, and CPU-specific builds. +| Method | Choose it when | Platforms and manual | +| --- | --- | --- | +| [GitHub Releases archive](#install-a-prebuilt-release-binary) | You want a runnable executable without installing Rust or Nix. | The six target platforms listed below; includes the offline manual. | +| [Cargo](#install-with-cargo) | You already use Rust and Cargo, or want Cargo to build RustiQ locally. | Native Cargo-supported platforms; uses the online manual. | +| [Nix](installation-nix.md) | You already use Nix or want declarative installation and a pinned package environment. | Linux x86_64/ARM64 and Apple Silicon macOS; includes the offline manual. | ## Install a prebuilt release binary -When a release is available, ordinary users can download the archive for their -operating system and CPU from the [GitHub Releases page](https://github.com/mveril/RustiQ/releases). +Download the archive for your operating system and CPU from the +[GitHub Releases page](https://github.com/mveril/RustiQ/releases). Archives are named `rustiq-chem-.tar.gz` on Unix and `rustiq-chem-.zip` on Windows. Supported targets are `x86_64-unknown-linux-gnu` (Linux Intel/AMD), @@ -51,15 +57,47 @@ Write-Host "SHA-256 verified: $archive" The [release guide](../development/releasing.md#binary-releases) has the full platform-specific verification instructions. For Windows ARM64, replace the archive filename with `rustiq-chem-aarch64-pc-windows-msvc.zip`. Extract the -archive only after the checksum comparison succeeds, then run -`./rustiq --help` from its directory on Linux or macOS, or -`.\rustiq.exe --help` from that directory in PowerShell. To use `rustiq` from -any directory, add the directory containing `rustiq` or `rustiq.exe` to `PATH` -and open a new terminal. +archive only after the checksum comparison succeeds. From the directory holding +the download, extract it with one of the following commands: + +```sh +tar -xzf rustiq-chem-.tar.gz # Linux or macOS +``` + +```powershell +Expand-Archive rustiq-chem-.zip -DestinationPath .\rustiq-chem +``` + +Open a terminal in the extracted directory and run `./rustiq --help` on Linux +or macOS, or `.\rustiq.exe --help` in PowerShell. This works without changing +`PATH`. To run `rustiq` from any directory, add the directory containing +`rustiq` or `rustiq.exe` to `PATH` and open a new terminal. The Cargo package is named `rustiq-chem`; the executable is named `rustiq` (or `rustiq.exe` on Windows). +## Install with Cargo + +Install the released Cargo package from crates.io from any directory. No source +checkout is needed. This builds RustiQ from source and requires Rust and Cargo, +a C/C++ toolchain, and CMake; see [manual setup](../development/manual-setup.md#install-and-build) +for platform prerequisites, but do not follow that page's checkout commands +unless you intend to contribute. + +```sh +cargo install --locked rustiq-chem --version '=0.1.0-beta.1' +rustiq --help +``` + +Ensure Cargo's binary directory is on `PATH`. Cargo-only installations use the +online manual, as described below. + +## Install with Nix + +See [installing with Nix](installation-nix.md) for the supported platforms, +profile and declarative installation, and CPU-specific builds. That page uses +the repository's default branch, `main`, which contains released versions only. + ## Consult the manual Release archives contain an offline HTML manual in `manual/html/` beside the @@ -100,15 +138,16 @@ If browser launching fails, the diagnostic includes the target and the `--print-path` route. RustiQ uses the operating system's default browser opener. PDF export is future work and `--pdf` is not supported. -## Make basis sets available +## After installation: obtain a basis and run a calculation -The archive contains neither sample inputs nor basis data. With network access, -download a basis using `rustiq basis download sto-3g`. This command is available -in online builds and requires network access. To work offline, import a local -Basis Set Exchange JSON file with `rustiq basis import /path/to/basis.json`; -import does not access the network. See the -[basis-set guide](../user-guide/basis-sets.md) and the -[first calculation](first-calculation.md) for a complete binary-only example. +Run `rustiq --version` to confirm the installation. Installed release packages +do not include sample inputs or basis data. With network access, download a +basis using `rustiq basis download sto-3g`. This command is available in online +builds and requires network access. To work offline, import a local Basis Set +Exchange JSON file with `rustiq basis import /path/to/basis.json`; import does +not access the network. The [first calculation](first-calculation.md) works +with an archive, Cargo, or Nix installation. See the +[basis-set guide](../user-guide/basis-sets.md) for basis-data details. ## Build and install from source @@ -118,11 +157,21 @@ parent directory, then run Cargo commands from the checkout root. For complete prerequisite and platform details, see the [manual setup](../development/manual-setup.md#install-and-build). ```sh -git clone https://github.com/mveril/RustiQ.git +git clone --branch develop --single-branch https://github.com/mveril/RustiQ.git cd RustiQ cargo build --locked ``` +The default branch, `main`, is reserved for released versions. Use `develop` +for an active development checkout; a checkout intended to reproduce a release +should instead use its release tag. + +For example, to reproduce the `0.1.0-beta.1` release source, clone its tag: + +```sh +git clone --branch v0.1.0-beta.1 --single-branch https://github.com/mveril/RustiQ.git +``` + `cargo build` does not add the executable to `PATH`. To run without installing, prefix commands with `cargo run --locked --`, for example `cargo run --locked -- --help`. To install the package executable into Cargo's @@ -133,7 +182,5 @@ cargo install --locked --path . rustiq --help ``` -The registry package is also named `rustiq-chem`; install from crates.io only -when the relevant version has been published. See the -[development environments](../development/environments.md) page for Nix, +See the [development environments](../development/environments.md) page for Nix, Docker, and other supported contributor setups. diff --git a/docs/src/getting-started/rustiq.nix b/docs/src/getting-started/rustiq.nix index d02128da..c5edc15c 100644 --- a/docs/src/getting-started/rustiq.nix +++ b/docs/src/getting-started/rustiq.nix @@ -2,6 +2,6 @@ { pkgs, inputs, ... }: { environment.systemPackages = [ - (inputs.rustiq.legacyPackages.${pkgs.stdenv.hostPlatform.system}.cpuTarget "native") + inputs.rustiq.packages.${pkgs.stdenv.hostPlatform.system}.default ]; } diff --git a/docs/src/reference/cli.md b/docs/src/reference/cli.md index 2e1f7188..d353ac39 100644 --- a/docs/src/reference/cli.md +++ b/docs/src/reference/cli.md @@ -75,7 +75,7 @@ For example, the grouped output has this shape (unknown optional fields are omitted and the values depend on the build): ```text -rustiq 0.1.0-alpha.1 +rustiq 0.1.0-beta.1 SOURCE Git commit diff --git a/tools/check-release.py b/tools/check-release.py index f1cc3b14..9f95ee70 100644 --- a/tools/check-release.py +++ b/tools/check-release.py @@ -29,6 +29,9 @@ def candidate(root): raise ValueError("workspace package versions differ") if manifest["dependencies"]["rustiq-core"]["version"].removeprefix("=") != version: raise ValueError("internal dependency must match release version") + citation = (root / "CITATION.cff").read_text(encoding="utf-8") + if re.findall(r"^version:\s*(\S+)\s*$", citation, re.MULTILINE) != [version]: + raise ValueError("citation version must match release version") return version diff --git a/tools/release_smoke.py b/tools/release_smoke.py index 5c793ce1..cdba11cd 100644 --- a/tools/release_smoke.py +++ b/tools/release_smoke.py @@ -174,6 +174,9 @@ def validate( f"EXTRACTION_FAILURE: expected one rustiq executable in archive, found {len(binaries)}" ) binary = binaries[0] + for name in ("LICENSE-MIT", "LICENSE-APACHE", "COPYING", "DISTRIBUTION.md", "THIRD-PARTY-NOTICES.txt"): + if not any(p.is_file() for p in extracted.rglob(name)): + raise ValueError(f"EXTRACTION_FAILURE: archive lacks {name}") if os.name != "nt": binary.chmod(binary.stat().st_mode | 0o111) clean_path = os.pathsep.join( diff --git a/tools/test_prepare_release.py b/tools/test_prepare_release.py index bc001136..f4f6554d 100644 --- a/tools/test_prepare_release.py +++ b/tools/test_prepare_release.py @@ -12,6 +12,7 @@ def manifests(root, version, core=None, dependency=None): (root / "crates/rustiq-core").mkdir(parents=True) + (root / "CITATION.cff").write_text(f"version: {version}\n") (root / "Cargo.toml").write_text( f'[package]\nversion = "{version}"\n[dependencies]\nrustiq-core = {{version = "{dependency or version}"}}\n' ) @@ -87,3 +88,10 @@ def lookup(url, token=None): monkeypatch.setitem(available.__globals__, "lookup", lookup) with pytest.raises(OSError, match="unavailable"): available("1.2.3", "mveril/RustiQ") + + +def test_rejects_mismatched_citation(tmp_path): + manifests(tmp_path, "1.2.3") + (tmp_path / "CITATION.cff").write_text("version: 1.2.2\n") + with pytest.raises(ValueError, match="citation version"): + candidate(tmp_path) diff --git a/tools/test_publish_docs.py b/tools/test_publish_docs.py index f70d2941..9ade81fb 100644 --- a/tools/test_publish_docs.py +++ b/tools/test_publish_docs.py @@ -225,6 +225,7 @@ def git(*args): (tmp_path / "crates/rustiq-core/Cargo.toml").write_text( f'[package]\nversion = "{release_version}"\n' ) + (tmp_path / "CITATION.cff").write_text(f"version: {release_version}\n") git("add", ".") git("commit", "-m", "Initial main") diff --git a/tools/test_release_smoke.py b/tools/test_release_smoke.py index c00d7bfa..c414e1be 100644 --- a/tools/test_release_smoke.py +++ b/tools/test_release_smoke.py @@ -33,9 +33,13 @@ def setUp(self): "mermaid-init-test.js", ]: (manual / name).write_text("controlled manual asset") + for name in ("LICENSE-MIT", "LICENSE-APACHE", "COPYING", "DISTRIBUTION.md", "THIRD-PARTY-NOTICES.txt"): + (content / name).write_text("document") with tarfile.open(self.archive, "w:gz") as bundle: bundle.add(content / "rustiq", arcname="rustiq") bundle.add(manual, arcname="manual/html") + for name in ("LICENSE-MIT", "LICENSE-APACHE", "COPYING", "DISTRIBUTION.md", "THIRD-PARTY-NOTICES.txt"): + bundle.add(content / name, arcname=name) self.checksum = self.root / "bundle.tar.gz.sha256" self.checksum.write_text( hashlib.sha256(self.archive.read_bytes()).hexdigest() + " bundle.tar.gz\n" @@ -119,6 +123,8 @@ def test_missing_manual_is_rejected(self): binary = self.root / "archive-content/rustiq" with tarfile.open(self.archive, "w:gz") as bundle: bundle.add(binary, arcname="rustiq") + for name in ("LICENSE-MIT", "LICENSE-APACHE", "COPYING", "DISTRIBUTION.md", "THIRD-PARTY-NOTICES.txt"): + bundle.add(binary.parent / name, arcname=name) self.checksum.write_text(hashlib.sha256(self.archive.read_bytes()).hexdigest()) with self.assertRaisesRegex(ValueError, "lacks the complete offline manual"): self.validate() @@ -277,6 +283,18 @@ def test_nonfinite_reference_energy_is_rejected(self): command_runner=self.runner(), ) + def test_missing_distribution_documents(self): + for missing in ("LICENSE-MIT", "LICENSE-APACHE", "COPYING", "DISTRIBUTION.md", "THIRD-PARTY-NOTICES.txt"): + with self.subTest(missing=missing): + content = self.root / "archive-content" + with tarfile.open(self.archive, "w:gz") as bundle: + for path in content.iterdir(): + if path.name != missing: + bundle.add(path, arcname=path.name) + self.checksum.write_text(hashlib.sha256(self.archive.read_bytes()).hexdigest() + " bundle.tar.gz\n") + with self.assertRaisesRegex(ValueError, missing): + self.validate() + def test_success(self): result = self.validate() self.assertEqual(result["checksum"], "verified")