diff --git a/.github/workflows/check-mise-checksums.yml b/.github/workflows/check-mise-checksums.yml new file mode 100644 index 000000000..5c1a598ff --- /dev/null +++ b/.github/workflows/check-mise-checksums.yml @@ -0,0 +1,20 @@ +name: Mise Checksums Check + +on: + pull_request: + paths: + - mise.toml + - mise.lock + +jobs: + check-mise-checksums: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Install uv + uses: astral-sh/setup-uv@0c5e2b8115b80b4c7c5ddf6ffdd634974642d182 # v5.4.1 + + - name: Check mise.lock checksums + run: uv run ci/check_mise_checksums.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 8966b5b03..e88dee7ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Added - Added new `!concat` generator to the `templated_json` payload generator. +- Use `mise` for tooling management ## [0.31.2] ## Changed @@ -28,7 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **Breaking Change**: Rename `lost_bytes` to `missed_bytes` in `logrotate_fs`. This reflects preexisting terminology. - **Breaking Change**: Replace `opentelemetry_traces` payload with a brand-new - service topology-based configuration scheme. This allows for defining an + service topology-based configuration scheme. This allows for defining an imaginary distributed system -- service type, operations, attributes, etc -- which is then simulated to generate realistic-looking traces and spans. ## Added diff --git a/ci/check_mise_checksums.py b/ci/check_mise_checksums.py new file mode 100644 index 000000000..d75214755 --- /dev/null +++ b/ci/check_mise_checksums.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python3 +# /// script +# requires-python = ">=3.11" +# dependencies = ["tomlkit"] +# /// +"""Check that mise.lock has checksums for all tools on all required platforms. + +Usage: + uv run ci/check_mise_checksums.py # Report missing checksums + uv run ci/check_mise_checksums.py --fix # Download and add missing checksums +""" + +import hashlib +import sys +import tempfile +import urllib.request +from dataclasses import dataclass +from pathlib import Path + +import tomlkit + +REQUIRED_PLATFORMS = ("macos-arm64", "linux-arm64", "linux-x64") +LOCK_FILE = Path(__file__).resolve().parent.parent / "mise.lock" + + +@dataclass +class MissingChecksum: + tool: str + platform: str + url: str + + +@dataclass +class FixFailure: + entry: MissingChecksum + reason: str + + +def fetch_checksum(url: str) -> str | None: + """Download a URL and return its sha256 checksum.""" + try: + with tempfile.NamedTemporaryFile() as tmp: + with urllib.request.urlopen(url) as resp: + while chunk := resp.read(8192): + tmp.write(chunk) + tmp.seek(0) + return hashlib.sha256(tmp.read()).hexdigest() + except Exception as e: + print(f" FAILED to fetch {url}: {e}", file=sys.stderr) + return None + + +def fix_lockfile(missing: list[MissingChecksum]) -> list[FixFailure]: + """Download artifacts and insert checksums into mise.lock.""" + doc = tomlkit.parse(LOCK_FILE.read_text()) + failures: list[FixFailure] = [] + + for entry in missing: + print(f" Fetching {entry.tool} ({entry.platform})... ", end="", flush=True) + checksum = fetch_checksum(entry.url) + if checksum is None: + failures.append(FixFailure(entry, "failed to download artifact")) + continue + print("done") + + # Walk the parsed TOML to find the matching platform table and insert the checksum. + tool_key = entry.tool.rsplit("@", 1)[0] + platform_key = f"platforms.{entry.platform}" + patched = False + for tool_entry in doc["tools"][tool_key]: + if platform_key in tool_entry and tool_entry[platform_key].get("url") == entry.url: + tool_entry[platform_key]["checksum"] = f"sha256:{checksum}" + patched = True + break + if not patched: + failures.append(FixFailure(entry, "could not locate entry in lockfile")) + + LOCK_FILE.write_text(tomlkit.dumps(doc)) + print(f"\nUpdated {LOCK_FILE.name}.") + return failures + + +def main() -> int: + fix_mode = "--fix" in sys.argv + + doc = tomlkit.parse(LOCK_FILE.read_text()) + + missing_platform: list[str] = [] + missing_checksum: list[MissingChecksum] = [] + + for tool_name, entries in doc.get("tools", {}).items(): + if not isinstance(entries, list): + entries = [entries] + + for entry in entries: + version = entry.get("version", "unknown") + label = f"{tool_name}@{version}" + + for platform in REQUIRED_PLATFORMS: + key = f"platforms.{platform}" + if key not in entry: + missing_platform.append(f"{label}: missing platform '{platform}'") + elif "checksum" not in entry[key]: + url = entry[key].get("url", "") + missing_checksum.append(MissingChecksum(label, platform, url)) + + errors = missing_platform + [ + f"{m.tool}: missing checksum for '{m.platform}'" for m in missing_checksum + ] + + if errors: + print(f"Found {len(errors)} issue(s) in {LOCK_FILE.name}:\n") + for err in errors: + print(f" - {err}") + print() + + if missing_platform: + print( + "Note: missing platforms cannot be auto-fixed. " + "Run `mise lock` to regenerate the lockfile." + ) + + if fix_mode and missing_checksum: + print(f"Fixing {len(missing_checksum)} missing checksum(s)...\n") + failures = fix_lockfile(missing_checksum) + if failures: + print(f"\n{len(failures)} fix(es) failed:") + for f in failures: + print(f" - {f.entry.tool} ({f.entry.platform}): {f.reason}") + return 1 + return 1 if missing_platform else 0 + + return 1 if errors else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/mise.lock b/mise.lock new file mode 100644 index 000000000..3a5fa2dd8 --- /dev/null +++ b/mise.lock @@ -0,0 +1,116 @@ +# @generated - this file is auto-generated by `mise lock` https://mise.jdx.dev/dev-tools/mise-lock.html + +[[tools.actionlint]] +version = "1.7.3" +backend = "aqua:rhysd/actionlint" + +[tools.actionlint."platforms.linux-arm64"] +checksum = "sha256:5fd82142c39208bfdc51b929ff9bd84c38bcc10b4362ef2261a5d70d38e68e05" +url = "https://github.com/rhysd/actionlint/releases/download/v1.7.3/actionlint_1.7.3_linux_arm64.tar.gz" + +[tools.actionlint."platforms.linux-x64"] +checksum = "sha256:37252b4d440b56374b0fc1726e05fd7452d30d6d774f6e9b52e65bb64475f9db" +url = "https://github.com/rhysd/actionlint/releases/download/v1.7.3/actionlint_1.7.3_linux_amd64.tar.gz" + +[tools.actionlint."platforms.macos-arm64"] +checksum = "sha256:b4e8dab8dda48eceff6afea67d0fe4a14b8d4ea7191cf233c1e1af8a62f37c24" +url = "https://github.com/rhysd/actionlint/releases/download/v1.7.3/actionlint_1.7.3_darwin_arm64.tar.gz" + +[[tools."aqua:EmbarkStudios/cargo-deny"]] +version = "0.19.0" +backend = "aqua:EmbarkStudios/cargo-deny" + +[tools."aqua:EmbarkStudios/cargo-deny"."platforms.linux-arm64"] +checksum = "sha256:2b3567a60b7491c159d1cef8b7d8479d1ad2a31e29ef49462634ad4552fcc77d" +url = "https://github.com/EmbarkStudios/cargo-deny/releases/download/0.19.0/cargo-deny-0.19.0-aarch64-unknown-linux-musl.tar.gz" + +[tools."aqua:EmbarkStudios/cargo-deny"."platforms.linux-x64"] +checksum = "sha256:0e8c2aa59128612c90d9e09c02204e912f29a5b8d9a64671b94608cbe09e064f" +url = "https://github.com/EmbarkStudios/cargo-deny/releases/download/0.19.0/cargo-deny-0.19.0-x86_64-unknown-linux-musl.tar.gz" + +[tools."aqua:EmbarkStudios/cargo-deny"."platforms.macos-arm64"] +checksum = "sha256:a22f2023c06f3eefd099a5d42dd828fd4fa74d1e1c167bd1dbc3cf59ad62ded0" +url = "https://github.com/EmbarkStudios/cargo-deny/releases/download/0.19.0/cargo-deny-0.19.0-aarch64-apple-darwin.tar.gz" + +[[tools."aqua:ast-grep/ast-grep"]] +version = "0.39.5" +backend = "aqua:ast-grep/ast-grep" + +[tools."aqua:ast-grep/ast-grep"."platforms.linux-arm64"] +checksum = "sha256:4b20d2032fec27d0863e9f58e2848861fd5b99bf71f56f271d636dc821056bbb" +url = "https://github.com/ast-grep/ast-grep/releases/download/0.39.5/app-aarch64-unknown-linux-gnu.zip" + +[tools."aqua:ast-grep/ast-grep"."platforms.linux-x64"] +checksum = "sha256:9a1cab3e7916c98c6fe0079cc2c3b44d98832ba3bdb9db492d04a4e60e41fd0f" +url = "https://github.com/ast-grep/ast-grep/releases/download/0.39.5/app-x86_64-unknown-linux-gnu.zip" + +[tools."aqua:ast-grep/ast-grep"."platforms.macos-arm64"] +checksum = "sha256:d672ef833d478423a54a57da6b937784e2fe9b768c89affa58d8ff6db3174d3d" +url = "https://github.com/ast-grep/ast-grep/releases/download/0.39.5/app-aarch64-apple-darwin.zip" + +[[tools."aqua:nextest-rs/nextest/cargo-nextest"]] +version = "0.9.72" +backend = "aqua:nextest-rs/nextest/cargo-nextest" + +[tools."aqua:nextest-rs/nextest/cargo-nextest"."platforms.linux-arm64"] +url = "https://github.com/nextest-rs/nextest/releases/download/cargo-nextest-0.9.72/cargo-nextest-0.9.72-aarch64-unknown-linux-gnu.tar.gz" +checksum = "sha256:f49577c199fc95c4076d90fc3017c0689d8a4982176fdefb6faa8505681da10e" + +[tools."aqua:nextest-rs/nextest/cargo-nextest"."platforms.linux-x64"] +url = "https://github.com/nextest-rs/nextest/releases/download/cargo-nextest-0.9.72/cargo-nextest-0.9.72-x86_64-unknown-linux-musl.tar.gz" +checksum = "sha256:4f471fecc32ca4bf745a2c85c2fde7339640cb366f59cd36fbe5bb63d3fd0880" + +[tools."aqua:nextest-rs/nextest/cargo-nextest"."platforms.macos-arm64"] +url = "https://github.com/nextest-rs/nextest/releases/download/cargo-nextest-0.9.72/cargo-nextest-0.9.72-universal-apple-darwin.tar.gz" +checksum = "sha256:2816fd2b39fdba8dc16b7144b2c85a6ef62e38c8df87645a8c510e2e78c160c2" + +[[tools.buf]] +version = "1.50.0" +backend = "aqua:bufbuild/buf" + +[tools.buf."platforms.linux-arm64"] +checksum = "sha256:4c920c5f96eb99ad13eb6f25cf740fdb42963401faa267bee03fbd3e163730b2" +url = "https://github.com/bufbuild/buf/releases/download/v1.50.0/buf-Linux-aarch64.tar.gz" + +[tools.buf."platforms.linux-x64"] +checksum = "sha256:80c1211dfc4844499c6ddad341bb21206579883fd33cea0a2c40c82befd70602" +url = "https://github.com/bufbuild/buf/releases/download/v1.50.0/buf-Linux-x86_64.tar.gz" + +[tools.buf."platforms.macos-arm64"] +checksum = "sha256:c80f7f8a1d8ffd36c5db31a360c7e0b65c8cf671d60bd3c34e1558e54f84f4cc" +url = "https://github.com/bufbuild/buf/releases/download/v1.50.0/buf-Darwin-arm64.tar.gz" + +[[tools."github:bnjbvr/cargo-machete"]] +version = "0.9.1" +backend = "github:bnjbvr/cargo-machete" + +[tools."github:bnjbvr/cargo-machete"."platforms.linux-arm64"] +checksum = "sha256:ec71436fb90acd8cb1e22ec1e9f9fe507abffcd66741b20b481a0d0f13ce4fa0" +url = "https://github.com/bnjbvr/cargo-machete/releases/download/v0.9.1/cargo-machete-v0.9.1-aarch64-unknown-linux-gnu.tar.gz" +url_api = "https://api.github.com/repos/bnjbvr/cargo-machete/releases/assets/282938034" + +[tools."github:bnjbvr/cargo-machete"."platforms.linux-x64"] +checksum = "sha256:640b0814480b401e4e72201e52a13e1311b8eb8d7c27faa08bbe9886f252f26d" +url = "https://github.com/bnjbvr/cargo-machete/releases/download/v0.9.1/cargo-machete-v0.9.1-x86_64-unknown-linux-musl.tar.gz" +url_api = "https://api.github.com/repos/bnjbvr/cargo-machete/releases/assets/282938086" + +[tools."github:bnjbvr/cargo-machete"."platforms.macos-arm64"] +checksum = "sha256:72355383848acb154060e6fea2d5b7d58a825ed49fef157b46a6fe25180f8638" +url = "https://github.com/bnjbvr/cargo-machete/releases/download/v0.9.1/cargo-machete-v0.9.1-aarch64-apple-darwin.tar.gz" +url_api = "https://api.github.com/repos/bnjbvr/cargo-machete/releases/assets/282938101" + +[[tools.protoc]] +version = "33.2" +backend = "aqua:protocolbuffers/protobuf/protoc" + +[tools.protoc."platforms.linux-arm64"] +checksum = "sha256:706662a332683aa2fffe1c4ea61588279d31679cd42d91c7d60a69651768edb8" +url = "https://github.com/protocolbuffers/protobuf/releases/download/v33.2/protoc-33.2-linux-aarch_64.zip" + +[tools.protoc."platforms.linux-x64"] +checksum = "sha256:b24b53f87c151bfd48b112fe4c3a6e6574e5198874f38036aff41df3456b8caf" +url = "https://github.com/protocolbuffers/protobuf/releases/download/v33.2/protoc-33.2-linux-x86_64.zip" + +[tools.protoc."platforms.macos-arm64"] +checksum = "sha256:5be1427127788c9f7dd7d606c3e69843dd3587327dea993917ffcb77e7234b44" +url = "https://github.com/protocolbuffers/protobuf/releases/download/v33.2/protoc-33.2-osx-aarch_64.zip" diff --git a/mise.toml b/mise.toml new file mode 100644 index 000000000..076242cfb --- /dev/null +++ b/mise.toml @@ -0,0 +1,48 @@ +# mise.toml - Development tool configuration +# +# This file configures mise (https://mise.jdx.dev/) to provide consistent tool +# versions for both local development and CI. +# +# # Setup +# +# Run `mise install`. This installs the locked versions of all required tools. +# +# # Updating tool versions +# +# MISE_LOCKED=0 mise upgrade --bump +# MISE_LOCKED=0 mise lock --platform linux-x64,macos-arm64,linux-arm64 +# +# When those complete, run: +# uv run ci/check_mise_checksums.py +# mise install +# ci/validate +# + +[settings] +# Require the use of a lockfile. +locked = true + +# Lockfile support is experimental. Enable it. +experimental = true + +[tools] +# GitHub Actions workflow linter +actionlint = "1.7.3" + +# Code pattern matching for custom lints +"aqua:ast-grep/ast-grep" = "0.39.5" + +# Fast test runner +"aqua:nextest-rs/nextest/cargo-nextest" = "0.9.72" + +# License and security auditing +"aqua:EmbarkStudios/cargo-deny" = "0.19.0" + +# Unused dependency detection +"github:bnjbvr/cargo-machete" = "0.9.1" + +# Protocol buffer linter and breaking change detector +buf = "1.50.0" + +# Protocol buffer compiler +protoc = "33.2"