javascript-refactoring

द्वारा github

जावास्क्रिप्ट कोड को अलग-अलग फ़ाइलों में रीफैक्टर करने के निर्देश

npx skills add https://github.com/github/gh-aw --skill javascript-refactoring

JavaScript Code Refactoring Guide

Use this guide to split JavaScript into maintainable CommonJS modules in gh-aw without drifting into dead embedding patterns.

Overview

The current gh-aw architecture is action-centric:

  • Shared JS modules live under pkg/workflow/js/*.cjs and actions/setup/js/*.cjs
  • Action source files live under actions/<action-name>/src/
  • Generated action bundles are committed under actions/<action-name>/index.js
  • Shipping is driven by the action build pipeline (make actions-build, gh aw actions-build) and dependency maps such as pkg/cli/actions_build_command.go
  • pkg/workflow/js.go is a stub; it no longer owns the runtime JavaScript shipping path for the main workflows

If you are refactoring a workflow utility, prefer the current action/module architecture over any older //go:embed pattern.

Top-Level Script Pattern

Top-level .cjs scripts executed directly in workflows follow this pattern:

✅ Correct Pattern - Export main, but don't call it:

async function main() {
  // Script logic here
  core.info("Running the script");
}

module.exports = { main };

❌ Incorrect Pattern - Don't call main in the file:

async function main() {
  // Script logic here
  core.info("Running the script");
}

await main(); // ❌ Don't do this!

module.exports = { main };

Why this pattern?

  • The workflow bundler or action build step can wrap the script with await main() at execution time
  • The module stays importable for tests while still being executable in GitHub Actions
  • It makes unit testing easier and preserves a clean module boundary

Step 1: Put the code in the right source tree

Choose the correct location for the module before writing code:

  • Shared workflow utilities: pkg/workflow/js/
  • Action-specific JavaScript: actions/<action-name>/src/ or actions/setup/js/
  • Generated bundle output: actions/<action-name>/index.js

File naming convention:

  • Use snake_case for filenames (for example sanitize_content.cjs, load_agent_output.cjs)
  • Use .cjs for CommonJS modules
  • Keep the name aligned with the responsibility of the module

Example file structure:

// @ts-check
/// <reference types="@actions/github-script" />

/**
 * Brief description of what this module does
 */

/**
 * Function documentation
 * @param {string} input - Description of parameter
 * @returns {string} Description of return value
 */
function myFunction(input) {
  return input;
}

module.exports = {
  myFunction,
};

Key points:

  • Include // @ts-check for TypeScript checking
  • Include /// <reference types="@actions/github-script" /> when the module is used with GitHub Actions scripts
  • Use JSDoc comments for documentation
  • Export functions via module.exports = { ... }
  • Do not import @actions/core or @actions/github directly unless the module is running in an action context that explicitly expects it

Step 2: Add tests next to the module

Create a matching test beside the module using the same base name plus .test.cjs:

Example: pkg/workflow/js/my_module.test.cjs

import { describe, it, expect, beforeEach, vi } from "vitest";

const mockCore = {
  debug: vi.fn(),
  info: vi.fn(),
  warning: vi.fn(),
  error: vi.fn(),
  setFailed: vi.fn(),
  setOutput: vi.fn(),
};

global.core = mockCore;

describe("myFunction", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("handles a normal input", async () => {
    const { myFunction } = await import("./my_module.cjs");
    expect(myFunction("test input")).toBe("expected output");
  });

  it("handles empty input", async () => {
    const { myFunction } = await import("./my_module.cjs");
    expect(myFunction("")).toBe("");
  });
});

Testing guidelines:

  • Use Vitest for test execution
  • Mock core and github globals as needed
  • Use dynamic imports (await import()) to allow module setup at test time
  • Clear mocks in beforeEach
  • Cover success, failure, and edge cases

Run tests:

make test-js

Step 3: Wire the module into the actual build path

Do not add a new //go:embed mapping just to ship a new runtime script. The current repo ships JavaScript through the action-generation/build pipeline.

Use this checklist:

  • Shared utility used by generated actions: update the relevant dependency mapping in pkg/cli/actions_build_command.go
  • Action-specific source file: add the module under actions/<action-name>/src/
  • Generated action bundle: rebuild with make actions-build
  • Shared workflow source for runtime modules: keep it under pkg/workflow/js/ and update the action or workflow definition that consumes it

