diff --git a/.github/workflows/tidy3d-docs-sync-readthedocs-repo.yml b/.github/workflows/tidy3d-docs-sync-readthedocs-repo.yml index 49e1157f94..e9a1c60427 100644 --- a/.github/workflows/tidy3d-docs-sync-readthedocs-repo.yml +++ b/.github/workflows/tidy3d-docs-sync-readthedocs-repo.yml @@ -18,6 +18,9 @@ on: - 'v*' - 'demo/*' +permissions: + contents: read + jobs: extract_branch_or_tag: outputs: @@ -46,6 +49,7 @@ jobs: fetch-depth: 0 ref: ${{ needs.extract_branch_or_tag.outputs.ref_name }} fetch-tags: true + persist-credentials: false - name: push-mirror-repo env: diff --git a/.github/workflows/tidy3d-python-client-daily.yml b/.github/workflows/tidy3d-python-client-daily.yml index 277b287c56..28c978e07d 100644 --- a/.github/workflows/tidy3d-python-client-daily.yml +++ b/.github/workflows/tidy3d-python-client-daily.yml @@ -6,18 +6,20 @@ on: - cron: '0 5 * * *' # Runs at 5am UTC permissions: - contents: write - pull-requests: write + contents: read jobs: update-lockfile: uses: ./.github/workflows/tidy3d-python-client-update-lockfile.yml + permissions: + contents: write + pull-requests: write with: run-workflow: true - secrets: inherit + secrets: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} submodule-tests: uses: ./.github/workflows/tidy3d-python-client-submodules-test.yml with: run-workflow: true - secrets: inherit diff --git a/.github/workflows/tidy3d-python-client-develop-cli.yml b/.github/workflows/tidy3d-python-client-develop-cli.yml index 07ee7f30fd..25d5c6a72e 100644 --- a/.github/workflows/tidy3d-python-client-develop-cli.yml +++ b/.github/workflows/tidy3d-python-client-develop-cli.yml @@ -9,6 +9,9 @@ on: - develop - latest +permissions: + contents: read + jobs: test-dev-commands: strategy: @@ -23,6 +26,7 @@ jobs: ref: develop fetch-depth: 1 submodules: false + persist-credentials: false - name: Set up Python uses: actions/setup-python@v5 @@ -58,7 +62,7 @@ jobs: # ----- install & configure poetry ----- #---------------------------------------------- - name: Install Poetry - uses: snok/install-poetry@v1 + uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a # v1.4.1 with: version: 1.8.2 virtualenvs-create: true diff --git a/.github/workflows/tidy3d-python-client-release.yml b/.github/workflows/tidy3d-python-client-release.yml index c5aeeb40ee..35255613ac 100644 --- a/.github/workflows/tidy3d-python-client-release.yml +++ b/.github/workflows/tidy3d-python-client-release.yml @@ -1,13 +1,13 @@ name: "public/tidy3d/python-client-release" -permissions: - contents: write - on: push: tags: - 'v*.*.*' +permissions: + contents: read + jobs: test-latest-submodules: runs-on: ubuntu-latest @@ -19,6 +19,7 @@ jobs: submodules: 'recursive' # This fetches only a single branch by default, so additional fetch is needed fetch-depth: 0 # Optionally, set to 0 to fetch all history for all branches and tags + persist-credentials: false - name: Initialize and update submodule run: | @@ -74,20 +75,23 @@ jobs: github-release: runs-on: ubuntu-latest + permissions: + contents: write steps: - uses: actions/checkout@v4 with: ref: ${{ github.ref }} + persist-credentials: false - name: Exit if any RC release if: contains(github.ref, 'rc') == false - uses: everlytic/branch-merge@1.1.2 + uses: everlytic/branch-merge@c4a244dc23143f824ae6c022a10732566cb8e973 # v1.1.5 with: github_token: ${{ secrets.GH_PAT }} source_ref: ${{ github.ref }} target_branch: "latest" commit_message_template: ':tada: RELEASE: Merged {source_ref} into target {target_branch}' - name: Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@aec2ec56f94eb8180ceec724245f64ef008b89f5 # v2.4.0 with: generate_release_notes: true env: @@ -98,6 +102,7 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ github.ref }} + persist-credentials: false - uses: actions/setup-python@v2 - name: Install dependencies run: | @@ -107,18 +112,19 @@ jobs: env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} - run: | + run: | # zizmor: ignore[use-trusted-publishing] python -m build - python -m twine upload --repository pypi dist/* + python -m twine upload --repository pypi dist/* sync_to_develop: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: ref: "latest" + persist-credentials: false - name: Exit if any RC release if: contains(github.ref, 'rc') == false - uses: everlytic/branch-merge@1.1.2 + uses: everlytic/branch-merge@c4a244dc23143f824ae6c022a10732566cb8e973 # v1.1.5 with: github_token: ${{ secrets.GH_PAT }} source_ref: "latest" diff --git a/.github/workflows/tidy3d-python-client-submodules-test.yml b/.github/workflows/tidy3d-python-client-submodules-test.yml index b53fc2ea74..b7d6976a7e 100644 --- a/.github/workflows/tidy3d-python-client-submodules-test.yml +++ b/.github/workflows/tidy3d-python-client-submodules-test.yml @@ -22,6 +22,9 @@ on: type: boolean default: true +permissions: + contents: read + jobs: test-latest-submodules: runs-on: ubuntu-latest @@ -33,6 +36,7 @@ jobs: submodules: 'recursive' # This fetches only a single branch by default, so additional fetch is needed fetch-depth: 0 # Optionally, set to 0 to fetch all history for all branches and tags + persist-credentials: false - name: Initialize and update submodule run: | diff --git a/.github/workflows/tidy3d-python-client-tests.yml b/.github/workflows/tidy3d-python-client-tests.yml index 41db2008a5..af7c041ce2 100644 --- a/.github/workflows/tidy3d-python-client-tests.yml +++ b/.github/workflows/tidy3d-python-client-tests.yml @@ -23,7 +23,6 @@ on: permissions: contents: read - pull-requests: write jobs: determine-test-scope: @@ -152,7 +151,8 @@ jobs: with: fetch-depth: 1 submodules: false - - uses: astral-sh/ruff-action@v3 + persist-credentials: false + - uses: astral-sh/ruff-action@57714a7c8a2e59f32539362ba31877a1957dded1 # v3.5.1 with: version: 0.11.11 - name: Run ruff format @@ -171,8 +171,24 @@ jobs: with: persist-credentials: false + - name: Install the latest version of uv + uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v6.7.0 + - name: Run zizmor 🌈 - uses: zizmorcore/zizmor-action@e673c3917a1aef3c65c972347ed84ccd013ecda4 # v0.2.0 + run: uvx zizmor .github/workflows/* --format=sarif . > results.sarif + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3 + with: + sarif_file: results.sarif + category: zizmor + + - name: run zizmor directly # this gets a success or fail result + run: uvx zizmor .github/workflows/* + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} lint-branch-name: needs: determine-test-scope @@ -185,14 +201,16 @@ jobs: - name: extract-branch-name id: extract-branch-name run: | - BRANCH_NAME="${{ github.head_ref }}" + BRANCH_NAME="${GITHUB_HEAD_REF}" echo "Branch name: $BRANCH_NAME" echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT - name: enforce-jira-key id: enforce-jira-key + env: + STEPS_EXTRACT_BRANCH_NAME_OUTPUTS_BRANCH_NAME: ${{ steps.extract-branch-name.outputs.branch_name }} run: | - BRANCH_NAME="${{ steps.extract-branch-name.outputs.branch_name }}" + BRANCH_NAME="${STEPS_EXTRACT_BRANCH_NAME_OUTPUTS_BRANCH_NAME}" echo $BRANCH_NAME JIRA_PATTERN='[A-Z]{2,}-[0-9]+' @@ -231,6 +249,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 # fetch all commits in the PR + persist-credentials: false - name: Setup node uses: actions/setup-node@v4 @@ -249,9 +268,11 @@ jobs: - name: Check commit messages (merge_group) if: github.event_name == 'merge_group' + env: + GITHUB_EVENT_MERGE_GROUP_HEAD_SHA: ${{ github.event.merge_group.head_sha }} run: | # For merge groups, check the commits being merged - npx commitlint --from ${{ github.event.merge_group.base_sha }} --to ${{ github.event.merge_group.head_sha }} --verbose || { + npx commitlint --from ${{ github.event.merge_group.base_sha }} --to ${GITHUB_EVENT_MERGE_GROUP_HEAD_SHA} --verbose || { echo "Commit message linting failed; please follow the conventional commits format at https://www.conventionalcommits.org/" exit 1 } @@ -275,6 +296,7 @@ jobs: ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} fetch-depth: 0 + persist-credentials: false - name: git-config run: | @@ -311,13 +333,16 @@ jobs: - name: run-schema-diff id: schema-diff + env: + GITHUB_EVENT_PULL_REQUEST_BASE_REPO_FULL_NAME: ${{ github.event.pull_request.base.repo.full_name }} + GITHUB_EVENT_PULL_REQUEST_BASE_REF: ${{ github.event.pull_request.base.ref }} run: | set -euo pipefail cd "$GITHUB_WORKSPACE" # Determine base repo/ref for PRs; default to current repo and 'develop' otherwise - BASE_REPO="${{ github.event.pull_request.base.repo.full_name }}" - BASE_REF="${{ github.event.pull_request.base.ref }}" + BASE_REPO="${GITHUB_EVENT_PULL_REQUEST_BASE_REPO_FULL_NAME}" + BASE_REF="${GITHUB_EVENT_PULL_REQUEST_BASE_REF}" if [ -z "$BASE_REPO" ]; then BASE_REPO="${{ github.repository }}" fi @@ -362,9 +387,11 @@ jobs: - name: verify-allowed-changes if: steps.schema-diff.outputs.changed == 'true' + env: + STEPS_GET_VERSION_OUTPUTS_VERSION: ${{ steps.get-version.outputs.version }} run: | set -e - version="${{ steps.get-version.outputs.version }}" + version="${STEPS_GET_VERSION_OUTPUTS_VERSION}" if [[ "$version" == *rc* ]]; then echo "✅ Passing: Schema changed on a release candidate version ($version), which is permitted." else @@ -390,12 +417,14 @@ jobs: env: # Set environment variables for the whole job PIP_ONLY_BINARY: gdstk MPLBACKEND: agg - + permissions: + pull-requests: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # Required 0 for diff report. submodules: false + persist-credentials: false - name: install-project env: @@ -436,11 +465,13 @@ jobs: matrix.python-version == '3.13' && github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'ignore_diff_coverage') + env: + GITHUB_EVENT_PULL_REQUEST_BASE_REF: ${{ github.event.pull_request.base.ref }} run: | source ${GITHUB_WORKSPACE}/.venv/bin/activate git config --global --add safe.directory ${GITHUB_WORKSPACE} diff-cover ${GITHUB_WORKSPACE}/coverage.xml \ - --compare-branch origin/${{ github.event.pull_request.base.ref }} \ + --compare-branch origin/${GITHUB_EVENT_PULL_REQUEST_BASE_REF} \ --format markdown:diff-coverage.md - uses: actions/github-script@v7 @@ -506,9 +537,10 @@ jobs: with: fetch-depth: 1 submodules: false + persist-credentials: false - name: install-poetry - uses: snok/install-poetry@v1 + uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a # v1.4.1 with: version: 2.1.1 virtualenvs-create: true @@ -521,7 +553,7 @@ jobs: - name: install-project shell: bash - if: ${{ matrix.platform }} != "windows-latest" + if: matrix.platform != 'windows-latest' run: | poetry --version python --version @@ -557,7 +589,7 @@ jobs: - name: create-badge if: ${{ github.ref == 'refs/heads/develop' }} # https://gist.githubusercontent.com/nedbat/8c6980f77988a327348f9b02bbaf67f5 - uses: schneegans/dynamic-badges-action@v1.7.0 + uses: schneegans/dynamic-badges-action@e9a478b16159b4d31420099ba146cdc50f134483 # v1.7.0 with: auth: ${{ secrets.GH_TIDY3D_COVERAGE_GIST }} gistID: 4702549574741e87deaadba436218ebd @@ -581,29 +613,39 @@ jobs: runs-on: ubuntu-latest steps: - name: check-passing-remote-tests + env: + NEEDS_LOCAL_TESTS_RESULT: ${{ needs.local-tests.result }} + NEEDS_REMOTE_TESTS_RESULT: ${{ needs.remote-tests.result }} + NEEDS_LINT_RESULT: ${{ needs.lint.result }} + NEEDS_VERIFY_SCHEMA_CHANGE_RESULT: ${{ needs.verify-schema-change.result }} + NEEDS_LINT_COMMIT_MESSAGES_RESULT: ${{ needs.lint-commit-messages.result }} + NEEDS_LINT_BRANCH_NAME_RESULT: ${{ needs.lint-branch-name.result }} + NEEDS_ZIZMOR_RESULT: ${{ needs.zizmor.result }} run: | - echo "Local tests result: ${{ needs.local-tests.result }}" - echo "Remote tests result: ${{ needs.remote-tests.result }}" + echo "Local tests result: ${NEEDS_LOCAL_TESTS_RESULT}" + echo "Remote tests result: ${NEEDS_REMOTE_TESTS_RESULT}" - if [[ "${{ needs.lint.result }}" != 'success' ]]; then + if [[ "${NEEDS_LINT_RESULT}" != 'success' ]]; then echo "❌ Linting failed or was skipped." exit 1 - elif [[ "${{ needs.verify-schema-change.result }}" != 'success' ]]; then + elif [[ "${NEEDS_VERIFY_SCHEMA_CHANGE_RESULT}" != 'success' ]]; then echo "❌ verify-schema-change failed or was skipped." exit 1 - elif [[ "${{ needs.remote-tests.result }}" != 'success' ]]; then + elif [[ "${NEEDS_REMOTE_TESTS_RESULT}" != 'success' ]]; then echo "❌ remote-tests failed or were skipped." exit 1 # Given remote-tests always run after a PR is approved - elif [[ "${{ needs.local-tests.result }}" != 'success' ]]; then + elif [[ "${NEEDS_LOCAL_TESTS_RESULT}" != 'success' ]]; then echo "❌ local-tests failed or were skipped." - elif [[ "${{ github.event_name }}" == 'merge_group' && "${{ needs.lint-commit-messages.result }}" != 'success' ]]; then + elif [[ "${{ github.event_name }}" == 'merge_group' && "${NEEDS_LINT_COMMIT_MESSAGES_RESULT}" != 'success' ]]; then echo "❌ Linting of commit messages failed or was skipped." exit 1 - elif [[ "${{ github.event_name }}" == 'pull_request' && "${{ needs.lint-branch-name.result }}" != 'success' ]]; then + elif [[ "${{ github.event_name }}" == 'pull_request' && "${NEEDS_LINT_BRANCH_NAME_RESULT}" != 'success' ]]; then echo "❌ Linting of branch name failed." exit 1 - elif [[ "${{ needs.zizmor.result }}" != 'success' ]]; then + elif [[ "${NEEDS_ZIZMOR_RESULT}" != 'success' ]]; then echo "❌ Static check of github actions with zizmor failed." exit 1 fi echo "✅ All required test jobs passed!" + + \ No newline at end of file diff --git a/.github/workflows/tidy3d-python-client-update-lockfile.yml b/.github/workflows/tidy3d-python-client-update-lockfile.yml index c06f806da7..d89c7a3b37 100644 --- a/.github/workflows/tidy3d-python-client-update-lockfile.yml +++ b/.github/workflows/tidy3d-python-client-update-lockfile.yml @@ -17,6 +17,9 @@ on: type: boolean default: true +permissions: + contents: read + jobs: update-lockfile: if: github.event.inputs.run-workflow || inputs.run-workflow @@ -26,18 +29,19 @@ jobs: pull-requests: write steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: fetch-depth: 1 submodules: false + persist-credentials: false - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c #v6.0.0 with: python-version: '3.10' - name: Install Poetry - uses: snok/install-poetry@v1 + uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a # v1.4.1 with: version: 2.1.1 virtualenvs-create: true @@ -49,7 +53,7 @@ jobs: poetry update --lock - name: Create Pull Request - uses: peter-evans/create-pull-request@v6 + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e #v7.0.8 with: token: ${{ secrets.GITHUB_TOKEN }} commit-message: "chore(deps): :robot: Daily update `poetry.lock`" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7ad3c2323f..ebc6a6b762 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,4 +15,16 @@ repos: stages: [commit-msg] verbose: true entry: bash -c 'commitlint --edit || exit 0' + - repo: local + hooks: + - id: zizmor + name: zizmor + entry: bash -c 'poetry run zizmor .github/workflows/*' -- + language: system + pass_filenames: false + # - repo: https://github.com/woodruffw/zizmor-pre-commit + # rev: v1.5.2 + # hooks: + # - id: zizmor + # args: [ .github/workflows/* ] diff --git a/poetry.lock b/poetry.lock index 51835bb611..06dcee75f8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. [[package]] name = "absl-py" @@ -7461,9 +7461,31 @@ enabler = ["pytest-enabler (>=2.2)"] test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] type = ["pytest-mypy"] +[[package]] +name = "zizmor" +version = "1.14.2" +description = "" +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"dev\"" +files = [ + {file = "zizmor-1.14.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c95caf9d303e38bce71a475bf1915c121cc6d415bad8396efd6af6a93cd828ff"}, + {file = "zizmor-1.14.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c97c1ca199ba06c79d18f103dce24fe84896dfd498e49b01e5a19eaba3d85992"}, + {file = "zizmor-1.14.2-py3-none-manylinux_2_24_aarch64.whl", hash = "sha256:c6ee0ad81b1def2030a3af7925527b1633899bd9db0a48843dcafa997d4881b2"}, + {file = "zizmor-1.14.2-py3-none-manylinux_2_28_armv7l.whl", hash = "sha256:1f2ce27f3c369aed20e92c9b99bfbb6b7ccfa60a2cbee3262b22193259e783e8"}, + {file = "zizmor-1.14.2-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:8c0b310f03902cc5175757f2bd6c135220f96f35501472f24fb6db8e8675b19e"}, + {file = "zizmor-1.14.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b0206029d772bd30087d8724fe3b2787302a531aefa236e3e4456bccea7370db"}, + {file = "zizmor-1.14.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7b53b2df89d83a44273fe6dc2a99356d2cfca37f9e1dce466db6e03debefb2a9"}, + {file = "zizmor-1.14.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:9a81e6a7aecc5250f7bd7f4b978f0652be7785a638f8b176fd73e12c29c8f68a"}, + {file = "zizmor-1.14.2-py3-none-win32.whl", hash = "sha256:3c94c9fb8da4692acaa3dd41e81fa4376f7ca9b3d419eb18cf7224f5b6908e03"}, + {file = "zizmor-1.14.2-py3-none-win_amd64.whl", hash = "sha256:fb945e754445d8f76d3ba3f9e3ea428eebce0117058aa75155c4c03d9934ed75"}, + {file = "zizmor-1.14.2.tar.gz", hash = "sha256:f9c0de529eb932d7af3c92f3d1004f5fed7fc357d30edf16ae31ce4bdf8f7514"}, +] + [extras] design = ["bayesian-optimization", "pygad", "pyswarms"] -dev = ["bayesian-optimization", "cma", "coverage", "devsim", "diff-cover", "dill", "gdstk", "grcwa", "ipython", "ipython", "jinja2", "jupyter", "memory_profiler", "myst-parser", "nbconvert", "nbdime", "nbsphinx", "networkx", "openpyxl", "optax", "pre-commit", "psutil", "pydata-sphinx-theme", "pygad", "pylint", "pyswarms", "pytest", "pytest-cov", "pytest-env", "pytest-timeout", "pytest-xdist", "rtree", "ruff", "sax", "scikit-rf", "signac", "sphinx", "sphinx-book-theme", "sphinx-copybutton", "sphinx-design", "sphinx-favicon", "sphinx-notfound-page", "sphinx-sitemap", "sphinx-tabs", "sphinxemoji", "tmm", "torch", "torch", "tox", "trimesh", "vtk"] +dev = ["bayesian-optimization", "cma", "coverage", "devsim", "diff-cover", "dill", "gdstk", "grcwa", "ipython", "ipython", "jinja2", "jupyter", "memory_profiler", "myst-parser", "nbconvert", "nbdime", "nbsphinx", "networkx", "openpyxl", "optax", "pre-commit", "psutil", "pydata-sphinx-theme", "pygad", "pylint", "pyswarms", "pytest", "pytest-cov", "pytest-env", "pytest-timeout", "pytest-xdist", "rtree", "ruff", "sax", "scikit-rf", "signac", "sphinx", "sphinx-book-theme", "sphinx-copybutton", "sphinx-design", "sphinx-favicon", "sphinx-notfound-page", "sphinx-sitemap", "sphinx-tabs", "sphinxemoji", "tmm", "torch", "torch", "tox", "trimesh", "vtk", "zizmor"] docs = ["cma", "devsim", "gdstk", "grcwa", "ipython", "jinja2", "jupyter", "myst-parser", "nbconvert", "nbdime", "nbsphinx", "openpyxl", "optax", "pydata-sphinx-theme", "pylint", "sax", "signac", "sphinx", "sphinx-book-theme", "sphinx-copybutton", "sphinx-design", "sphinx-favicon", "sphinx-notfound-page", "sphinx-sitemap", "sphinx-tabs", "sphinxemoji", "tmm"] gdstk = ["gdstk"] heatcharge = ["devsim", "trimesh", "vtk"] @@ -7476,4 +7498,4 @@ vtk = ["vtk"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<3.14" -content-hash = "591568dd5f68370208830b200214d40918ff9e5a85b8c17a44c86a15b867e3b2" +content-hash = "d32f706b170b45b160e876c1efeb373b9b9a794e1f204156f70dcfb85596b95c" diff --git a/pyproject.toml b/pyproject.toml index 242ad0003e..b7950f0b6b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,6 +65,7 @@ pytest-cov = "^6.0.0" pytest-env = "^1.1.5" tox = { version = "*", optional = true } diff-cover = { version = "*", optional = true } +zizmor = { version = "*", optional = true } # gdstk gdstk = { version = ">=0.9.49", optional = true } @@ -170,7 +171,8 @@ dev = [ 'devsim', 'cma', 'diff-cover', - "openpyxl", + 'openpyxl', + 'zizmor', ] docs = [ "jupyter",