chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:49:22 +08:00
commit a41b2ab474
303 changed files with 64772 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
---
name: Bug Report
about: Use this template to report a bug.
title: "[Short summary of the bug]"
labels: needs triage
assignees: ''
---
<!-- Briefly summarize the issue. INCLUDE the exact code you are trying to run! Ideally in a self-contained script so we can reproduce your bug. -->
# Stack trace
<!-- If applicable, please include a full stack trace here. If you need to omit
the bottom of the stack trace (e.g. it includes stack frames from your private
code), that is okay. Try to include all cleanlab stack frames. -->
# Steps to reproduce
<!-- Be as detailed as possible here. If possible, include a self-contained
runnable example that demonstrates the issue. Remember to supply any data
necessary to run your example, or construct your example with synthetic data.
This is not strictly required, but the more detailed your bug report, the more
quickly we can help you and fix the bug. -->
# Additional information
- **Cleanlab version**: <!-- `cleanlab.__version__`, or the git commit hash if you're using an unreleased version -->
- **Operating system**: <!-- e.g. macOS 12.1, Ubuntu 20.04, Windows 10 -->
- **Python version**: <!-- you can find this with `python --version` -->
<!-- Please include any other information that could be helpful for debugging. -->
@@ -0,0 +1,26 @@
---
name: Feature Request
about: Use this template to ask for new functionality in cleanlab.
title: "[Short summary of the feature]"
labels: needs triage
assignees: ''
---
<!-- Briefly summarize the proposed feature. -->
# Details
<!--
Describe your proposed feature in more detail. INCLUDE the exact code you are trying to run or would like to see, if your question is related to code. Answer any of the following
questions that you can:
* What is the problem you're trying to solve?
* What tasks or workflows would be enabled by having support for your
proposed feature in cleanlab?
* Can you share code snippets or pseudocode describing uses of your feature?
* Can you share any datasets that can help us assess the usefulness of the
proposed feature?
* Have you considered any alternatives to your proposed feature/design?
* How are you working around the lack of native support for your proposed
feature?
-->
+17
View File
@@ -0,0 +1,17 @@
---
name: Help
about: Use this template to ask for help.
title: "[Short summary of the question]"
labels: question
assignees: ''
---
<!--
Please be as detailed as possible in your question. INCLUDE the exact code you are trying to run, if your question is related to code.
We will answer questions posted here, but you will likely get an answer faster
by posting in our Slack Community:
https://cleanlab.ai/slack
-->
+10
View File
@@ -0,0 +1,10 @@
---
name: Other
about: Use this template when no other template applies.
title: "[Short summary of the issue]"
labels: needs triage
assignees: ''
---
<!-- Please be as detailed as possible in your issue. INCLUDE the exact code you are trying to run, if your question is related to code. -->
+16
View File
@@ -0,0 +1,16 @@
"""This script fetches minimum dependencies of cleanlab package and writes them to the file requirements-min.txt"""
import json
if __name__ == "__main__":
with open("./deps.json", "r") as f:
deps = json.load(f)
for package in deps:
if package["package"]["package_name"] == "cleanlab":
for dep in package["dependencies"]:
req_version = dep["required_version"]
with open("requirements-min.txt", "a") as f:
if req_version.startswith(">="):
f.write(f"{dep['package_name']}=={req_version[2:]}\n")
+82
View File
@@ -0,0 +1,82 @@
## Summary
> 🎯 **Purpose**: Describe the objective of your changes in this Pull-Request.
>
> 📜 **Example Usage**: If adding new functionality, strive to provide a minimal working example (MWE) that demonstrates end-to-end usage and output of your new methods. If creating a MWE is not feasible, a conceptual code snippet showcasing the usage is also appreciated. Ensure that the code provided can be copied, pasted, and run without modifications.
**[ ✏️ Write your summary here. ]**
```python
# Example code snippet
# Necessary Imports:
from my_module import my_new_function
# Setup if needed (e.g., data loading, model instantiation):
a = 20
b = 22
# Usage and Output:
result = my_new_function(a, b)
# 42
# ---- Your code below ----
# [Replace the example above with your own code, ensuring it is executable and demonstrates your feature or fix.]
[your_uncommented_runnable_code_here]
# [your_output_here_as_a_comment]
```
## Impact
> 🌐 Areas Affected: Enumerate modules, functions, or documentation impacted by your code.
>
> 👥 Whos Affected: Mention who might be impacted (if applicable).
**Screenshots**
> 📸 If your changes modify documentation or a tutorial notebook, please include screenshots or GIFs showing the rendered outputs for a quicker initial review, highlighting the main changes.
## Testing
> 🔍 Testing Done: Outline what kinds of tests you performed.
>
> 🔗 Test Case Link: Directly link to the most end-to-end check of your new functionality.
**Unaddressed Cases**
> It's ok if your unit tests are not yet
> comprehensive when you first open the PR,
> we can revisit them later!
>
> ⚠️ Mention any aspects of testing that have *not* been covered, and why.
-
## Links to Relevant Issues or Conversations
> 🔗 What Git or Slack items (Issues, threads, etc) that are specifically related to
> this work? Please link them here.
-
## References
> 📚 Include any extra information that may be helpful to reviewers of your
> Pull-Request here (e.g. relevant URLs or Wiki pages that could help give
> background information).
>
> Share links, docs, or sources that facilitated your changes.
>
> If relevant, please include additional code snippets
> (and their outputs/return values) showing alternative ways to use your newly added methods.
```python
[additional code snippets and explanations]
```
-
## Reviewer Notes
> 💡 Include any specific points for the reviewer to consider during their review.
+35
View File
@@ -0,0 +1,35 @@
name: Bleeding Edge Dependencies Test
on:
schedule:
- cron: '0 6 1 * *' # First day of each month at 6:00 UTC
workflow_dispatch: # Allow manual triggering
jobs:
test-bleeding-edge:
name: "Bleeding Edge Dependencies: Python Latest"
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v6
- uses: snok/latest-python-versions@v1
id: python-versions
with:
min-version: '3.14'
include-prereleases: false
- uses: actions/setup-python@v6
with:
python-version: ${{ fromJson(steps.python-versions.outputs.latest-python-versions)[0] }}
- name: Download cleanvision test data
run: |
git clone https://github.com/cleanlab/assets.git
mv assets/cleanlab_test_data ./tests/datalab/data
- name: Install bleeding-edge dependencies
run: |
python -m pip install --upgrade pip
pip install --pre --upgrade numpy scikit-learn pandas tqdm termcolor
pip install --pre torch torchvision || pip install torch torchvision
pip install -e ".[all]"
- name: Install test dependencies
run: pip install --no-cache-dir -r requirements-test-core.txt
- name: Test with bleeding-edge deps
run: pytest --verbose --maxfail=10 -m "not slow" --ignore=tests/test_frameworks.py --ignore=tests/test_model_pytorch_cnn.py
+165
View File
@@ -0,0 +1,165 @@
name: CI
on:
push:
pull_request:
schedule:
- cron: '0 12 * * 1' # Monday at 12:00 UTC
jobs:
test-core:
name: "Core Tests: Python ${{ matrix.python }} on ${{ matrix.os }}"
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
python:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- name: Download cleanvision test data
run: |
git clone https://github.com/cleanlab/assets.git
mv assets/cleanlab_test_data ./tests/datalab/data
- name: Install cleanlab
run: |
python -m pip install --upgrade pip
pip install -e ".[all]"
- name: Install core test dependencies
run: pip install --no-cache-dir -r requirements-test-core.txt
- name: Audit dependencies for vulnerabilities
uses: pypa/gh-action-pip-audit@v1.1.0
with:
inputs: requirements-test-core.txt
- name: Run core tests (excluding ML framework tests)
run: pytest --verbose --maxfail=30 --order-tests --cov=cleanlab/ --cov-config .coveragerc --cov-report=xml -m "not slow" --ignore=tests/test_frameworks.py --ignore=tests/test_model_pytorch_cnn.py
- uses: codecov/codecov-action@v5
with:
version: "v0.7.3"
test-ml-frameworks:
name: "ML Framework Tests: Python ${{ matrix.python }} on ubuntu-latest"
runs-on: ubuntu-latest
strategy:
matrix:
python:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- name: Download cleanvision test data
run: |
git clone https://github.com/cleanlab/assets.git
mv assets/cleanlab_test_data ./tests/datalab/data
- name: Install cleanlab
run: |
python -m pip install --upgrade pip
pip install -e ".[all]"
- name: Install ML framework dependencies
run: pip install --no-cache-dir -r requirements-dev.txt
- name: Audit dependencies for vulnerabilities
uses: pypa/gh-action-pip-audit@v1.1.0
with:
inputs: requirements-dev.txt
- name: Run ML framework tests
run: pytest --verbose --maxfail=30 tests/test_frameworks.py tests/test_model_pytorch_cnn.py
test-without-extras-min-versions:
name: Test without optional dependencies and with minimum compatible versions of dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.10'
- name: Install cleanlab
run: |
python -m pip install --upgrade pip
pip install .
- name: Install test dependencies
run: |
pip install pytest pipdeptree hypothesis
pipdeptree -j > deps.json
- name: Install minimum versions
run: |
python ./.github/get_min_dependencies.py
pip install -r requirements-min.txt
- name: Run tests
run: |
pytest tests/test_multilabel_classification.py tests/test_multiannotator.py tests/test_filter_count.py
test-max-versions:
name: "Maximum Dependency Versions: Python 3.14"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.14'
- name: Download cleanvision test data
run: |
git clone https://github.com/cleanlab/assets.git
mv assets/cleanlab_test_data ./tests/datalab/data
- name: Install latest stable versions
run: |
python -m pip install --upgrade pip
pip install --upgrade numpy scikit-learn pandas tqdm termcolor
pip install --upgrade torch torchvision
pip install -e ".[all]"
- name: Install test dependencies
run: pip install --no-cache-dir -r requirements-test-core.txt
- name: Test with latest stable versions
run: pytest --verbose --maxfail=10 -m "not slow" --ignore=tests/test_frameworks.py --ignore=tests/test_model_pytorch_cnn.py
typecheck:
name: Type check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.14'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install ".[all]" # install dependencies
pip install --no-cache-dir -r requirements-test-core.txt # install core dependencies and type stubs
- name: Type check
run: mypy --install-types --non-interactive cleanlab
fmt:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: psf/black@stable
flake8:
name: Check for unused/wildcard imports
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.14'
- name: Install flake8
run: pip install flake8
- name: Lint with flake8
run: flake8 cleanlab tests
nblint:
name: Lint Notebooks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: cleanlab/nblint-action@v1
with:
directory: 'docs'
+210
View File
@@ -0,0 +1,210 @@
name: GitHub Pages
on:
push:
branches:
- "**"
release:
types: [published]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-24.04
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install Pandoc
# pin Pandoc version
run: |
cd /tmp
wget https://github.com/jgm/pandoc/releases/download/2.19.2/pandoc-2.19.2-linux-amd64.tar.gz
sudo tar xzvf pandoc-2.19.2-linux-amd64.tar.gz --strip-components 1 -C /usr/local
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: "22"
- name: Install FFmpeg
run: |
sudo apt-get update
sudo apt-get install -y ffmpeg
- name: Upgrade pip
run: python3 -m pip install --upgrade pip
# Caching removed to resolve disk space issues
# Heavy ML packages (TensorFlow, PyTorch, HuggingFace) will be downloaded fresh each run
# but this avoids the 3.7GB cache that causes "No space left on device" errors
- name: Install cleanlab
run: pip install -e ".[all]"
- name: Install dependencies
run: python3 -m pip install -r docs/requirements.txt
- name: Install katex
run: npm install -g katex
- name: Find and replace "%pip install cleanlab" with master branch in .ipynb files
if: ${{ github.ref_type == 'branch' }}
uses: jacobtomlinson/gha-find-replace@v2
with:
find: "%pip install cleanlab ${{ '#' }} for colab"
replace: "%pip install git+https://github.com/${{ github.repository }}.git@${{ github.sha }}"
include: "docs/source**.ipynb"
- name: Find and replace "%pip install cleanlab" with release tag in .ipynb files
if: ${{ github.ref_type == 'tag' }}
uses: jacobtomlinson/gha-find-replace@v2
with:
find: "%pip install cleanlab ${{ '#' }} for colab"
replace: "%pip install cleanlab==${{ github.ref_name }}"
include: "docs/source**.ipynb"
- name: Add and Commit changes to .ipynb files
run: |
git config --global user.email "actions@github.com"
git config --global user.name "GitHub Actions"
git add -A && git commit -m "Change cleanlab ver in .ipynb files"
- name: Change tag to the latest commit
if: ${{ github.ref_type == 'tag' }}
run: |
git tag -f $GITHUB_REF_NAME
- name: Run Sphinx with sphinx-multiversion wrapper - branch trigger
if: ${{ github.ref_type == 'branch' }}
env:
TF_CPP_MIN_LOG_LEVEL: 3
HF_HOME: /tmp/hf_cache
HF_HUB_DISABLE_SYMLINKS_WARNING: 1
TRANSFORMERS_CACHE: /tmp/transformers
TORCH_HOME: /tmp/torch
run: sphinx-multiversion docs/source cleanlab-docs -D smv_branch_whitelist=${{ github.ref_name }} -D smv_tag_whitelist=None
- name: Run Sphinx with sphinx-multiversion wrapper - tag trigger
if: ${{ github.ref_type == 'tag' }}
env:
TF_CPP_MIN_LOG_LEVEL: 3
HF_HOME: /tmp/hf_cache
HF_HUB_DISABLE_SYMLINKS_WARNING: 1
TRANSFORMERS_CACHE: /tmp/transformers
TORCH_HOME: /tmp/torch
run: sphinx-multiversion docs/source cleanlab-docs -D smv_branch_whitelist=None -D smv_tag_whitelist=${{ github.ref_name }}
- name: Debug temporary cache usage (not saved)
run: |
echo "=== Temporary Cache Usage ==="
echo "These caches are created in /tmp and cleaned up after build:"
echo " /tmp/hf_cache: $(du -sh /tmp/hf_cache 2>/dev/null | cut -f1 || echo 'not found')"
echo " /tmp/transformers: $(du -sh /tmp/transformers 2>/dev/null | cut -f1 || echo 'not found')"
echo " /tmp/torch: $(du -sh /tmp/torch 2>/dev/null | cut -f1 || echo 'not found')"
echo "Pip cache directory: $(pip cache dir)"
echo "Pip cache size: $(du -sh $(pip cache dir) 2>/dev/null | cut -f1 || echo 'not found')"
echo "========================"
- name: Get latest stable release
id: stable_release
continue-on-error: true
uses: pozetroninc/github-action-get-latest-release@master
with:
owner: ${{ github.repository_owner }}
repo: cleanlab
excludes: prerelease, draft
- name: Create latest_release.txt file
if: ${{ steps.stable_release.outcome == 'success' }}
run: echo ${{ steps.stable_release.outputs.release }} > cleanlab-docs/latest_release.txt
- name: Find and replace "placeholder_version_number" in versioning.js
if: ${{ steps.stable_release.outcome == 'success' }}
uses: jacobtomlinson/gha-find-replace@v2
with:
find: "placeholder_version_number"
replace: ${{ steps.stable_release.outputs.release }}
include: "docs/source/_templates/versioning.js"
- name: Find and replace "placeholder_commit_hash" in versioning.js
uses: jacobtomlinson/gha-find-replace@v2
with:
find: "placeholder_commit_hash"
replace: ${{ github.sha }}
include: "docs/source/_templates/versioning.js"
- name: Copy versioning JS file to cleanlab-docs/
run: |
cp docs/source/_templates/versioning.js cleanlab-docs/versioning.js
- name: Find and replace "stable_url" in redirect-to-stable.html
if: ${{ github.ref_type == 'tag' && steps.stable_release.outcome == 'success' }}
uses: jacobtomlinson/gha-find-replace@v2
with:
find: "stable_url"
replace: ${{ env.DOCS_SITE_URL }}stable/index.html
include: "docs/source/_templates/redirect-to-stable.html"
- name: Copy redirecting HTML file to cleanlab-docs/
if: ${{ github.ref_type == 'tag' }}
run: cp docs/source/_templates/redirect-to-stable.html cleanlab-docs/index.html
- name: Update OpenGraph URLs in HTML files
# This code fixes the URLs in the HTML files with OpenGraph tags.
# It uses a regular expression to capture two parts of the URL:
# $1: The first part of the URL, including the protocol and domain.
# $2: The rest of the URL, including the path and query string.
# The replacement string combines the captured parts with the ref name.
# This ensures that the ref name is inserted into the URL correctly.
env:
REF_URL_SEGMENT: ${{ (github.ref_type == 'tag' && steps.stable_release.outcome == 'success') && 'stable' || github.ref_name }}
uses: jacobtomlinson/gha-find-replace@v2
with:
find: '(<meta property="og:url" content="https?://[^/]+)/([^"]+")'
replace: '$1/${{ env.REF_URL_SEGMENT }}/$2'
include: "cleanlab-docs/**/*.html"
regex: true
- name: Deploy
if: ${{ (github.ref == 'refs/heads/master') || (github.ref_type == 'tag') }}
uses: peaceiris/actions-gh-pages@v4
with:
deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
external_repository: ${{ github.repository_owner }}/cleanlab-docs
publish_branch: master
publish_dir: cleanlab-docs
keep_files: true
exclude_assets: ""
- uses: actions/upload-artifact@v5
with:
name: docs-html
path: cleanlab-docs
retention-days: 1 # don't need this except in link checking step below
links:
needs: deploy
runs-on: ubuntu-24.04
steps:
- uses: actions/download-artifact@v5
with:
name: docs-html
path: cleanlab-docs
- uses: anishathalye/proof-html@v1
with:
directory: ./cleanlab-docs
external_only: true
url_ignore_re: |
^https://pradyunsg.me/
^https://keras.io/
+35
View File
@@ -0,0 +1,35 @@
name: GitHub Markdown Links
on:
push:
pull_request:
schedule:
- cron: "0 8 * * 6"
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: sudo apt-get update -y
- run: >-
sudo apt-get install -y
pandoc
- uses: actions/checkout@v6
- run: |
find . -name '*.html' -delete
- run: |
find . -name '*.md' -exec pandoc -i {} -o {}.html \;
- uses: anishathalye/proof-html@v2
with:
directory: .
check_html: false
check_favicon: false
ignore_missing_alt: true
tokens: |
{"https://github.com": "${{ secrets.GITHUB_TOKEN }}"}
ignore_url: |
https://jair.org/index.php/jair/article/view/12125
https://stackoverflow.com/questions/41573587/what-is-the-difference-between-venv-pyvenv-pyenv-virtualenv-virtualenvwrappe
ignore_url_re: |
https://www.gnu.org/software/wget
swap_urls: |
{"^(\\..*)\\.md(#?.*)$": "\\1.md.html\\2",
"^(https://github\\.com/.*)#.*$": "\\1"}
+154
View File
@@ -0,0 +1,154 @@
name: Manual TestPyPI Release
on:
workflow_dispatch: # Manual trigger only
inputs:
reason:
description: 'Reason for this test release'
required: false
default: 'Testing changes before official release'
jobs:
extract_project_name:
runs-on: ubuntu-latest
outputs:
cleanlab_package_name: ${{ steps.extract_name.outputs.value }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: TOML Reader
uses: SebRollen/toml-action@v1.2.0
id: extract_name
with:
file: "pyproject.toml"
field: "project.name"
build:
needs: extract_project_name
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Remove tests directory
run: |
TEST_DIR=$(find . -type d -name "tests")
if [ -n "$TEST_DIR" ]; then
rm -rf $TEST_DIR
else
echo "No tests directory found! This is unexpected."
exit 1
fi
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: 3.11
- name: Modify version for TestPyPI
run: |
# Add .dev suffix with run number for TestPyPI
sed -i "s/__version__ = \"\(.*\)\"/__version__ = \"\1.dev${{ github.run_number }}\"/" cleanlab/version.py
echo "Modified version for TestPyPI:"
grep "__version__" cleanlab/version.py
- name: Install dependencies
run: pip install --upgrade "setuptools>=65.0,<70.0" wheel twine==5.0.0 pkginfo
- name: Clean build artifacts
run: |
rm -rf build/ dist/ *.egg-info cleanlab.egg-info/
- name: Perform some tests on the metadata of the package
run: |
python setup.py check --metadata --strict
- name: Build package
run: |
python setup.py sdist bdist_wheel
- name: Test package
run: |
twine check dist/*
- name: Display package info
run: |
echo "📦 Built packages:"
ls -lh dist/
echo ""
echo "📝 Reason: ${{ github.event.inputs.reason }}"
- name: Store build artifacts
uses: actions/upload-artifact@v5
with:
name: package
path: dist/*
publish-testpypi:
needs: build
runs-on: ubuntu-latest
permissions:
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
steps:
- name: Fetch build artifacts
uses: actions/download-artifact@v5
with:
name: package
path: dist/
- name: Publish to TestPyPI
uses: pypa/gh-action-pypi-publish@e53eb8b103ffcb59469888563dc324e3c8ba6f06
with:
repository-url: https://test.pypi.org/legacy/
verify-metadata: true
test-basic-import:
needs: [publish-testpypi, extract_project_name]
runs-on: ubuntu-latest
steps:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: 3.11
- name: Install package from TestPyPI
env:
CLEANLAB_PACKAGE_NAME: ${{ needs.extract_project_name.outputs.cleanlab_package_name }}
run: pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ $CLEANLAB_PACKAGE_NAME
- name: Test importing package
run: |
python -c "import cleanlab
from cleanlab.outlier import OutOfDistribution
ood = OutOfDistribution()
print(ood)
print('✅ Basic import test passed!')
print('Version:', cleanlab.__version__)"
test-extras-import:
needs: [publish-testpypi, extract_project_name]
runs-on: ubuntu-latest
steps:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: 3.11
- name: Install package with extras
env:
CLEANLAB_PACKAGE_NAME: ${{ needs.extract_project_name.outputs.cleanlab_package_name }}
run: pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ $CLEANLAB_PACKAGE_NAME[all]
- name: Test importing package with extras
run: |
python -c "import cleanlab
from cleanlab import Datalab
lab = Datalab({'a': [1, 2, 3, 4, 5], 'b': ['a', 'b', 'c', 'b', 'a']})
print(lab)
print('✅ Extras import test passed!')
print('Version:', cleanlab.__version__)"
+260
View File
@@ -0,0 +1,260 @@
name: Release Build Publish
on:
release:
types: [ published ]
jobs:
extract_project_name:
runs-on: ubuntu-latest
outputs:
cleanlab_package_name: ${{ steps.extract_name.outputs.value }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: TOML Reader
uses: SebRollen/toml-action@v1.2.0
id: extract_name
with:
file: "pyproject.toml"
field: "project.name"
store_published_version:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.compare.outputs.version }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: 3.11
- name: Install package
run: pip install .
- name: Compare the published version with the package version
id: compare
run: |
TAG_NAME="${{ github.ref_name }}"
# TAG_NAME must be in the form "v1.2.3[...]", error if it doesn't match
if [[ ! $TAG_NAME =~ ^v[0-9]+\.[0-9]+\.[0-9]+ ]]; then
echo "Tag name '$TAG_NAME' does not match the expected pattern 'vX.Y.Z'"
exit 1
fi
# Strip the 'v' prefix from the tag, and store the version in an output variable
VERSION=${TAG_NAME:1} # Strip the 'v' prefix from the tag
echo "version=$VERSION" >> $GITHUB_OUTPUT
# Check that the package version matches the tag version
PACKAGE_VERSION=$(python -c "import cleanlab; print(cleanlab.__version__)")
if [ "$PACKAGE_VERSION" != "$VERSION" ]; then
echo "Package version $PACKAGE_VERSION does not match tag $VERSION"
exit 1
fi
build:
needs: [store_published_version, extract_project_name]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Remove tests directory
run: |
# Remove the tests directory from the package
TEST_DIR=$(find . -type d -name "tests")
if [ -n "$TEST_DIR" ]; then
rm -rf $TEST_DIR
else
echo "No tests directory found! This is unexpected."
exit 1
fi
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: 3.11
- name: Install dependencies
run: pip install --upgrade "setuptools>=65.0,<70.0" wheel twine==5.0.0 pkginfo
- name: Clean build artifacts
run: |
rm -rf build/ dist/ *.egg-info cleanlab.egg-info/
- name: Perform some tests on the metadata of the package
run: |
python setup.py check --metadata --strict
- name: Build package
run: |
python setup.py sdist bdist_wheel
- name: Test package
run: |
twine check dist/*
- name: Verify contents of the tar.gz
env:
CLEANLAB_PACKAGE_NAME: ${{ needs.extract_project_name.outputs.cleanlab_package_name }}
run: |
# Extract the tar.gz to a temporary directory
TMPDIR=$(mktemp -d)
tar -xzf dist/*.tar.gz -C $TMPDIR
PACKAGE_DIR=$TMPDIR/$(ls $TMPDIR) # Assuming there's only one directory extracted
# Define expected files and directories
EXPECTED_FILES="LICENSE PKG-INFO MANIFEST.in DEVELOPMENT.md CONTRIBUTING.md CODE_OF_CONDUCT.md README.md pyproject.toml setup.cfg setup.py"
EXPECTED_DIRS="cleanlab $CLEANLAB_PACKAGE_NAME.egg-info"
# Collect actual top-level files and directories
ACTUAL_CONTENTS=$(ls $PACKAGE_DIR)
ACTUAL_FILES=$(find $PACKAGE_DIR -maxdepth 1 -type f -exec basename {} \;)
ACTUAL_DIRS=$(find $PACKAGE_DIR -maxdepth 1 -type d -exec basename {} \; | sed "1d") # Remove the package directory itself from the list
# Function to check for unexpected or missing files and directories
check_contents() {
local missing=0
# Check for expected files
for expected_file in $EXPECTED_FILES; do
echo $ACTUAL_FILES | grep -qw $expected_file || { echo "Missing expected file: $expected_file"; missing=1; }
done
# Check for expected directories
for expected_dir in $EXPECTED_DIRS; do
echo $ACTUAL_DIRS | grep -qw $expected_dir || { echo "Missing expected directory: $expected_dir"; missing=1; }
done
# Check for unexpected files and directories
for actual in $ACTUAL_CONTENTS; do
echo $EXPECTED_FILES $EXPECTED_DIRS | grep -qw $actual || { echo "Unexpected item in package: $actual"; missing=1; }
done
# Exit if anything unexpected or missing
if [ $missing -ne 0 ]; then
echo "Package content verification failed."
exit 1
fi
}
# Execute checks
check_contents
- name: Store build artifacts
uses: actions/upload-artifact@v5
with:
name: package
path: dist/*
publish-testpypi:
needs: build
runs-on: ubuntu-latest
permissions:
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
steps:
- name: Fetch build artifacts
uses: actions/download-artifact@v5
with:
name: package
path: dist/
- name: Publish to TestPyPI
uses: pypa/gh-action-pypi-publish@e53eb8b103ffcb59469888563dc324e3c8ba6f06
with:
repository-url: https://test.pypi.org/legacy/
verify-metadata: true
verify-version:
needs: [publish-testpypi, store_published_version, extract_project_name]
runs-on: ubuntu-latest
environment: testpypi
steps:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: 3.11
- name: Install package from TestPyPI
env:
CLEANLAB_PACKAGE_NAME: ${{ needs.extract_project_name.outputs.cleanlab_package_name }}
run: pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ $CLEANLAB_PACKAGE_NAME
- name: Verify the published version
env:
VERSION: ${{ needs.store_published_version.outputs.version }}
run: |
TEST_IMPORT_VERSION=$(python -c "import cleanlab; print(cleanlab.__version__)")
if [ "$TEST_IMPORT_VERSION" != "$VERSION" ]; then
echo "Imported version $TEST_IMPORT_VERSION does not match tag $VERSION"
exit 1
fi
test-basic-import:
needs: [verify-version, extract_project_name]
runs-on: ubuntu-latest
steps:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: 3.11
- name: Install package from TestPyPI
env:
CLEANLAB_PACKAGE_NAME: ${{ needs.extract_project_name.outputs.cleanlab_package_name }}
run: pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ $CLEANLAB_PACKAGE_NAME
- name: Test importing package
run: |
python -c "import cleanlab
from cleanlab.outlier import OutOfDistribution
ood = OutOfDistribution()
print(ood)"
test-extras-import:
needs: [verify-version, extract_project_name]
runs-on: ubuntu-latest
steps:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: 3.11
- name: Install package with extras
env:
CLEANLAB_PACKAGE_NAME: ${{ needs.extract_project_name.outputs.cleanlab_package_name }}
run: pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ $CLEANLAB_PACKAGE_NAME[all]
- name: Test importing package with extras
run: |
python -c "import cleanlab
from cleanlab import Datalab
lab = Datalab({'a': [1, 2, 3, 4, 5], 'b': ['a', 'b', 'c', 'b', 'a']})
print(lab)"
publish-pypi:
needs: [test-basic-import, test-extras-import]
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
steps:
- name: Fetch build artifacts
uses: actions/download-artifact@v5
with:
name: package
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@e53eb8b103ffcb59469888563dc324e3c8ba6f06
with:
verify-metadata: true