Example design:

const { myFunction } = require("./my_module.cjs");

async function main() {
  const result = myFunction("some input");
  core.info(`Result: ${result}`);
}

module.exports = { main };

Step 4: Validate the refactor

Run the relevant checks for the area you changed:

make fmt-cjs
make lint-cjs
make test-js
make test-unit
make actions-build

Verification Checklist

Before committing your refactor:

  • New .cjs file created in the correct source directory
  • Matching .test.cjs file created
  • Tests pass with make test-js or the targeted Vitest suite
  • The module is wired through the real action/workflow build path
  • No stale embedding instructions were added for the current action-based JS build flow
  • Local require() statements work correctly in other JS files
  • Code formatted with make fmt-cjs
  • Relevant validation passes with make lint-cjs or make test-unit

Common Patterns

Pattern 1: Shared Utility Module

Files like sanitize_content.cjs or load_agent_output.cjs are best kept under pkg/workflow/js/ or actions/setup/js/ and consumed by other JS modules via require().

Pattern 2: Action-specific file

When the JavaScript belongs to a single action, keep it under actions/<action-name>/src/ and regenerate the output bundle with make actions-build.

Pattern 3: Top-level workflow script

If the script is executed directly in a workflow, export main and omit the direct await main() call. The host build/runtime step handles execution.

Troubleshooting

Issue: changes are not showing up in generated actions

Cause: Action bundle was not rebuilt after editing the source file

Solution:

make actions-build

Issue: tests fail with core is not defined

Cause: Missing global mocks

Solution:

global.core = mockCore;

Issue: the module is only used in one place

Cause: It was added to the wrong layer

Solution: Move it to the action-specific source tree instead of creating a broad workflow-level registry entry.

References

  • actions/README.md - current action-generation/build workflow
  • pkg/cli/actions_build_command.go - action dependency mapping
  • pkg/workflow/js/*.cjs - existing shared module patterns
  • actions/setup/js/*.cjs - action runtime/source examples

github की और Skills

debugging-workflows
github
GitHub एजेंटिक वर्कफ़्लो को डीबग करने के लिए गाइड - लॉग का विश्लेषण, रन का ऑडिट, और समस्याओं का समाधान
go-codemod
github
gh aw fix कमांड के लिए Go कोडमॉड को लागू और परीक्षण करें।
acreadiness-policy
github
उपयोगकर्ता को AgentRC नीति चुनने, लिखने या लागू करने में सहायता करें। नीतियाँ अप्रासंगिक जाँचों को अक्षम करके, प्रभाव/स्तर को ओवरराइड करके, सेट करके तत्परता स्कोरिंग को अनुकूलित करती हैं…
ai-ready
github
किसी भी रिपॉजिटरी को AI-तैयार बनाएं — आपके कोडबेस का विश्लेषण करता है और AGENTS.md, copilot-instructions.md, CI वर्कफ़्लो, इश्यू टेम्पलेट और अधिक जनरेट करता है। आपकी PR समीक्षा को माइन करता है…
create-oo-component-documentation
github
वस्तु-उन्मुख घटकों के लिए उद्योग की सर्वोत्तम प्रथाओं और वास्तुकला दस्तावेज़ीकरण मानकों का पालन करते हुए व्यापक, मानकीकृत दस्तावेज़ीकरण तैयार करें।
dependabot
github
Dependabot GitHub का अंतर्निहित निर्भरता प्रबंधन उपकरण है जिसमें तीन मुख्य क्षमताएँ हैं:
doublecheck
github
AI आउटपुट के लिए तीन-स्तरीय सत्यापन पाइपलाइन। सत्यापन योग्य दावों को निकालता है, वेब खोज के माध्यम से समर्थन या विरोधाभासी स्रोत ढूंढता है, प्रतिकूल समीक्षा चलाता है…
foundry-agent-sync
github
Azure AI Foundry में REST API के माध्यम से स्थानीय JSON मैनिफेस्ट से प्रॉम्प्ट-आधारित AI एजेंट बनाएं और सिंक्रोनाइज़ करें। स्कैफोल्डिंग कौशल के विपरीत जो केवल…