feat: implement CI

This commit is contained in:
2026-08-07 15:23:58 -04:00
parent fc63991c39
commit 3df06a9992
11 changed files with 1126 additions and 38 deletions
+29
View File
@@ -0,0 +1,29 @@
[tool.bumpversion]
current_version = "26.8.0"
parse = """(?x)
(?P<release>
(?:[1-9][0-9]?)\\. # YY short year, no leading zero
(?:1[0-2]|[1-9]) # MM month 1-12, no leading zero
)
\\.(?P<patch>\\d+) # patch
"""
serialize = ["{release}.{patch}"]
allow_dirty = false
commit = true
tag = true
message = "Release {new_version}"
tag_name = "{new_version}"
tag_message = "coursebank {new_version}"
[tool.bumpversion.parts.release]
calver_format = "{YY}.{MM}"
[[tool.bumpversion.files]]
filename = "Cargo.toml"
search = 'version = "{current_version}"'
replace = 'version = "{new_version}"'
[[tool.bumpversion.files]]
filename = "pixi.toml"
search = 'version = "{current_version}"'
replace = 'version = "{new_version}"'
+19
View File
@@ -0,0 +1,19 @@
name: CI
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
jobs:
check:
runs-on: pixi-build-rust
steps:
- uses: actions/checkout@v4
- name: Install the pinned toolchain
run: pixi install
- name: Verify (formatting, lint, tests, docs)
run: pixi run check
+67
View File
@@ -0,0 +1,67 @@
name: Deploy docs
on:
push:
branches: [main]
tags: ['*.*.*']
workflow_dispatch:
env:
SITE_SLUG: coursebank
CRATE: coursebank
jobs:
deploy:
runs-on: pixi-build-rust
steps:
- uses: actions/checkout@v4
- name: Write the channel switcher
run: |
cat > "${{ gitea.workspace }}/docs-banner.html" <<'HTML'
<div style="padding:.4rem .75rem;font:0.85rem/1.4 sans-serif;border-bottom:1px solid var(--border-color,#ddd);background:var(--sidebar-background-color,#f7f7f7);color:var(--main-color,#000)">
Docs channel:
<a id="ch-release" href="#" style="margin:0 .35rem">release</a>|
<a id="ch-nightly" href="#" style="margin:0 .35rem">nightly</a>
<script>
(function () {
var m = location.pathname.match(/^(.*\/)(release|nightly)\//);
var base = m ? m[1] : location.pathname.replace(/[^\/]*$/, "");
document.getElementById("ch-release").href = base + "release/";
document.getElementById("ch-nightly").href = base + "nightly/";
if (m) { document.getElementById("ch-" + m[2]).style.fontWeight = "bold"; }
})();
</script>
</div>
HTML
- name: Build the API docs
env:
RUSTDOCFLAGS: "--html-before-content ${{ gitea.workspace }}/docs-banner.html"
run: |
pixi install --locked
pixi run doc-build
- name: Redirect the channel root to the crate page
run: |
printf '%s\n' "<!doctype html><meta http-equiv=\"refresh\" content=\"0; url=${CRATE}/\">" > target/doc/index.html
- name: Publish the channel to /srv/www
run: |
case "${{ gitea.ref }}" in
refs/tags/*) channel=release ;;
*) channel=nightly ;;
esac
dest="/srv/www/${SITE_SLUG}/${channel}"
mkdir -p "$dest"
rsync -a --delete "target/doc/" "$dest/"
- name: Point the site root at the latest release, else nightly
run: |
root="/srv/www/${SITE_SLUG}"
if [ -d "$root/release/${CRATE}" ]; then
target="release/${CRATE}/"
else
target="nightly/${CRATE}/"
fi
printf '%s\n' "<!doctype html><meta http-equiv=\"refresh\" content=\"0; url=${target}\">" > "$root/index.html"
+71
View File
@@ -0,0 +1,71 @@
name: Nightly
on:
push:
branches: [main]
schedule:
- cron: '0 6 * * *'
workflow_dispatch:
jobs:
nightly:
runs-on: pixi-build-rust
permissions:
contents: write
env:
API: ${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}
TOKEN: ${{ secrets.GITEA_TOKEN }}
TAG: nightly
ASSET: coursebank-nightly-linux-x64.tar.gz
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install the pinned toolchain
run: pixi install
- name: Build the release binary
run: pixi run build
- name: Package
run: |
set -euo pipefail
tar -czf "$ASSET" \
-C target/release coursebank \
-C "${{ gitea.workspace }}" LICENSE.md
sha256sum "$ASSET" > "$ASSET.sha256"
- name: Publish the rolling nightly prerelease
run: |
set -euo pipefail
auth="Authorization: token ${TOKEN}"
# jq is fetched on demand; no toolchain change needed for it.
jq() { pixi exec --spec jq -- jq "$@"; }
sha="${{ gitea.sha }}"
version=$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')
body="Nightly build of ${version} at $(date -u +%Y-%m-%d) (commit ${sha:0:8}). Not a stable release."
# Drop the previous nightly release and its moving tag, if present, so
# the new one points at the current commit.
existing=$(curl -fsSL -H "$auth" "${API}/releases/tags/${TAG}" 2>/dev/null || true)
if [ -n "$existing" ]; then
id=$(printf '%s' "$existing" | jq -r '.id // empty')
[ -n "$id" ] && curl -fsSL -X DELETE -H "$auth" "${API}/releases/${id}"
fi
curl -fsSL -X DELETE -H "$auth" "${API}/tags/${TAG}" 2>/dev/null || true
# Create the release at the current commit.
rid=$(curl -fsSL -X POST -H "$auth" -H "Content-Type: application/json" \
"${API}/releases" \
-d "$(jq -n --arg tag "$TAG" --arg sha "$sha" --arg body "$body" \
'{tag_name:$tag, target_commitish:$sha, name:"Nightly", body:$body, draft:false, prerelease:true}')" \
| jq -r '.id')
# Attach the tarball and its checksum.
for f in "$ASSET" "$ASSET.sha256"; do
curl -fsSL -X POST -H "$auth" \
-F "attachment=@${f}" \
"${API}/releases/${rid}/assets?name=${f}"
done
+61
View File
@@ -0,0 +1,61 @@
name: Release
on:
push:
tags:
- '*.*.*'
jobs:
release:
runs-on: pixi-build-rust
permissions:
contents: write
env:
API: ${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}
TOKEN: ${{ secrets.GITEA_TOKEN }}
TAG: ${{ gitea.ref_name }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check the tag matches the crate version
run: |
set -euo pipefail
version=$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')
tag="${TAG#v}"
if [ "$tag" != "$version" ]; then
echo "tag ${TAG} does not match Cargo.toml version ${version}" >&2
exit 1
fi
- name: Install the pinned toolchain
run: pixi install
- name: Build the full bundle (binary and license notices)
run: |
pixi run setup-tools
pixi run dist
- name: Package and publish the release
run: |
set -euo pipefail
auth="Authorization: token ${TOKEN}"
jq() { pixi exec --spec jq -- jq "$@"; }
version=$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')
asset="coursebank-${version}-linux-x64.tar.gz"
tar -czf "$asset" -C dist coursebank LICENSE.md THIRD-PARTY-LICENSES.txt
sha256sum "$asset" > "$asset.sha256"
rid=$(curl -fsSL -X POST -H "$auth" -H "Content-Type: application/json" \
"${API}/releases" \
-d "$(jq -n --arg tag "$TAG" \
'{tag_name:$tag, name:$tag, body:"See CHANGELOG.md.", draft:false, prerelease:false}')" \
| jq -r '.id')
for f in "$asset" "$asset.sha256"; do
curl -fsSL -X POST -H "$auth" \
-F "attachment=@${f}" \
"${API}/releases/${rid}/assets?name=${f}"
done
+11
View File
@@ -0,0 +1,11 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to calendar versioning (`YY.MM.PATCH`); see [README.md](README.md#versioning).
## [Unreleased]
### Added
- First public release.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "coursebank"
version = "0.1.0"
version = "26.8.0"
edition = "2024"
rust-version = "1.85"
description = "Author, assemble, administer, and analyze leveled course assessments from YAML item banks"
+15 -2
View File
@@ -26,11 +26,14 @@ coursebank builds with Rust 1.85 or newer (edition 2024).
The repository uses [pixi](https://pixi.sh) to pin the toolchain and wrap the common tasks:
```sh
pixi run build # release binary at target/release/coursebank
pixi run build # release binary at target/release/coursebank
pixi run install # install the binary onto your PATH
pixi run tests
pixi run check # format, lint, test, and doc build
pixi run check # verify: formatting, lint, tests, and doc build
```
`pixi task list` prints every task with a one-line description.
Plain cargo works too with a recent toolchain:
```sh
@@ -50,6 +53,16 @@ coursebank export typst exam-4 --form A
Run `coursebank --help` for the full command set.
## Versioning
Releases use calendar versioning in `YY.MM.PATCH` form.
The first release of August 2026 is `26.8.0`; a second that month is `26.8.1`; the first in September is `26.9.0`.
Neither the year nor the month is zero-padded, because the version also has to parse as SemVer and SemVer forbids leading zeros.
The number carries no compatibility promise, so treat any release as one that can change behavior and read [`CHANGELOG.md`](CHANGELOG.md) before upgrading a live course.
`pixi run bump` cuts the next version and tags it; pushing that tag publishes a release, and every push to `main` refreshes a rolling `nightly` prerelease.
The workflows live in `.gitea/workflows/`; [RELEASING.md](RELEASING.md) explains the release flow and what to configure on the Gitea side.
## License
coursebank is source-available under the [Prosperity Public License 3.0.0](LICENSE.md).
+77
View File
@@ -0,0 +1,77 @@
# Releasing
This is the maintainer's guide to versioning and the release automation.
End users do not need it; they want the [README](README.md) and the setup guide.
## Versioning
Releases are dated, not semantic. The version is `YY.MM.PATCH`:
- `YY` is the two-digit year. 2026 is `26`.
- `MM` is the month with no leading zero. August is `8`, not `08`.
The version has to parse as SemVer (Cargo insists), and SemVer rejects leading zeros in a numeric field, so `26.08.0` is invalid and `26.8.0` is the form to use.
- `PATCH` starts at `0` in a new month and counts up for any further releases that month.
So the sequence across a few releases reads `26.8.0`, `26.8.1`, `26.9.0`.
These sort correctly both as dates and as SemVer, because each field is compared as a number.
The number is a date, not a compatibility contract.
Any release can change behavior; the [CHANGELOG](CHANGELOG.md) is where that is written down.
This is separate from `rust-version` in `Cargo.toml`, which is the oldest Rust that compiles the crate (currently `1.85`, the edition-2024 floor).
The pixi manifest pins a specific recent toolchain for reproducible builds. The two numbers answer different questions and are allowed to differ.
## Cutting a stable release
The version lives in two files, `Cargo.toml` and `pixi.toml`.
bump-my-version keeps them in step and computes the next number from today's date; it is configured in `.bumpversion.toml` and installed in the `release` pixi environment.
1. Record what changed: move the `Unreleased` notes in `CHANGELOG.md` under a heading for the new version, and commit that.
A clean working tree is required, so this commit comes first.
2. Preview the number the bump would produce:
```sh
pixi run bump-show
```
3. Cut it:
```sh
pixi run bump
```
This rewrites the version in both manifests, makes a `Release <version>` commit, and tags it.
The number follows the calendar: the first release in a month is `.0`, and a later one that month is `.1`.
To see every edit before it happens, run `pixi run --environment release bump-my-version bump patch --dry-run --verbose`.
4. Push the commit and its tag:
```sh
git push --follow-tags
```
The pushed tag triggers `.gitea/workflows/release.yml`, which rebuilds from the tagged commit, checks that the tag matches the `Cargo.toml` version (the bump has just made them agree), and publishes a Gitea release with the packaged binary and its checksum attached.
A `v` prefix on the tag is tolerated if you ever tag by hand.
## The workflows
All three live in `.gitea/workflows/` and build through pixi, the same way the site deploy does, so the runner needs pixi rather than a hand-installed Rust toolchain.
Each workflow installs pixi if it is not already on the runner.
- `ci.yml` runs on every push to `main` and every pull request.
It runs `pixi run check`: formatting, clippy, the full test suite, and a docs build.
This is the gate.
- `nightly.yml` runs on every push to `main`, so the nightly build tracks the branch.
It also carries an optional daily `cron`.
It builds the binary and publishes it as a single rolling prerelease tagged `nightly`, replacing the previous one so the tag always points at the current tip.
- `release.yml` runs on a version tag.
It builds, regenerates the third-party license notices, packages the full bundle, and publishes a normal (non-prerelease) release named after the tag.
## Publishing the API docs
`.gitea/workflows/docs.yml` builds the rustdoc and publishes it in two channels: `release/`, built from a version tag, and `nightly/`, built from `main`.
The site root redirects to the latest release, falling back to nightly until the first release exists.
Each page carries a small switcher to flip between the two channels.
It runs on the `pixi-build-rust` runner, so the doc build reuses the baked toolchain and the crate cache rather than compiling cold.
That runner builds inside a container, so give its job containers access to the docs directory by adding it to the runner's `config.yaml` alongside the cache volumes.
+729
View File
@@ -394,6 +394,232 @@ environments:
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-hb561403_3.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/typst-0.15.1-h6fdd925_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda
release:
channels:
- url: https://conda.anaconda.org/conda-forge/
packages:
linux-64:
- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/binutils-2.46.1-default_h4852527_102.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.46.1-default_hfdba357_102.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.46.1-default_h4852527_102.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_10.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.4.0-h611768e_1.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/gcc-14.4.0-hc6a0c74_1.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.4.0-h9711763_1.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.4.0-hc469d41_0.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h54a6638_2.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.46.1-default_hbd61a6d_102.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_1.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-16.1.0-ha9f2e26_1.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-16.1.0-h69a702a_1.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-16.1.0-he0feb66_1.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.4.0-hf39dbba_1.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.4-hf4e2dac_0.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-16.1.0-h934c35e_1.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.2-h5347b49_0.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_3.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.3-h35e630c_1.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/pkg-config-0.29.2-h4bc722e_1009.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py314h2e6c369_0.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.6-habeac84_101_cp314.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/rust-1.96.1-h53717f1_2.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd70dff1_3.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.8.0-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.14.2-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/bracex-3.0.1-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/bump-my-version-1.5.0-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-hbd8a1cb_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.3-pyhc90fa1f_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/httpcore2-2.5.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/httpx2-2.5.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.18-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.4.0-hd9a9cd0_101.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.4.0-ha5b54cb_101.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.2.0-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.53-pyha770c72_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.53-hd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-settings-2.14.2-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.8-pyh8f84b5b_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/rust-std-x86_64-unknown-linux-gnu-1.96.1-h2c6d0dc_2.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.15.1-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.16.0-h69aa097_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/wcmatch-11.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.8.2-pyhd8ed1ab_0.conda
osx-64:
- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.8.0-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.14.2-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/bracex-3.0.1-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/bump-my-version-1.5.0-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-hbd8a1cb_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.3-pyhc90fa1f_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-64-19.1.7-h138dee1_1.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/httpcore2-2.5.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/httpx2-2.5.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.18-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.2.0-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.53-pyha770c72_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.53-hd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-settings-2.14.2-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.8-pyh8f84b5b_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/rust-std-x86_64-apple-darwin-1.96.1-h38e4360_2.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-64-26.0-h62b880e_7.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.15.1-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.16.0-h69aa097_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/wcmatch-11.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.8.2-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h374f1ed_10.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/c-compiler-1.11.0-h7a00415_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/cctools-1030.6.3-llvm19_1_h67a6458_5.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_impl_osx-64-1030.6.3-llvm19_1_h6ae9dcd_5.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_osx-64-1030.6.3-llvm19_1_h67a6458_5.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/clang-19-19.1.7-default_h9399c5b_9.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/clang-19.1.7-default_h1323312_9.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/clang_impl_osx-64-19.1.7-default_ha1a018a_9.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/clang_osx-64-19.1.7-h8a78ed7_34.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/compiler-rt-19.1.7-he914875_1.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/ld64-956.6-llvm19_1_hc3792c1_5.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/ld64_osx-64-956.6-llvm19_1_hf4e8e46_5.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp19.1-19.1.7-default_h9399c5b_9.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.8-h19cb2f5_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.8.1-hcc62823_1.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm19-19.1.7-h56e7563_2.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/libsigtool-0.1.3-h8c25ef7_1.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.53.4-h77d7759_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.3-h0d7f165_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.3-h0712280_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_3.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.8-h0d3cbff_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-19-19.1.7-h879f4bc_2.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-19.1.7-hb0207f0_2.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.6-hcc0dc9a_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.3-hc881268_1.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/pkg-config-0.29.2-hf7e621a_1009.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.46.4-py314h8916c15_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.6-h7c6738f_101_cp314.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/rust-1.96.1-h5655b98_2.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/sigtool-codesign-0.1.3-h8c25ef7_1.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/tapi-1600.0.11.8-h44950e2_3.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hb794df6_3.conda
- conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda
osx-arm64:
- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.8.0-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.14.2-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/bracex-3.0.1-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/bump-my-version-1.5.0-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-hbd8a1cb_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.3-pyhc90fa1f_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/httpcore2-2.5.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/httpx2-2.5.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.18-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.2.0-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.53-pyha770c72_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.53-hd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-settings-2.14.2-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.8-pyh8f84b5b_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/rust-std-aarch64-apple-darwin-1.96.1-hf6ec828_2.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_7.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.15.1-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.16.0-h69aa097_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/wcmatch-11.0-pyhcf101f3_0.conda
- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.8.2-pyhd8ed1ab_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h4e30115_10.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_5.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_hc7668c6_5.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_hd01ab73_5.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_9.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_9.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_9.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h75f8d18_34.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hc7cc350_2.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_5.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_ha2625f7_5.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_9.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.8-h55c6f16_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.1-hf6b4638_1.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.88.3-ha08bb59_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libintl-0.25.1-h493aca8_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_1.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.4-h1ae2325_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.3-h5ef1a60_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.3-h5654f7c_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_3.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.8-hc7d1edf_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.3-hd24854e_1.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.47-h30297fc_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pkg-config-0.29.2-hde07d2e_1009.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py314h54f3292_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.6-h156bc91_101_cp314.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rust-1.96.1-h4ff7c5d_2.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_1.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-hb561403_3.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-hd3d0363_3.conda
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda
packages:
- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda
build_number: 20
@@ -876,6 +1102,22 @@ packages:
run_exports: {}
size: 115175
timestamp: 1720805894943
- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py314h2e6c369_0.conda
sha256: 802e216c39f1359aed60823b6e11d8ccd812b0ae1c81ae5ac1c81f99446409ab
md5: 0c96993dbeadf3a277cf757b9f1c9412
depends:
- python
- typing-extensions >=4.6.0,!=4.7.0
- libgcc >=14
- __glibc >=2.17,<3.0.a0
- python_abi 3.14.* *_cp314
constrains:
- __glibc >=2.17
license: MIT
license_family: MIT
run_exports: {}
size: 1895020
timestamp: 1778084229247
- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.6-habeac84_101_cp314.conda
build_number: 101
sha256: ee8f2006e1724b1f2e9e0ccc5a7cfdcab973460faa2f63ac1f6e44fdad4c0344
@@ -994,6 +1236,65 @@ packages:
- zstd >=1.5.7,<1.6.0a0
size: 601375
timestamp: 1764777111296
- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.8.0-pyhd8ed1ab_0.conda
sha256: b8fcb994134d3918d1c64a9d62f4168ff85d5bfb89e698102fe4ed679fe0df24
md5: 108c928d2a8551832dbc762b535e90bb
depends:
- python >=3.10
- typing-extensions >=4.0.0
license: MIT
license_family: MIT
run_exports: {}
size: 19461
timestamp: 1784935220549
- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.14.2-pyhcf101f3_0.conda
sha256: e36998c5e860e26b22e5dbcd5726dd0c4eabad949c84d383cad8512757bbf6a1
md5: fb568fbae6908ba86a090a85a089d11f
depends:
- exceptiongroup >=1.0.2
- idna >=2.8
- python >=3.10
- typing_extensions >=4.5
- python
constrains:
- trio >=0.32.0
- uvloop >=0.22.1
- winloop >=0.2.3
license: MIT
license_family: MIT
run_exports: {}
size: 164465
timestamp: 1783889660383
- conda: https://conda.anaconda.org/conda-forge/noarch/bracex-3.0.1-pyhcf101f3_0.conda
sha256: 958861098a6985d27eb72579adf0866b3dc99076b5e21362aeb02e4773cb5bc1
md5: 97f749ec797659e8338561149df0b76b
depends:
- python >=3.10
- python
license: MIT
license_family: MIT
run_exports: {}
size: 18298
timestamp: 1784591912561
- conda: https://conda.anaconda.org/conda-forge/noarch/bump-my-version-1.5.0-pyhd8ed1ab_0.conda
sha256: 961fadf4bf69ff62437e6032618c71b3c29a7565ec60c6741668d977cb923c96
md5: b7c38694ce6e74e390565c23f4231ef7
depends:
- click <8.4
- httpx2
- pydantic >=2.0.0
- pydantic-settings
- python >=3.10
- questionary
- rich
- rich-click
- tomlkit
- wcmatch >=8.5.1
license: MIT
license_family: MIT
run_exports: {}
size: 54116
timestamp: 1785233212974
- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-hbd8a1cb_0.conda
sha256: 0a0544cf95f64394fe4959286f5c71f5444ad58feb0602e53becb27448d24da6
md5: 0f51e2391ade309db462a55611263e9c
@@ -1003,6 +1304,18 @@ packages:
run_exports: {}
size: 131780
timestamp: 1784754889428
- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.3-pyhc90fa1f_0.conda
sha256: 37a5d8b10ea3516e2c42f870c9c351b9f7b31ff48c66d83490039f417e1e5228
md5: 2266262ce8a425ecb6523d765f79b303
depends:
- __unix
- python
- python >=3.10
license: BSD-3-Clause
license_family: BSD
run_exports: {}
size: 100048
timestamp: 1777219902525
- conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-64-19.1.7-h138dee1_1.conda
sha256: e6effe89523fc6143819f7a68372b28bf0c176af5b050fe6cf75b62e9f6c6157
md5: 32deecb68e11352deaa3235b709ddab2
@@ -1029,6 +1342,80 @@ packages:
run_exports: {}
size: 10490535
timestamp: 1757411851093
- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
sha256: ee6cf346d017d954255bbcbdb424cddea4d14e4ed7e9813e429db1d795d01144
md5: 8e662bd460bda79b1ea39194e3c4c9ab
depends:
- python >=3.10
- typing_extensions >=4.6.0
license: MIT and PSF-2.0
run_exports: {}
size: 21333
timestamp: 1763918099466
- conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda
sha256: 96cac6573fd35ae151f4d6979bab6fbc90cb6b1fb99054ba19eb075da9822fcb
md5: b8993c19b0c32a2f7b66cbb58ca27069
depends:
- python >=3.10
- typing_extensions
- python
license: MIT
license_family: MIT
run_exports: {}
size: 39069
timestamp: 1767729720872
- conda: https://conda.anaconda.org/conda-forge/noarch/httpcore2-2.5.0-pyhcf101f3_0.conda
sha256: 24f4cda7df09d9f5e79bf1eaa47cfe0cf379beef13788f4cbb32bb9c29076f7a
md5: d58db3677b5352fe18bf36254b350c16
depends:
- h11 >=0.16
- python >=3.10
- truststore >=0.10
- python
constrains:
- anyio >=4.5.0,<5.0
- h2 >=3,<5
- socksio 1.*
- trio >=0.22.0,<1.0
license: BSD-3-Clause
license_family: BSD
run_exports: {}
size: 52749
timestamp: 1782411845881
- conda: https://conda.anaconda.org/conda-forge/noarch/httpx2-2.5.0-pyhcf101f3_0.conda
sha256: 458d054e9641c8f5f792074bc85ce70ebc0928d1973c2c57ffb87c3c060cc62e
md5: 85b059d837508ef81872a293a563dd1a
depends:
- anyio
- httpcore2 ==2.5.0
- idna >=3.18
- python >=3.10
- truststore >=0.10
- typing_extensions >=4.5.0
- python
constrains:
- click 8.*
- pygments 2.*
- rich >=10,<16
- h2 >=3,<5
- socksio 1.*
- zstandard >=0.18.0
license: BSD-3-Clause
license_family: BSD
run_exports: {}
size: 72841
timestamp: 1782420230376
- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.18-pyhcf101f3_0.conda
sha256: c75632ea624aa450a394f570749420c5a2e0997d0216bc29d5d45b0f39df0426
md5: 577b04680ae422adb86fc60d7b940659
depends:
- python >=3.10
- python
license: BSD-3-Clause
license_family: BSD
run_exports: {}
size: 163869
timestamp: 1781620148226
- conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda
sha256: 41557eeadf641de6aeae49486cef30d02a6912d8da98585d687894afd65b356a
md5: 86d9cba083cd041bfbf242a01a7a1999
@@ -1059,6 +1446,99 @@ packages:
run_exports: {}
size: 19516469
timestamp: 1785374476067
- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.2.0-pyhd8ed1ab_0.conda
sha256: 0c4c35376fe920714390d46e4b8d31c876d65f18e1655899e0763ec25f2a902f
md5: 6d03368f2b2b0a5fb6839df53b2eb5e0
depends:
- mdurl >=0.1,<1
- python >=3.10
license: MIT
license_family: MIT
run_exports: {}
size: 69017
timestamp: 1778169663339
- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda
sha256: 78c1bbe1723449c52b7a9df1af2ee5f005209f67e40b6e1d3c7619127c43b1c7
md5: 592132998493b3ff25fd7479396e8351
depends:
- python >=3.9
license: MIT
license_family: MIT
run_exports: {}
size: 14465
timestamp: 1733255681319
- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.53-pyha770c72_0.conda
sha256: efe8def2c93aa34cd8d3c9af1dc4c7d312791cf769d8b2b615e32733e6df6051
md5: 39c92a39517316e5001d645ae63d9ab9
depends:
- python >=3.10
- wcwidth
constrains:
- prompt_toolkit 3.0.53
license: BSD-3-Clause
license_family: BSD
run_exports: {}
size: 276081
timestamp: 1785160613307
- conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.53-hd8ed1ab_0.conda
sha256: 59628c765189e99ca5d3c51f0758a325bc020dfafb8fef6068045595aaae1baf
md5: 4c7171dde29a2f2b1dac681c1154a291
depends:
- prompt-toolkit >=3.0.53,<3.0.54.0a0
license: BSD-3-Clause
license_family: BSD
run_exports: {}
size: 7083
timestamp: 1785160614678
- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda
sha256: 69700e31165df070e9716315e042196aa92525dae5deb5107785847ab9f4189f
md5: 729843edafc0899b3348bd3f19525b9d
depends:
- typing-inspection >=0.4.2
- typing_extensions >=4.14.1
- python >=3.10
- annotated-types >=0.6.0
- pydantic-core ==2.46.4
- python
license: MIT
license_family: MIT
run_exports: {}
size: 346511
timestamp: 1778103405862
- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-settings-2.14.2-pyhcf101f3_0.conda
sha256: de1eb2cdb22a678387ec7757f10b7815c4c2a4d62f23b2a70fe4beff7e8a1fd4
md5: a1c5305893d9956abd2079d377c5113f
depends:
- typing-inspection >=0.4.0
- python >=3.10
- pydantic >=2.7.0
- python-dotenv >=0.21.0
- python
license: MIT
license_family: MIT
run_exports: {}
size: 52920
timestamp: 1781884990751
- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda
sha256: cf70b2f5ad9ae472b71235e5c8a736c9316df3705746de419b59d442e8348e86
md5: 16c18772b340887160c79a6acc022db0
depends:
- python >=3.10
license: BSD-2-Clause
license_family: BSD
run_exports: {}
size: 893031
timestamp: 1774796815820
- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda
sha256: 74e417a768f59f02a242c25e7db0aa796627b5bc8c818863b57786072aeb85e5
md5: 130584ad9f3a513cdd71b1fdc1244e9c
depends:
- python >=3.10
license: BSD-3-Clause
license_family: BSD
run_exports: {}
size: 27848
timestamp: 1772388605021
- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
build_number: 8
sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5
@@ -1070,6 +1550,46 @@ packages:
run_exports: {}
size: 6989
timestamp: 1752805904792
- conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda
sha256: 0604c6dff3af5f53e34fceb985395d08287137f220450108a795bcd1959caf14
md5: 34fa231b5c5927684b03bb296bb94ddc
depends:
- prompt_toolkit >=2.0,<4.0
- python >=3.10
license: MIT
license_family: MIT
run_exports: {}
size: 31257
timestamp: 1757356458097
- conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda
sha256: 3d6ba2c0fcdac3196ba2f0615b4104e532525ffa1335b50a2878be5ff488814a
md5: 0242025a3c804966bf71aa04eee82f66
depends:
- markdown-it-py >=2.2.0
- pygments >=2.13.0,<3.0.0
- python >=3.10
- typing_extensions >=4.0.0,<5.0.0
- python
license: MIT
license_family: MIT
run_exports: {}
size: 208577
timestamp: 1775991661559
- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.8-pyh8f84b5b_0.conda
sha256: 771b335400554d812dcdf7e40e54e47247db1f96ca0ab4413d061e6960844d9c
md5: 3251fe7203751993d1ee7ecb492b4a42
depends:
- python >=3.10
- rich >=12
- click >=8
- typing-extensions >=4
- __unix
- python
license: MIT
license_family: MIT
run_exports: {}
size: 64412
timestamp: 1780016631584
- conda: https://conda.anaconda.org/conda-forge/noarch/rust-std-aarch64-apple-darwin-1.96.1-hf6ec828_2.conda
sha256: 1360d8d01a301379415b37a8ffc78f755302af3ee5603ba0546e4db82673af02
md5: 11b9425f6987f6fc387d98798befc850
@@ -1147,6 +1667,61 @@ packages:
- __glibc >=2.28,<3.0.a0
size: 24008591
timestamp: 1765578833462
- conda: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.15.1-pyhcf101f3_0.conda
sha256: 5cf833b4d199688b7652fb322ecc134de9555e9444d9249750de9a153421ad0a
md5: e4942e2de7436ff28be7f5645cf3c8d6
depends:
- python >=3.10
- python
license: MIT
license_family: MIT
run_exports: {}
size: 49054
timestamp: 1784287707171
- conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
sha256: eece5be81588c39a855a0b70da84e0febb878a6d91dd27d6d21370ce9e5c5a46
md5: c2db35b004913ec69bcac64fb0783de0
depends:
- python >=3.10,<4
- python
license: MIT
license_family: MIT
run_exports: {}
size: 24279
timestamp: 1766494826559
- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.16.0-h69aa097_0.conda
sha256: b141933ece3518f6d7b75dfb59451e2f26b405a44c18e2518a83e9a02e09315c
md5: c680b5747e8c4c8f23dca0bb7042a8fc
depends:
- typing_extensions ==4.16.0 pyhcf101f3_0
license: PSF-2.0
license_family: PSF
run_exports: {}
size: 94080
timestamp: 1783002732887
- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda
sha256: 8b90d2f19f9458b8c58a55e1fcdc1d90c1603a847a47654d8a454549413ba60a
md5: 53f5409c5cfd6c5a66417d68e3f0a864
depends:
- python >=3.10
- typing_extensions >=4.12.0
- python
license: MIT
license_family: MIT
run_exports: {}
size: 20935
timestamp: 1777105465795
- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda
sha256: 2d888f90af0686044882c74193ec80a90ec1943145d94a7b1b048958acda1848
md5: c70ad746c22219b9700931707482992c
depends:
- python >=3.10
- python
license: PSF-2.0
license_family: PSF
run_exports: {}
size: 52631
timestamp: 1783002732887
- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda
sha256: b928c30ddcb0e3f544c6eade8352737e6e610e263276b90232db6a578ef899d8
md5: fcb489df604d100968b737f2cb6076c6
@@ -1154,6 +1729,28 @@ packages:
run_exports: {}
size: 118849
timestamp: 1784250406640
- conda: https://conda.anaconda.org/conda-forge/noarch/wcmatch-11.0-pyhcf101f3_0.conda
sha256: e77239d6a599be8b70b08fb06d1eb754288ad219a68bb28cfd3a92d226389243
md5: c44743c4f4eb35b3078623bdff134af2
depends:
- python >=3.10
- bracex >=3.0
- python
license: MIT
license_family: MIT
run_exports: {}
size: 42758
timestamp: 1783680391789
- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.8.2-pyhd8ed1ab_0.conda
sha256: 4acf845da404e84cef1acccc66cc0156af1b83a5b5d7077b2ca19b705c561e57
md5: 99f7755ec8648a042b0dbe906234f888
depends:
- python >=3.10
license: MIT
license_family: MIT
run_exports: {}
size: 132415
timestamp: 1782771807703
- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h374f1ed_10.conda
sha256: 4ed83961876dc8844a6f0df49c07b408efbaea275ffb0b37133e24c006990b3a
md5: 9d9a39212a876e4bb751c1cc3927b678
@@ -1480,6 +2077,16 @@ packages:
run_exports: {}
size: 79899
timestamp: 1769482558610
- conda: https://conda.anaconda.org/conda-forge/osx-64/libsigtool-0.1.3-h8c25ef7_1.conda
sha256: c3d76ff04ebed64d00a7ff5106297a55af20082a3d3df0ea7dfb235f94ba31c3
md5: acc366a7706c83b5364f5f81e1b4857b
depends:
- __osx >=11.0
- openssl >=3.5.7,<4.0a0
license: MIT
run_exports: {}
size: 38559
timestamp: 1786115361068
- conda: https://conda.anaconda.org/conda-forge/osx-64/libsigtool-0.1.3-hc0f2934_0.conda
sha256: f87b743d5ab11c1a8ddd800dd9357fc0fabe47686068232ddc1d1eed0d7321ec
md5: 3576aba85ce5e9ab15aa0ea376ab864b
@@ -1659,6 +2266,21 @@ packages:
run_exports: {}
size: 239818
timestamp: 1720806136579
- conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.46.4-py314h8916c15_0.conda
sha256: 555021648575077c62d429feb4530c724915af6f92e3d77f2accb4789c071778
md5: a98f01ef277ca30e27a29bda4168b158
depends:
- python
- typing-extensions >=4.6.0,!=4.7.0
- __osx >=11.0
- python_abi 3.14.* *_cp314
constrains:
- __osx >=10.13
license: MIT
license_family: MIT
run_exports: {}
size: 1883108
timestamp: 1778084289874
- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.6-h7c6738f_101_cp314.conda
build_number: 101
sha256: 08c788453bdf61071e075a97684291286877536ee92f23a73b4127f1b85bdbcd
@@ -1724,6 +2346,17 @@ packages:
run_exports: {}
size: 11567252
timestamp: 1777398362461
- conda: https://conda.anaconda.org/conda-forge/osx-64/sigtool-codesign-0.1.3-h8c25ef7_1.conda
sha256: 37aac42f05e21b48a3b61b28ae624ed5a3d2acfcbaabf2cd10ef7762c4fb4c45
md5: e7eb95a1f841fbbb8312dcd65963334f
depends:
- __osx >=11.0
- libsigtool 0.1.3 h8c25ef7_1
- openssl >=3.5.7,<4.0a0
license: MIT
run_exports: {}
size: 123458
timestamp: 1786115396108
- conda: https://conda.anaconda.org/conda-forge/osx-64/sigtool-codesign-0.1.3-hc0f2934_0.conda
sha256: b89d89d0b62e0a84093205607d071932cca228d4d6982a5b073eec7e765b146d
md5: 1261fc730f1d8af7eeea8a0024b23493
@@ -1933,6 +2566,18 @@ packages:
run_exports: {}
size: 97085
timestamp: 1757411887557
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hc7cc350_2.conda
sha256: f0b22bc30e4cc29e29ba3234cb38497fe8def2c2aae4b775d42fe5b378a018c9
md5: 6133ddbb17ba2b50700dd88e9303ce27
depends:
- __osx >=11.0
license: MIT
license_family: MIT
run_exports:
weak:
- icu >=78.3,<79.0a0
size: 14070698
timestamp: 1784916459058
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_5.conda
sha256: 65a01b4adde1c1c7f4f6195590e90280bcb6ac34c03a81297a594a7830003c31
md5: 972af8a8dee1002cc8a9d331d273326c
@@ -2151,6 +2796,29 @@ packages:
run_exports: {}
size: 36416
timestamp: 1767045062496
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_1.conda
sha256: fcfa03afe31f40dfabf011629d99836adbebbc3ed1b38c7e9eee9ffc7581975b
md5: c70eb797aa92a294b09ef8f41f6bd578
depends:
- __osx >=11.0
- openssl >=3.5.7,<4.0a0
license: MIT
run_exports: {}
size: 36651
timestamp: 1786115069018
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.4-h1ae2325_0.conda
sha256: 745662565e103f290e9dc4263bbd88285082f8cf699854fe2d5f1e35a4a0d326
md5: 0e3477c0c3e718dcf2eb74ccc8f68570
depends:
- __osx >=11.0
- icu >=78.3,<79.0a0
- libzlib >=1.3.2,<2.0a0
license: blessing
run_exports:
weak:
- libsqlite >=3.53.4,<4.0a0
size: 929203
timestamp: 1785016131414
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.4-h1b79a29_0.conda
sha256: 9c50de03f8ff9f7e57fc5c13748736bae0538b93421eca0d3471ccb93f8b3d19
md5: 4aad9a4de332ab9ce571ef3901810b32
@@ -2163,6 +2831,22 @@ packages:
- libsqlite >=3.53.4,<4.0a0
size: 925226
timestamp: 1785016124520
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.3-h5ef1a60_0.conda
sha256: ff75b84cdb9e8d123db2fa694a8ac2c2059516b6cbc98ac21fb68e235d0fd354
md5: 19edaa53885fc8205614b03da2482282
depends:
- __osx >=11.0
- icu >=78.3,<79.0a0
- libiconv >=1.18,<2.0a0
- liblzma >=5.8.3,<6.0a0
- libzlib >=1.3.2,<2.0a0
constrains:
- libxml2 2.15.3
license: MIT
license_family: MIT
run_exports: {}
size: 466360
timestamp: 1776377102261
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.3-h6967ea9_0.conda
sha256: 43895a7517c055b8893531290f9dc48bd751eb04be04f14bbce3b6c71b052be6
md5: 6c8292c2ee808aeef2406083beaa6da7
@@ -2179,6 +2863,24 @@ packages:
run_exports: {}
size: 465820
timestamp: 1776377317454
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.3-h5654f7c_0.conda
sha256: 2fe1d8de0854342ae9cabe408b476935f82f5636e153b3b497456264dc8ff3a1
md5: 8e037d73747d6fe34e12d7bcac10cf21
depends:
- __osx >=11.0
- icu >=78.3,<79.0a0
- libiconv >=1.18,<2.0a0
- liblzma >=5.8.3,<6.0a0
- libxml2-16 2.15.3 h5ef1a60_0
- libzlib >=1.3.2,<2.0a0
license: MIT
license_family: MIT
run_exports:
weak:
- libxml2
- libxml2-16 >=2.15.3
size: 41102
timestamp: 1776377119495
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.3-heed7d32_0.conda
sha256: 4d9c117b2dd222cf891710d5f6a570ebb275479979843a1477ac54ed50907b40
md5: 0c1fdc80534d8f25fd74722aba81f044
@@ -2333,6 +3035,22 @@ packages:
run_exports: {}
size: 49724
timestamp: 1720806128118
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py314h54f3292_0.conda
sha256: c034a7cc16f279c260d3456fcfc625838495a7f9f55aa79408a629a427769bb2
md5: 16314d88257820013e698381af19153f
depends:
- python
- typing-extensions >=4.6.0,!=4.7.0
- __osx >=11.0
- python 3.14.* *_cp314
- python_abi 3.14.* *_cp314
constrains:
- __osx >=11.0
license: MIT
license_family: MIT
run_exports: {}
size: 1722694
timestamp: 1778084354332
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.6-h156bc91_101_cp314.conda
build_number: 101
sha256: fc70ae73df7798bce7cac7adef7fdfb874208b2623a0e8ccb4354194b8508769
@@ -2408,6 +3126,17 @@ packages:
run_exports: {}
size: 114331
timestamp: 1767045086274
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_1.conda
sha256: 7efd6d7d18bf9cc5788bfe1c1e1620d9dbbe00a81c646814929a82ff31944cf3
md5: a322c0a0d3b5be99ee11f9ccec99b60e
depends:
- __osx >=11.0
- libsigtool 0.1.3 h98dc951_1
- openssl >=3.5.7,<4.0a0
license: MIT
run_exports: {}
size: 114653
timestamp: 1786115093248
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-hb561403_3.conda
sha256: 9f1cc109e6e57861110e9de6e03beca7fd2b7fbdb46124cccc07990b0844d88a
md5: 0676b8719dd1e9bb1003e59a481c6c3e
+46 -35
View File
@@ -1,62 +1,73 @@
[workspace]
authors = ["Alex Maldonado <alexm@scient.ing>"]
channels = ["conda-forge"]
name = "coursebank"
version = "26.8.0"
authors = ["Scientific Computing Studio <opensource@scient.ing>"]
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "osx-64"]
version = "0.1.0"
[environments]
dev = ["dev"]
docs = ["docs"]
[dependencies]
rust = ">=1.96.0,<1.97"
c-compiler = "*"
pkg-config = "*"
[tasks]
build = "cargo build --release"
debug = "cargo build"
tests = "cargo test"
format = "cargo fmt"
lint = { cmd = "cargo clippy --all-targets -- -D warnings", depends-on = [
"format",
] }
check-docs = "cargo test --test docs"
doc = { cmd = "cargo doc --no-deps --open", depends-on = ["check-docs"] }
doc-build = { cmd = "cargo doc --no-deps", depends-on = ["check-docs"] }
doctests = "cargo test --doc"
# --- Build and run ---
build = { cmd = "cargo build --release", description = "Compile the release binary at target/release/coursebank" }
debug = { cmd = "cargo build", description = "Compile the debug binary" }
build-lean = { cmd = "cargo build --release --no-default-features", description = "Release build without the parquet feature" }
install = { cmd = "cargo install --path . --locked", description = "Install the coursebank binary onto your PATH" }
clean = { cmd = "cargo clean", description = "Remove the target directory" }
cb = { cmd = "cargo run --release --quiet --", description = "Run the CLI, e.g., `pixi run cb validate -C path/to/course`" }
clean = "cargo clean"
install = "cargo install --path . --locked"
check = { depends-on = ["format", "lint", "tests", "check-docs", "doc-build"] }
build-lean = "cargo build --release --no-default-features"
# --- Quality gate ---
format = { cmd = "cargo fmt --all", description = "Reformat the source in place" }
fmt-check = { cmd = "cargo fmt --all --check", description = "Fail if the source is not formatted; does not rewrite" }
lint = { cmd = "cargo clippy --all-targets -- -D warnings", description = "Run clippy with warnings treated as errors" }
tests = { cmd = "cargo test", description = "Run all tests: unit, integration, and doctests" }
doctests = { cmd = "cargo test --doc", description = "Run only the documentation examples" }
check-docs = { cmd = "cargo test --test docs", description = "Check that included markdown fences declare a language" }
check = { depends-on = ["fmt-check", "lint", "tests", "doctests", "check-docs", "doc-build"], description = "Full verify-only gate: formatting, lint, tests, and doc build" }
setup-tools = "cargo install cargo-about --locked --features cli"
licenses = "cargo about generate about.hbs -o THIRD-PARTY-LICENSES.txt"
# --- Documentation ---
doc = { cmd = "cargo doc --no-deps --open", depends-on = ["check-docs"], description = "Build the API docs and open them in a browser" }
doc-build = { cmd = "cargo doc --no-deps", depends-on = ["check-docs"], description = "Build the API docs without opening a browser" }
[tasks.dist]
description = "Assemble a release bundle (binary + license notices) in dist/"
depends-on = ["build", "licenses"]
cmd = "mkdir -p dist && cp target/release/coursebank dist/ && cp LICENSE.md THIRD-PARTY-LICENSES.txt dist/"
# --- Release packaging ---
setup-tools = { cmd = "cargo install cargo-about --locked --features cli", description = "Install cargo-about, which the licenses task needs" }
licenses = { cmd = "cargo about generate about.hbs -o THIRD-PARTY-LICENSES.txt", description = "Regenerate THIRD-PARTY-LICENSES.txt" }
dist = { cmd = "mkdir -p dist && cp target/release/coursebank dist/ && cp LICENSE.md THIRD-PARTY-LICENSES.txt dist/", depends-on = ["build", "licenses"], description = "Assemble a release bundle (binary and license notices) in dist/" }
[environments]
dev = ["dev"]
docs = ["docs"]
release = ["release"]
[tasks.cb]
cmd = "cargo run --release --quiet --"
description = "Run the CLI, e.g., `pixi run cb validate --course examples/course`"
# Developer tooling: editor support, a debugger, a faster test runner, and a
# file watcher.
[feature.dev.dependencies]
rust-analyzer = "*"
lldb = "*"
cargo-nextest = "*"
[feature.dev.tasks]
watch = "cargo watch -x check -x test"
nextest = "cargo nextest run"
nextest = { cmd = "cargo nextest run", description = "Run the test suite with nextest" }
# Typst is only needed to typeset exported .typ files by hand. The exporter
# writes .typ on its own and does not require typst to be installed.
[feature.docs.dependencies]
typst = "*"
[feature.docs.tasks]
typeset = "typst compile"
typeset = { cmd = "typst compile", description = "Compile a .typ file to PDF" }
# Release tooling, kept in its own environment so the default and dev
# environments do not pull in Python. bump-my-version reads .bumpversion.toml,
# which encodes the YY.MM.PATCH scheme.
[feature.release.dependencies]
bump-my-version = "*"
[feature.release.tasks]
bump = { cmd = "bump-my-version bump patch", description = "Cut the next release: rewrite the version in both manifests, commit, and tag" }
bump-show = { cmd = "bump-my-version show-bump", description = "Preview the next version without changing anything" }