From 973523432b2815505c8e2a761443a8c984b2fbe7 Mon Sep 17 00:00:00 2001 From: Tim Saucer Date: Mon, 2 Mar 2026 12:01:10 -0500 Subject: [PATCH] Add check for crates.io patches to CI --- .github/workflows/build.yml | 9 ++++++ Cargo.toml | 5 +++ dev/check_crates_patch.py | 61 +++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 dev/check_crates_patch.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b86b37c6e..455a0dc1a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -98,6 +98,15 @@ jobs: - name: Check Cargo.toml formatting run: taplo format --check + check-crates-patch: + if: inputs.build_mode == 'release' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Ensure [patch.crates-io] is empty + run: python3 dev/check_crates_patch.py + generate-license: runs-on: ubuntu-latest steps: diff --git a/Cargo.toml b/Cargo.toml index 313640ec2..c19ae21f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,3 +91,8 @@ crate-type = ["cdylib", "rlib"] [profile.release] lto = true codegen-units = 1 + +# We cannot publish to crates.io with any patches in the below section. Developers +# must remove any entries in this section before creating a release candidate. +[patch.crates-io] +# datafusion = { git = "https://github.com/apache/datafusion.git", rev = "6713439497561fa74a94177e5b8632322fb7cea5" } diff --git a/dev/check_crates_patch.py b/dev/check_crates_patch.py new file mode 100644 index 000000000..74e489e1f --- /dev/null +++ b/dev/check_crates_patch.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +"""Check that no Cargo.toml files contain [patch.crates-io] entries. + +Release builds must not depend on patched crates. During development it is +common to temporarily patch crates-io dependencies, but those patches must +be removed before creating a release. + +An empty [patch.crates-io] section is allowed. +""" + +import sys +from pathlib import Path + +import tomllib + + +def main() -> int: + errors: list[str] = [] + for cargo_toml in sorted(Path().rglob("Cargo.toml")): + if "target" in cargo_toml.parts: + continue + with Path.open(cargo_toml, "rb") as f: + data = tomllib.load(f) + patch = data.get("patch", {}).get("crates-io", {}) + if patch: + errors.append(str(cargo_toml)) + for name, spec in patch.items(): + errors.append(f" {name} = {spec}") + + if errors: + print("ERROR: Release builds must not contain [patch.crates-io] entries.") + print() + for line in errors: + print(line) + print() + print("Remove all [patch.crates-io] entries before creating a release.") + return 1 + + print("OK: No [patch.crates-io] entries found.") + return 0 + + +if __name__ == "__main__": + sys.exit(main())