aimodelshare 0.1.55__tar.gz → 0.1.59__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.
Potentially problematic release.
This version of aimodelshare might be problematic. Click here for more details.
- aimodelshare-0.1.59/.github/workflows/aimodelshare-tests.yml +84 -0
- aimodelshare-0.1.59/.github/workflows/bootstrap-terraform.yml +149 -0
- aimodelshare-0.1.59/.github/workflows/deploy-infra.yml +224 -0
- aimodelshare-0.1.59/.github/workflows/destroy-infra.yml +114 -0
- aimodelshare-0.1.59/.github/workflows/playground-integration-tests.yml +536 -0
- aimodelshare-0.1.59/.github/workflows/publish-lambda-layers.yml +556 -0
- aimodelshare-0.1.59/.github/workflows/pypi-manual-publish.yml +149 -0
- aimodelshare-0.1.59/.github/workflows/test-colab-install.yml +122 -0
- aimodelshare-0.1.59/.github/workflows/test-colab-simulated.yml +90 -0
- aimodelshare-0.1.59/.github/workflows/unit-tests.yml +77 -0
- aimodelshare-0.1.59/.gitignore +174 -0
- aimodelshare-0.1.59/CHANGES_SUMMARY.md +225 -0
- aimodelshare-0.1.59/CODE_REVIEW.md +113 -0
- aimodelshare-0.1.59/IMPLEMENTATION_SUMMARY.md +300 -0
- aimodelshare-0.1.59/IMPLEMENTATION_SUMMARY_DIAGNOSTICS.md +174 -0
- aimodelshare-0.1.59/IMPLEMENTATION_SUMMARY_REGION_AWARE.md +177 -0
- aimodelshare-0.1.59/LICENSE +5 -0
- aimodelshare-0.1.59/MANIFEST.in +3 -0
- aimodelshare-0.1.59/METADATA_FIX_DOCUMENTATION.md +331 -0
- aimodelshare-0.1.59/MODERNIZATION_SUMMARY.md +127 -0
- aimodelshare-0.1.59/PKG-INFO +258 -0
- aimodelshare-0.1.59/PLAYGROUND_TEST_ISOLATION.md +202 -0
- aimodelshare-0.1.59/PREPROCESSOR_DIAGNOSTICS.md +259 -0
- aimodelshare-0.1.59/PR_SUMMARY.md +240 -0
- aimodelshare-0.1.59/README.md +202 -0
- aimodelshare-0.1.59/aimodelshare/__init__.py +98 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/aimsonnx.py +263 -82
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/api.py +13 -12
- aimodelshare-0.1.59/aimodelshare/auth.py +163 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/base_image.py +1 -1
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/containerisation.py +1 -1
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/data_sharing/download_data.py +133 -83
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/generatemodelapi.py +7 -6
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/authorization.txt +275 -275
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/eval_lambda.txt +81 -13
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/model.py +492 -196
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/modeluser.py +22 -0
- aimodelshare-0.1.59/aimodelshare/moral_compass/README.md +367 -0
- aimodelshare-0.1.59/aimodelshare/moral_compass/__init__.py +58 -0
- aimodelshare-0.1.59/aimodelshare/moral_compass/_version.py +3 -0
- aimodelshare-0.1.59/aimodelshare/moral_compass/api_client.py +553 -0
- aimodelshare-0.1.59/aimodelshare/moral_compass/challenge.py +365 -0
- aimodelshare-0.1.59/aimodelshare/moral_compass/config.py +187 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/playground.py +26 -14
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/preprocessormodules.py +60 -6
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/authorization.txt +258 -258
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/eval_lambda.txt +1 -1
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/reproducibility.py +20 -5
- aimodelshare-0.1.59/aimodelshare/utils/__init__.py +78 -0
- aimodelshare-0.1.59/aimodelshare/utils/optional_deps.py +38 -0
- aimodelshare-0.1.59/aimodelshare.egg-info/PKG-INFO +258 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare.egg-info/SOURCES.txt +115 -1
- aimodelshare-0.1.59/aimodelshare.egg-info/requires.txt +41 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare.egg-info/top_level.txt +0 -1
- aimodelshare-0.1.59/docs/DEPRECATION_PLAN.md +89 -0
- aimodelshare-0.1.59/docs/REGION_AWARE_NAMING.md +243 -0
- aimodelshare-0.1.59/docs/aimodshare_banner.jpg +0 -0
- aimodelshare-0.1.59/docs/justice_equity_challenge_example.md +254 -0
- aimodelshare-0.1.59/infra/README.md +542 -0
- aimodelshare-0.1.59/infra/ROLLOUT_GUIDE.md +266 -0
- aimodelshare-0.1.59/infra/bootstrap/README.md +84 -0
- aimodelshare-0.1.59/infra/bootstrap/main.tf +275 -0
- aimodelshare-0.1.59/infra/bootstrap/outputs.tf +40 -0
- aimodelshare-0.1.59/infra/bootstrap/variables.tf +17 -0
- aimodelshare-0.1.59/infra/lambda/app.py +1381 -0
- aimodelshare-0.1.59/infra/lambda-layer-bucket/README.md +94 -0
- aimodelshare-0.1.59/infra/lambda-layer-bucket/main.tf +74 -0
- aimodelshare-0.1.59/infra/layer/build_layer.sh +14 -0
- aimodelshare-0.1.59/infra/main.tf +312 -0
- aimodelshare-0.1.59/infra/outputs.tf +14 -0
- aimodelshare-0.1.59/infra/terraform.tfvars +1 -0
- aimodelshare-0.1.59/infra/variables.tf +106 -0
- aimodelshare-0.1.59/meta.yaml +71 -0
- aimodelshare-0.1.59/notebooks/aimodelshare_colab_smoke.ipynb +309 -0
- aimodelshare-0.1.59/pyproject.toml +61 -0
- aimodelshare-0.1.59/requirements-auth.txt +2 -0
- aimodelshare-0.1.59/requirements-eval.txt +6 -0
- aimodelshare-0.1.59/requirements.txt +31 -0
- aimodelshare-0.1.59/scripts/cache_terraform_outputs.sh +49 -0
- aimodelshare-0.1.59/scripts/demo_moral_compass_metrics.py +259 -0
- aimodelshare-0.1.59/scripts/verify_api_reachable.sh +80 -0
- aimodelshare-0.1.59/setup.cfg +8 -0
- aimodelshare-0.1.59/setup.py +6 -0
- aimodelshare-0.1.59/source/about.rst +18 -0
- aimodelshare-0.1.59/source/advanced_features.rst +137 -0
- aimodelshare-0.1.59/source/competition.rst +218 -0
- aimodelshare-0.1.59/source/conf.py +58 -0
- aimodelshare-0.1.59/source/create_credentials.rst +86 -0
- aimodelshare-0.1.59/source/example_notebooks.rst +132 -0
- aimodelshare-0.1.59/source/functions.rst +151 -0
- aimodelshare-0.1.59/source/gettingstarted.rst +390 -0
- aimodelshare-0.1.59/source/images/creds1.png +0 -0
- aimodelshare-0.1.59/source/images/creds2.png +0 -0
- aimodelshare-0.1.59/source/images/creds3.png +0 -0
- aimodelshare-0.1.59/source/images/creds4.png +0 -0
- aimodelshare-0.1.59/source/images/creds5.png +0 -0
- aimodelshare-0.1.59/source/images/creds_file_example.png +0 -0
- aimodelshare-0.1.59/source/images/predict_tab.png +0 -0
- aimodelshare-0.1.59/source/index.rst +110 -0
- aimodelshare-0.1.59/source/modelplayground.rst +132 -0
- aimodelshare-0.1.59/tests/README.md +80 -0
- aimodelshare-0.1.59/tests/load_mixed_duration.py +376 -0
- aimodelshare-0.1.59/tests/load_multi_table.py +328 -0
- aimodelshare-0.1.59/tests/load_single_table.py +285 -0
- aimodelshare-0.1.59/tests/requirements.txt +3 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/tests/test_aimsonnx.py +6 -19
- aimodelshare-0.1.59/tests/test_api_integration.py +421 -0
- aimodelshare-0.1.59/tests/test_api_pagination.py +213 -0
- aimodelshare-0.1.59/tests/test_moral_compass_auth.py +319 -0
- aimodelshare-0.1.59/tests/test_moral_compass_client_minimal.py +227 -0
- aimodelshare-0.1.59/tests/test_moral_compass_dynamic_metrics.py +415 -0
- aimodelshare-0.1.59/tests/test_moral_compass_unit.py +300 -0
- aimodelshare-0.1.59/tests/test_playground_compas_multiframework.py +776 -0
- aimodelshare-0.1.59/tests/test_playground_compas_multiframework_short.py +582 -0
- aimodelshare-0.1.59/tests/test_playground_keras_model_types.py +344 -0
- aimodelshare-0.1.59/tests/test_playground_model_types.py +314 -0
- aimodelshare-0.1.59/tests/test_playground_moral_compass_challenge.py +183 -0
- aimodelshare-0.1.59/tests/test_playground_torch_model_types.py +396 -0
- aimodelshare-0.1.59/tests/test_playgrounds_nodataimport.py +141 -0
- aimodelshare-0.1.59/tests/test_region_aware_naming.py +133 -0
- aimodelshare-0.1.59/tests/unit/DEBUGGING_GUIDE.md +250 -0
- aimodelshare-0.1.59/tests/unit/README.md +204 -0
- aimodelshare-0.1.59/tests/unit/__init__.py +1 -0
- aimodelshare-0.1.59/tests/unit/run_tests.sh +74 -0
- aimodelshare-0.1.59/tests/unit/test_credentials.py +145 -0
- aimodelshare-0.1.59/tests/unit/test_data_preprocessing.py +171 -0
- aimodelshare-0.1.59/tests/unit/test_eval_metrics_smoke.py +263 -0
- aimodelshare-0.1.59/tests/unit/test_model_helpers.py +547 -0
- aimodelshare-0.1.59/tests/unit/test_model_training.py +168 -0
- aimodelshare-0.1.59/tests/unit/test_modernization.py +229 -0
- aimodelshare-0.1.59/tests/unit/test_playground_init.py +119 -0
- aimodelshare-0.1.59/tests/unit/test_playground_operations.py +198 -0
- aimodelshare-0.1.59/tests/unit/test_preprocessor_diagnostics.py +140 -0
- aimodelshare-0.1.59/tests/unit/test_preprocessor_validation.py +220 -0
- aimodelshare-0.1.59/tests/unit/test_setup_sanity.py +96 -0
- aimodelshare-0.1.59/tests/unit/test_submit_model_returns.py +130 -0
- aimodelshare-0.1.59/tests/unit/test_transformer_preprocessor.py +247 -0
- aimodelshare-0.1.59/tests/unit/test_utils_imports.py +113 -0
- aimodelshare-0.1.59/validate_modernization.py +194 -0
- aimodelshare-0.1.59/verify_enhancements.py +154 -0
- aimodelshare-0.1.59/verify_preprocessor_diagnostics.py +180 -0
- aimodelshare-0.1.55/LICENSE +0 -2
- aimodelshare-0.1.55/MANIFEST.in +0 -3
- aimodelshare-0.1.55/PKG-INFO +0 -63
- aimodelshare-0.1.55/README.md +0 -27
- aimodelshare-0.1.55/aimodelshare/__init__.py +0 -18
- aimodelshare-0.1.55/aimodelshare.egg-info/PKG-INFO +0 -63
- aimodelshare-0.1.55/aimodelshare.egg-info/requires.txt +0 -12
- aimodelshare-0.1.55/setup.cfg +0 -4
- aimodelshare-0.1.55/setup.py +0 -41
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/README.md +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/aws.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/aws_client.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/bucketpolicy.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/color_mappings/color_mapping_keras.csv +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/color_mappings/color_mapping_pytorch.csv +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/containerization.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/containerization_templates/Dockerfile.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/containerization_templates/Dockerfile_PySpark.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/containerization_templates/buildspec.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/containerization_templates/lambda_function.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/custom_approach/__init__.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/custom_approach/lambda_function.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/custom_eval_metrics.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/data_sharing/__init__.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/data_sharing/data_sharing_templates/Dockerfile.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/data_sharing/data_sharing_templates/__init__.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/data_sharing/data_sharing_templates/buildspec.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/data_sharing/data_sharing_templates/codebuild_policies.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/data_sharing/data_sharing_templates/codebuild_trust_relationship.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/data_sharing/share_data.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/data_sharing/utils.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/deploy_custom_lambda.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/Makefile +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/__init__.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/_version.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/breadcrumbs.html +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/layout.html +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/search.html +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/searchbox.html +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/static/css/custom.css +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/static/css/custom.css.map +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/static/css/theme.css +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/static/css/theme.css.map +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/static/css/theme.min.css +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/static/css/theme.min.css.map +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/static/font/fontello.eot +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/static/font/fontello.svg +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/static/font/fontello.ttf +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/static/font/fontello.woff +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/static/font/fontello.woff2 +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/static/js/theme.js +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/karma_sphinx_theme/theme.conf +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/make.bat +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/requirements.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/about.rst +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/advanced_features.rst +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/competition.rst +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/conf.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/create_credentials.rst +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/example_notebooks.rst +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/functions.rst +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/gettingstarted.rst +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/images/creds1.png +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/images/creds2.png +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/images/creds3.png +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/images/creds4.png +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/images/creds5.png +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/images/creds_file_example.png +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/images/predict_tab.png +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/index.rst +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/documentation/source/modelplayground.rst +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/exceptions.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/iam/codebuild_policy.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/iam/codebuild_trust_relationship.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/iam/lambda_policy.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/iam/lambda_trust_relationship.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/__init__.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/api_json.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/auth/policy.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/auth/role.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/eval/policy.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/eval/role.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/function/policy.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/function/role.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/integration_response.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/lambda_policy_1.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/lambda_policy_2.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/lambda_role_1.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/json_templates/lambda_role_2.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/leaderboard.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/1.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/1B.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/2.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/3.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/4.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/5.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/6.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/7.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/8.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/__init__.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/eval_classification.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/eval_regression.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/lambda_function.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/main/nst.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/placeholders/model.onnx +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/placeholders/preprocessor.zip +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/postprocessormodules.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/1.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/1B.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/2.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/3.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/4.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/5.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/6.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/7.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/8.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/__init__.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/eval_classification.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/eval_regression.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/lambda_function.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/pyspark/nst.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/python/my_preprocessor.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/readme.md +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/sam/Dockerfile.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/sam/Dockerfile_PySpark.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/sam/__init__.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/sam/buildspec.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/sam/codebuild_policies.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/sam/codebuild_trust_relationship.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/sam/codepipeline_policies.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/sam/codepipeline_trust_relationship.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/sam/spark-class.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/sam/template.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/tools.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare/utils.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/aimodelshare.egg-info/dependency_links.txt +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/tests/__init__.py +0 -0
- {aimodelshare-0.1.55 → aimodelshare-0.1.59}/tests/test_playground.py +0 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
name: Test latest master branch aimodelshare
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch: # Manual trigger only
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: master-aimodelshare-tests
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
run-tests:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
timeout-minutes: 120
|
|
17
|
+
|
|
18
|
+
env:
|
|
19
|
+
USERNAME: ${{ secrets.AIMODELSHARE_USERNAME }}
|
|
20
|
+
PASSWORD: ${{ secrets.AIMODELSHARE_PASSWORD }}
|
|
21
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.DATA_AWS_ACCESS_KEY_ID }}
|
|
22
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.DATA_AWS_SECRET_ACCESS_KEY }}
|
|
23
|
+
AWS_REGION: us-east-1
|
|
24
|
+
|
|
25
|
+
steps:
|
|
26
|
+
- name: Checkout repository (master)
|
|
27
|
+
uses: actions/checkout@v4
|
|
28
|
+
with:
|
|
29
|
+
# Uncomment the next line if you want to ALWAYS test master even when dispatching from another ref
|
|
30
|
+
# ref: master
|
|
31
|
+
fetch-depth: 0
|
|
32
|
+
|
|
33
|
+
- name: Show commit being tested
|
|
34
|
+
run: |
|
|
35
|
+
echo "Testing commit:"
|
|
36
|
+
git --no-pager log -1 --oneline
|
|
37
|
+
echo "Current branch (if detached this may be a commit SHA):"
|
|
38
|
+
git branch --show-current || true
|
|
39
|
+
|
|
40
|
+
- name: Set up Python
|
|
41
|
+
uses: actions/setup-python@v5
|
|
42
|
+
with:
|
|
43
|
+
python-version: "3.10"
|
|
44
|
+
cache: "pip"
|
|
45
|
+
|
|
46
|
+
- name: Upgrade pip
|
|
47
|
+
run: |
|
|
48
|
+
python -m pip install --upgrade pip
|
|
49
|
+
|
|
50
|
+
- name: Install local aimodelshare (editable) + test dependencies
|
|
51
|
+
run: |
|
|
52
|
+
pip install boto3 onnx onnxmltools onnxruntime Pympler scikeras shortuuid skl2onnx tf2onnx wget
|
|
53
|
+
pip install -e .
|
|
54
|
+
pip install pytest scikit-learn pandas numpy opencv-python-headless tensorflow pydot regex psutil IPython "PyJWT<2.0" matplotlib seaborn importlib_resources onnxscript
|
|
55
|
+
pip install --index-url https://download.pytorch.org/whl/cpu torch torchvision
|
|
56
|
+
python -c "import aimodelshare, os; print('aimodelshare imported from:', aimodelshare.__file__)"
|
|
57
|
+
|
|
58
|
+
- name: Verify import now points to repository source (not PyPI)
|
|
59
|
+
run: |
|
|
60
|
+
python - <<'PYCODE'
|
|
61
|
+
import aimodelshare, os
|
|
62
|
+
path = aimodelshare.__file__
|
|
63
|
+
print("Resolved aimodelshare.__file__:", path)
|
|
64
|
+
repo_root = os.getcwd()
|
|
65
|
+
assert repo_root in os.path.abspath(path), f"aimodelshare does not appear to come from the checked-out repository root: {repo_root}"
|
|
66
|
+
assert "site-packages" not in path, "aimodelshare should NOT be the PyPI site-packages build."
|
|
67
|
+
print("Verification passed: using local master branch source.")
|
|
68
|
+
PYCODE
|
|
69
|
+
|
|
70
|
+
- name: Run targeted tests against local master branch
|
|
71
|
+
run: |
|
|
72
|
+
echo "Starting pytest for tests/test_playgrounds_nodataimport.py"
|
|
73
|
+
pytest -vv tests/test_aimsonnx.py
|
|
74
|
+
pytest -vv tests/test_playgrounds_nodataimport.py
|
|
75
|
+
|
|
76
|
+
- name: Post-run diagnostics (always runs)
|
|
77
|
+
if: always()
|
|
78
|
+
run: |
|
|
79
|
+
echo "Job conclusion: ${{ job.status }}"
|
|
80
|
+
python - <<'PYCODE'
|
|
81
|
+
import aimodelshare
|
|
82
|
+
print("aimodelshare version attribute (may reflect local dev state):", getattr(aimodelshare, "__version__", "unknown"))
|
|
83
|
+
print("Module file path:", aimodelshare.__file__)
|
|
84
|
+
PYCODE
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
name: Bootstrap Terraform State Resources
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
workflow_call:
|
|
6
|
+
outputs:
|
|
7
|
+
s3_bucket_name:
|
|
8
|
+
description: "Name of the created S3 bucket"
|
|
9
|
+
value: ${{ jobs.bootstrap.outputs.s3_bucket_name }}
|
|
10
|
+
dynamodb_table_name:
|
|
11
|
+
description: "Name of the created DynamoDB table"
|
|
12
|
+
value: ${{ jobs.bootstrap.outputs.dynamodb_table_name }}
|
|
13
|
+
github_actions_role_arn:
|
|
14
|
+
description: "ARN of the created GitHub Actions IAM role"
|
|
15
|
+
value: ${{ jobs.bootstrap.outputs.github_actions_role_arn }}
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
bootstrap:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
|
|
21
|
+
outputs:
|
|
22
|
+
s3_bucket_name: ${{ steps.terraform_output.outputs.s3_bucket_name }}
|
|
23
|
+
dynamodb_table_name: ${{ steps.terraform_output.outputs.dynamodb_table_name }}
|
|
24
|
+
github_actions_role_arn: ${{ steps.terraform_output.outputs.github_actions_role_arn }}
|
|
25
|
+
|
|
26
|
+
permissions:
|
|
27
|
+
contents: read
|
|
28
|
+
|
|
29
|
+
env:
|
|
30
|
+
AWS_REGION: ${{ vars.AWS_REGION || 'us-east-1' }}
|
|
31
|
+
TF_IN_AUTOMATION: "true"
|
|
32
|
+
|
|
33
|
+
steps:
|
|
34
|
+
- name: Checkout
|
|
35
|
+
uses: actions/checkout@v4
|
|
36
|
+
|
|
37
|
+
- name: Setup Terraform
|
|
38
|
+
uses: hashicorp/setup-terraform@v3
|
|
39
|
+
with:
|
|
40
|
+
terraform_version: 1.9.5
|
|
41
|
+
terraform_wrapper: false
|
|
42
|
+
|
|
43
|
+
# Configure AWS credentials using access keys per company policy
|
|
44
|
+
# Note: Requires AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY repository secrets
|
|
45
|
+
# Security: Ensure access keys follow principle of least privilege and key rotation policies
|
|
46
|
+
- name: Configure AWS credentials
|
|
47
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
48
|
+
with:
|
|
49
|
+
aws-access-key-id: ${{ secrets.DATA_AWS_ACCESS_KEY_ID }}
|
|
50
|
+
aws-secret-access-key: ${{ secrets.DATA_AWS_SECRET_ACCESS_KEY }}
|
|
51
|
+
aws-region: ${{ env.AWS_REGION }}
|
|
52
|
+
|
|
53
|
+
- name: Check if resources already exist
|
|
54
|
+
id: check_resources
|
|
55
|
+
working-directory: infra/bootstrap
|
|
56
|
+
run: |
|
|
57
|
+
# Check if S3 bucket exists
|
|
58
|
+
if aws s3api head-bucket --bucket "aimodelshare-tfstate-prod-copilot-2024" 2>/dev/null; then
|
|
59
|
+
echo "s3_exists=true" >> $GITHUB_OUTPUT
|
|
60
|
+
else
|
|
61
|
+
echo "s3_exists=false" >> $GITHUB_OUTPUT
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# Check if DynamoDB table exists
|
|
65
|
+
if aws dynamodb describe-table --table-name "aimodelshare-tf-locks" 2>/dev/null; then
|
|
66
|
+
echo "dynamodb_exists=true" >> $GITHUB_OUTPUT
|
|
67
|
+
else
|
|
68
|
+
echo "dynamodb_exists=false" >> $GITHUB_OUTPUT
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Check if GitHub OIDC provider exists
|
|
72
|
+
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
|
73
|
+
if aws iam get-open-id-connect-provider --open-id-connect-provider-arn "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/token.actions.githubusercontent.com" 2>/dev/null; then
|
|
74
|
+
echo "oidc_provider_exists=true" >> $GITHUB_OUTPUT
|
|
75
|
+
else
|
|
76
|
+
echo "oidc_provider_exists=false" >> $GITHUB_OUTPUT
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# Check if GitHub Actions IAM role exists
|
|
80
|
+
if aws iam get-role --role-name "aimodelshare-github-oidc-deployer" 2>/dev/null; then
|
|
81
|
+
echo "github_role_exists=true" >> $GITHUB_OUTPUT
|
|
82
|
+
else
|
|
83
|
+
echo "github_role_exists=false" >> $GITHUB_OUTPUT
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
- name: Terraform Init
|
|
87
|
+
working-directory: infra/bootstrap
|
|
88
|
+
run: terraform init -input=false
|
|
89
|
+
|
|
90
|
+
- name: Terraform Validate
|
|
91
|
+
working-directory: infra/bootstrap
|
|
92
|
+
run: terraform validate
|
|
93
|
+
|
|
94
|
+
- name: Import existing resources (if they exist)
|
|
95
|
+
working-directory: infra/bootstrap
|
|
96
|
+
if: steps.check_resources.outputs.s3_exists == 'true' || steps.check_resources.outputs.dynamodb_exists == 'true' || steps.check_resources.outputs.oidc_provider_exists == 'true' || steps.check_resources.outputs.github_role_exists == 'true'
|
|
97
|
+
run: |
|
|
98
|
+
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
|
99
|
+
|
|
100
|
+
if [ "${{ steps.check_resources.outputs.s3_exists }}" = "true" ]; then
|
|
101
|
+
echo "Importing existing S3 bucket..."
|
|
102
|
+
terraform import aws_s3_bucket.terraform_state aimodelshare-tfstate-prod-copilot-2024 || true
|
|
103
|
+
terraform import aws_s3_bucket_versioning.terraform_state aimodelshare-tfstate-prod-copilot-2024 || true
|
|
104
|
+
terraform import aws_s3_bucket_server_side_encryption_configuration.terraform_state aimodelshare-tfstate-prod-copilot-2024 || true
|
|
105
|
+
terraform import aws_s3_bucket_public_access_block.terraform_state aimodelshare-tfstate-prod-copilot-2024 || true
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
if [ "${{ steps.check_resources.outputs.dynamodb_exists }}" = "true" ]; then
|
|
109
|
+
echo "Importing existing DynamoDB table..."
|
|
110
|
+
terraform import aws_dynamodb_table.terraform_locks aimodelshare-tf-locks || true
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
if [ "${{ steps.check_resources.outputs.oidc_provider_exists }}" = "true" ]; then
|
|
114
|
+
echo "Importing existing GitHub OIDC provider..."
|
|
115
|
+
terraform import aws_iam_openid_connect_provider.github "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/token.actions.githubusercontent.com" || true
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
if [ "${{ steps.check_resources.outputs.github_role_exists }}" = "true" ]; then
|
|
119
|
+
echo "Importing existing GitHub Actions IAM role..."
|
|
120
|
+
terraform import aws_iam_role.github_actions aimodelshare-github-oidc-deployer || true
|
|
121
|
+
# Also try to import the policy and attachment if they exist
|
|
122
|
+
terraform import aws_iam_policy.github_actions_deployment "arn:aws:iam::${ACCOUNT_ID}:policy/aimodelshare-github-actions-deployment" || true
|
|
123
|
+
terraform import aws_iam_role_policy_attachment.github_actions_deployment aimodelshare-github-oidc-deployer/arn:aws:iam::${ACCOUNT_ID}:policy/aimodelshare-github-actions-deployment || true
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
- name: Terraform Plan
|
|
127
|
+
id: plan
|
|
128
|
+
working-directory: infra/bootstrap
|
|
129
|
+
run: |
|
|
130
|
+
terraform plan -input=false -out=tfplan
|
|
131
|
+
|
|
132
|
+
- name: Terraform Apply
|
|
133
|
+
working-directory: infra/bootstrap
|
|
134
|
+
run: terraform apply -input=false -auto-approve tfplan
|
|
135
|
+
|
|
136
|
+
- name: Get Terraform Outputs
|
|
137
|
+
id: terraform_output
|
|
138
|
+
working-directory: infra/bootstrap
|
|
139
|
+
run: |
|
|
140
|
+
S3_BUCKET=$(terraform output -raw s3_bucket_name)
|
|
141
|
+
DYNAMODB_TABLE=$(terraform output -raw dynamodb_table_name)
|
|
142
|
+
GITHUB_ROLE_ARN=$(terraform output -raw github_actions_role_arn)
|
|
143
|
+
echo "s3_bucket_name=$S3_BUCKET" >> $GITHUB_OUTPUT
|
|
144
|
+
echo "dynamodb_table_name=$DYNAMODB_TABLE" >> $GITHUB_OUTPUT
|
|
145
|
+
echo "github_actions_role_arn=$GITHUB_ROLE_ARN" >> $GITHUB_OUTPUT
|
|
146
|
+
echo "✅ Bootstrap completed successfully!"
|
|
147
|
+
echo " S3 Bucket: $S3_BUCKET"
|
|
148
|
+
echo " DynamoDB Table: $DYNAMODB_TABLE"
|
|
149
|
+
echo " GitHub Actions Role ARN: $GITHUB_ROLE_ARN"
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
name: Deploy Infra (Terraform Workspaces)
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master ]
|
|
6
|
+
paths:
|
|
7
|
+
- 'infra/**'
|
|
8
|
+
- 'aimodelshare/moral_compass/**'
|
|
9
|
+
- '.github/workflows/deploy-infra.yml'
|
|
10
|
+
- '.github/workflows/bootstrap-terraform.yml'
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
bootstrap:
|
|
15
|
+
uses: ./.github/workflows/bootstrap-terraform.yml
|
|
16
|
+
secrets: inherit
|
|
17
|
+
|
|
18
|
+
deploy:
|
|
19
|
+
needs: bootstrap
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
|
|
22
|
+
strategy:
|
|
23
|
+
matrix:
|
|
24
|
+
env: [dev]
|
|
25
|
+
|
|
26
|
+
permissions:
|
|
27
|
+
contents: read
|
|
28
|
+
|
|
29
|
+
env:
|
|
30
|
+
AWS_REGION: ${{ vars.AWS_REGION || 'us-east-1' }}
|
|
31
|
+
TF_IN_AUTOMATION: "true"
|
|
32
|
+
|
|
33
|
+
steps:
|
|
34
|
+
- name: Checkout
|
|
35
|
+
uses: actions/checkout@v4
|
|
36
|
+
|
|
37
|
+
- name: Setup Terraform
|
|
38
|
+
uses: hashicorp/setup-terraform@v3
|
|
39
|
+
with:
|
|
40
|
+
terraform_version: 1.9.5
|
|
41
|
+
|
|
42
|
+
- name: Configure AWS credentials
|
|
43
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
44
|
+
with:
|
|
45
|
+
aws-access-key-id: ${{ secrets.DATA_AWS_ACCESS_KEY_ID }}
|
|
46
|
+
aws-secret-access-key: ${{ secrets.DATA_AWS_SECRET_ACCESS_KEY }}
|
|
47
|
+
aws-region: ${{ env.AWS_REGION }}
|
|
48
|
+
|
|
49
|
+
- name: (Optional) Build Lambda Layer
|
|
50
|
+
working-directory: infra/layer
|
|
51
|
+
run: |
|
|
52
|
+
if [ -f requirements.txt ]; then
|
|
53
|
+
bash build_layer.sh || true
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
- name: Terraform Init
|
|
57
|
+
working-directory: infra
|
|
58
|
+
run: terraform init -input=false
|
|
59
|
+
|
|
60
|
+
- name: Select/Create Workspace
|
|
61
|
+
working-directory: infra
|
|
62
|
+
run: |
|
|
63
|
+
set -euo pipefail
|
|
64
|
+
|
|
65
|
+
WS="${{ matrix.env }}"
|
|
66
|
+
echo "Ensuring Terraform workspace '${WS}' exists..."
|
|
67
|
+
if terraform workspace list | sed 's/^[* ]*//' | grep -Fxq "$WS"; then
|
|
68
|
+
echo "Selecting existing workspace: $WS"
|
|
69
|
+
terraform workspace select "$WS"
|
|
70
|
+
else
|
|
71
|
+
echo "Creating new workspace: $WS"
|
|
72
|
+
terraform workspace new "$WS"
|
|
73
|
+
fi
|
|
74
|
+
echo "Current workspace: $(terraform workspace show)"
|
|
75
|
+
|
|
76
|
+
if [ ! -d .terraform ]; then
|
|
77
|
+
echo "Terraform not initialized yet; running 'terraform init'..."
|
|
78
|
+
terraform init -input=false
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
STATE_KEY="env:/${WS}/aimodelshare/infra/terraform.tfstate"
|
|
82
|
+
echo "Checking if remote state object exists: ${STATE_KEY}"
|
|
83
|
+
if aws s3api head-object --bucket "aimodelshare-tfstate-prod-copilot-2024" --key "${STATE_KEY}" >/dev/null 2>&1; then
|
|
84
|
+
echo "Remote state object exists for workspace '${WS}'"
|
|
85
|
+
else
|
|
86
|
+
echo "Remote state object missing for workspace '${WS}' - creating initial state"
|
|
87
|
+
terraform apply -auto-approve -target=null_resource.state_seed
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
echo "Workspace '$WS' ready; proceeding to plan/apply steps."
|
|
91
|
+
|
|
92
|
+
- name: Terraform Validate
|
|
93
|
+
working-directory: infra
|
|
94
|
+
run: terraform validate
|
|
95
|
+
|
|
96
|
+
- name: Terraform Plan
|
|
97
|
+
id: plan
|
|
98
|
+
working-directory: infra
|
|
99
|
+
run: terraform plan -input=false -out=tfplan
|
|
100
|
+
|
|
101
|
+
- name: Terraform Apply
|
|
102
|
+
if: github.ref == 'refs/heads/master'
|
|
103
|
+
working-directory: infra
|
|
104
|
+
run: terraform apply -input=false -auto-approve tfplan
|
|
105
|
+
|
|
106
|
+
- name: Show Outputs
|
|
107
|
+
working-directory: infra
|
|
108
|
+
run: terraform output -json
|
|
109
|
+
|
|
110
|
+
- name: Wait for DynamoDB GSI readiness
|
|
111
|
+
if: github.ref == 'refs/heads/master'
|
|
112
|
+
working-directory: infra
|
|
113
|
+
run: |
|
|
114
|
+
TABLE_NAME=$(terraform output -raw dynamodb_table_name)
|
|
115
|
+
echo "Waiting for GSI 'byUser' on table $TABLE_NAME to become ACTIVE..."
|
|
116
|
+
ATTEMPTS=0
|
|
117
|
+
MAX_ATTEMPTS=30
|
|
118
|
+
SLEEP_SECONDS=5
|
|
119
|
+
while true; do
|
|
120
|
+
STATUS=$(aws dynamodb describe-table --table-name "$TABLE_NAME" \
|
|
121
|
+
--query "Table.GlobalSecondaryIndexes[?IndexName=='byUser'].IndexStatus" --output text 2>/dev/null || echo "UNKNOWN")
|
|
122
|
+
if [ "$STATUS" = "ACTIVE" ]; then
|
|
123
|
+
echo "GSI 'byUser' is ACTIVE."
|
|
124
|
+
break
|
|
125
|
+
fi
|
|
126
|
+
ATTEMPTS=$((ATTEMPTS+1))
|
|
127
|
+
if [ $ATTEMPTS -ge $MAX_ATTEMPTS ]; then
|
|
128
|
+
echo "Timeout waiting for GSI 'byUser' to become ACTIVE (last status: $STATUS)"
|
|
129
|
+
exit 1
|
|
130
|
+
fi
|
|
131
|
+
echo "Attempt $ATTEMPTS/$MAX_ATTEMPTS: status=$STATUS; sleeping $SLEEP_SECONDS s..."
|
|
132
|
+
sleep $SLEEP_SECONDS
|
|
133
|
+
done
|
|
134
|
+
|
|
135
|
+
- name: Cache Terraform Outputs
|
|
136
|
+
if: github.ref == 'refs/heads/master'
|
|
137
|
+
working-directory: .
|
|
138
|
+
run: |
|
|
139
|
+
bash scripts/cache_terraform_outputs.sh
|
|
140
|
+
|
|
141
|
+
- name: Verify API Health Endpoint
|
|
142
|
+
if: github.ref == 'refs/heads/master'
|
|
143
|
+
working-directory: .
|
|
144
|
+
run: |
|
|
145
|
+
bash scripts/verify_api_reachable.sh
|
|
146
|
+
|
|
147
|
+
- name: Install Package in Editable Mode
|
|
148
|
+
if: github.ref == 'refs/heads/master'
|
|
149
|
+
working-directory: .
|
|
150
|
+
run: |
|
|
151
|
+
python -m pip install --upgrade pip
|
|
152
|
+
python -m pip install -e .
|
|
153
|
+
|
|
154
|
+
- name: Run moral_compass Integration Tests
|
|
155
|
+
if: github.ref == 'refs/heads/master'
|
|
156
|
+
working-directory: .
|
|
157
|
+
run: |
|
|
158
|
+
python -m pip install pytest
|
|
159
|
+
pytest -m integration tests/test_moral_compass_client_minimal.py -v
|
|
160
|
+
|
|
161
|
+
- name: Run API Integration Tests
|
|
162
|
+
if: github.ref == 'refs/heads/master'
|
|
163
|
+
working-directory: .
|
|
164
|
+
run: |
|
|
165
|
+
API_BASE_URL=$(cd infra && terraform output -raw api_base_url)
|
|
166
|
+
echo "API Base URL: $API_BASE_URL"
|
|
167
|
+
|
|
168
|
+
if [[ -z "$API_BASE_URL" || "$API_BASE_URL" == "null" ]]; then
|
|
169
|
+
echo "❌ Failed to get API base URL from Terraform outputs"
|
|
170
|
+
exit 1
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
python -m pip install --upgrade pip
|
|
174
|
+
python -m pip install requests
|
|
175
|
+
|
|
176
|
+
echo "⏳ Extra stabilization wait (30s) after GSI readiness..."
|
|
177
|
+
sleep 30
|
|
178
|
+
|
|
179
|
+
echo "🚀 Starting API Integration Tests..."
|
|
180
|
+
python tests/test_api_integration.py "$API_BASE_URL"
|
|
181
|
+
|
|
182
|
+
- name: Run Pagination Tests
|
|
183
|
+
if: github.ref == 'refs/heads/master'
|
|
184
|
+
working-directory: .
|
|
185
|
+
run: |
|
|
186
|
+
API_BASE_URL=$(cd infra && terraform output -raw api_base_url)
|
|
187
|
+
echo "API Base URL: $API_BASE_URL"
|
|
188
|
+
python -m pip install requests
|
|
189
|
+
python tests/test_api_pagination.py "$API_BASE_URL"
|
|
190
|
+
|
|
191
|
+
- name: Install Load Test Dependencies
|
|
192
|
+
if: github.ref == 'refs/heads/master' && (vars.RUN_LOAD_TESTS != 'false')
|
|
193
|
+
working-directory: .
|
|
194
|
+
run: |
|
|
195
|
+
python -m pip install aiohttp rich
|
|
196
|
+
|
|
197
|
+
- name: Run Load Tests - Single Table
|
|
198
|
+
if: github.ref == 'refs/heads/master' && (vars.RUN_LOAD_TESTS != 'false')
|
|
199
|
+
working-directory: .
|
|
200
|
+
run: |
|
|
201
|
+
API_BASE_URL=$(cd infra && terraform output -raw api_base_url)
|
|
202
|
+
export API_BASE_URL
|
|
203
|
+
echo "🚀 Running Single Table Load Test..."
|
|
204
|
+
python tests/load_single_table.py
|
|
205
|
+
|
|
206
|
+
- name: Run Load Tests - Multi Table
|
|
207
|
+
if: github.ref == 'refs/heads/master' && (vars.RUN_LOAD_TESTS != 'false')
|
|
208
|
+
working-directory: .
|
|
209
|
+
run: |
|
|
210
|
+
API_BASE_URL=$(cd infra && terraform output -raw api_base_url)
|
|
211
|
+
export API_BASE_URL
|
|
212
|
+
echo "🚀 Running Multi Table Load Test..."
|
|
213
|
+
python tests/load_multi_table.py
|
|
214
|
+
|
|
215
|
+
- name: Run Load Tests - Mixed Duration
|
|
216
|
+
if: github.ref == 'refs/heads/master' && (vars.RUN_LOAD_TESTS != 'false')
|
|
217
|
+
working-directory: .
|
|
218
|
+
env:
|
|
219
|
+
LOAD_DURATION_SECONDS: 20
|
|
220
|
+
run: |
|
|
221
|
+
API_BASE_URL=$(cd infra && terraform output -raw api_base_url)
|
|
222
|
+
export API_BASE_URL
|
|
223
|
+
echo "🚀 Running Mixed Duration Load Test (20s for CI)..."
|
|
224
|
+
python tests/load_mixed_duration.py
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
name: Destroy Infra (Terraform, OIDC, Workspaces)
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
environment:
|
|
7
|
+
description: 'Workspace to destroy (dev|stage|prod)'
|
|
8
|
+
required: true
|
|
9
|
+
default: 'dev'
|
|
10
|
+
destroy_bootstrap:
|
|
11
|
+
description: 'Also destroy bootstrap resources (S3 bucket and DynamoDB table) - USE WITH EXTREME CAUTION'
|
|
12
|
+
required: false
|
|
13
|
+
default: false
|
|
14
|
+
type: boolean
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
destroy:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
|
|
20
|
+
permissions:
|
|
21
|
+
contents: read
|
|
22
|
+
|
|
23
|
+
env:
|
|
24
|
+
AWS_REGION: ${{ vars.AWS_REGION || 'us-east-1' }}
|
|
25
|
+
TF_IN_AUTOMATION: "true"
|
|
26
|
+
|
|
27
|
+
steps:
|
|
28
|
+
- name: Checkout
|
|
29
|
+
uses: actions/checkout@v4
|
|
30
|
+
|
|
31
|
+
- name: Setup Terraform
|
|
32
|
+
uses: hashicorp/setup-terraform@v3
|
|
33
|
+
with:
|
|
34
|
+
terraform_version: 1.9.5
|
|
35
|
+
terraform_wrapper: false
|
|
36
|
+
|
|
37
|
+
# Configure AWS credentials using access keys per company policy
|
|
38
|
+
# Note: Requires AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY repository secrets
|
|
39
|
+
# Security: Ensure access keys follow principle of least privilege and key rotation policies
|
|
40
|
+
- name: Configure AWS credentials
|
|
41
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
42
|
+
with:
|
|
43
|
+
aws-access-key-id: ${{ secrets.DATA_AWS_ACCESS_KEY_ID }}
|
|
44
|
+
aws-secret-access-key: ${{ secrets.DATA_AWS_SECRET_ACCESS_KEY }}
|
|
45
|
+
aws-region: ${{ env.AWS_REGION }}
|
|
46
|
+
|
|
47
|
+
- name: Terraform Init (Main Infrastructure)
|
|
48
|
+
working-directory: infra
|
|
49
|
+
run: terraform init -input=false
|
|
50
|
+
|
|
51
|
+
- name: Select Workspace and Validate
|
|
52
|
+
working-directory: infra
|
|
53
|
+
run: |
|
|
54
|
+
set -euo pipefail
|
|
55
|
+
|
|
56
|
+
WS="${{ github.event.inputs.environment }}"
|
|
57
|
+
echo "Checking for existing Terraform workspace '${WS}'..."
|
|
58
|
+
|
|
59
|
+
# Verify backend is initialized
|
|
60
|
+
if [ ! -d .terraform ]; then
|
|
61
|
+
echo "Terraform not initialized yet; running 'terraform init'..."
|
|
62
|
+
terraform init -input=false
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Check if workspace exists - abort if not (don't create for destroy)
|
|
66
|
+
if terraform workspace list | sed 's/^[* ]*//' | grep -Fxq "$WS"; then
|
|
67
|
+
echo "Selecting existing workspace: $WS"
|
|
68
|
+
terraform workspace select "$WS"
|
|
69
|
+
else
|
|
70
|
+
echo "❌ ERROR: Workspace '$WS' does not exist. Cannot destroy non-existent workspace."
|
|
71
|
+
echo "Available workspaces:"
|
|
72
|
+
terraform workspace list
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
echo "✅ Workspace '$WS' validated and selected."
|
|
77
|
+
|
|
78
|
+
- name: Terraform Destroy Plan
|
|
79
|
+
working-directory: infra
|
|
80
|
+
run: |
|
|
81
|
+
echo "🔍 Generating destroy plan for audit..."
|
|
82
|
+
terraform plan -destroy -input=false -out=destroy.tfplan
|
|
83
|
+
echo "✅ Destroy plan generated. Proceeding with destroy..."
|
|
84
|
+
|
|
85
|
+
- name: Terraform Destroy (Main Infrastructure)
|
|
86
|
+
working-directory: infra
|
|
87
|
+
run: terraform destroy -input=false -auto-approve
|
|
88
|
+
|
|
89
|
+
- name: Destroy Bootstrap Resources
|
|
90
|
+
if: github.event.inputs.destroy_bootstrap == 'true'
|
|
91
|
+
working-directory: infra/bootstrap
|
|
92
|
+
run: |
|
|
93
|
+
echo "⚠️ WARNING: Destroying bootstrap resources (S3 bucket and DynamoDB table)"
|
|
94
|
+
echo "This will remove the Terraform state storage and could cause data loss!"
|
|
95
|
+
|
|
96
|
+
# Initialize bootstrap Terraform
|
|
97
|
+
terraform init -input=false
|
|
98
|
+
|
|
99
|
+
# Check if state bucket is empty (except for our state files)
|
|
100
|
+
BUCKET_NAME="aimodelshare-tfstate-prod-copilot-2024"
|
|
101
|
+
OBJECT_COUNT=$(aws s3api list-objects-v2 --bucket "$BUCKET_NAME" --query 'Contents | length(@)' --output text 2>/dev/null || echo "0")
|
|
102
|
+
|
|
103
|
+
# AWS CLI returns 'None' for empty buckets, 'null' if bucket doesn't exist, or a number for non-empty buckets
|
|
104
|
+
if [[ "$OBJECT_COUNT" =~ ^[0-9]+$ ]] && [ "$OBJECT_COUNT" -gt 0 ]; then
|
|
105
|
+
echo "⚠️ S3 bucket contains $OBJECT_COUNT objects. Emptying bucket first..."
|
|
106
|
+
aws s3 rm s3://$BUCKET_NAME --recursive
|
|
107
|
+
else
|
|
108
|
+
echo "✅ S3 bucket is empty or doesn't exist (count: $OBJECT_COUNT), proceeding with destroy..."
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
# Destroy bootstrap resources
|
|
112
|
+
terraform destroy -input=false -auto-approve
|
|
113
|
+
|
|
114
|
+
echo "✅ Bootstrap resources destroyed"
|