[GH-ISSUE #519] Asset uploads: use upload timeout config in UploadAssetFromFile #144

Closed
opened 2026-02-26 21:33:45 +03:00 by kerem · 3 comments
Owner

Originally created by @rudrankriyam on GitHub (Feb 14, 2026).
Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/519

Summary

internal/asc/assets_upload.go uses ResolveTimeout() for asset upload HTTP client timeout instead of ResolveUploadTimeout().

Why this matters

Upload flows should honor upload timeout policy (ASC_UPLOAD_TIMEOUT / ASC_UPLOAD_TIMEOUT_SECONDS). Using the normal request timeout can prematurely fail larger uploads.

Current behavior

UploadAssetFromFile initializes:

client := &http.Client{Timeout: ResolveTimeout()}

Expected behavior

Upload code should use upload timeout resolution:

  • ResolveUploadTimeout()

Reproduction

  1. Configure shorter normal timeout and longer upload timeout.
  2. Trigger a slower/larger asset upload path using UploadAssetFromFile.
  3. Observe timeout aligns with normal timeout, not upload timeout settings.

Detailed implementation plan

  • Update UploadAssetFromFile to use ResolveUploadTimeout().
  • Verify consistency with other upload paths (internal/asc/upload.go, publish/notary helpers where applicable).
  • Add/adjust unit tests to assert timeout source for asset upload client creation.
  • Document timeout behavior for upload-related commands if needed.

Acceptance criteria

  • Asset uploads honor upload timeout config/env variables.
  • No regressions in upload operation behavior.
  • Timeout handling remains explicit and test-covered.

cc @cursor please implement this end-to-end.

Originally created by @rudrankriyam on GitHub (Feb 14, 2026). Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/519 ## Summary `internal/asc/assets_upload.go` uses `ResolveTimeout()` for asset upload HTTP client timeout instead of `ResolveUploadTimeout()`. ## Why this matters Upload flows should honor upload timeout policy (`ASC_UPLOAD_TIMEOUT` / `ASC_UPLOAD_TIMEOUT_SECONDS`). Using the normal request timeout can prematurely fail larger uploads. ## Current behavior `UploadAssetFromFile` initializes: ```go client := &http.Client{Timeout: ResolveTimeout()} ``` ## Expected behavior Upload code should use upload timeout resolution: - `ResolveUploadTimeout()` ## Reproduction 1. Configure shorter normal timeout and longer upload timeout. 2. Trigger a slower/larger asset upload path using `UploadAssetFromFile`. 3. Observe timeout aligns with normal timeout, not upload timeout settings. ## Detailed implementation plan - [ ] Update `UploadAssetFromFile` to use `ResolveUploadTimeout()`. - [ ] Verify consistency with other upload paths (`internal/asc/upload.go`, publish/notary helpers where applicable). - [ ] Add/adjust unit tests to assert timeout source for asset upload client creation. - [ ] Document timeout behavior for upload-related commands if needed. ## Acceptance criteria - [ ] Asset uploads honor upload timeout config/env variables. - [ ] No regressions in upload operation behavior. - [ ] Timeout handling remains explicit and test-covered. cc @cursor please implement this end-to-end.
kerem 2026-02-26 21:33:45 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@rudrankriyam commented on GitHub (Feb 14, 2026):

@cursor please implement this issue end-to-end using the checklist and acceptance criteria.

<!-- gh-comment-id:3900361530 --> @rudrankriyam commented on GitHub (Feb 14, 2026): @cursor please implement this issue end-to-end using the checklist and acceptance criteria.
Author
Owner

@cursor[bot] commented on GitHub (Feb 14, 2026):

Implemented end-to-end on cursor/upload-timeout-resolution-907d and pushed as commit 0ab3178.

  • I fixed the timeout source in UploadAssetFromFile to use upload timeout config:
func UploadAssetFromFile(ctx context.Context, file *os.File, fileSize int64, operations []UploadOperation) error {
	if len(operations) == 0 {
		return fmt.Errorf("no upload operations provided")
	}

	client := &http.Client{Timeout: ResolveUploadTimeout()}
  • I added explicit behavioral tests that prove ASC_UPLOAD_TIMEOUT is honored (both directions: longer upload timeout succeeds, shorter upload timeout fails even if normal timeout is longer):
func TestUploadAssetFromFileUsesUploadTimeoutEnv(t *testing.T) {
	t.Setenv("ASC_TIMEOUT", "10ms")
	t.Setenv("ASC_UPLOAD_TIMEOUT", "250ms")
	// ...
	if err := UploadAssetFromFile(context.Background(), file, 3, ops); err != nil {
		t.Fatalf("UploadAssetFromFile() error: %v", err)
	}
}

func TestUploadAssetFromFileUsesUploadTimeoutWhenShorter(t *testing.T) {
	t.Setenv("ASC_TIMEOUT", "250ms")
	t.Setenv("ASC_UPLOAD_TIMEOUT", "10ms")
	// ...
	if err == nil {
		t.Fatalf("expected timeout error, got nil")
	}
}

Validation and checklist coverage:

  • Reproduced RED state first (new tests failed before fix exactly as expected).
  • Verified GREEN state after fix: go test ./internal/asc -run TestUploadAssetFromFileUsesUploadTimeout -count=1 passed.
  • Ran repo guardrails: make format, make lint, make test (all passing).
  • Walkthrough artifact uploaded: /opt/cursor/artifacts/upload_timeout_end_to_end_validation.txt (contains targeted timeout tests + lint + full test suite output).

View PR

Open in Cursor Open in Web

<!-- gh-comment-id:3900361634 --> @cursor[bot] commented on GitHub (Feb 14, 2026): Implemented end-to-end on `cursor/upload-timeout-resolution-907d` and pushed as commit **`0ab3178`**. - I fixed the timeout source in `UploadAssetFromFile` to use upload timeout config: ```39:45:internal/asc/assets_upload.go func UploadAssetFromFile(ctx context.Context, file *os.File, fileSize int64, operations []UploadOperation) error { if len(operations) == 0 { return fmt.Errorf("no upload operations provided") } client := &http.Client{Timeout: ResolveUploadTimeout()} ``` - I added explicit behavioral tests that prove `ASC_UPLOAD_TIMEOUT` is honored (both directions: longer upload timeout succeeds, shorter upload timeout fails even if normal timeout is longer): ```134:191:internal/asc/assets_upload_test.go func TestUploadAssetFromFileUsesUploadTimeoutEnv(t *testing.T) { t.Setenv("ASC_TIMEOUT", "10ms") t.Setenv("ASC_UPLOAD_TIMEOUT", "250ms") // ... if err := UploadAssetFromFile(context.Background(), file, 3, ops); err != nil { t.Fatalf("UploadAssetFromFile() error: %v", err) } } func TestUploadAssetFromFileUsesUploadTimeoutWhenShorter(t *testing.T) { t.Setenv("ASC_TIMEOUT", "250ms") t.Setenv("ASC_UPLOAD_TIMEOUT", "10ms") // ... if err == nil { t.Fatalf("expected timeout error, got nil") } } ``` Validation and checklist coverage: - Reproduced RED state first (new tests failed before fix exactly as expected). - Verified GREEN state after fix: `go test ./internal/asc -run TestUploadAssetFromFileUsesUploadTimeout -count=1` passed. - Ran repo guardrails: `make format`, `make lint`, `make test` (all passing). - Walkthrough artifact uploaded: **`/opt/cursor/artifacts/upload_timeout_end_to_end_validation.txt`** (contains targeted timeout tests + lint + full test suite output). <p><a href="https://github.com/rudrankriyam/App-Store-Connect-CLI/pull/526"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/view-pr-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/view-pr-light.png"><img alt="View PR" width="86" height="28" src="https://cursor.com/assets/images/view-pr-light.png"></picture></a></p> <p><a href="https://cursor.com/background-agent?bcId=bc-689502de-e55f-4c3a-8675-17dfd8162779"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/agents?id=bc-689502de-e55f-4c3a-8675-17dfd8162779"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a></p>
Author
Owner

@rudrankriyam commented on GitHub (Feb 14, 2026):

Fixed in #526 (merged to main).

<!-- gh-comment-id:3900688920 --> @rudrankriyam commented on GitHub (Feb 14, 2026): Fixed in #526 (merged to main).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/App-Store-Connect-CLI#144
No description provided.