diff --git a/.github/workflows/build_and_publish.yml b/.github/workflows/build_and_publish.yml index 75518c5..f3067ff 100644 --- a/.github/workflows/build_and_publish.yml +++ b/.github/workflows/build_and_publish.yml @@ -5,7 +5,7 @@ on: tags: - "v*" -# Least privilege at the workflow level; the publish job widens `id-token` only. +# Least privilege at the workflow level. permissions: contents: read @@ -54,12 +54,18 @@ jobs: environment: name: pypi url: https://pypi.org/project/deepdefend/ - permissions: - # Trusted Publishing (OIDC). No long-lived API token is stored. - id-token: write steps: - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: dist path: dist/ + # Trusted Publishing (OIDC) is not registered for this project on PyPI, + # so uploads use the existing PYPI_API_TOKEN secret (as 0.1.x releases did). + # Attestations require OIDC, so they stay off. - uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # release/v1 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} + packages-dir: dist + skip-existing: true + attestations: false diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c50780..08d796e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,7 @@ on: push: branches: [master, main] pull_request: + branches: [master, main] workflow_dispatch: permissions: @@ -35,7 +36,9 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.10", "3.11", "3.12"] + # Full interpreter matrix only on master/main. PRs and other refs + # run 3.12 so each branch does not spawn three test jobs. + python-version: ${{ (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main') && fromJSON('["3.10", "3.11", "3.12"]') || fromJSON('["3.12"]') }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -55,6 +58,8 @@ jobs: name: Build distribution runs-on: ubuntu-latest needs: [lint, test] + # Packaging is verified on the default branches; PRs already lint and test. + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 518a8d3..8066218 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -112,8 +112,8 @@ attacks and defenses changes, the minor version was bumped. probe directions, `delta=epsilon/5`. - `median_smoothing` is documented as an alias of `spatial_smoothing`. - The publish workflow uses SHA-pinned actions, a tag/version consistency check, - a test gate, `python -m build`, `twine check`, PyPI Trusted Publishing (OIDC) - and a protected `pypi` environment. + a test gate, `python -m build`, `twine check`, the `PYPI_API_TOKEN` secret and + a `pypi` environment. CI runs the full Python matrix only on `master`/`main`. ### Removed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 618badc..4adcc92 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,9 +22,9 @@ Thank you for considering contributing to **DeepDefend**! Contributions, whether ruff check . # lint ``` - Both run in CI on every pull request (Python 3.10 – 3.12). New behaviour - should come with a test; bug fixes should come with a test that fails - before the fix. + Pull requests run lint and the Python 3.12 test job. The full 3.10 – 3.12 + matrix runs on `master`/`main`. New behaviour should come with a test; bug + fixes should come with a test that fails before the fix. > [!TIP] > The test-suite uses a tiny synthetic dataset and a small CNN, so the whole diff --git a/readme.md b/readme.md index c1ee7a1..e017702 100644 --- a/readme.md +++ b/readme.md @@ -34,7 +34,7 @@ either crashed on every call or returned silently wrong results. See - Fixed `randomized_smoothing`, `pixel_deflection` and the text helpers being non-reproducible and destroying whitespace/newlines. - Fixed silent `NaN`s from invalid parameters such as `bit_depth=0` or `num_bins=0`. - Fixed `pip install .` from a checkout, which failed because the version was a placeholder. -- Fixed the release pipeline: SHA-pinned actions, a tag/version check, a test gate, and PyPI Trusted Publishing instead of a long-lived API token. +- Fixed the release pipeline: SHA-pinned actions, a tag/version check, a test gate, and PyPI upload via `PYPI_API_TOKEN`. **Added** — `deepdefend.__version__`, lazy imports, `smooth_predict()` with a certified-radius estimate, a 170-test suite, CI, `SECURITY.md`,