From 9b6aa054e7aa9add87480106e72ed6d948c9939d Mon Sep 17 00:00:00 2001 From: Damian Reeves <957246+DamianReeves@users.noreply.github.com> Date: Tue, 27 Oct 2026 07:53:57 -0500 Subject: [PATCH 1/2] ci: prepare trusted PyPI publishing for 0.0.1 Qualify the exact published artifacts through CI, metadata and install checks, vulnerability auditing, and a license allowlist. Restrict OIDC permission to publishing jobs and align package versions and artifact paths. Require Pygments 2.20.0 or later to exclude CVE-2026-4539. --- .config/mise/tasks/build | 4 +- .config/mise/tasks/install | 5 +- .config/mise/tasks/release-check | 94 ++++++++ .github/workflows/ci.yml | 34 ++- .github/workflows/release.yml | 55 ++--- README.md | 55 +++++ packages/morphir-tools/LICENSE | 201 ++++++++++++++++++ packages/morphir-tools/pyproject.toml | 10 +- .../src/morphir_tools/__init__.py | 4 +- packages/morphir/LICENSE | 201 ++++++++++++++++++ packages/morphir/pyproject.toml | 6 +- packages/morphir/src/morphir/__init__.py | 4 +- pyproject.toml | 2 +- tests/conftest.py | 2 +- uv.lock | 14 +- 15 files changed, 628 insertions(+), 63 deletions(-) create mode 100755 .config/mise/tasks/release-check create mode 100644 packages/morphir-tools/LICENSE create mode 100644 packages/morphir/LICENSE diff --git a/.config/mise/tasks/build b/.config/mise/tasks/build index 7596b6e6..c56bfdd3 100755 --- a/.config/mise/tasks/build +++ b/.config/mise/tasks/build @@ -3,9 +3,9 @@ set -euo pipefail echo "Building morphir package..." -uv build packages/morphir +uv build packages/morphir --out-dir packages/morphir/dist echo "Building morphir-tools package..." -uv build packages/morphir-tools +uv build packages/morphir-tools --out-dir packages/morphir-tools/dist echo "Build complete!" diff --git a/.config/mise/tasks/install b/.config/mise/tasks/install index 1f91d6cc..c1fc27db 100755 --- a/.config/mise/tasks/install +++ b/.config/mise/tasks/install @@ -3,9 +3,6 @@ set -euo pipefail echo "Syncing dependencies..." -uv sync --all-groups - -echo "Installing workspace packages in editable mode..." -uv pip install -e packages/morphir -e packages/morphir-tools +uv sync --frozen --all-packages --all-groups echo "Install complete!" diff --git a/.config/mise/tasks/release-check b/.config/mise/tasks/release-check new file mode 100755 index 00000000..e6ec9580 --- /dev/null +++ b/.config/mise/tasks/release-check @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +#MISE description="Check built distributions and scan runtime dependencies" +set -euo pipefail + +# Keep the candidate environment separate from development and scanner dependencies. +release_dir="$(pwd)/.dev/release-check" +mkdir -p "$release_dir" + +uv lock --check +python - <<'PY' +import os +import tarfile +import tomllib +import zipfile +from email.parser import BytesParser +from pathlib import Path + +versions = set() +for name in ("morphir", "morphir-tools"): + directory = Path("packages") / name + project = tomllib.loads((directory / "pyproject.toml").read_text())["project"] + versions.add(project["version"]) + tag = os.environ.get("RELEASE_TAG", "") + if tag and tag != f"v{project['version']}": + raise SystemExit(f"{tag} does not match {name} {project['version']}") + stem = name.replace("-", "_") + "-" + project["version"] + expected = {f"{stem}-py3-none-any.whl", f"{stem}.tar.gz"} + files = {p.name for p in (directory / "dist").iterdir() + if p.is_file() and p.name != ".gitignore"} + if files != expected: + raise SystemExit(f"Unexpected distributions for {name}: {files}") + for filename in expected: + path = directory / "dist" / filename + if path.suffix == ".whl": + with zipfile.ZipFile(path) as archive: + metadata = [n for n in archive.namelist() if n.endswith(".dist-info/METADATA")] + raw = archive.read(metadata[0]) + has_license = any(n.endswith("/licenses/LICENSE") for n in archive.namelist()) + else: + with tarfile.open(path) as archive: + member = archive.extractfile(f"{stem}/PKG-INFO") + if member is None: + raise SystemExit(f"Missing metadata in {path}") + raw = member.read() + has_license = f"{stem}/LICENSE" in archive.getnames() + metadata = BytesParser().parsebytes(raw) + if metadata["Name"] != name or metadata["Version"] != project["version"]: + raise SystemExit(f"Incorrect name or version in {path}") + if metadata["License-Expression"] != "Apache-2.0" or not has_license: + raise SystemExit(f"Missing Apache-2.0 license in {path}") +if len(versions) != 1: + raise SystemExit("Both packages must use the same release version") +PY + +uvx --from twine==7.0.0 twine check --strict \ + packages/morphir/dist/* packages/morphir-tools/dist/* + +uv export --frozen --all-packages --no-default-groups --no-emit-workspace \ + --no-hashes --output-file "$release_dir/constraints.txt" +uv venv --clear --python 3.14 "$release_dir/venv" +release_python="$release_dir/venv/bin/python" +uv pip install --python "$release_python" --constraint "$release_dir/constraints.txt" \ + packages/morphir/dist/*.whl packages/morphir-tools/dist/*.whl +uv pip check --python "$release_python" + +"$release_python" -I - <<'PY' +from importlib.metadata import version + +import morphir +import morphir_tools +from morphir.ir import format_version +from morphir.sdk import basics + +assert morphir.__version__ == version("morphir") +assert morphir_tools.__version__ == version("morphir-tools") +assert basics.round(2.5) == 3 +assert format_version.V3.major == 3 +PY +"$release_dir/venv/bin/morphir-tools" --help + +# These two first-party packages are not yet on PyPI. Audit the exact installed +# third-party versions, without querying PyPI for the unpublished packages. +uv pip freeze --python "$release_python" --exclude morphir --exclude morphir-tools \ + > "$release_dir/requirements.txt" +uvx --from pip-audit==2.10.1 pip-audit --strict --no-deps --disable-pip \ + --requirement "$release_dir/requirements.txt" \ + --format json --output "$release_dir/vulnerabilities.json" + +# An exact allowlist rejects unknown licenses and newly introduced copyleft or +# proprietary licenses. Changes to this policy require maintainer review. +uvx --from pip-licenses==5.5.0 pip-licenses --python "$release_python" \ + --from=mixed \ + --allow-only='Apache-2.0;Apache Software License;MIT;MIT License;BSD-2-Clause;BSD-3-Clause;BSD License;ISC;ISC License;ISC License (ISCL)' \ + --format=json --output-file "$release_dir/licenses.json" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7ebd7fc0..f308c063 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,12 @@ on: branches: [main] pull_request: branches: [main] + workflow_call: + inputs: + release-tag: + description: Tag that must match both package versions + type: string + default: '' permissions: contents: read @@ -86,10 +92,28 @@ jobs: - name: Build packages run: mise run build - - name: Upload artifacts + - name: Check distributions, vulnerabilities and licenses + run: mise run release-check + env: + RELEASE_TAG: ${{ inputs.release-tag }} + + - name: Upload morphir distributions + uses: actions/upload-artifact@v6 + with: + name: morphir-dist + path: packages/morphir/dist/ + if-no-files-found: error + + - name: Upload morphir-tools distributions + uses: actions/upload-artifact@v6 + with: + name: morphir-tools-dist + path: packages/morphir-tools/dist/ + if-no-files-found: error + + - name: Upload release scan reports + if: always() uses: actions/upload-artifact@v6 with: - name: dist - path: | - packages/morphir/dist/ - packages/morphir-tools/dist/ + name: release-scan-reports + path: .dev/release-check/*.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c3731726..1a6ccf7e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,46 +4,30 @@ on: push: tags: - 'v*' + # Qualification only. Publishing requires a tag push. + workflow_dispatch: permissions: - contents: write - id-token: write + contents: read -jobs: - build: - name: Build packages - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v6 - - - name: Set up uv - uses: astral-sh/setup-uv@v7 - with: - enable-cache: true - - - name: Build morphir package - run: uv build packages/morphir +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false - - name: Build morphir-tools package - run: uv build packages/morphir-tools - - - name: Upload morphir dist - uses: actions/upload-artifact@v6 - with: - name: morphir-dist - path: packages/morphir/dist/ - - - name: Upload morphir-tools dist - uses: actions/upload-artifact@v6 - with: - name: morphir-tools-dist - path: packages/morphir-tools/dist/ +jobs: + qualify: + name: Qualify release + uses: ./.github/workflows/ci.yml + with: + release-tag: ${{ github.ref_type == 'tag' && github.ref_name || '' }} publish-morphir: name: Publish morphir to PyPI - needs: build + if: github.event_name == 'push' && github.repository == 'finos/morphir-python' + needs: qualify runs-on: ubuntu-latest + permissions: + id-token: write environment: name: pypi url: https://pypi.org/project/morphir/ @@ -59,8 +43,10 @@ jobs: publish-morphir-tools: name: Publish morphir-tools to PyPI - needs: [build, publish-morphir] + needs: [qualify, publish-morphir] runs-on: ubuntu-latest + permissions: + id-token: write environment: name: pypi url: https://pypi.org/project/morphir-tools/ @@ -78,6 +64,8 @@ jobs: name: Create GitHub Release needs: [publish-morphir, publish-morphir-tools] runs-on: ubuntu-latest + permissions: + contents: write steps: - name: Checkout repository uses: actions/checkout@v6 @@ -85,6 +73,7 @@ jobs: - name: Download all artifacts uses: actions/download-artifact@v7 with: + pattern: '*-dist' path: dist/ merge-multiple: true diff --git a/README.md b/README.md index 150030f6..4510134d 100644 --- a/README.md +++ b/README.md @@ -161,8 +161,63 @@ mise run check | `mise run coverage` | Run tests with coverage | | `mise run check` | Run all checks | | `mise run build` | Build packages | +| `mise run release-check` | Validate built packages and scan runtime dependencies for vulnerabilities and licenses | | `mise run clean` | Clean build artifacts | +## Releases + +The initial release is `0.0.1` for both PyPI distributions: + +| PyPI distribution | Python import | Command | +|-------------------|---------------|---------| +| `morphir` | `morphir` | None | +| `morphir-tools` | `morphir_tools` | `morphir-tools` | + +`morphir-python` is the repository name. The workspace itself is not published. +Both packages require Python 3.14 or later. `morphir-tools` installs `morphir` as +a dependency. + +Publishing uses [PyPI trusted publishing](https://docs.pypi.org/trusted-publishers/using-a-publisher/), +without a stored PyPI token. Configure a publisher for **each** distribution on +PyPI, including a pending publisher if the project has not been created yet: + +| Publisher field | Value | +|-----------------|-------| +| Owner | `finos` | +| Repository | `morphir-python` | +| Workflow filename | `release.yml` | +| Environment | `pypi` | + +The GitHub `pypi` environment permits release tags matching `v*`. After maintainer +approval, push a tag such as `v0.0.1` whose version matches both package metadata +files and their runtime `__version__` values. Update the tools package's minimum +`morphir` dependency and refresh `uv.lock` when changing versions. + +The release workflow runs the same lint, format, type, coverage and BDD checks as +PR CI. It builds each package once, validates wheel and source metadata and license +files, installs the wheels in an isolated environment, checks imports and the CLI, +then scans the locked runtime dependency versions with `pip-audit` and +`pip-licenses`. Known vulnerabilities, audit failures, unknown licenses and +licenses outside the exact Apache-2.0, MIT, BSD-2-Clause, BSD-3-Clause and ISC +allowlist block publication. The license allowlist also accepts the corresponding +legacy license classifiers. The CVE scan queries third-party dependencies; +the unpublished first-party packages are excluded from that query. These checks +use package metadata and known vulnerability advisories, not a source-code license +or security review. Scan reports are retained as workflow artifacts. + +Only the two publishing jobs receive `id-token: write`. They publish the checked +artifacts, core library first, and then create a GitHub release. The workflow's +manual **Run workflow** action runs qualification without publishing. To qualify +locally: + +```bash +mise run install +mise run check +mise run coverage +mise run build +RELEASE_TAG=v0.0.1 mise run release-check +``` + ## Project Principles This project follows functional programming principles: diff --git a/packages/morphir-tools/LICENSE b/packages/morphir-tools/LICENSE new file mode 100644 index 00000000..8dada3ed --- /dev/null +++ b/packages/morphir-tools/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed 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. diff --git a/packages/morphir-tools/pyproject.toml b/packages/morphir-tools/pyproject.toml index 274aefe4..c390f35f 100644 --- a/packages/morphir-tools/pyproject.toml +++ b/packages/morphir-tools/pyproject.toml @@ -1,16 +1,16 @@ [project] name = "morphir-tools" -version = "0.1.0" +version = "0.0.1" description = "CLI tools and extensions for Morphir Python" readme = "README.md" license = "Apache-2.0" +license-files = ["LICENSE"] requires-python = ">=3.14" keywords = ["morphir", "cli", "tools", "code-generation", "domain-modeling"] classifiers = [ "Development Status :: 3 - Alpha", "Environment :: Console", "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.14", @@ -22,8 +22,10 @@ authors = [ { name = "FINOS", email = "morphir@finos.org" } ] dependencies = [ - "morphir>=0.1.0", + "morphir>=0.0.1", "typer>=0.15", + # Rich uses Pygments; older versions are affected by CVE-2026-4539. + "pygments>=2.20.0", ] [project.urls] @@ -36,7 +38,7 @@ Issues = "https://github.com/finos/morphir-python/issues" morphir-tools = "morphir_tools.cli:main" [build-system] -requires = ["hatchling"] +requires = ["hatchling>=1.27"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] diff --git a/packages/morphir-tools/src/morphir_tools/__init__.py b/packages/morphir-tools/src/morphir_tools/__init__.py index 4b4d52d8..31cfe934 100644 --- a/packages/morphir-tools/src/morphir_tools/__init__.py +++ b/packages/morphir-tools/src/morphir_tools/__init__.py @@ -6,8 +6,8 @@ Example: >>> import morphir_tools >>> morphir_tools.__version__ - '0.1.0' + '0.0.1' """ -__version__ = "0.1.0" +__version__ = "0.0.1" __all__ = ["__version__"] diff --git a/packages/morphir/LICENSE b/packages/morphir/LICENSE new file mode 100644 index 00000000..8dada3ed --- /dev/null +++ b/packages/morphir/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed 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. diff --git a/packages/morphir/pyproject.toml b/packages/morphir/pyproject.toml index 5e67c9b2..81dfeb96 100644 --- a/packages/morphir/pyproject.toml +++ b/packages/morphir/pyproject.toml @@ -1,15 +1,15 @@ [project] name = "morphir" -version = "0.1.0" +version = "0.0.1" description = "Python port of Morphir - functional domain modeling for the enterprise" readme = "README.md" license = "Apache-2.0" +license-files = ["LICENSE"] requires-python = ">=3.14" keywords = ["morphir", "domain-modeling", "functional", "dsl", "type-safe", "ir"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.14", @@ -29,7 +29,7 @@ Repository = "https://github.com/finos/morphir-python" Issues = "https://github.com/finos/morphir-python/issues" [build-system] -requires = ["hatchling"] +requires = ["hatchling>=1.27"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] diff --git a/packages/morphir/src/morphir/__init__.py b/packages/morphir/src/morphir/__init__.py index 8074c7d1..13cc505d 100644 --- a/packages/morphir/src/morphir/__init__.py +++ b/packages/morphir/src/morphir/__init__.py @@ -7,8 +7,8 @@ Example: >>> import morphir >>> morphir.__version__ - '0.1.0' + '0.0.1' """ -__version__ = "0.1.0" +__version__ = "0.0.1" __all__ = ["__version__"] diff --git a/pyproject.toml b/pyproject.toml index d0e39037..77e54459 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "morphir-workspace" -version = "0.1.0" +version = "0.0.1" description = "Morphir Python monorepo workspace" requires-python = ">=3.14" readme = "README.md" diff --git a/tests/conftest.py b/tests/conftest.py index f95a2880..fcb5de7e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,4 +6,4 @@ @pytest.fixture def sample_version() -> str: """Provide the expected version string for tests.""" - return "0.1.0" + return "0.0.1" diff --git a/uv.lock b/uv.lock index ce656869..00624e74 100644 --- a/uv.lock +++ b/uv.lock @@ -195,27 +195,29 @@ wheels = [ [[package]] name = "morphir" -version = "0.1.0" +version = "0.0.1" source = { editable = "packages/morphir" } [[package]] name = "morphir-tools" -version = "0.1.0" +version = "0.0.1" source = { editable = "packages/morphir-tools" } dependencies = [ { name = "morphir" }, + { name = "pygments" }, { name = "typer" }, ] [package.metadata] requires-dist = [ { name = "morphir", editable = "packages/morphir" }, + { name = "pygments", specifier = ">=2.20.0" }, { name = "typer", specifier = ">=0.15" }, ] [[package]] name = "morphir-workspace" -version = "0.1.0" +version = "0.0.1" source = { virtual = "." } [package.dev-dependencies] @@ -363,11 +365,11 @@ wheels = [ [[package]] name = "pygments" -version = "2.19.2" +version = "2.21.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, + { url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" }, ] [[package]] From 0b938708667ffe98d9b46de176e46a58181609d0 Mon Sep 17 00:00:00 2001 From: Damian Reeves <957246+DamianReeves@users.noreply.github.com> Date: Tue, 27 Oct 2026 07:55:00 -0500 Subject: [PATCH 2/2] ci: retain scan reports from the local directory --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f308c063..1248bdfd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,3 +117,4 @@ jobs: with: name: release-scan-reports path: .dev/release-check/*.json + include-hidden-files: true