Skip to content

Add --wait to corgea upload and print scan page URL when not waiting - #131

Merged
Ibrahimrahhal merged 2 commits into
mainfrom
cursor/upload-wait-and-scan-url-f604
Jul 30, 2026
Merged

Add --wait to corgea upload and print scan page URL when not waiting#131
Ibrahimrahhal merged 2 commits into
mainfrom
cursor/upload-wait-and-scan-url-f604

Conversation

@Ibrahimrahhal

@Ibrahimrahhal Ibrahimrahhal commented Jul 20, 2026

Copy link
Copy Markdown
Member

Summary

The corgea upload command previously uploaded a report and only printed a generic "Go to <base_url> to see results." line, with no way to track the specific scan or block until it completed. This brings upload in line with corgea scan:

  • Adds a --wait flag to corgea upload. When set, the command blocks until the uploaded scan completes and prints the results (reusing the same wait::run flow as corgea scan semgrep/snyk).
  • When --wait is not set, the command now prints the scan page URL (<url>/project/<project>?scan_id=<id>) so the user can track results in the web app, mirroring the tracking link shown by a regular blast scan.

Changes

  • src/main.rs: add the wait: bool arg to the Upload subcommand and wire the handler to either wait or print the tracking URL based on the returned ScanUploadResult.
  • src/scan.rs:
    • ScanUploadResult now carries project_name so the tracking URL can be built when the server does not return a project_id.
    • read_file_report / read_stdin_report now return Option<ScanUploadResult> instead of discarding it.
    • Added build_scan_url / print_scan_tracking_url helpers. The project_name fallback path segment is percent-encoded (via urlencoding) so CI project names of the form {owner/repo}-{pr} don't break the URL path — addresses review feedback. Added unit tests covering both the project_id and encoded project_name branches.
  • src/scanners/fortify.rs: parse now returns Option<ScanUploadResult> so .fpr uploads support --wait and URL printing too.
  • skills/corgea/SKILL.md: documented --wait and the default tracking-URL behavior.

Notes

  • If the server does not return a scan id (e.g. failed/empty upload), neither waiting nor URL printing occurs — the existing behavior is preserved.
  • ./harness check passes (clippy strict, fmt, 450 tests).

Testing

  • ./harness check — clippy fix, format, strict clippy, tests (450 passed), deps skill drift: all pass.
Open in Web Open in Cursor 

@Ibrahimrahhal
Ibrahimrahhal marked this pull request as ready for review July 20, 2026 13:29

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Production review of --wait / scan-URL tracking for corgea upload. Found concrete merge blockers around project identity when waiting, and --wait failing open when the upload response has no scan id. Details in the inline comments.

Open in Web View Automation 

Sent by Cursor Automation: pr-flow

Comment thread src/main.rs

