From ac2fce24505553325c139d9d96cc9b57a7477096 Mon Sep 17 00:00:00 2001 From: raphaeltimbo Date: Mon, 20 Jul 2026 15:48:30 -0300 Subject: [PATCH 1/2] Add GitHub Actions test workflow with private REFPROP REFPROP is proprietary and cannot live in this public repository. The workflow fetches a private repository containing the compiled Linux build (librefprop.so + FLUIDS/MIXTURES) using a read-only deploy key stored as the REFPROP_DEPLOY_KEY actions secret, points RPPREFIX at the checkout and runs the full test suite. Secrets are not exposed to workflows triggered by fork PRs, so the test job skips itself when the key is absent - the REFPROP binary cannot be exfiltrated through a malicious PR. Forks wanting CI must provide their own private REFPROP repository and deploy key. Also expose ccp.REFPROP_AVAILABLE so the workflow (and users) can assert that REFPROP was actually picked up instead of silently falling back to HEOS. --- .github/workflows/tests.yml | 74 +++++++++++++++++++++++++++++++++++++ ccp/__init__.py | 4 +- 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000..323230d6 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,74 @@ +name: Tests + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + # REFPROP is proprietary (NIST license), so the compiled library lives in a + # private repository and is fetched with a read-only deploy key stored as + # the REFPROP_DEPLOY_KEY secret. Secrets are never exposed to workflows + # triggered by pull requests from forks, so the test job is skipped there: + # forks need their own private REFPROP repository and secret to run CI. + # Do NOT convert the pull_request trigger to pull_request_target - that + # would expose the secret to arbitrary code from fork PRs. + check-secret: + name: Check REFPROP secret + runs-on: ubuntu-latest + outputs: + has-key: ${{ steps.check.outputs.has-key }} + steps: + - id: check + env: + KEY: ${{ secrets.REFPROP_DEPLOY_KEY }} + run: | + if [ -n "$KEY" ]; then + echo "has-key=true" >> "$GITHUB_OUTPUT" + else + echo "has-key=false" >> "$GITHUB_OUTPUT" + fi + + test: + name: Tests (REFPROP) + needs: check-secret + if: needs.check-secret.outputs.has-key == 'true' + runs-on: ubuntu-latest + timeout-minutes: 40 + env: + RPPREFIX: ${{ github.workspace }}/refprop + steps: + - uses: actions/checkout@v4 + + - name: Fetch REFPROP (private repository) + uses: actions/checkout@v4 + with: + repository: raphaeltimbo/refprop-linux + ssh-key: ${{ secrets.REFPROP_DEPLOY_KEY }} + path: refprop + + - name: Install libgfortran + run: sudo apt-get update -q && sudo apt-get install -y -q libgfortran5 + + - uses: astral-sh/setup-uv@v6 + with: + python-version: "3.12" + + - name: Install dependencies + run: uv sync --locked --all-extras + + - name: Check REFPROP is loaded + run: | + uv run python -c " + import ccp + assert ccp.REFPROP_AVAILABLE, 'librefprop.so not found at RPPREFIX' + print(ccp.__version__full) + " + + - name: Run tests + run: uv run pytest ccp/tests -n 4 --dist loadfile diff --git a/ccp/__init__.py b/ccp/__init__.py index ed5ffe22..86ea91bf 100644 --- a/ccp/__init__.py +++ b/ccp/__init__.py @@ -116,7 +116,9 @@ # Auto-switch to HEOS if REFPROP is not available -if not _library_path.is_file(): +REFPROP_AVAILABLE = _library_path.is_file() + +if not REFPROP_AVAILABLE: _warnings.warn( f"{_library_path}.\nREFPROP not configured. " f"Automatically switching to EOS='HEOS' (CoolProp backend)." From 8946d6c58c81210c47d9890942a7f798707800d4 Mon Sep 17 00:00:00 2001 From: raphaeltimbo Date: Mon, 20 Jul 2026 15:50:33 -0300 Subject: [PATCH 2/2] CI: don't require uv.lock, constrain CoolProp<8 for dev/CI uv.lock is gitignored in this repo, so uv sync --locked cannot work in CI. Sync without the flag and add a uv constraint (dev/CI resolution only, not published metadata) keeping CoolProp on 7.x until ccp is adapted to the exception-type and cubic-EOS roundoff changes in CoolProp 8. --- .github/workflows/tests.yml | 2 +- pyproject.toml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 323230d6..14bca4e2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -60,7 +60,7 @@ jobs: python-version: "3.12" - name: Install dependencies - run: uv sync --locked --all-extras + run: uv sync --all-extras - name: Check REFPROP is loaded run: | diff --git a/pyproject.toml b/pyproject.toml index c690e589..64d5ea57 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -112,3 +112,7 @@ dev = [ [tool.uv] package = true +# Dev/CI resolution constraint only (does not affect published metadata): +# CoolProp 8 changed the exception type raised for unknown fluids and the +# cubic-EOS roundoff, breaking three tests. Remove once ccp is adapted. +constraint-dependencies = ["coolprop<8"]