launchable 1.76.3__tar.gz → 1.78.0__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.
- launchable-1.78.0/.github/workflows/bazel-test.yml +34 -0
- {launchable-1.76.3 → launchable-1.78.0}/.github/workflows/e2e.yml +1 -1
- {launchable-1.76.3 → launchable-1.78.0}/.github/workflows/python-package.yml +13 -6
- {launchable-1.76.3 → launchable-1.78.0}/.github/workflows/python-publish.yml +4 -4
- {launchable-1.76.3 → launchable-1.78.0}/PKG-INFO +1 -1
- {launchable-1.76.3 → launchable-1.78.0}/Pipfile +3 -5
- {launchable-1.76.3 → launchable-1.78.0}/WORKSPACE +3 -3
- launchable-1.78.0/launchable/commands/record/build.py +356 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable.egg-info/PKG-INFO +1 -1
- {launchable-1.76.3 → launchable-1.78.0}/launchable.egg-info/SOURCES.txt +2 -1
- launchable-1.78.0/renovate.json +6 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/cli_test_case.py +3 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/record/test_build.py +10 -12
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/test_api_error.py +3 -3
- launchable-1.76.3/.github/workflows/publicize-doc-change.yml +0 -22
- launchable-1.76.3/launchable/commands/record/build.py +0 -319
- {launchable-1.76.3 → launchable-1.78.0}/.bazelrc +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/.bazelversion +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/.editorconfig +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/.github/release.yml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/.gitignore +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/.pre-commit-config.yaml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/.python-version +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/.tagpr +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/CONTRIBUTING.md +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/Dockerfile +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/LICENSE.txt +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/README.md +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/__main__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/helper.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/inspect/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/inspect/subset.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/inspect/tests.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/record/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/record/attachment.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/record/case_event.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/record/commit.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/record/session.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/record/tests.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/split_subset.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/stats/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/stats/test_sessions.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/subset.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/test_path_writer.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/commands/verify.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/jar/exe_deploy.jar +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/plugins/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/adb.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/ant.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/bazel.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/behave.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/ctest.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/cts.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/cucumber.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/cypress.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/dotnet.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/file.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/go_test.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/googletest.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/gradle.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/jest.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/launchable.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/maven.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/minitest.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/nunit.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/prove.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/pytest.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/raw.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/robot.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/test_runners/rspec.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/testpath.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/authentication.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/ci_provider.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/click.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/commit_ingester.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/env_keys.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/exceptions.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/file_name_pattern.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/git_log_parser.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/glob.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/gzipgen.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/http_client.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/java.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/key_value_type.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/launchable_client.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/link.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/logger.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/no_build.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/sax.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/session.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/subprocess.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/utils/tracking.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable/version.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable.egg-info/dependency_links.txt +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable.egg-info/entry_points.txt +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable.egg-info/requires.txt +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/launchable.egg-info/top_level.txt +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/pyproject.toml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/setup.cfg +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/setup.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/BUILD +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/main/java/com/launchableinc/ingest/commits/Authenticator.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/main/java/com/launchableinc/ingest/commits/BUILD +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/main/java/com/launchableinc/ingest/commits/CommitGraphCollector.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/main/java/com/launchableinc/ingest/commits/CommitIngester.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/main/java/com/launchableinc/ingest/commits/CountingDiffFormatter.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/main/java/com/launchableinc/ingest/commits/GitHubActionsAuthenticator.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/main/java/com/launchableinc/ingest/commits/GitHubIdTokenAuthenticator.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/main/java/com/launchableinc/ingest/commits/JSCommit.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/main/java/com/launchableinc/ingest/commits/JSFileChange.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/main/java/com/launchableinc/ingest/commits/TokenAuthenticator.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/maven_install.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/test/java/com/launchableinc/ingest/commits/BUILD +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/test/java/com/launchableinc/ingest/commits/CommitGraphCollectorTest.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/src/test/java/com/launchableinc/ingest/commits/CommitIngesterTest.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/test-runner/__main__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/inspect/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/inspect/test_subset.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/inspect/test_tests.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/record/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/record/test_attachment.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/record/test_commit.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/record/test_session.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/record/test_tests.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/test_helper.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/test_split_subset.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/test_subset.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/commands/test_verify.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/adb/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ant/junitreport/TEST-com.launchable.HelloWorldTest.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ant/junitreport/TEST-com.launchable.library.CacheTest.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ant/junitreport/TESTS-TestSuites.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ant/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ant/src/com/launchable/HelloWorld.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ant/src/com/launchable/HelloWorldTest.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ant/src/com/launchable/library/Cache.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ant/src/com/launchable/library/CacheTest.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ant/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test1/test.cache_status +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test1/test.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test2/test.cache_status +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test2/test.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test3/test.cache_status +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test3/test.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test4/test.cache_status +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test4/test.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test5/test.cache_status +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test5/test.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test6/test.cache_status +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test6/test.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test7/test.cache_status +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test7/test.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test8/test.cache_status +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test8/test.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test9/test.cache_status +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test9/test.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/build_event.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/build_event_rest.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/record_test_with_build_event_json_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/record_test_with_multiple_build_event_json_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/bazel/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/behave/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/behave/reports/report.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/behave/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/broken_xml/broken.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/broken_xml/normal.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ctest/Testing/latest/Test.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ctest/ctest_list.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ctest/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/ctest/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cts/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cts/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cts/test_result.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cucumber/features/foo/bar.feature +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cucumber/features/foo/is_it_friday_yet.feature +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cucumber/features/foo-bar.feature +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cucumber/features/is_it_friday_yet.feature +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cucumber/record_test_json_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cucumber/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cucumber/report/TEST-features-foo-bar.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cucumber/report/TEST-features-foo-is_it_friday_yet.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cucumber/report/TEST-features-is_it_friday_yet.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cucumber/report/dummy.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cucumber/report/result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cypress/empty.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cypress/empty.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cypress/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cypress/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/cypress/test-result.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/dotnet/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/dotnet/test-result.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/git_log_ingest/sample.out +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/go_test/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/go_test/reportv1/reportv1.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/go_test/reportv2/reportv2.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/go_test/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/googletest/fail/output.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/googletest/fail/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/googletest/output_a.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/googletest/output_b.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/googletest/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/googletest/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/gradle/java/app/src/test/java/com/launchableinc/rocket_car_gradle/App2Test.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/gradle/java/app/src/test/java/com/launchableinc/rocket_car_gradle/AppTest.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/gradle/java/app/src/test/java/com/launchableinc/rocket_car_gradle/sub/App3Test.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/gradle/recursion/expected.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/gradle/recursion/foo/bar/reports/1.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/jest/junit.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/jest/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/jest/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/createdFile_1.lst +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/createdFile_2.lst +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/java/test/src/java/com/launchableinc/rocket_car_maven/App2Test.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/java/test/src/java/com/launchableinc/rocket_car_maven/AppTest.java +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/list.lst +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/reports/TEST-1.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/reports/TEST-2.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/reports/dummy.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/subset_by_absolute_time_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/subset_by_confidence_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/subset_from_file_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/maven/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/minitest/TEST-Admin_UserTest.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/minitest/TEST-Admin_UserTest_ChildlenTest.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/minitest/TEST-UserControllerTest.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/minitest/TEST-UserCopyTest.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/minitest/TEST-UserTest.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/minitest/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/minitest/record_test_result_chunk1.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/minitest/record_test_result_chunk2.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/minitest/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/minitest/test/example_test.rb +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/list.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/nunit-reporter-bug-with-nested-type.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/nunit-reporter-bug-with-nested-type.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/output-linux.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/output-windows.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/record_test_result-linux.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/record_test_result-windows.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/src/.gitignore +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/src/Program.cs +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/src/README.md +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/src/Test.cs +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/src/calc.csproj +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/nunit/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/prove/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/prove/report.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/pytest/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/pytest/record_test_result_json.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/pytest/report.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/pytest/report.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/pytest/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/pytest/tests/conftest.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/pytest/tests/fooo/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/pytest/tests/fooo/filenameonly_test.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/pytest/tests/fooo/func4_test.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/pytest/tests/funcs3_test.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/pytest/tests/test_funcs1.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/pytest/tests/test_funcs2.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/robot/dryrun.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/robot/output.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/robot/record_test_executed_only_one_file_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/robot/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/robot/single-output.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/robot/subset_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/rspec/record_test_result.json +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/data/rspec/rspec.xml +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/helper.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/plugins/foo.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_plugin.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_adb.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_ant.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_bazel.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_behave.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_ctest.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_cts.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_cucumber.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_cypress.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_dotnet.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_go_test.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_googletest.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_gradle.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_jest.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_maven.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_minitest.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_nunit.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_prove.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_pytest.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_raw.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_robot.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_runners/test_rspec.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_session.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_testpath.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/test_version.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/utils/__init__.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/utils/test_authentication.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/utils/test_click.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/utils/test_file_name_pattern.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/utils/test_git_log_parser.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/utils/test_glob.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/utils/test_gzipgen.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/utils/test_http_client.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/utils/test_key_value_type.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/utils/test_link.py +0 -0
- {launchable-1.76.3 → launchable-1.78.0}/tests/utils/test_logger.py +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Bazel test
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- main
|
|
6
|
+
paths:
|
|
7
|
+
- 'WORKSPACE'
|
|
8
|
+
- 'src/**'
|
|
9
|
+
- '!src/**.md'
|
|
10
|
+
pull_request:
|
|
11
|
+
paths:
|
|
12
|
+
- 'WORKSPACE'
|
|
13
|
+
- 'src/**'
|
|
14
|
+
- '!src/**.md'
|
|
15
|
+
jobs:
|
|
16
|
+
test:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
20
|
+
- name: Set up JDK 8
|
|
21
|
+
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0
|
|
22
|
+
with:
|
|
23
|
+
distribution: temurin
|
|
24
|
+
java-version: '8'
|
|
25
|
+
- name: Setup Bazel
|
|
26
|
+
uses: bazelbuild/setup-bazelisk@95c9bf48d0c570bb3e28e57108f3450cd67c1a44 # v2.0.0
|
|
27
|
+
- name: Cache Bazel outputs
|
|
28
|
+
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
|
29
|
+
with:
|
|
30
|
+
path: "~/.cache/bazel"
|
|
31
|
+
key: bazel
|
|
32
|
+
- name: Run Bazel test
|
|
33
|
+
run: |
|
|
34
|
+
bazel test //...
|
|
@@ -7,8 +7,14 @@ on:
|
|
|
7
7
|
workflow_dispatch:
|
|
8
8
|
push:
|
|
9
9
|
branches: [ main ]
|
|
10
|
+
paths-ignore:
|
|
11
|
+
- 'WORKSPACE'
|
|
12
|
+
- 'src/**'
|
|
10
13
|
pull_request:
|
|
11
14
|
branches: [ main ]
|
|
15
|
+
paths-ignore:
|
|
16
|
+
- 'WORKSPACE'
|
|
17
|
+
- 'src/**'
|
|
12
18
|
schedule:
|
|
13
19
|
# This job runs at 00:00 JST every day.
|
|
14
20
|
- cron: '0 9 * * *'
|
|
@@ -16,8 +22,8 @@ on:
|
|
|
16
22
|
env:
|
|
17
23
|
LAUNCHABLE_ORGANIZATION: "launchableinc"
|
|
18
24
|
LAUNCHABLE_WORKSPACE: "cli"
|
|
19
|
-
EXPERIMENTAL_GITHUB_OIDC_TOKEN_AUTH: 1
|
|
20
25
|
GITHUB_PULL_REQUEST_URL: ${{ github.event.pull_request.html_url }}
|
|
26
|
+
GITHUB_PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
21
27
|
|
|
22
28
|
permissions:
|
|
23
29
|
id-token: write
|
|
@@ -30,20 +36,21 @@ jobs:
|
|
|
30
36
|
strategy:
|
|
31
37
|
matrix:
|
|
32
38
|
os: [ubuntu-20.04, windows-latest]
|
|
33
|
-
python-version: [3.6, 3.7, 3.8, 3.9, "3.10"]
|
|
39
|
+
python-version: [3.6, 3.7, 3.8, 3.9, "3.10", "3.11", "3.12"]
|
|
34
40
|
|
|
35
41
|
steps:
|
|
36
|
-
- uses: actions/checkout@
|
|
42
|
+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
37
43
|
with:
|
|
38
44
|
fetch-depth: 0
|
|
39
45
|
- name: Set up Python ${{ matrix.python-version }}
|
|
40
|
-
uses: actions/setup-python@
|
|
46
|
+
uses: actions/setup-python@v5
|
|
41
47
|
with:
|
|
42
48
|
python-version: ${{ matrix.python-version }}
|
|
43
49
|
- name: Set up JDK 1.8
|
|
44
|
-
uses: actions/setup-java@
|
|
50
|
+
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
|
|
45
51
|
with:
|
|
46
|
-
java-version:
|
|
52
|
+
java-version: 8
|
|
53
|
+
distribution: 'temurin'
|
|
47
54
|
- name: Install specific dependencies in 3.6
|
|
48
55
|
if: matrix.python-version == '3.6'
|
|
49
56
|
uses: nick-fields/retry@14672906e672a08bd6eeb15720e9ed3ce869cdd4 # v2.9.0
|
|
@@ -19,9 +19,9 @@ jobs:
|
|
|
19
19
|
outputs:
|
|
20
20
|
tag: ${{ steps.run-tagpr.outputs.tag }}
|
|
21
21
|
steps:
|
|
22
|
-
- uses: actions/checkout@
|
|
22
|
+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
23
23
|
- id: run-tagpr
|
|
24
|
-
uses: Songmu/tagpr@
|
|
24
|
+
uses: Songmu/tagpr@d240cfd0ec8d697b1f19b4b67b0b52c151214f45 # v1.1.4
|
|
25
25
|
env:
|
|
26
26
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
27
27
|
|
|
@@ -36,7 +36,7 @@ jobs:
|
|
|
36
36
|
with:
|
|
37
37
|
fetch-depth: 0
|
|
38
38
|
- name: Set up Python
|
|
39
|
-
uses: actions/setup-python@
|
|
39
|
+
uses: actions/setup-python@v5
|
|
40
40
|
with:
|
|
41
41
|
python-version: '3.x'
|
|
42
42
|
# build and publish package using GitHub Actions workflow
|
|
@@ -62,7 +62,7 @@ jobs:
|
|
|
62
62
|
user: __token__
|
|
63
63
|
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
64
64
|
- name: Actions for Discord
|
|
65
|
-
uses: Ilshidur/action-discord@0.3.
|
|
65
|
+
uses: Ilshidur/action-discord@0.3.2
|
|
66
66
|
env:
|
|
67
67
|
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
|
68
68
|
with:
|
|
@@ -14,10 +14,10 @@ wheel = "*"
|
|
|
14
14
|
# The last flake8 version that supports Python 3.6 specifies "pycodestyle >=
|
|
15
15
|
# 2.9.0, < 2.10.0". ref: https://github.com/PyCQA/flake8/pull/1633
|
|
16
16
|
# The latest autopep8 specifies "pycodestyle >= 2.10.0". This conflict cannot be resolved. Pin the version to resolve this.
|
|
17
|
-
autopep8 = "<=1.
|
|
17
|
+
autopep8 = "<=1.7.0"
|
|
18
18
|
importlib-metadata = "<5.0"
|
|
19
19
|
isort = "*"
|
|
20
|
-
more_itertools = "<8.
|
|
20
|
+
more_itertools = "<8.15"
|
|
21
21
|
mypy = "*"
|
|
22
22
|
pre-commit = "*"
|
|
23
23
|
responses = "*"
|
|
@@ -26,9 +26,7 @@ types-pkg_resources = "*"
|
|
|
26
26
|
types-python-dateutil = "*"
|
|
27
27
|
types-requests = "*"
|
|
28
28
|
types-tabulate = "*"
|
|
29
|
-
|
|
30
|
-
# ref: https://github.com/launchableinc/cli/actions/runs/3691265723
|
|
31
|
-
lxml = "<=4.9.1"
|
|
29
|
+
lxml = "<=4.9.4"
|
|
32
30
|
unittest-xml-reporting = "*"
|
|
33
31
|
|
|
34
32
|
[packages]
|
|
@@ -19,7 +19,7 @@ maven_install(
|
|
|
19
19
|
"com.fasterxml.jackson.core:jackson-core:2.13.3",
|
|
20
20
|
"com.fasterxml.jackson.core:jackson-databind:2.13.3",
|
|
21
21
|
"com.google.guava:guava:31.1-jre",
|
|
22
|
-
"org.apache.httpcomponents:httpclient:4.5.
|
|
22
|
+
"org.apache.httpcomponents:httpclient:4.5.14",
|
|
23
23
|
# This is the last release that produce Java 8 class files.
|
|
24
24
|
"org.eclipse.jgit:org.eclipse.jgit:5.13.1.202206130422-r",
|
|
25
25
|
"org.slf4j:slf4j-api:1.7.36",
|
|
@@ -27,7 +27,7 @@ maven_install(
|
|
|
27
27
|
testonly = 1,
|
|
28
28
|
artifact = "mockserver-junit-rule-no-dependencies",
|
|
29
29
|
group = "org.mock-server",
|
|
30
|
-
version = "5.
|
|
30
|
+
version = "5.15.0",
|
|
31
31
|
),
|
|
32
32
|
maven.artifact(
|
|
33
33
|
testonly = 1,
|
|
@@ -39,7 +39,7 @@ maven_install(
|
|
|
39
39
|
testonly = 1,
|
|
40
40
|
artifact = "truth",
|
|
41
41
|
group = "com.google.truth",
|
|
42
|
-
version = "1.
|
|
42
|
+
version = "1.2.0",
|
|
43
43
|
),
|
|
44
44
|
],
|
|
45
45
|
maven_install_json = "//src:maven_install.json",
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
import sys
|
|
4
|
+
from typing import Dict, List, Optional
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
from tabulate import tabulate
|
|
8
|
+
|
|
9
|
+
from launchable.utils.key_value_type import normalize_key_value_types
|
|
10
|
+
from launchable.utils.link import CIRCLECI_KEY, GITHUB_ACTIONS_KEY, JENKINS_URL_KEY, LinkKind, capture_link
|
|
11
|
+
from launchable.utils.tracking import Tracking, TrackingClient
|
|
12
|
+
|
|
13
|
+
from ...utils import subprocess
|
|
14
|
+
from ...utils.authentication import get_org_workspace
|
|
15
|
+
from ...utils.click import KeyValueType
|
|
16
|
+
from ...utils.env_keys import REPORT_ERROR_KEY
|
|
17
|
+
from ...utils.launchable_client import LaunchableClient
|
|
18
|
+
from ...utils.session import clean_session_files, write_build
|
|
19
|
+
from .commit import commit
|
|
20
|
+
|
|
21
|
+
JENKINS_GIT_BRANCH_KEY = "GIT_BRANCH"
|
|
22
|
+
JENKINS_GIT_LOCAL_BRANCH_KEY = "GIT_LOCAL_BRANCH"
|
|
23
|
+
GITHUB_ACTIONS_GITHUB_HEAD_REF_KEY = "GITHUB_HEAD_REF"
|
|
24
|
+
GITHUB_ACTIONS_GITHUB_BASE_REF_KEY = "GITHUB_BASE_REF"
|
|
25
|
+
CIRCLECI_CIRCLE_BRANCH_KEY = "CIRCLE_BRANCH"
|
|
26
|
+
CODE_BUILD_BUILD_ID_KEY = "CODEBUILD_BUILD_ID"
|
|
27
|
+
CODE_BUILD_WEBHOOK_HEAD_REF_KEY = "CODEBUILD_WEBHOOK_HEAD_REF"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@click.command()
|
|
31
|
+
@click.option(
|
|
32
|
+
'--name',
|
|
33
|
+
'build_name',
|
|
34
|
+
help='build name',
|
|
35
|
+
required=True,
|
|
36
|
+
type=str,
|
|
37
|
+
metavar='BUILD_NAME'
|
|
38
|
+
)
|
|
39
|
+
@click.option(
|
|
40
|
+
'--source',
|
|
41
|
+
help='path to local Git workspace, optionally prefixed by a label. '
|
|
42
|
+
' like --source path/to/ws or --source main=path/to/ws',
|
|
43
|
+
default=["."],
|
|
44
|
+
metavar="REPO_NAME",
|
|
45
|
+
multiple=True
|
|
46
|
+
)
|
|
47
|
+
@click.option(
|
|
48
|
+
'--max-days',
|
|
49
|
+
help="the maximum number of days to collect commits retroactively",
|
|
50
|
+
default=30
|
|
51
|
+
)
|
|
52
|
+
@click.option(
|
|
53
|
+
'--no-submodules',
|
|
54
|
+
is_flag=True,
|
|
55
|
+
help="stop collecting information from Git Submodules",
|
|
56
|
+
default=False
|
|
57
|
+
)
|
|
58
|
+
@click.option(
|
|
59
|
+
'--no-commit-collection',
|
|
60
|
+
is_flag=True,
|
|
61
|
+
help="""do not collect commit data.
|
|
62
|
+
|
|
63
|
+
This is useful if the repository is a shallow clone and the RevWalk is not
|
|
64
|
+
possible. The commit data must be collected with a separate fully-cloned
|
|
65
|
+
repository.
|
|
66
|
+
""",
|
|
67
|
+
default=False
|
|
68
|
+
)
|
|
69
|
+
@click.option('--scrub-pii', is_flag=True, help='Scrub emails and names', hidden=True)
|
|
70
|
+
@click.option(
|
|
71
|
+
'--commit',
|
|
72
|
+
'commits',
|
|
73
|
+
help="set repository name and commit hash when you use --no-commit-collection option",
|
|
74
|
+
multiple=True,
|
|
75
|
+
default=[],
|
|
76
|
+
cls=KeyValueType,
|
|
77
|
+
)
|
|
78
|
+
@click.option(
|
|
79
|
+
'--link',
|
|
80
|
+
'links',
|
|
81
|
+
help="Set external link of title and url",
|
|
82
|
+
multiple=True,
|
|
83
|
+
default=[],
|
|
84
|
+
cls=KeyValueType,
|
|
85
|
+
)
|
|
86
|
+
@click.option(
|
|
87
|
+
'--branch',
|
|
88
|
+
'branches',
|
|
89
|
+
help="Set repository name and branch name when you use --no-commit-collection option. Please use the same repository name with a commit option", # noqa: E501
|
|
90
|
+
multiple=True,
|
|
91
|
+
default=[],
|
|
92
|
+
cls=KeyValueType,
|
|
93
|
+
)
|
|
94
|
+
@click.pass_context
|
|
95
|
+
def build(ctx: click.core.Context, build_name: str, source: List[str], max_days: int, no_submodules: bool,
|
|
96
|
+
no_commit_collection: bool, scrub_pii: bool, commits: List[str], links: List[str], branches: List[str]):
|
|
97
|
+
|
|
98
|
+
if "/" in build_name or "%2f" in build_name.lower():
|
|
99
|
+
sys.exit("--name must not contain a slash and an encoded slash")
|
|
100
|
+
if "%25" in build_name:
|
|
101
|
+
sys.exit("--name must not contain encoded % (%25)")
|
|
102
|
+
if not no_commit_collection and len(commits) != 0:
|
|
103
|
+
sys.exit("--no-commit-collection must be specified when --commit is used")
|
|
104
|
+
|
|
105
|
+
clean_session_files(days_ago=14)
|
|
106
|
+
|
|
107
|
+
# Information we want to collect for each Git repository
|
|
108
|
+
# The key data structure throughout the implementation of this command
|
|
109
|
+
class Workspace:
|
|
110
|
+
# identifier given to a Git repository to track the same repository from one 'record build' to next
|
|
111
|
+
name: str
|
|
112
|
+
# path to the Git workspace. Can be None if there's no local workspace present
|
|
113
|
+
dir: str
|
|
114
|
+
# current branch of this workspace
|
|
115
|
+
branch: str
|
|
116
|
+
# SHA1 commit hash that's currently checked out
|
|
117
|
+
commit_hash: str
|
|
118
|
+
|
|
119
|
+
def __init__(self, name, dir=None, branch=None, commit_hash=None):
|
|
120
|
+
self.name = name
|
|
121
|
+
self.dir = dir
|
|
122
|
+
self.branch = branch
|
|
123
|
+
self.commit_hash = commit_hash
|
|
124
|
+
|
|
125
|
+
def calc_branch_name(self):
|
|
126
|
+
'''
|
|
127
|
+
figure out the branch using the workspace. requires `dir` and `commit_hash` to be set.
|
|
128
|
+
'''
|
|
129
|
+
|
|
130
|
+
# Jenkins
|
|
131
|
+
# ref:
|
|
132
|
+
# https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/Complete-Jenkins-Git-environment-variables-list-for-batch-jobs-and-shell-script-builds
|
|
133
|
+
if os.environ.get(JENKINS_URL_KEY):
|
|
134
|
+
self.branch = os.environ.get(JENKINS_GIT_BRANCH_KEY) or os.environ.get(JENKINS_GIT_LOCAL_BRANCH_KEY)
|
|
135
|
+
|
|
136
|
+
# Github Actions
|
|
137
|
+
# ref: https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables
|
|
138
|
+
if os.environ.get(GITHUB_ACTIONS_KEY):
|
|
139
|
+
self.branch = os.environ.get(GITHUB_ACTIONS_GITHUB_HEAD_REF_KEY) or \
|
|
140
|
+
os.environ.get(GITHUB_ACTIONS_GITHUB_BASE_REF_KEY)
|
|
141
|
+
|
|
142
|
+
# CircleCI
|
|
143
|
+
# ref: https://circleci.com/docs/variables/
|
|
144
|
+
if os.environ.get(CIRCLECI_KEY):
|
|
145
|
+
self.branch = os.environ.get(CIRCLECI_CIRCLE_BRANCH_KEY)
|
|
146
|
+
# AWS CodeBuild
|
|
147
|
+
# ref: https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html
|
|
148
|
+
if os.environ.get(CODE_BUILD_BUILD_ID_KEY):
|
|
149
|
+
v = os.environ.get(CODE_BUILD_WEBHOOK_HEAD_REF_KEY)
|
|
150
|
+
if v:
|
|
151
|
+
# refs/head/<branch name>
|
|
152
|
+
self.branch = v.split("/")[-1]
|
|
153
|
+
|
|
154
|
+
if self.branch:
|
|
155
|
+
return # if we've figured this out, great
|
|
156
|
+
|
|
157
|
+
try:
|
|
158
|
+
show_ref = subprocess.check_output(["git", "show-ref"], cwd=self.dir).decode()
|
|
159
|
+
refs = [ref for ref in show_ref.split("\n") if self.commit_hash in ref]
|
|
160
|
+
|
|
161
|
+
if len(refs) > 0:
|
|
162
|
+
# e.g) ed6de84bde58d51deebe90e01ddfa5fa78899b1c refs/heads/branch-name
|
|
163
|
+
self.branch = refs[0].split("/")[-1]
|
|
164
|
+
except Exception:
|
|
165
|
+
# cannot get branch name by git command
|
|
166
|
+
pass
|
|
167
|
+
|
|
168
|
+
# The first order of business is to ascertain what Git repositories we have in the workspace
|
|
169
|
+
def list_sources() -> List[Workspace]:
|
|
170
|
+
# This command accepts REPO_NAME=REPO_DIR as well as just REPO_DIR
|
|
171
|
+
pattern = re.compile(r'[^=]+=[^=]+')
|
|
172
|
+
ws: List[Workspace] = []
|
|
173
|
+
for s in source:
|
|
174
|
+
if pattern.match(s):
|
|
175
|
+
kv = s.split('=')
|
|
176
|
+
ws.append(Workspace(name=kv[0], dir=kv[1]))
|
|
177
|
+
else:
|
|
178
|
+
ws.append(Workspace(name=s, dir=s))
|
|
179
|
+
# TODO: if repo_dir is absolute path, warn the user that that's probably
|
|
180
|
+
# not what they want to do
|
|
181
|
+
return ws
|
|
182
|
+
|
|
183
|
+
# `record commit` on each top-level (= non submodule) Git repository
|
|
184
|
+
# `record commit` command processes Git submodule on its own,
|
|
185
|
+
# so we need to do this between list_sources and list_submodules
|
|
186
|
+
def collect_commits():
|
|
187
|
+
if not no_commit_collection:
|
|
188
|
+
for w in ws:
|
|
189
|
+
ctx.invoke(commit, source=w.dir, max_days=max_days, scrub_pii=scrub_pii)
|
|
190
|
+
else:
|
|
191
|
+
click.echo(click.style(
|
|
192
|
+
"Warning: Commit collection is turned off. The commit data must be collected separately.",
|
|
193
|
+
fg='yellow'), err=True)
|
|
194
|
+
|
|
195
|
+
# tally up all the submodules, unless we are told not to
|
|
196
|
+
def list_submodules(workspaces: List[Workspace]) -> List[Workspace]:
|
|
197
|
+
if no_submodules:
|
|
198
|
+
return workspaces
|
|
199
|
+
|
|
200
|
+
r = workspaces.copy()
|
|
201
|
+
for w in workspaces:
|
|
202
|
+
submodule_pattern = re.compile(r"^[\+\-U ](?P<hash>[a-f0-9]{40}) (?P<name>\S+)")
|
|
203
|
+
|
|
204
|
+
# invoke git directly because dulwich's submodule feature was broken
|
|
205
|
+
submodule_stdouts = subprocess.check_output("git submodule status --recursive".split(),
|
|
206
|
+
cwd=w.dir).decode().splitlines()
|
|
207
|
+
for submodule_stdout in submodule_stdouts:
|
|
208
|
+
# the output is e.g.
|
|
209
|
+
# "+bbf213437a65e82dd6dda4391ecc5d598200a6ce sub1 (heads/master)"
|
|
210
|
+
matched = submodule_pattern.search(submodule_stdout)
|
|
211
|
+
if matched:
|
|
212
|
+
commit_hash = matched.group('hash')
|
|
213
|
+
name = matched.group('name')
|
|
214
|
+
if commit_hash and name:
|
|
215
|
+
r.append(Workspace(
|
|
216
|
+
name=w.name + "/" + name,
|
|
217
|
+
dir=w.dir + "/" + name,
|
|
218
|
+
commit_hash=commit_hash))
|
|
219
|
+
return r
|
|
220
|
+
|
|
221
|
+
# figure out the commit hash and branch of those workspaces
|
|
222
|
+
def compute_hash_and_branch(ws: List[Workspace]):
|
|
223
|
+
# figure out w.commit_hash and w.branch
|
|
224
|
+
for w in ws:
|
|
225
|
+
try:
|
|
226
|
+
if not w.commit_hash:
|
|
227
|
+
w.commit_hash = subprocess.check_output("git rev-parse HEAD".split(), cwd=w.dir).decode().replace("\n", "")
|
|
228
|
+
except Exception as e:
|
|
229
|
+
click.echo(
|
|
230
|
+
click.style(
|
|
231
|
+
"Can't get commit hash for {}. Do you run command under git-controlled directory? "
|
|
232
|
+
"If not, please set a directory use by --source option.".format(w.dir),
|
|
233
|
+
fg='yellow'),
|
|
234
|
+
err=True)
|
|
235
|
+
print(e, file=sys.stderr)
|
|
236
|
+
sys.exit(1)
|
|
237
|
+
w.calc_branch_name()
|
|
238
|
+
|
|
239
|
+
# Our historical behaviour is to ignore --branch options. In that case, we should reject if that option is present
|
|
240
|
+
# I also think it's OK to allow this option to explicitly let the branch name set, since the inference
|
|
241
|
+
# of the branch name from the workspace is inherently a little fragile
|
|
242
|
+
|
|
243
|
+
# Rely on --commit and --branch to create a list of workspaces, even when there's no local Git workspaces
|
|
244
|
+
def synthesize_workspaces() -> List[Workspace]:
|
|
245
|
+
# workspace by its name
|
|
246
|
+
ws: Dict[str, Workspace] = {}
|
|
247
|
+
|
|
248
|
+
commit_pattern = re.compile("[0-9A-Fa-f]{5,40}$")
|
|
249
|
+
|
|
250
|
+
branch_name_map = dict(normalize_key_value_types(branches))
|
|
251
|
+
|
|
252
|
+
for name, hash in normalize_key_value_types(commits):
|
|
253
|
+
if not commit_pattern.match(hash):
|
|
254
|
+
click.echo(click.style(
|
|
255
|
+
"{}'s commit hash `{}` is invalid.".format(name, hash),
|
|
256
|
+
fg="yellow"),
|
|
257
|
+
err=True)
|
|
258
|
+
sys.exit(1)
|
|
259
|
+
|
|
260
|
+
ws[name] = Workspace(name=name, commit_hash=hash, branch=branch_name_map.get(name))
|
|
261
|
+
|
|
262
|
+
# make sure no invalid branch name options are given
|
|
263
|
+
for k in branch_name_map:
|
|
264
|
+
if not ws.get(k):
|
|
265
|
+
click.echo(click.style(
|
|
266
|
+
"Invalid repository name {} in a --branch option. "
|
|
267
|
+
"Perhaps you missed the corresponding --commit option?".format(k),
|
|
268
|
+
fg="yellow"),
|
|
269
|
+
err=True)
|
|
270
|
+
# TODO: is there any reason this is not an error? for now erring on caution
|
|
271
|
+
# sys.exit(1)
|
|
272
|
+
|
|
273
|
+
return list(ws.values())
|
|
274
|
+
|
|
275
|
+
# send all the data to server and obtain build_id, or none if the service is down, to recover
|
|
276
|
+
def send(ws: List[Workspace]) -> Optional[str]:
|
|
277
|
+
# figure out all the CI links to capture
|
|
278
|
+
def compute_links():
|
|
279
|
+
_links = capture_link(os.environ)
|
|
280
|
+
for k, v in normalize_key_value_types(links):
|
|
281
|
+
_links.append({
|
|
282
|
+
"title": k,
|
|
283
|
+
"url": v,
|
|
284
|
+
"kind": LinkKind.CUSTOM_LINK.name,
|
|
285
|
+
})
|
|
286
|
+
return _links
|
|
287
|
+
|
|
288
|
+
tracking_client = TrackingClient(Tracking.Command.RECORD_BUILD)
|
|
289
|
+
try:
|
|
290
|
+
payload = {
|
|
291
|
+
"buildNumber": build_name,
|
|
292
|
+
"commitHashes": [{
|
|
293
|
+
'repositoryName': w.name,
|
|
294
|
+
'commitHash': w.commit_hash,
|
|
295
|
+
'branchName': w.branch or ""
|
|
296
|
+
} for w in ws],
|
|
297
|
+
"links": compute_links()
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
client = LaunchableClient(dry_run=ctx.obj.dry_run, tracking_client=tracking_client)
|
|
301
|
+
|
|
302
|
+
res = client.request("post", "builds", payload=payload)
|
|
303
|
+
res.raise_for_status()
|
|
304
|
+
|
|
305
|
+
# at this point we've successfully send the data, so it's OK to record this build
|
|
306
|
+
write_build(build_name)
|
|
307
|
+
|
|
308
|
+
return res.json().get("id", None)
|
|
309
|
+
except Exception as e:
|
|
310
|
+
tracking_client.send_error_event(
|
|
311
|
+
event_name=Tracking.ErrorEvent.INTERNAL_CLI_ERROR,
|
|
312
|
+
stack_trace=str(e),
|
|
313
|
+
)
|
|
314
|
+
if os.getenv(REPORT_ERROR_KEY):
|
|
315
|
+
raise e
|
|
316
|
+
else:
|
|
317
|
+
print(e)
|
|
318
|
+
return None
|
|
319
|
+
|
|
320
|
+
# report what we did to the user to assist diagnostics
|
|
321
|
+
def report(ws: List[Workspace], build_id: str):
|
|
322
|
+
org, workspace = get_org_workspace()
|
|
323
|
+
click.echo(
|
|
324
|
+
"Launchable recorded build {} to workspace {}/{} with commits from {} {}:\n".format(
|
|
325
|
+
build_name,
|
|
326
|
+
org,
|
|
327
|
+
workspace,
|
|
328
|
+
len(ws),
|
|
329
|
+
("repositories" if len(ws) > 1 else "repository"),
|
|
330
|
+
),
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
header = ["Name", "Path", "HEAD Commit"]
|
|
334
|
+
rows = [[w.name, w.dir, w.commit_hash] for w in ws]
|
|
335
|
+
click.echo(tabulate(rows, header, tablefmt="github"))
|
|
336
|
+
click.echo(
|
|
337
|
+
"\nVisit https://app.launchableinc.com/organizations/{organization}/workspaces/"
|
|
338
|
+
"{workspace}/data/builds/{build_id} to view this build and its test sessions"
|
|
339
|
+
.format(
|
|
340
|
+
organization=org,
|
|
341
|
+
workspace=workspace,
|
|
342
|
+
build_id=build_id,
|
|
343
|
+
))
|
|
344
|
+
|
|
345
|
+
# all the logics at the high level
|
|
346
|
+
if len(commits) == 0:
|
|
347
|
+
ws = list_sources()
|
|
348
|
+
collect_commits()
|
|
349
|
+
ws = list_submodules(ws)
|
|
350
|
+
compute_hash_and_branch(ws)
|
|
351
|
+
else:
|
|
352
|
+
ws = synthesize_workspaces()
|
|
353
|
+
build_id = send(ws)
|
|
354
|
+
if not build_id:
|
|
355
|
+
return # recover from service outage gracefully
|
|
356
|
+
report(ws, build_id)
|
|
@@ -12,11 +12,12 @@ Pipfile
|
|
|
12
12
|
README.md
|
|
13
13
|
WORKSPACE
|
|
14
14
|
pyproject.toml
|
|
15
|
+
renovate.json
|
|
15
16
|
setup.cfg
|
|
16
17
|
setup.py
|
|
17
18
|
.github/release.yml
|
|
19
|
+
.github/workflows/bazel-test.yml
|
|
18
20
|
.github/workflows/e2e.yml
|
|
19
|
-
.github/workflows/publicize-doc-change.yml
|
|
20
21
|
.github/workflows/python-package.yml
|
|
21
22
|
.github/workflows/python-publish.yml
|
|
22
23
|
launchable/__init__.py
|
|
@@ -187,6 +187,9 @@ class CliTestCase(unittest.TestCase):
|
|
|
187
187
|
"""
|
|
188
188
|
return CliRunner(mix_stderr=mix_stderr).invoke(main, args, catch_exceptions=False, **kwargs)
|
|
189
189
|
|
|
190
|
+
def assert_success(self, result: click.testing.Result):
|
|
191
|
+
self.assertEqual(result.exit_code, 0, result.stdout)
|
|
192
|
+
|
|
190
193
|
def load_json_from_file(self, file):
|
|
191
194
|
try:
|
|
192
195
|
with file.open() as json_file:
|
|
@@ -19,25 +19,23 @@ class BuildTest(CliTestCase):
|
|
|
19
19
|
@mock.patch.dict(os.environ, {"GITHUB_PULL_REQUEST_URL": ""})
|
|
20
20
|
def test_submodule(self, mock_check_output):
|
|
21
21
|
mock_check_output.side_effect = [
|
|
22
|
-
# the first call is git
|
|
23
|
-
('c50f5de0f06fe16afa4fd1dd615e4903e40b42a2').encode(),
|
|
24
|
-
# the second call is git rev-parse HEAD for detect branch name
|
|
25
|
-
('c50f5de0f06fe16afa4fd1dd615e4903e40b42a2').encode(),
|
|
26
|
-
# the third call is git show-ref for detect branch name
|
|
27
|
-
('c50f5de0f06fe16afa4fd1dd615e4903e40b42a2 refs/head/main\nc50f5de0f06fe16afa4fd1dd615e4903e40b42a2 refs/remotes/origin/main\n').encode(), # noqa: E501
|
|
28
|
-
# the forth call is git submodule status --recursive
|
|
22
|
+
# the first call is git submodule status --recursive
|
|
29
23
|
(
|
|
30
24
|
' 491e03096e2234dab9a9533da714fb6eff5dcaa7 foo (v1.51.0-560-g491e030)\n'
|
|
31
25
|
' 8bccab48338219e73c3118ad71c8c98fbd32a4be bar-zot (v1.32.0-516-g8bccab4)\n'
|
|
32
26
|
).encode(),
|
|
27
|
+
# the second call is git rev-parse HEAD for the '.' workspace
|
|
28
|
+
('c50f5de0f06fe16afa4fd1dd615e4903e40b42a2').encode(),
|
|
29
|
+
# the third call is git show-ref for detect branch name
|
|
30
|
+
('c50f5de0f06fe16afa4fd1dd615e4903e40b42a2 refs/head/main\nc50f5de0f06fe16afa4fd1dd615e4903e40b42a2 refs/remotes/origin/main\n').encode(), # noqa: E501
|
|
33
31
|
]
|
|
34
32
|
|
|
35
33
|
self.assertEqual(read_build(), None)
|
|
36
34
|
result = self.cli("record", "build", "--no-commit-collection", "--name", self.build_name)
|
|
37
|
-
self.
|
|
35
|
+
self.assert_success(result)
|
|
38
36
|
|
|
39
37
|
# Name & Path should both reflect the submodule path
|
|
40
|
-
self.assertTrue("| ./bar-zot | ./bar-zot | 8bccab48338219e73c3118ad71c8c98fbd32a4be |" in result.stdout)
|
|
38
|
+
self.assertTrue("| ./bar-zot | ./bar-zot | 8bccab48338219e73c3118ad71c8c98fbd32a4be |" in result.stdout, result.stdout)
|
|
41
39
|
|
|
42
40
|
payload = json.loads(responses.calls[0].request.body.decode())
|
|
43
41
|
self.assert_json_orderless_equal(
|
|
@@ -80,7 +78,7 @@ class BuildTest(CliTestCase):
|
|
|
80
78
|
self.assertEqual(read_build(), None)
|
|
81
79
|
|
|
82
80
|
result = self.cli("record", "build", "--no-commit-collection", "--no-submodules", "--name", self.build_name)
|
|
83
|
-
self.
|
|
81
|
+
self.assert_success(result)
|
|
84
82
|
|
|
85
83
|
payload = json.loads(responses.calls[0].request.body.decode())
|
|
86
84
|
self.assert_json_orderless_equal(
|
|
@@ -194,7 +192,7 @@ class BuildTest(CliTestCase):
|
|
|
194
192
|
"B=feature-yyy",
|
|
195
193
|
"--name",
|
|
196
194
|
self.build_name)
|
|
197
|
-
self.
|
|
195
|
+
self.assert_success(result)
|
|
198
196
|
|
|
199
197
|
payload = json.loads(responses.calls[0].request.body.decode())
|
|
200
198
|
self.assert_json_orderless_equal(
|
|
@@ -210,7 +208,7 @@ class BuildTest(CliTestCase):
|
|
|
210
208
|
"links": []
|
|
211
209
|
}, payload)
|
|
212
210
|
responses.calls.reset()
|
|
213
|
-
self.assertIn("
|
|
211
|
+
self.assertIn("Invalid repository name B in a --branch option. ", result.output)
|
|
214
212
|
|
|
215
213
|
# case multiple --commit options and multiple --branch options
|
|
216
214
|
result = self.cli(
|
|
@@ -6,14 +6,14 @@ import threading
|
|
|
6
6
|
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from unittest import mock
|
|
9
|
-
from requests.exceptions import ReadTimeout
|
|
10
9
|
|
|
11
10
|
import responses # type: ignore
|
|
11
|
+
from requests.exceptions import ReadTimeout
|
|
12
12
|
|
|
13
|
+
from launchable.commands.verify import compare_version
|
|
13
14
|
from launchable.utils.env_keys import BASE_URL_KEY
|
|
14
15
|
from launchable.utils.http_client import get_base_url
|
|
15
16
|
from tests.cli_test_case import CliTestCase
|
|
16
|
-
from launchable.commands.verify import compare_version
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
# dummy server for exe.jar
|
|
@@ -392,7 +392,7 @@ class APIErrorTest(CliTestCase):
|
|
|
392
392
|
self.assert_tracking_count(tracking=tracking, count=2)
|
|
393
393
|
|
|
394
394
|
result = self.cli("record", "build", "--name", "example")
|
|
395
|
-
self.
|
|
395
|
+
self.assert_success(result)
|
|
396
396
|
|
|
397
397
|
# Since Timeout error is caught inside of LaunchableClient, the tracking event is sent twice.
|
|
398
398
|
self.assert_tracking_count(tracking=tracking, count=4)
|