Fix basecall.config path and publish .nextflow.log to LOG_BUCKET - #27
Conversation
Wraps the Nextflow subprocess in a try/finally that uploads
/workflow/.nextflow.log to s3://{log_bucket}/basecall-workflow/automated/
{delivery}/{ts}/ on both success and failure, so failed Fargate head jobs
are debuggable post-mortem instead of losing the log on container teardown.
Upload errors are logged and swallowed to avoid masking Nextflow's real
exit code.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
So a misconfigured IAM policy or bucket name shows up in CloudWatch error metrics instead of being buried in warnings — without raising, which would block the samplesheet generation step from running on an otherwise successful Nextflow run. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
katherine-stansifer
left a comment
There was a problem hiding this comment.
review-pr
This review was generated by an automated code review tool (review-pr), not by the GitHub user whose account posted it. Findings reflect automated analysis and may not represent the views of the account owner.
Correctness
- C1 (suggestion):
upload_nextflow_logonly catchesClientError, buts3_client.upload_filecan also raiseboto3.exceptions.S3UploadFailedError(the transfer wrapper's preferred exception for non-AWS upload errors) andbotocore.exceptions.BotoCoreError. Because the call lives in afinallyblock, an uncaught upload exception will replace any in-flightCalledProcessErrorfrom Nextflow and surface that instead of the underlying basecalling failure — the opposite of the docstring's stated intent ("log the error and return normally rather than raising"). Consider broadening toexcept Exception as eso the upload genuinely never masks the original failure, which is the only reason the function exists in the first place.
Testing
No issues found. The docker-build smoke test was extended to assert --log-bucket appears in argparse's required-args error output, matching the existing per-flag verification pattern. The repository has no Python test suite, so unit-level coverage for upload_nextflow_log isn't feasible here, and the PR description lays out the manual end-to-end test plan that gates merging.
Documentation
- D1 (issue):
README.md(lines 80–84) lists the required CLI arguments forautomation/run_automation.py—--delivery,--kit,--aws-queue,--base-bucket,--work-bucket— but does not include the newly-required--log-bucket. Anyone reading the README to wire up a caller, or comparing the Lambda'scontainerOverrides.commandagainst the documented contract, will miss this. Add--log-bucketto that list with a one-line description matching the argparse help string.
Quality
No issues found. Hoisting s3_client above the try so it's shared between the upload and generate_samplesheet is a small, sensible refactor; the new helper is appropriately scoped; and the rest of the changes follow existing patterns in the file (typed signatures, log.info/log.warning levels, Path for filesystem locations).
Risks
No issues found. The PR description already calls out the cross-repo dependency (--log-bucket is required, so the matching Lambda + IAM changes in det-terraform-production-role must ship in tandem) and explicitly states this PR will not merge until the end-to-end path works.
…-log-bucket Wrap the upload_nextflow_log call inside the finally block with an outer try/except Exception, so an unexpected upload error can't replace an in-flight CalledProcessError from Nextflow. Mirrors the two-layer pattern used in mgs-orchestrator (automation/run_automation.py:213-220): inner helper catches ClientError, outer call site catches Exception. Also add --log-bucket to the Automation section's required-arguments list in README.md so callers see the full Lambda containerOverrides.command contract. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous commit mirrored mgs-orchestrator's two-layer exception pattern, but that pattern is justified there by a multi-file upload loop and a larger try-block scope. For our single-file, single-call upload, broadening the helper's catch to `except Exception` (with `log.exception` for the traceback) gives the same safety property — the finally block can't mask a Nextflow CalledProcessError — without the call-site nesting. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dp-rice
left a comment
There was a problem hiding this comment.
One thing to check on re error handling, but looks good.
…s call site The docstring now states the function's contract (logs and swallows all upload errors); the finally call site explains why that contract is required there. Suggested by dp-rice in PR #27 review.
In actually testing out basecalling lambda end-to-end I realized a few pieces of the entrypoint I'd left out--passing the config (absolutely essential for anything to run) and saving the .nextflow.log on S3 (not literally essential, but not having it makes debugging really hard)
Summary
basecall.configso Nextflow picks up the intended params (c83803c)./workflow/.nextflow.logtos3://{log_bucket}/basecall-workflow/automated/{delivery}/{ts}/on both success and failure, so failed Fargate head jobs are debuggable post-mortem instead of losing the log on container teardown (0d3af8c). Adds a required--log-bucketCLI arg and extends the docker-build smoke test to assert it.Caveat — depends on Lambda + IAM changes
The
--log-bucketflag is required, so this PR is not functional end-to-end until the concurrent changes indet-terraform-production-roleship:startOntBasecallLambda must append--log-bucket <bucket>tocontainerOverrides.command.s3:PutObjectonarn:aws:s3:::<log_bucket>/basecall-workflow/*.I'm testing them both (from branches) in tandem and will only merge this when the whole system is working end-to-end.
Test plan
Docker Buildpasses (the smoke test now asserts--log-bucketis listed in the argparse error output).), confirms3://<log_bucket>/basecall-workflow/automated///.nextflow.log` exists once the Batch job terminates.🤖 Generated with Claude Code