otdf-python 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- otdf_python-0.3.1/.github/check_entitlements.sh +56 -0
- otdf_python-0.3.1/.github/start_opentdf_docker.sh +61 -0
- otdf_python-0.3.1/.github/workflows/build-python.yaml +42 -0
- otdf_python-0.3.1/.github/workflows/platform-integration-test.yaml +213 -0
- otdf_python-0.3.1/.github/workflows/release-please.yaml +139 -0
- otdf_python-0.3.1/.github/workflows/test-suite.yaml +121 -0
- otdf_python-0.3.1/.gitignore +179 -0
- otdf_python-0.3.1/.pre-commit-config.yaml +48 -0
- otdf_python-0.3.1/.release-please-config-develop.json +44 -0
- otdf_python-0.3.1/.release-please-config.json +42 -0
- otdf_python-0.3.1/.release-please-manifest-develop.json +3 -0
- otdf_python-0.3.1/.release-please-manifest.json +3 -0
- otdf_python-0.3.1/.vscode/extensions.json +5 -0
- otdf_python-0.3.1/.vscode/settings.json +8 -0
- otdf_python-0.3.1/CHANGELOG.md +28 -0
- otdf_python-0.3.1/LICENSE +21 -0
- otdf_python-0.3.1/PKG-INFO +231 -0
- otdf_python-0.3.1/README.md +212 -0
- otdf_python-0.3.1/conftest.py +68 -0
- otdf_python-0.3.1/docs/CONNECT_RPC_MIGRATION.md +283 -0
- otdf_python-0.3.1/docs/DEVELOPING.md +18 -0
- otdf_python-0.3.1/docs/LEGACY_VERSION.md +20 -0
- otdf_python-0.3.1/docs/PROTOBUF_SETUP.md +135 -0
- otdf_python-0.3.1/docs/RELEASES.md +205 -0
- otdf_python-0.3.1/otdf-python-proto/README.md +186 -0
- otdf_python-0.3.1/otdf-python-proto/buf.gen.yaml +28 -0
- otdf_python-0.3.1/otdf-python-proto/buf.lock +12 -0
- otdf_python-0.3.1/otdf-python-proto/buf.yaml +24 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/authorization/authorization.proto +305 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/authorization/v2/authorization.proto +171 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/common/common.proto +41 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/entity/entity.proto +41 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/entityresolution/entity_resolution.proto +124 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/entityresolution/v2/entity_resolution.proto +46 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/kas/kas.proto +160 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/logger/audit/test.proto +40 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/policy/actions/actions.proto +108 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/policy/attributes/attributes.proto +464 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/policy/kasregistry/key_access_server_registry.proto +663 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/policy/keymanagement/key_management.proto +84 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/policy/namespaces/namespaces.proto +200 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/policy/objects.proto +556 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/policy/registeredresources/registered_resources.proto +330 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/policy/resourcemapping/resource_mapping.proto +276 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/policy/selectors.proto +70 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/policy/subjectmapping/subject_mapping.proto +215 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/policy/unsafe/unsafe.proto +209 -0
- otdf_python-0.3.1/otdf-python-proto/proto-files/wellknownconfiguration/wellknown_configuration.proto +23 -0
- otdf_python-0.3.1/otdf-python-proto/pyproject.toml +32 -0
- otdf_python-0.3.1/otdf-python-proto/scripts/build_connect_proto.sh +95 -0
- otdf_python-0.3.1/otdf-python-proto/scripts/generate_connect_proto.py +299 -0
- otdf_python-0.3.1/otdf-python-proto/scripts/setup_connect_rpc.py +0 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/__init__.py +37 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/authorization/__init__.py +1 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/authorization/authorization_pb2.py +80 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/authorization/authorization_pb2.pyi +161 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/authorization/authorization_pb2_connect.py +191 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/authorization/v2/authorization_pb2.py +105 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/authorization/v2/authorization_pb2.pyi +134 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/authorization/v2/authorization_pb2_connect.py +233 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/common/__init__.py +1 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/common/common_pb2.py +52 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/common/common_pb2.pyi +61 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/entity/__init__.py +1 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/entity/entity_pb2.py +47 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/entity/entity_pb2.pyi +50 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/entityresolution/__init__.py +1 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/entityresolution/entity_resolution_pb2.py +57 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/entityresolution/entity_resolution_pb2.pyi +55 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/entityresolution/entity_resolution_pb2_connect.py +149 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/entityresolution/v2/entity_resolution_pb2.py +55 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/entityresolution/v2/entity_resolution_pb2.pyi +55 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/entityresolution/v2/entity_resolution_pb2_connect.py +149 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/kas/__init__.py +9 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/kas/kas_pb2.py +103 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/kas/kas_pb2.pyi +170 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/kas/kas_pb2_connect.py +192 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/__init__.py +1 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/authorization/authorization_pb2_grpc.py +163 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/authorization/v2/authorization_pb2_grpc.py +206 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/common/common_pb2_grpc.py +4 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/entity/entity_pb2_grpc.py +4 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/entityresolution/entity_resolution_pb2_grpc.py +122 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/entityresolution/v2/entity_resolution_pb2_grpc.py +120 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/kas/kas_pb2_grpc.py +172 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/logger/audit/test_pb2_grpc.py +4 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/actions/actions_pb2_grpc.py +249 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/attributes/attributes_pb2_grpc.py +873 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/kasregistry/key_access_server_registry_pb2_grpc.py +602 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/keymanagement/key_management_pb2_grpc.py +251 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/namespaces/namespaces_pb2_grpc.py +427 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/objects_pb2_grpc.py +4 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/registeredresources/registered_resources_pb2_grpc.py +524 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/resourcemapping/resource_mapping_pb2_grpc.py +516 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/selectors_pb2_grpc.py +4 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/subjectmapping/subject_mapping_pb2_grpc.py +551 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/unsafe/unsafe_pb2_grpc.py +485 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/legacy_grpc/wellknownconfiguration/wellknown_configuration_pb2_grpc.py +77 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/logger/__init__.py +1 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/logger/audit/test_pb2.py +43 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/logger/audit/test_pb2.pyi +45 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/__init__.py +1 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/actions/actions_pb2.py +75 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/actions/actions_pb2.pyi +87 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/actions/actions_pb2_connect.py +275 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/attributes/attributes_pb2.py +234 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/attributes/attributes_pb2.pyi +328 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/attributes/attributes_pb2_connect.py +863 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2.py +266 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2.pyi +450 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2_connect.py +611 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/keymanagement/key_management_pb2.py +79 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/keymanagement/key_management_pb2.pyi +87 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/keymanagement/key_management_pb2_connect.py +275 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/namespaces/namespaces_pb2.py +117 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/namespaces/namespaces_pb2.pyi +147 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/namespaces/namespaces_pb2_connect.py +443 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/objects_pb2.py +150 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/objects_pb2.pyi +464 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/registeredresources/registered_resources_pb2.py +139 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/registeredresources/registered_resources_pb2.pyi +196 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/registeredresources/registered_resources_pb2_connect.py +527 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/resourcemapping/resource_mapping_pb2.py +139 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/resourcemapping/resource_mapping_pb2.pyi +194 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/resourcemapping/resource_mapping_pb2_connect.py +527 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/selectors_pb2.py +57 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/selectors_pb2.pyi +90 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/subjectmapping/subject_mapping_pb2.py +127 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/subjectmapping/subject_mapping_pb2.pyi +189 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/subjectmapping/subject_mapping_pb2_connect.py +569 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/unsafe/unsafe_pb2.py +113 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/unsafe/unsafe_pb2.pyi +145 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/policy/unsafe/unsafe_pb2_connect.py +485 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/wellknownconfiguration/__init__.py +1 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2.py +51 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2.pyi +32 -0
- otdf_python-0.3.1/otdf-python-proto/src/otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2_connect.py +107 -0
- otdf_python-0.3.1/otdf-python-proto/uv.lock +759 -0
- otdf_python-0.3.1/pyproject.toml +84 -0
- otdf_python-0.3.1/src/otdf_python/__init__.py +25 -0
- otdf_python-0.3.1/src/otdf_python/__main__.py +12 -0
- otdf_python-0.3.1/src/otdf_python/address_normalizer.py +84 -0
- otdf_python-0.3.1/src/otdf_python/aesgcm.py +55 -0
- otdf_python-0.3.1/src/otdf_python/assertion_config.py +84 -0
- otdf_python-0.3.1/src/otdf_python/asym_crypto.py +85 -0
- otdf_python-0.3.1/src/otdf_python/asym_decryption.py +53 -0
- otdf_python-0.3.1/src/otdf_python/asym_encryption.py +75 -0
- otdf_python-0.3.1/src/otdf_python/auth_headers.py +21 -0
- otdf_python-0.3.1/src/otdf_python/autoconfigure_utils.py +113 -0
- otdf_python-0.3.1/src/otdf_python/cli.py +570 -0
- otdf_python-0.3.1/src/otdf_python/collection_store.py +41 -0
- otdf_python-0.3.1/src/otdf_python/collection_store_impl.py +22 -0
- otdf_python-0.3.1/src/otdf_python/config.py +69 -0
- otdf_python-0.3.1/src/otdf_python/connect_client.py +0 -0
- otdf_python-0.3.1/src/otdf_python/constants.py +1 -0
- otdf_python-0.3.1/src/otdf_python/crypto_utils.py +78 -0
- otdf_python-0.3.1/src/otdf_python/dpop.py +81 -0
- otdf_python-0.3.1/src/otdf_python/ecc_mode.py +32 -0
- otdf_python-0.3.1/src/otdf_python/eckeypair.py +75 -0
- otdf_python-0.3.1/src/otdf_python/header.py +143 -0
- otdf_python-0.3.1/src/otdf_python/invalid_zip_exception.py +8 -0
- otdf_python-0.3.1/src/otdf_python/kas_client.py +603 -0
- otdf_python-0.3.1/src/otdf_python/kas_connect_rpc_client.py +207 -0
- otdf_python-0.3.1/src/otdf_python/kas_info.py +25 -0
- otdf_python-0.3.1/src/otdf_python/kas_key_cache.py +52 -0
- otdf_python-0.3.1/src/otdf_python/key_type.py +31 -0
- otdf_python-0.3.1/src/otdf_python/key_type_constants.py +43 -0
- otdf_python-0.3.1/src/otdf_python/manifest.py +215 -0
- otdf_python-0.3.1/src/otdf_python/nanotdf.py +553 -0
- otdf_python-0.3.1/src/otdf_python/nanotdf_ecdsa_struct.py +132 -0
- otdf_python-0.3.1/src/otdf_python/nanotdf_type.py +43 -0
- otdf_python-0.3.1/src/otdf_python/policy_binding_serializer.py +39 -0
- otdf_python-0.3.1/src/otdf_python/policy_info.py +78 -0
- otdf_python-0.3.1/src/otdf_python/policy_object.py +22 -0
- otdf_python-0.3.1/src/otdf_python/policy_stub.py +2 -0
- otdf_python-0.3.1/src/otdf_python/resource_locator.py +44 -0
- otdf_python-0.3.1/src/otdf_python/sdk.py +528 -0
- otdf_python-0.3.1/src/otdf_python/sdk_builder.py +448 -0
- otdf_python-0.3.1/src/otdf_python/sdk_exceptions.py +16 -0
- otdf_python-0.3.1/src/otdf_python/symmetric_and_payload_config.py +30 -0
- otdf_python-0.3.1/src/otdf_python/tdf.py +479 -0
- otdf_python-0.3.1/src/otdf_python/tdf_reader.py +153 -0
- otdf_python-0.3.1/src/otdf_python/tdf_writer.py +23 -0
- otdf_python-0.3.1/src/otdf_python/token_source.py +34 -0
- otdf_python-0.3.1/src/otdf_python/version.py +57 -0
- otdf_python-0.3.1/src/otdf_python/zip_reader.py +47 -0
- otdf_python-0.3.1/src/otdf_python/zip_writer.py +70 -0
- otdf_python-0.3.1/tests/__init__.py +1 -0
- otdf_python-0.3.1/tests/config_pydantic.py +104 -0
- otdf_python-0.3.1/tests/integration/conftest.py +74 -0
- otdf_python-0.3.1/tests/integration/otdfctl_only/test_otdfctl_generated_fixtures.py +113 -0
- otdf_python-0.3.1/tests/integration/otdfctl_to_python/test_cli_comparison.py +178 -0
- otdf_python-0.3.1/tests/integration/otdfctl_to_python/test_cli_decrypt.py +191 -0
- otdf_python-0.3.1/tests/integration/otdfctl_to_python/test_cli_inspect.py +122 -0
- otdf_python-0.3.1/tests/integration/otdfctl_to_python/test_tdf_reader_integration.py +272 -0
- otdf_python-0.3.1/tests/integration/python_only/test_kas_client_integration.py +244 -0
- otdf_python-0.3.1/tests/integration/support_sdk.py +75 -0
- otdf_python-0.3.1/tests/integration/test_cli_integration.py +304 -0
- otdf_python-0.3.1/tests/integration/test_cli_tdf_validation.py +568 -0
- otdf_python-0.3.1/tests/integration/test_data/empty_file.txt +0 -0
- otdf_python-0.3.1/tests/integration/test_data/sample_binary.png +0 -0
- otdf_python-0.3.1/tests/integration/test_data/sample_text.txt +5 -0
- otdf_python-0.3.1/tests/integration/test_data/sample_with_attributes.txt +4 -0
- otdf_python-0.3.1/tests/integration/test_pe_interaction.py +96 -0
- otdf_python-0.3.1/tests/mock_crypto.py +35 -0
- otdf_python-0.3.1/tests/server_logs.py +97 -0
- otdf_python-0.3.1/tests/support_cli_args.py +183 -0
- otdf_python-0.3.1/tests/support_common.py +90 -0
- otdf_python-0.3.1/tests/support_otdfctl.py +26 -0
- otdf_python-0.3.1/tests/support_otdfctl_args.py +280 -0
- otdf_python-0.3.1/tests/test_address_normalizer.py +73 -0
- otdf_python-0.3.1/tests/test_aesgcm.py +35 -0
- otdf_python-0.3.1/tests/test_assertion_config.py +56 -0
- otdf_python-0.3.1/tests/test_asym_encryption.py +13 -0
- otdf_python-0.3.1/tests/test_autoconfigure_utils.py +50 -0
- otdf_python-0.3.1/tests/test_cli.py +188 -0
- otdf_python-0.3.1/tests/test_collection_store.py +43 -0
- otdf_python-0.3.1/tests/test_config.py +35 -0
- otdf_python-0.3.1/tests/test_crypto_utils.py +38 -0
- otdf_python-0.3.1/tests/test_eckeypair.py +34 -0
- otdf_python-0.3.1/tests/test_header.py +38 -0
- otdf_python-0.3.1/tests/test_inner_classes.py +67 -0
- otdf_python-0.3.1/tests/test_kas_client.py +526 -0
- otdf_python-0.3.1/tests/test_kas_key_cache.py +44 -0
- otdf_python-0.3.1/tests/test_kas_key_management.py +121 -0
- otdf_python-0.3.1/tests/test_key_type.py +30 -0
- otdf_python-0.3.1/tests/test_log_collection.py +39 -0
- otdf_python-0.3.1/tests/test_manifest.py +65 -0
- otdf_python-0.3.1/tests/test_manifest_format.py +103 -0
- otdf_python-0.3.1/tests/test_nanotdf.py +70 -0
- otdf_python-0.3.1/tests/test_nanotdf_ecdsa_struct.py +91 -0
- otdf_python-0.3.1/tests/test_nanotdf_integration.py +42 -0
- otdf_python-0.3.1/tests/test_nanotdf_type.py +44 -0
- otdf_python-0.3.1/tests/test_policy_object.py +38 -0
- otdf_python-0.3.1/tests/test_sdk.py +97 -0
- otdf_python-0.3.1/tests/test_sdk_builder.py +214 -0
- otdf_python-0.3.1/tests/test_sdk_exceptions.py +22 -0
- otdf_python-0.3.1/tests/test_sdk_mock.py +58 -0
- otdf_python-0.3.1/tests/test_sdk_tdf_integration.py +263 -0
- otdf_python-0.3.1/tests/test_tdf.py +58 -0
- otdf_python-0.3.1/tests/test_tdf_key_management.py +151 -0
- otdf_python-0.3.1/tests/test_tdf_reader.py +155 -0
- otdf_python-0.3.1/tests/test_tdf_writer.py +60 -0
- otdf_python-0.3.1/tests/test_token_source.py +42 -0
- otdf_python-0.3.1/tests/test_url_normalization.py +50 -0
- otdf_python-0.3.1/tests/test_use_plaintext_flow.py +103 -0
- otdf_python-0.3.1/tests/test_validate_otdf_python.py +191 -0
- otdf_python-0.3.1/tests/test_version.py +39 -0
- otdf_python-0.3.1/tests/test_zip_reader.py +70 -0
- otdf_python-0.3.1/tests/test_zip_writer.py +35 -0
- otdf_python-0.3.1/uv.lock +1274 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Derive additional environment variables
|
|
4
|
+
TOKEN_URL="${OIDC_OP_TOKEN_ENDPOINT}"
|
|
5
|
+
OTDF_HOST_AND_PORT="${OPENTDF_PLATFORM_HOST}"
|
|
6
|
+
OTDF_CLIENT="${OPENTDF_CLIENT_ID}"
|
|
7
|
+
OTDF_CLIENT_SECRET="${OPENTDF_CLIENT_SECRET}"
|
|
8
|
+
|
|
9
|
+
echo "🔧 Environment Configuration:"
|
|
10
|
+
echo " TOKEN_URL: ${TOKEN_URL}"
|
|
11
|
+
echo " OTDF_HOST_AND_PORT: ${OTDF_HOST_AND_PORT}"
|
|
12
|
+
echo " OTDF_CLIENT: ${OTDF_CLIENT}"
|
|
13
|
+
echo " OTDF_CLIENT_SECRET: ${OTDF_CLIENT_SECRET}"
|
|
14
|
+
echo ""
|
|
15
|
+
|
|
16
|
+
get_token() {
|
|
17
|
+
curl -k --location "$TOKEN_URL" \
|
|
18
|
+
--header "X-VirtruPubKey;" \
|
|
19
|
+
--header "Content-Type: application/x-www-form-urlencoded" \
|
|
20
|
+
--data-urlencode "grant_type=client_credentials" \
|
|
21
|
+
--data-urlencode "client_id=$OTDF_CLIENT" \
|
|
22
|
+
--data-urlencode "client_secret=$OTDF_CLIENT_SECRET"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
echo "🔐 Getting access token..."
|
|
26
|
+
BEARER=$( get_token | jq -r '.access_token' )
|
|
27
|
+
# NOTE: It's always okay to print this token, because it will
|
|
28
|
+
# only be valid / available in dummy / dev scenarios
|
|
29
|
+
[[ "${DEBUG:-}" == "1" ]] && echo "Got Access Token: ${BEARER}"
|
|
30
|
+
echo ""
|
|
31
|
+
|
|
32
|
+
# Array of usernames to check
|
|
33
|
+
USERNAMES=("opentdf" "sample-user" "sample-user-1" "cli-client" "opentdf-sdk")
|
|
34
|
+
|
|
35
|
+
for USERNAME in "${USERNAMES[@]}"; do
|
|
36
|
+
echo "👤 Fetching entitlements for username: ${USERNAME}"
|
|
37
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
38
|
+
|
|
39
|
+
grpcurl -plaintext \
|
|
40
|
+
-H "authorization: Bearer $BEARER" \
|
|
41
|
+
-d "{
|
|
42
|
+
\"entities\": [
|
|
43
|
+
{
|
|
44
|
+
\"userName\": \"$USERNAME\"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}" \
|
|
48
|
+
"$OTDF_HOST_AND_PORT" \
|
|
49
|
+
authorization.AuthorizationService/GetEntitlements
|
|
50
|
+
|
|
51
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
52
|
+
echo "✅ Entitlements retrieval complete for ${USERNAME}!"
|
|
53
|
+
echo ""
|
|
54
|
+
done
|
|
55
|
+
|
|
56
|
+
echo "🎉 All entitlement checks completed!"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
if ! [ -d platform ]; then
|
|
6
|
+
git clone https://github.com/opentdf/platform.git
|
|
7
|
+
fi
|
|
8
|
+
cd platform
|
|
9
|
+
git checkout 3360befcb3e6e9791d7bfd2e89128aee0e7d2818 # Branch 'DSPX-1539-keytoolnomore'
|
|
10
|
+
|
|
11
|
+
yq -i '.realms[0].clients[0].client.directAccessGrantsEnabled = true | .realms[0].clients[0].client.serviceAccountsEnabled = true' service/cmd/keycloak_data.yaml
|
|
12
|
+
|
|
13
|
+
yq -i '.realms[0].clients[1].client.directAccessGrantsEnabled = true | .realms[0].clients[1].client.serviceAccountsEnabled = true' service/cmd/keycloak_data.yaml
|
|
14
|
+
|
|
15
|
+
yq -i '.realms[0].clients[4].client.directAccessGrantsEnabled = true | .realms[0].clients[4].client.serviceAccountsEnabled = true' service/cmd/keycloak_data.yaml
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
if ! [ -d ./keys ]; then
|
|
19
|
+
go mod download
|
|
20
|
+
|
|
21
|
+
go mod verify
|
|
22
|
+
|
|
23
|
+
.github/scripts/init-temp-keys.sh
|
|
24
|
+
cp opentdf-example.yaml opentdf.yaml
|
|
25
|
+
|
|
26
|
+
# Edit 'opentdf.yaml' for our use case
|
|
27
|
+
yq -i 'del(.db) | .services.entityresolution.url = "http://localhost:8888/auth" | .server.auth.issuer = "http://localhost:8888/auth/realms/opentdf"' opentdf.yaml
|
|
28
|
+
# The above expression can also be written as 3 separate commands:
|
|
29
|
+
# yq -i 'del(.db)' opentdf.yaml
|
|
30
|
+
# yq -i '.services.entityresolution.url = "http://localhost:8888/auth"' opentdf.yaml
|
|
31
|
+
# yq -i '.server.auth.issuer = "http://localhost:8888/auth/realms/opentdf"' opentdf.yaml
|
|
32
|
+
|
|
33
|
+
yq -i '
|
|
34
|
+
.server.cryptoProvider = {
|
|
35
|
+
"type": "standard",
|
|
36
|
+
"standard": {
|
|
37
|
+
"keys": [
|
|
38
|
+
{
|
|
39
|
+
"kid": "r1",
|
|
40
|
+
"alg": "rsa:2048",
|
|
41
|
+
"private": "kas-private.pem",
|
|
42
|
+
"cert": "kas-cert.pem"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"kid": "e1",
|
|
46
|
+
"alg": "ec:secp256r1",
|
|
47
|
+
"private": "kas-ec-private.pem",
|
|
48
|
+
"cert": "kas-ec-cert.pem"
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
' opentdf.yaml
|
|
54
|
+
chmod -R 700 ./keys
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
docker compose up -d --wait --wait-timeout 360
|
|
58
|
+
|
|
59
|
+
go run ./service provision keycloak
|
|
60
|
+
|
|
61
|
+
go run ./service provision fixtures
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Build otdf-python wheel using uv and output the wheel path for downstream workflows
|
|
2
|
+
name: "Build Python Wheel"
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- chore/rewrite
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-22.04
|
|
12
|
+
outputs:
|
|
13
|
+
wheel: ${{ steps.find_wheel.outputs.wheel_path }}
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout this repo
|
|
16
|
+
uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Set up uv
|
|
19
|
+
uses: astral-sh/setup-uv@v6
|
|
20
|
+
with:
|
|
21
|
+
enable-cache: true
|
|
22
|
+
cache-dependency-glob: "uv.lock"
|
|
23
|
+
|
|
24
|
+
- name: Build otdf-python wheel using uv
|
|
25
|
+
run: |
|
|
26
|
+
uv sync --frozen
|
|
27
|
+
uv build
|
|
28
|
+
shell: bash
|
|
29
|
+
|
|
30
|
+
- name: Find built wheel
|
|
31
|
+
id: find_wheel
|
|
32
|
+
run: |
|
|
33
|
+
wheel_path=$(ls dist/*.whl | head -n1)
|
|
34
|
+
echo "wheel_path=$wheel_path" >> $GITHUB_OUTPUT
|
|
35
|
+
shell: bash
|
|
36
|
+
|
|
37
|
+
# - name: Upload wheel as artifact
|
|
38
|
+
# uses: actions/upload-artifact@v4
|
|
39
|
+
# with:
|
|
40
|
+
# name: python-wheel
|
|
41
|
+
# path: dist/*.whl
|
|
42
|
+
# overwrite: true
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Based on
|
|
2
|
+
# https://github.com/opentdf/java-sdk/blob/v0.6.1/.github/workflows/checks.yaml
|
|
3
|
+
#
|
|
4
|
+
# Except, that this is a "Composite Action", and specifies 'shell: bash' for
|
|
5
|
+
# each 'run:' step.
|
|
6
|
+
name: "NEW: Platform Integration testing"
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
workflow_call:
|
|
10
|
+
inputs:
|
|
11
|
+
wheel:
|
|
12
|
+
required: true
|
|
13
|
+
type: string
|
|
14
|
+
python_version:
|
|
15
|
+
required: true
|
|
16
|
+
type: string
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
integration_test:
|
|
23
|
+
runs-on: ubuntu-22.04
|
|
24
|
+
steps:
|
|
25
|
+
- name: Checkout this repo
|
|
26
|
+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
|
27
|
+
|
|
28
|
+
# - uses: bufbuild/buf-setup-action@382440cdb8ec7bc25a68d7b4711163d95f7cc3aa
|
|
29
|
+
# with:
|
|
30
|
+
# github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
31
|
+
|
|
32
|
+
- name: Check out platform
|
|
33
|
+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
|
34
|
+
with:
|
|
35
|
+
repository: opentdf/platform
|
|
36
|
+
ref: main
|
|
37
|
+
path: platform
|
|
38
|
+
- name: Set up go
|
|
39
|
+
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
|
40
|
+
with:
|
|
41
|
+
go-version: "1.24.x"
|
|
42
|
+
check-latest: false
|
|
43
|
+
cache-dependency-path: |
|
|
44
|
+
platform/service/go.sum
|
|
45
|
+
platform/examples/go.sum
|
|
46
|
+
platform/protocol/go/go.sum
|
|
47
|
+
platform/sdk/go.sum
|
|
48
|
+
- run: go mod download
|
|
49
|
+
shell: bash
|
|
50
|
+
working-directory: platform
|
|
51
|
+
- run: go mod verify
|
|
52
|
+
shell: bash
|
|
53
|
+
working-directory: platform
|
|
54
|
+
- name: Create keys
|
|
55
|
+
shell: bash
|
|
56
|
+
run: |
|
|
57
|
+
.github/scripts/init-temp-keys.sh
|
|
58
|
+
# Edit Keycloak sample file for our use case
|
|
59
|
+
yq -i '.realms[0].clients[0].client.directAccessGrantsEnabled = true | .realms[0].clients[0].client.serviceAccountsEnabled = true' service/cmd/keycloak_data.yaml
|
|
60
|
+
yq -i '.realms[0].clients[1].client.directAccessGrantsEnabled = true | .realms[0].clients[1].client.serviceAccountsEnabled = true' service/cmd/keycloak_data.yaml
|
|
61
|
+
yq -i '.realms[0].clients[4].client.directAccessGrantsEnabled = true | .realms[0].clients[4].client.serviceAccountsEnabled = true' service/cmd/keycloak_data.yaml
|
|
62
|
+
|
|
63
|
+
cp opentdf-example.yaml opentdf.yaml
|
|
64
|
+
# Edit 'opentdf.yaml' for our use case
|
|
65
|
+
yq -i 'del(.db) | .services.entityresolution.url = "http://localhost:8888/auth" | .server.auth.issuer = "http://localhost:8888/auth/realms/opentdf"' opentdf.yaml
|
|
66
|
+
# The above expression can also be written as 3 separate commands:
|
|
67
|
+
# yq -i 'del(.db)' opentdf.yaml
|
|
68
|
+
# yq -i '.services.entityresolution.url = "http://localhost:8888/auth"' opentdf.yaml
|
|
69
|
+
# yq -i '.server.auth.issuer = "http://localhost:8888/auth/realms/opentdf"' opentdf.yaml
|
|
70
|
+
yq -i '
|
|
71
|
+
.server.cryptoProvider = {
|
|
72
|
+
"type": "standard",
|
|
73
|
+
"standard": {
|
|
74
|
+
"keys": [
|
|
75
|
+
{
|
|
76
|
+
"kid": "r1",
|
|
77
|
+
"alg": "rsa:2048",
|
|
78
|
+
"private": "kas-private.pem",
|
|
79
|
+
"cert": "kas-cert.pem"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"kid": "e1",
|
|
83
|
+
"alg": "ec:secp256r1",
|
|
84
|
+
"private": "kas-ec-private.pem",
|
|
85
|
+
"cert": "kas-ec-cert.pem"
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
' opentdf.yaml
|
|
91
|
+
sudo chmod -R 777 ./keys
|
|
92
|
+
working-directory: platform
|
|
93
|
+
# - name: Trust the locally issued cert
|
|
94
|
+
# run: |
|
|
95
|
+
# keytool \
|
|
96
|
+
# -importcert \
|
|
97
|
+
# -storepass changeit \
|
|
98
|
+
# -noprompt \
|
|
99
|
+
# -file localhost.crt \
|
|
100
|
+
# -keystore $JAVA_HOME/lib/security/cacerts \
|
|
101
|
+
# -alias localhost-for-tests
|
|
102
|
+
# working-directory: platform/keys
|
|
103
|
+
- name: Bring the services up
|
|
104
|
+
shell: bash
|
|
105
|
+
run: docker compose up -d --wait --wait-timeout 240
|
|
106
|
+
working-directory: platform
|
|
107
|
+
- name: Provision keycloak
|
|
108
|
+
shell: bash
|
|
109
|
+
run: go run ./service provision keycloak
|
|
110
|
+
working-directory: platform
|
|
111
|
+
- name: Provision fixtures
|
|
112
|
+
shell: bash
|
|
113
|
+
run: go run ./service provision fixtures
|
|
114
|
+
working-directory: platform
|
|
115
|
+
- name: Start server in background
|
|
116
|
+
uses: JarvusInnovations/background-action@2428e7b970a846423095c79d43f759abf979a635
|
|
117
|
+
with:
|
|
118
|
+
run: |
|
|
119
|
+
go run ./service start
|
|
120
|
+
wait-on: |
|
|
121
|
+
tcp:localhost:8080
|
|
122
|
+
log-output-if: true
|
|
123
|
+
wait-for: 90s
|
|
124
|
+
working-directory: platform
|
|
125
|
+
- name: Get grpcurl
|
|
126
|
+
shell: bash
|
|
127
|
+
run: go install github.com/fullstorydev/grpcurl/cmd/grpcurl@v1.8.9
|
|
128
|
+
- name: Make sure that the platform is up
|
|
129
|
+
shell: bash
|
|
130
|
+
run: |
|
|
131
|
+
grpcurl -plaintext localhost:8080 list && \
|
|
132
|
+
grpcurl -plaintext localhost:8080 kas.AccessService/PublicKey
|
|
133
|
+
|
|
134
|
+
- name: Install otdfctl
|
|
135
|
+
run: go install github.com/opentdf/otdfctl@latest
|
|
136
|
+
shell: bash
|
|
137
|
+
|
|
138
|
+
- name: Create creds.json for otdfctl
|
|
139
|
+
run: echo -n '{"clientId":"opentdf-sdk","clientSecret":"secret"}' > creds.json
|
|
140
|
+
shell: bash
|
|
141
|
+
|
|
142
|
+
- name: Create a plaintext file
|
|
143
|
+
run: echo "integration test secret" > secret.txt
|
|
144
|
+
shell: bash
|
|
145
|
+
|
|
146
|
+
- name: Encrypt file with otdfctl (no attributes)
|
|
147
|
+
run: |
|
|
148
|
+
export PATH=$PATH:$(go env GOPATH)/bin
|
|
149
|
+
otdfctl encrypt -o secret.txt.tdf --host http://localhost:8080 --tls-no-verify --with-client-creds-file creds.json secret.txt
|
|
150
|
+
shell: bash
|
|
151
|
+
|
|
152
|
+
- name: Set up uv
|
|
153
|
+
uses: astral-sh/setup-uv@v6
|
|
154
|
+
with:
|
|
155
|
+
enable-cache: true
|
|
156
|
+
cache-dependency-glob: "uv.lock"
|
|
157
|
+
|
|
158
|
+
- name: Run all tests, minus integration tests
|
|
159
|
+
env:
|
|
160
|
+
OPENTDF_CLIENT_ID: "opentdf"
|
|
161
|
+
OPENTDF_CLIENT_SECRET: "secret"
|
|
162
|
+
OPENTDF_HOSTNAME: "localhost:8080"
|
|
163
|
+
OIDC_TOKEN_ENDPOINT: "http://localhost:8888/auth/realms/opentdf/protocol/openid-connect/token"
|
|
164
|
+
OPENTDF_KAS_URL: "http://localhost:8080/kas"
|
|
165
|
+
INSECURE_SKIP_VERIFY: "TRUE"
|
|
166
|
+
TEST_OPENTDF_ATTRIBUTE_1: "https://example.net/attr/attr1/value/value1"
|
|
167
|
+
TEST_OPENTDF_ATTRIBUTE_2: "https://example.com/attr/attr1/value/value1"
|
|
168
|
+
run: |
|
|
169
|
+
uv sync
|
|
170
|
+
# Skip the tests marked "integration"
|
|
171
|
+
uv run pytest -m "not integration" --tb=short -vv tests
|
|
172
|
+
shell: bash
|
|
173
|
+
|
|
174
|
+
- name: Run integration tests
|
|
175
|
+
env:
|
|
176
|
+
OPENTDF_CLIENT_ID: "opentdf"
|
|
177
|
+
OPENTDF_CLIENT_SECRET: "secret"
|
|
178
|
+
OPENTDF_PLATFORM_HOST: "localhost:8080"
|
|
179
|
+
OPENTDF_PLATFORM_URL: "http://localhost:8080"
|
|
180
|
+
OIDC_OP_TOKEN_ENDPOINT: "http://localhost:8888/auth/realms/opentdf/protocol/openid-connect/token"
|
|
181
|
+
OPENTDF_KAS_URL: "http://localhost:8080/kas"
|
|
182
|
+
INSECURE_SKIP_VERIFY: "TRUE"
|
|
183
|
+
TEST_OPENTDF_ATTRIBUTE_1: "https://example.net/attr/attr1/value/value1"
|
|
184
|
+
TEST_OPENTDF_ATTRIBUTE_2: "https://example.com/attr/attr1/value/value1"
|
|
185
|
+
run: |
|
|
186
|
+
# Run check_entitlements.sh
|
|
187
|
+
./.github/check_entitlements.sh
|
|
188
|
+
|
|
189
|
+
uv sync
|
|
190
|
+
# Skip the tests marked "integration"
|
|
191
|
+
uv run pytest -m "integration" --tb=short -vv tests
|
|
192
|
+
shell: bash
|
|
193
|
+
|
|
194
|
+
# platform-xtest:
|
|
195
|
+
# permissions:
|
|
196
|
+
# contents: read
|
|
197
|
+
# packages: read
|
|
198
|
+
# needs: platform-integration
|
|
199
|
+
# uses: opentdf/tests/.github/workflows/xtest.yml@main
|
|
200
|
+
# with:
|
|
201
|
+
# java-ref: ${{ github.ref }}
|
|
202
|
+
|
|
203
|
+
# ci:
|
|
204
|
+
# needs:
|
|
205
|
+
# - platform-integration
|
|
206
|
+
# - platform-xtest
|
|
207
|
+
# - mavenverify
|
|
208
|
+
# - pr
|
|
209
|
+
# runs-on: ubuntu-22.04
|
|
210
|
+
# if: always()
|
|
211
|
+
# steps:
|
|
212
|
+
# - if: contains(needs.*.result, 'failure')
|
|
213
|
+
# run: echo "Failed due to ${{ contains(needs.*.result, 'failure') }}" && exit 1
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
name: Release Please
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
- develop
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: write
|
|
12
|
+
pull-requests: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
# Run full test suite before any release operations
|
|
16
|
+
test-suite:
|
|
17
|
+
uses: ./.github/workflows/test-suite.yaml
|
|
18
|
+
|
|
19
|
+
release-please:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
needs: test-suite
|
|
22
|
+
if: needs.test-suite.outputs.tests_passed == 'true'
|
|
23
|
+
outputs:
|
|
24
|
+
releases_created: ${{ steps.release-develop.outputs.releases_created || steps.release-main.outputs.releases_created }}
|
|
25
|
+
paths_released: ${{ steps.release-develop.outputs.paths_released || steps.release-main.outputs.paths_released }}
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
# Release-please for develop branch (creates alpha prereleases)
|
|
30
|
+
- uses: googleapis/release-please-action@v4
|
|
31
|
+
if: github.ref == 'refs/heads/develop'
|
|
32
|
+
id: release-develop
|
|
33
|
+
with:
|
|
34
|
+
config-file: .release-please-config-develop.json
|
|
35
|
+
manifest-file: .release-please-manifest-develop.json
|
|
36
|
+
target-branch: develop
|
|
37
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
38
|
+
|
|
39
|
+
# Release-please for main branch (creates stable releases)
|
|
40
|
+
- uses: googleapis/release-please-action@v4
|
|
41
|
+
if: github.ref == 'refs/heads/main'
|
|
42
|
+
id: release-main
|
|
43
|
+
with:
|
|
44
|
+
config-file: .release-please-config.json
|
|
45
|
+
manifest-file: .release-please-manifest.json
|
|
46
|
+
target-branch: main
|
|
47
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
48
|
+
|
|
49
|
+
# Trigger appropriate publish workflows based on release type
|
|
50
|
+
trigger-publish:
|
|
51
|
+
permissions:
|
|
52
|
+
contents: write
|
|
53
|
+
# This permission is mandatory for PyPI's trusted publishing
|
|
54
|
+
id-token: write
|
|
55
|
+
needs: release-please
|
|
56
|
+
if: ${{ needs.release-please.outputs.releases_created }}
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
|
|
61
|
+
- name: Install uv
|
|
62
|
+
uses: astral-sh/setup-uv@v6
|
|
63
|
+
with:
|
|
64
|
+
version: "latest"
|
|
65
|
+
|
|
66
|
+
- name: Build package
|
|
67
|
+
shell: bash
|
|
68
|
+
run: |
|
|
69
|
+
uv build
|
|
70
|
+
|
|
71
|
+
- name: Test import
|
|
72
|
+
shell: bash
|
|
73
|
+
run: |
|
|
74
|
+
uv run python -c 'import otdf_python; print("Package imported successfully")'
|
|
75
|
+
|
|
76
|
+
# While we improve the release process, prevent publishing to TestPyPI for versions <= 0.3.2
|
|
77
|
+
- name: Store version and determine if should publish to TestPyPI
|
|
78
|
+
id: check_version
|
|
79
|
+
shell: bash
|
|
80
|
+
run: |
|
|
81
|
+
PROJECT_VERSION=$(uv version --short)
|
|
82
|
+
echo "PROJECT_VERSION=$PROJECT_VERSION" >> $GITHUB_ENV
|
|
83
|
+
|
|
84
|
+
if [[ "$PROJECT_VERSION" =~ [0-9]+\.[0-9]+\.[0-9]+a[0-9]+ ]]; then
|
|
85
|
+
echo "is_alpha=true" >> $GITHUB_OUTPUT
|
|
86
|
+
echo "Alpha version detected: $PROJECT_VERSION"
|
|
87
|
+
else
|
|
88
|
+
echo "is_alpha=false" >> $GITHUB_OUTPUT
|
|
89
|
+
echo "Stable version detected: $PROJECT_VERSION"
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
# Remove any alpha/beta/rc suffixes for comparison
|
|
93
|
+
CLEAN_VERSION=$(echo "$PROJECT_VERSION" | sed 's/[a-zA-Z].*//')
|
|
94
|
+
echo "clean_version=$CLEAN_VERSION" >> $GITHUB_OUTPUT
|
|
95
|
+
|
|
96
|
+
# Convert versions to comparable format (e.g., "0.3.2" -> "000300020000")
|
|
97
|
+
version_to_number() {
|
|
98
|
+
echo "$1" | awk -F. '{ printf("%04d%04d%04d\n", $1,$2,$3); }'
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
CURRENT_NUM=$(version_to_number "$CLEAN_VERSION")
|
|
102
|
+
THRESHOLD_NUM=$(version_to_number "0.3.2")
|
|
103
|
+
|
|
104
|
+
if [ "$CURRENT_NUM" -gt "$THRESHOLD_NUM" ]; then
|
|
105
|
+
echo "should_publish=true" >> $GITHUB_OUTPUT
|
|
106
|
+
echo "Version $PROJECT_VERSION (clean: $CLEAN_VERSION) is > 0.3.2, will publish to TestPyPI"
|
|
107
|
+
else
|
|
108
|
+
echo "should_publish=false" >> $GITHUB_OUTPUT
|
|
109
|
+
echo "Version $PROJECT_VERSION (clean: $CLEAN_VERSION) is <= 0.3.2, skipping TestPyPI publish"
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
# For develop branch: trigger TestPyPI build (alpha prereleases go to TestPyPI from develop)
|
|
113
|
+
|
|
114
|
+
# Publish with "trusted publisher" mechanism:
|
|
115
|
+
# https://docs.pypi.org/trusted-publishers/
|
|
116
|
+
#
|
|
117
|
+
# Requires GHA token permission (above in YAML) and PyPI management:
|
|
118
|
+
# https://test.pypi.org/manage/project/otdf-python/settings/publishing/
|
|
119
|
+
- name: Publish package distributions to TestPyPI
|
|
120
|
+
if: github.ref == 'refs/heads/develop' && steps.check_version.outputs.should_publish == 'true'
|
|
121
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
122
|
+
with:
|
|
123
|
+
repository-url: https://test.pypi.org/legacy/
|
|
124
|
+
verbose: true
|
|
125
|
+
packages-dir: dist/
|
|
126
|
+
|
|
127
|
+
# For main branch: trigger PyPI build (stable releases go to PyPI from main)
|
|
128
|
+
# Publish with "trusted publisher" mechanism:
|
|
129
|
+
# https://docs.pypi.org/trusted-publishers/
|
|
130
|
+
#
|
|
131
|
+
# Requires GHA token permission (above in YAML) and PyPI management:
|
|
132
|
+
# https://pypi.org/manage/project/otdf-python/settings/publishing/
|
|
133
|
+
- name: Publish package distributions to PyPI
|
|
134
|
+
if: github.ref == 'refs/heads/main'
|
|
135
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
136
|
+
with:
|
|
137
|
+
# repository-url: https://pypi.org/legacy/
|
|
138
|
+
packages-dir: dist/
|
|
139
|
+
verbose: true
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
name: Test Suite
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
- develop
|
|
8
|
+
pull_request:
|
|
9
|
+
workflow_call:
|
|
10
|
+
outputs:
|
|
11
|
+
tests_passed:
|
|
12
|
+
description: "Whether all tests passed"
|
|
13
|
+
value: ${{ jobs.report.outputs.success }}
|
|
14
|
+
workflow_dispatch:
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
# Step 1: Fast lint and format checks (fail fast on code style)
|
|
18
|
+
lint-check:
|
|
19
|
+
runs-on: ubuntu-22.04
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Set up uv
|
|
24
|
+
uses: astral-sh/setup-uv@v6
|
|
25
|
+
with:
|
|
26
|
+
enable-cache: true
|
|
27
|
+
cache-dependency-glob: "uv.lock"
|
|
28
|
+
|
|
29
|
+
- name: Run linting (fail fast)
|
|
30
|
+
run: |
|
|
31
|
+
uv sync --frozen
|
|
32
|
+
uv run ruff check
|
|
33
|
+
uv run ruff format --check
|
|
34
|
+
|
|
35
|
+
# Step 2: Build (only after linting passes)
|
|
36
|
+
build:
|
|
37
|
+
runs-on: ubuntu-22.04
|
|
38
|
+
needs: lint-check
|
|
39
|
+
outputs:
|
|
40
|
+
wheel: ${{ steps.find_wheel.outputs.wheel_path }}
|
|
41
|
+
steps:
|
|
42
|
+
- name: Checkout this repo
|
|
43
|
+
uses: actions/checkout@v4
|
|
44
|
+
|
|
45
|
+
- name: Set up uv
|
|
46
|
+
uses: astral-sh/setup-uv@v6
|
|
47
|
+
with:
|
|
48
|
+
enable-cache: true
|
|
49
|
+
cache-dependency-glob: "uv.lock"
|
|
50
|
+
|
|
51
|
+
- name: Build otdf-python wheel using uv
|
|
52
|
+
run: |
|
|
53
|
+
uv sync --frozen
|
|
54
|
+
uv build
|
|
55
|
+
shell: bash
|
|
56
|
+
|
|
57
|
+
- name: Find built wheel
|
|
58
|
+
id: find_wheel
|
|
59
|
+
run: |
|
|
60
|
+
wheel_path=$(ls dist/*.whl | head -n1)
|
|
61
|
+
echo "wheel_path=$wheel_path" >> $GITHUB_OUTPUT
|
|
62
|
+
shell: bash
|
|
63
|
+
|
|
64
|
+
- name: Upload wheel as artifact
|
|
65
|
+
uses: actions/upload-artifact@v4
|
|
66
|
+
with:
|
|
67
|
+
name: python-wheel
|
|
68
|
+
path: dist/*.whl
|
|
69
|
+
|
|
70
|
+
# Step 3: Unit tests (only after build succeeds)
|
|
71
|
+
unit-tests:
|
|
72
|
+
runs-on: ubuntu-22.04
|
|
73
|
+
needs: build
|
|
74
|
+
steps:
|
|
75
|
+
- uses: actions/checkout@v4
|
|
76
|
+
|
|
77
|
+
- name: Set up uv
|
|
78
|
+
uses: astral-sh/setup-uv@v6
|
|
79
|
+
with:
|
|
80
|
+
enable-cache: true
|
|
81
|
+
cache-dependency-glob: "uv.lock"
|
|
82
|
+
|
|
83
|
+
- name: Run unit tests
|
|
84
|
+
run: |
|
|
85
|
+
uv sync --frozen
|
|
86
|
+
uv run pytest -m "not integration" --tb=short -v tests/
|
|
87
|
+
|
|
88
|
+
# Step 4: Integration tests (only after unit tests pass)
|
|
89
|
+
integration-tests:
|
|
90
|
+
strategy:
|
|
91
|
+
fail-fast: true
|
|
92
|
+
matrix:
|
|
93
|
+
python3_version: ["3.10", "3.11", "3.12", "3.13"]
|
|
94
|
+
needs: [build, unit-tests]
|
|
95
|
+
uses: ./.github/workflows/platform-integration-test.yaml
|
|
96
|
+
with:
|
|
97
|
+
wheel: ${{ needs.build.outputs.wheel }}
|
|
98
|
+
python_version: ${{ matrix.python3_version }}
|
|
99
|
+
|
|
100
|
+
report:
|
|
101
|
+
runs-on: ubuntu-22.04
|
|
102
|
+
needs: [lint-check, build, unit-tests, integration-tests]
|
|
103
|
+
if: always()
|
|
104
|
+
outputs:
|
|
105
|
+
success: ${{ steps.check.outputs.success }}
|
|
106
|
+
steps:
|
|
107
|
+
- name: Check all jobs succeeded
|
|
108
|
+
id: check
|
|
109
|
+
run: |
|
|
110
|
+
if [[ "${{ needs.lint-check.result }}" == "success" && "${{ needs.build.result }}" == "success" && "${{ needs.unit-tests.result }}" == "success" && "${{ needs.integration-tests.result }}" == "success" ]]; then
|
|
111
|
+
echo "success=true" >> $GITHUB_OUTPUT
|
|
112
|
+
echo "✅ All tests passed!"
|
|
113
|
+
else
|
|
114
|
+
echo "success=false" >> $GITHUB_OUTPUT
|
|
115
|
+
echo "❌ Some tests failed:"
|
|
116
|
+
echo " Lint Check: ${{ needs.lint-check.result }}"
|
|
117
|
+
echo " Build: ${{ needs.build.result }}"
|
|
118
|
+
echo " Unit Tests: ${{ needs.unit-tests.result }}"
|
|
119
|
+
echo " Integration Tests: ${{ needs.integration-tests.result }}"
|
|
120
|
+
exit 1
|
|
121
|
+
fi
|