do_upload.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #!/usr/bin/env python3
  2. import glob
  3. import itertools
  4. import os
  5. from subprocess import Popen
  6. def run_command(command: list[str], log_file: str):
  7. with open(log_file, "wb") as f:
  8. return Popen(command, stdout=f, stderr=f)
  9. def get_files(input_files: list[str]) -> list[str]:
  10. """
  11. this function expands the globs specified in the input file then
  12. filters for paths that are actually files
  13. """
  14. glob_expanded_files = [glob.glob(file, recursive=True) for file in input_files]
  15. flattened_glob_matches = list(itertools.chain.from_iterable(glob_expanded_files))
  16. filtered_glob_matches = [file for file in flattened_glob_matches if os.path.isfile(file)]
  17. return filtered_glob_matches
  18. def main():
  19. """
  20. First we get the arguments passed to the upload artifacts action via the env vars,
  21. then we build the command for uploading coverage, run it in a thread, and build the
  22. command for uploading test results and run it in a thread. We wait for both commands
  23. to finish running then print their logs sequentially.
  24. When we run the commands we're piping their stdout and stderr to a file so we can print the
  25. contents of the files sequentially. We don't want the output of each command to be interleaved.
  26. --plugin noop is passed to both commands, we don't need the CLI plugins because we're already
  27. generating the coverage files ourselves.
  28. """
  29. input_token = os.getenv("INPUT_TOKEN")
  30. input_commit_sha = os.getenv("INPUT_COMMIT_SHA")
  31. input_type = os.getenv("INPUT_TYPE")
  32. input_files = os.getenv("INPUT_FILES", "").split(",")
  33. input_test_result_files = os.getenv("INPUT_TEST_RESULT_FILES", "").split(",")
  34. codecov_base_cmd = ["./codecov", "--verbose"]
  35. upload_flags = [
  36. "-t",
  37. input_token,
  38. "--plugin",
  39. "noop",
  40. "--flag",
  41. input_type,
  42. ]
  43. if input_commit_sha:
  44. upload_flags += ["--commit-sha", input_commit_sha]
  45. upload_coverage_cmd = [*codecov_base_cmd, "upload-process", *upload_flags]
  46. coverage_files = get_files(input_files)
  47. for file in coverage_files:
  48. upload_coverage_cmd += ["--file", file]
  49. upload_coverage_log_file = "coverage-upload.log"
  50. test_result_files = get_files(input_test_result_files)
  51. upload_test_results_cmd = [
  52. *codecov_base_cmd,
  53. "do-upload",
  54. "--report-type",
  55. "test_results",
  56. *upload_flags,
  57. ]
  58. for file in test_result_files:
  59. upload_test_results_cmd += ["--file", file]
  60. upload_test_results_log_file = "upload-test-results.log"
  61. # so that the logs are not interleaved when printed
  62. jobs = [
  63. run_command(upload_test_results_cmd, upload_test_results_log_file),
  64. run_command(upload_coverage_cmd, upload_coverage_log_file),
  65. ]
  66. tail_args = ("tail", "-f", "--sleep-interval", "3")
  67. for job in jobs:
  68. tail_args += ("--pid", str(job.pid))
  69. tail_args += (
  70. upload_coverage_log_file,
  71. upload_test_results_log_file,
  72. )
  73. # wait, while showing un-interleaved logs
  74. jobs.append(Popen(tail_args))
  75. return_codes = []
  76. for job in jobs:
  77. job.wait()
  78. if any(return_codes):
  79. raise Exception("Error uploading to codecov")
  80. if __name__ == "__main__":
  81. main()