if let Some(result) = result {
if *wait {
wait::run(&corgea_config, Some(result.scan_id), result.project_id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--wait uses the wrong project identity (breaks --project-name and CI uploads)

ScanUploadResult now carries project_name, but this call discards it:

wait::run(&corgea_config, Some(result.scan_id), result.project_id);

wait::run always re-derives the project from the CWD and unconditionally queries that project's scan list before using the provided scan_id:

pub fn run(config: &Config, scan_id: Option<String>, project_id: Option<String>) {
    let project_name = match utils::generic::get_current_working_directory() { ... };
    let scans_result =
        utils::api::query_scan_list(&config.get_url(), Some(&project_name), Some(1), None);
    // Err => process::exit(1)  — even when scan_id was already known

Impact

  • corgea upload report.json --project-name my-svc --wait uploads to my-svc, then waits against the CWD project. If that CWD project is missing/unreachable, wait exits 1 after a successful upload.
  • In CI, upload_scan names the project {GITHUB_REPOSITORY}-{GITHUB_PR} (src/scan.rs ~204–214), which almost never matches the checkout directory name — so upload --wait in Actions is likely to fail or print the wrong fallback URL when project_id is absent.

Fix

  1. Extend wait::run to accept the upload’s project_name (or skip query_scan_list entirely when scan_id is Some).
  2. Pass result.project_name through from this call site (and ideally from run_semgrep / run_snyk too).
  3. Add a regression test: upload with --project-name ≠ CWD + --wait must not query/exit on the CWD project.

Comment thread src/main.rs
} else {
scan::print_scan_tracking_url(&corgea_config, &result);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--wait fails open when the upload returns no scan id

If upload_scan succeeds but the response has no sast_scan_id (allowed for non-chunked uploads — only chunked treats a missing id as hard failure), result is None and this block is skipped. With --wait set, the process still exits 0 without waiting or printing results.

Impact: Users/CI that pass --wait get a false success: the command claimed it would block until completion, but it did not.

Fix: When *wait is true and result is None, error and exit(1) (e.g. “upload succeeded but server did not return a scan id; cannot wait”). Optionally also harden upload_scan so a missing sast_scan_id on any successful response is always a hard failure.

Comment thread src/scan.rs
Comment thread src/scan.rs
@@ -517,5 +561,6 @@ pub fn upload_scan(
sast_scan_id.map(|scan_id| ScanUploadResult {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale generic “Go to {base_url}” undercuts the new tracking URL

upload_scan still always prints Go to {base_url} to see results. before the caller prints the specific /project/.../?scan_id=... link via print_scan_tracking_url. Users now see two different destinations for the same upload.

Impact: Misleading output (and noisier CI logs) right as this PR’s value prop is “print the scan page URL.”

Fix: Drop or gate this generic line when a ScanUploadResult (with scan id) is being returned, and let the new tracking helper be the sole post-upload navigation hint.

Comment thread src/scan.rs

@yhoztak yhoztak left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Co-authored-by: ibrahim <ibrahim@corgea.com>
@Ibrahimrahhal
Ibrahimrahhal merged commit 4faf96b into main Jul 30, 2026
16 checks passed
@Ibrahimrahhal
Ibrahimrahhal deleted the cursor/upload-wait-and-scan-url-f604 branch July 30, 2026 06:23
Comment thread src/main.rs

if let Some(result) = result {
if *wait {
wait::run(&corgea_config, Some(result.scan_id), result.project_id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--wait still discards the uploaded project identity

upload_scan chooses the project from --project-name or, in CI, {GITHUB_REPOSITORY}-{GITHUB_PR} (src/scan.rs:209-222) and returns that value as ScanUploadResult.project_name (src/scan.rs:566-570). This call passes only the scan/project IDs. wait::run then derives project_name from the current directory and unconditionally calls query_scan_list for that unrelated project before it examines the supplied scan ID (src/wait.rs:6-32); an error exits 1. It also uses the CWD name for fallback links and reporting (src/wait.rs:54-79).

Impact: corgea upload report.json --project-name svc --wait and the documented CI upload path can successfully upload, then fail while querying the CWD project or print/report against the wrong project.

Concrete fix: pass result.project_name into wait::run, use it for reporting/fallback URLs, and skip the scan-list lookup when a scan_id is already supplied. Add a regression test where the uploaded project differs from the CWD project.

Comment thread src/main.rs
} else {
scan::print_scan_tracking_url(&corgea_config, &result);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--wait still fails open when a successful response has no scan ID

This gate silently does nothing when result is None. That state is reachable after a 2xx non-chunked upload: upload_scan treats a missing sast_scan_id as an error only for chunked uploads (src/scan.rs:462-467), then maps the absent ID to None (src/scan.rs:566).

Impact: CI can invoke upload --wait, receive exit code 0, and continue even though the command never waited for completion or printed results.

A narrow fix is to fail when waiting was requested but the API did not provide the ID:

Suggested change
}
} else if *wait {
log::error!(
"Upload succeeded but the server did not return a scan ID; cannot wait."
);
std::process::exit(1);
}

Also cover this branch with a CLI-level regression test so --wait cannot become a no-op again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants