Skip to content

[jsweep] Clean upload_assets.cjs#38284

Closed
github-actions[bot] wants to merge 1 commit into
mainfrom
signed/jsweep/upload-assets-20260610-16932af298d45312
Closed

[jsweep] Clean upload_assets.cjs#38284
github-actions[bot] wants to merge 1 commit into
mainfrom
signed/jsweep/upload-assets-20260610-16932af298d45312

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Summary

Cleaned upload_assets.cjs as part of the daily jsweep run.

Context

Execution context: github-script (uses core, exec globals)

Changes to upload_assets.cjs

  • Added a @typedef for UploadAssetItem to properly type the filtered items array
  • Replaced the awkward inline /** @param {any} item */ annotation inside filter() with a clean type-cast using the new typedef

Changes to upload_assets.test.cjs

Full rewrite of the test file from minified/compressed form to readable, well-structured format.

Tests: 5 → 14 (+9 new test cases)

New tests added:

  • branch env var validation — fails with ERR_CONFIG when GH_AW_ASSETS_BRANCH is not set
  • agent output handlingupload_count=0 when agent output fails to load
  • agent output handlingupload_count=0 when items list has no upload-asset entries
  • asset validation — fails with ERR_VALIDATION on SHA mismatch
  • asset validation — fails with ERR_SYSTEM when source file is missing
  • asset validation — fails with ERR_VALIDATION when required asset fields are absent
  • file upload behaviour — skips assets whose target file already exists
  • file upload behaviour — suppresses git push in staged mode
  • file upload behaviour — calls git push origin in non-staged mode

All pre-existing tests were preserved in a cleaner, more readable form.

Validation ✅

  • Formatting: npm run format:cjs
  • Linting: npm run lint:cjs
  • Type checking: npm run typecheck
  • Tests: npm run test:js14 passed

Generated by 🧹 jsweep - JavaScript Unbloater · ⌖ 47.1 AIC · ⊞ 18.7K ·

  • expires on Jun 11, 2026, 9:19 PM UTC-08:00

- Add `@typedef` for `UploadAssetItem` to type the filtered items array properly
- Remove the awkward inline `/** @param {any} item */` annotation inside `filter()`
- Rewrite test file from minified/compact form to readable, well-structured format
- Expand test suite from 5 to 14 tests, adding coverage for:
  - Missing `GH_AW_ASSETS_BRANCH` env var (ERR_CONFIG)
  - Agent output load failures
  - Empty upload-asset items list
  - SHA mismatch (ERR_VALIDATION)
  - Missing asset source file (ERR_SYSTEM)
  - Missing required asset fields (ERR_VALIDATION)
  - Skipping assets whose target file already exists
  - Staged mode suppressing git push
  - Non-staged mode calling git push

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@pelikhan pelikhan marked this pull request as ready for review June 10, 2026 05:33
Copilot AI review requested due to automatic review settings June 10, 2026 05:33
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #38284 does not have the 'implementation' label (has_implementation_label=false) and has 0 new lines of code in business logic directories (≤100 threshold, requires_adr_by_default_volume=false).

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

🧠 Matt Pocock Skills Reviewer was skipped during the skills-based review.

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Test Quality Sentinel was skipped during test quality analysis.

Copilot AI 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.

Pull request overview

This PR cleans up the actions/setup/js/upload_assets.cjs github-script helper and fully rewrites actions/setup/js/upload_assets.test.cjs from a compressed/minified format into readable, structured Vitest tests, substantially expanding coverage for validation and git-flow behaviors.

Changes:

  • Added a JSDoc @typedef and replaced an inline filter() param annotation with a type-cast for the filtered upload-asset items array.
  • Rewrote upload_assets.test.cjs into a maintainable structure and added many new targeted test cases (env validation, agent output handling, asset validation, staged vs non-staged push behavior).
Show a summary per file
File Description
actions/setup/js/upload_assets.cjs Introduces a typedef and cleans up typing around filtering upload-asset items.
actions/setup/js/upload_assets.test.cjs Reformats and expands tests to cover more validation and upload/push behaviors.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment on lines +80 to +84
afterEach(() => {
for (const f of tempFiles) {
if (fs.existsSync(f)) fs.unlinkSync(f);
}
});
@github-actions github-actions Bot mentioned this pull request Jun 10, 2026
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Three cleanup regressions need fixing before merge.

### Blocking issues (3)

Test file temp-file leaks (2 regressions from the old code):

  • setAgentOutput() — the old code tracked the agent-output JSON in tempFilePath and deleted it in afterEach; the rewrite returns the path but no call site registers it, so every test leaves a file in /tmp.
  • createAssetFile() — callers push only the local targetFileName (CWD copy) into tempFiles, never assetPath (the fixture in /tmp/gh-aw/safeoutputs/assets/). Stale ASSET_DIR fixtures can cause false positives on test retry or re-run (e.g. the ERR_SYSTEM/ghost.png test).

mockCore dropped debug and notice: the previous mock included both; their absence will produce cryptic TypeError: core.xxx is not a function errors the moment either method is called in the script.

### Non-blocking (1)

upload_assets.cjs line 82: JSDoc type assertion is missing the required parentheses (/** @type {T} */ (expr)).

🔎 Code quality review by PR Code Quality Reviewer · 11 AIC · ⌖ 13.5 AIC

const content = typeof data === "string" ? data : JSON.stringify(data);
fs.writeFileSync(filePath, content);
process.env.GH_AW_AGENT_OUTPUT = filePath;
return filePath;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

setAgentOutput leaks temp files on every test invocation: the returned filePath is never pushed to tempFiles, so afterEach never removes it. The old code explicitly tracked this in a tempFilePath variable and cleaned it up — this PR silently drops that.

💡 Suggested fix

Either have callers push the return value, or have the helper register it directly:

function setAgentOutput(data) {
  const filePath = path.join("/tmp", `test_agent_output_${Date.now()}_${Math.random().toString(36).slice(2)}.json`);
  const content = typeof data === "string" ? data : JSON.stringify(data);
  fs.writeFileSync(filePath, content);
  process.env.GH_AW_AGENT_OUTPUT = filePath;
  tempFiles.push(filePath); // register for cleanup
  return filePath;
}

Note: tempFiles is suite-scoped so setAgentOutput can’t access it directly as written. The simplest fix is for each call site to do tempFiles.push(setAgentOutput(...)), or pass tempFiles as a parameter.

const assetPath = path.join(ASSET_DIR, fileName);
fs.writeFileSync(assetPath, content);
const sha = crypto.createHash("sha256").update(fs.readFileSync(assetPath)).digest("hex");
return { assetPath, sha, size: content.length };

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ASSET_DIR fixture files are never cleaned up: createAssetFile writes to /tmp/gh-aw/safeoutputs/assets/<fileName> and returns assetPath, but callers only push the local targetFileName into tempFiles — never assetPath. The source fixtures accumulate across test runs.

💡 Why this matters

If the same runner executes the suite twice (retry, re-run, parallel shard), stale files linger in ASSET_DIR. Any test that expects a file to not exist there (e.g. the ERR_SYSTEM test for ghost.png) could false-pass if a previous run left a matching file behind — or vice versa.

Fix: push assetPath into tempFiles at every call site:

const { assetPath, sha, size } = createAssetFile("orphan-test.png");
tempFiles.push(assetPath); // ← was missing

or have createAssetFile accept the tempFiles array and register itself.

}));
}));
}));
};

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

mockCore silently dropped debug and notice: the previous mock included both debug: vi.fn() and notice: vi.fn(). Removing them means any future core.debug() or core.notice() call in upload_assets.cjs will throw TypeError: core.debug is not a function rather than failing with a meaningful assertion.

💡 Suggested fix

Add the missing stubs to keep the mock surface complete:

mockCore = {
  debug: vi.fn(), // ← restore
  info: vi.fn(),
  notice: vi.fn(), // ← restore
  warning: vi.fn(),
  error: vi.fn(),
  setFailed: vi.fn(),
  setOutput: vi.fn(),
  summary: {
    addRaw: vi.fn().mockReturnThis(),
    write: vi.fn().mockResolvedValue(undefined),
  },
};

@actions/core exposes all of these publicly; the mock should match its shape.


// Find all upload-asset items
const uploadItems = result.items.filter(/** @param {any} item */ item => item.type === "upload_asset");
const uploadItems = /** @type {UploadAssetItem[]} */ result.items.filter(item => item.type === "upload_asset");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

JSDoc type assertion requires parentheses around the expression: TypeScript JSDoc mandates /** @type {T} */ (expr) with parens. Without them, TypeScript treats @type as a variable annotation on uploadItems (silencing inference) rather than a checked cast that validates result.items.filter(...) is actually assignable to UploadAssetItem[]. The file is // @ts-check``, so the distinction matters.

💡 Suggested fix
const uploadItems = /** `@type` {UploadAssetItem[]} */ (result.items.filter(item => item.type === "upload_asset"));

The parenthesized form is the only form TypeScript recognises as a proper type assertion in JSDoc; see the [TypeScript JSDoc reference]((www.typescriptlang.org/redacted)

@pelikhan pelikhan closed this Jun 10, 2026
@github-actions github-actions Bot added the closed:unknown PR was closed without merging: unknown label Jun 10, 2026
Copilot stopped work on behalf of pelikhan due to an error June 10, 2026 05:49
Copilot AI requested a review from pelikhan June 10, 2026 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automation closed:unknown PR was closed without merging: unknown unbloat

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants