From 3d2b23804d95377315c3c91ddb7fc4d912c1faf0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Dec 2025 03:47:20 +0000 Subject: [PATCH 1/3] Initial plan From b445202f707649e883a78f03e13f4e4e4c3913d4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Dec 2025 03:53:13 +0000 Subject: [PATCH 2/3] Initial plan: Update JavaScript developer instructions for top-level .cjs export pattern Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/issue-classifier.lock.yml | 2 +- .github/workflows/release.lock.yml | 6 +++--- .github/workflows/stale-repo-identifier.lock.yml | 2 +- .github/workflows/super-linter.lock.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/issue-classifier.lock.yml b/.github/workflows/issue-classifier.lock.yml index 44eafee6c7..02134fb672 100644 --- a/.github/workflows/issue-classifier.lock.yml +++ b/.github/workflows/issue-classifier.lock.yml @@ -2204,7 +2204,7 @@ jobs: path: /tmp/gh-aw/aw_info.json if-no-files-found: warn - name: Run AI Inference - uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v2.0.4 + uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v1 env: GH_AW_MCP_CONFIG: /tmp/gh-aw/mcp-config/mcp-servers.json GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 658d3b9a1d..0be3614def 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -6017,13 +6017,13 @@ jobs: - name: Download Go modules run: go mod download - name: Generate SBOM (SPDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 with: artifact-name: sbom.spdx.json format: spdx-json output-file: sbom.spdx.json - name: Generate SBOM (CycloneDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 with: artifact-name: sbom.cdx.json format: cyclonedx-json @@ -6227,7 +6227,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Release with gh-extension-precompile - uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2.1.0 + uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2 with: build_script_override: scripts/build-release.sh go_version_file: go.mod diff --git a/.github/workflows/stale-repo-identifier.lock.yml b/.github/workflows/stale-repo-identifier.lock.yml index 144161022a..eee179e885 100644 --- a/.github/workflows/stale-repo-identifier.lock.yml +++ b/.github/workflows/stale-repo-identifier.lock.yml @@ -174,7 +174,7 @@ jobs: ORGANIZATION: ${{ env.ORGANIZATION }} id: stale-repos name: Run stale_repos tool - uses: github/stale-repos@a21e55567b83cf3c3f3f9085d3038dc6cee02598 # v3.0.2 + uses: github/stale-repos@a21e55567b83cf3c3f3f9085d3038dc6cee02598 # v3 - env: INACTIVE_REPOS: ${{ steps.stale-repos.outputs.inactiveRepos }} name: Save stale repos output diff --git a/.github/workflows/super-linter.lock.yml b/.github/workflows/super-linter.lock.yml index 5207834200..4d0e7e71fe 100644 --- a/.github/workflows/super-linter.lock.yml +++ b/.github/workflows/super-linter.lock.yml @@ -6146,7 +6146,7 @@ jobs: persist-credentials: false - name: Super-linter id: super-linter - uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.3.1 + uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.2.1 env: CREATE_LOG_FILE: "true" DEFAULT_BRANCH: main From ceabab0c7f7ee6a05f3f835945a49f54272f05e2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Dec 2025 03:59:48 +0000 Subject: [PATCH 3/3] Update JavaScript developer instructions to clarify export main pattern - Add new "Top-Level Script Pattern" section explaining the correct pattern - Show correct pattern: export main but don't call it - Show incorrect pattern: calling await main() in the file - Explain why: bundler injects await main() during inline execution - Update all examples to use correct pattern (module.exports only) - Add clarification to Pattern 2 section about main workflow scripts - Provide real examples from codebase (create_issue.cjs, add_comment.cjs, etc.) Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/issue-classifier.lock.yml | 2 +- .github/workflows/release.lock.yml | 6 +-- .../workflows/stale-repo-identifier.lock.yml | 2 +- .github/workflows/super-linter.lock.yml | 2 +- pkg/workflow/js/create_issue.test.cjs | 4 +- skills/javascript-refactoring/SKILL.md | 49 ++++++++++++++++++- 6 files changed, 54 insertions(+), 11 deletions(-) diff --git a/.github/workflows/issue-classifier.lock.yml b/.github/workflows/issue-classifier.lock.yml index 02134fb672..44eafee6c7 100644 --- a/.github/workflows/issue-classifier.lock.yml +++ b/.github/workflows/issue-classifier.lock.yml @@ -2204,7 +2204,7 @@ jobs: path: /tmp/gh-aw/aw_info.json if-no-files-found: warn - name: Run AI Inference - uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v1 + uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v2.0.4 env: GH_AW_MCP_CONFIG: /tmp/gh-aw/mcp-config/mcp-servers.json GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 0be3614def..658d3b9a1d 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -6017,13 +6017,13 @@ jobs: - name: Download Go modules run: go mod download - name: Generate SBOM (SPDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 with: artifact-name: sbom.spdx.json format: spdx-json output-file: sbom.spdx.json - name: Generate SBOM (CycloneDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 with: artifact-name: sbom.cdx.json format: cyclonedx-json @@ -6227,7 +6227,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Release with gh-extension-precompile - uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2 + uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2.1.0 with: build_script_override: scripts/build-release.sh go_version_file: go.mod diff --git a/.github/workflows/stale-repo-identifier.lock.yml b/.github/workflows/stale-repo-identifier.lock.yml index eee179e885..144161022a 100644 --- a/.github/workflows/stale-repo-identifier.lock.yml +++ b/.github/workflows/stale-repo-identifier.lock.yml @@ -174,7 +174,7 @@ jobs: ORGANIZATION: ${{ env.ORGANIZATION }} id: stale-repos name: Run stale_repos tool - uses: github/stale-repos@a21e55567b83cf3c3f3f9085d3038dc6cee02598 # v3 + uses: github/stale-repos@a21e55567b83cf3c3f3f9085d3038dc6cee02598 # v3.0.2 - env: INACTIVE_REPOS: ${{ steps.stale-repos.outputs.inactiveRepos }} name: Save stale repos output diff --git a/.github/workflows/super-linter.lock.yml b/.github/workflows/super-linter.lock.yml index 4d0e7e71fe..5207834200 100644 --- a/.github/workflows/super-linter.lock.yml +++ b/.github/workflows/super-linter.lock.yml @@ -6146,7 +6146,7 @@ jobs: persist-credentials: false - name: Super-linter id: super-linter - uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.2.1 + uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.3.1 env: CREATE_LOG_FILE: "true" DEFAULT_BRANCH: main diff --git a/pkg/workflow/js/create_issue.test.cjs b/pkg/workflow/js/create_issue.test.cjs index 06cd766eb7..8d8bcfa268 100644 --- a/pkg/workflow/js/create_issue.test.cjs +++ b/pkg/workflow/js/create_issue.test.cjs @@ -49,9 +49,7 @@ const mockCore = { delete process.env.GH_AW_ALLOWED_REPOS, delete global.context.payload.issue); const scriptPath = path.join(process.cwd(), "create_issue.cjs"); - ((createIssueScript = fs.readFileSync(scriptPath, "utf8")), - (createIssueScript = createIssueScript.replace("export {};", "")), - (createIssueScript = createIssueScript.replace(/module\.exports = \{ main \};?\s*$/, ""))); + ((createIssueScript = fs.readFileSync(scriptPath, "utf8")), (createIssueScript = createIssueScript.replace("export {};", "")), (createIssueScript = createIssueScript.replace(/module\.exports = \{ main \};?\s*$/, ""))); }), afterEach(() => { tempFilePath && require("fs").existsSync(tempFilePath) && (require("fs").unlinkSync(tempFilePath), (tempFilePath = void 0)); diff --git a/skills/javascript-refactoring/SKILL.md b/skills/javascript-refactoring/SKILL.md index 39b29ab16e..fa99b1cf6d 100644 --- a/skills/javascript-refactoring/SKILL.md +++ b/skills/javascript-refactoring/SKILL.md @@ -15,6 +15,46 @@ The gh-aw project uses CommonJS modules (`.cjs` files) for JavaScript code that - Bundled using a custom JavaScript bundler that inlines local `require()` calls - Executed in GitHub Actions using `actions/github-script@v8` +### Top-Level Script Pattern + +Top-level `.cjs` scripts (those that are executed directly in workflows) follow a specific pattern: + +**✅ Correct Pattern - Export main, but don't call it:** +```javascript +async function main() { + // Script logic here + core.info("Running the script"); +} + +module.exports = { main }; +``` + +**❌ Incorrect Pattern - Don't call main in the file:** +```javascript +async function main() { + // Script logic here + core.info("Running the script"); +} + +await main(); // ❌ Don't do this! + +module.exports = { main }; +``` + +**Why this pattern?** +- The bundler automatically injects `await main()` during inline execution in GitHub Actions +- This allows the script to be both imported (for testing) and executed (in workflows) +- It provides a clean separation between module definition and execution +- It enables better testing by allowing tests to import and call `main()` with mocks + +**Examples of top-level scripts:** +- `create_issue.cjs` - Creates GitHub issues +- `add_comment.cjs` - Adds comments to issues/PRs +- `add_labels.cjs` - Adds labels to issues/PRs +- `update_project.cjs` - Updates GitHub Projects + +All of these files export `main` but do not call it directly. + ## Step 1: Create the New .cjs File Create your new file in `/home/runner/work/gh-aw/gh-aw/pkg/workflow/js/` with a descriptive name: @@ -218,9 +258,11 @@ async function main() { core.info(`Result: ${result}`); } -await main(); +module.exports = { main }; ``` +**Important:** Top-level scripts should export `main` but **NOT** call it directly. The bundler injects `await main()` during inline execution in GitHub Actions. + **Require guidelines:** - Use relative paths starting with `./` - Include the `.cjs` extension @@ -339,9 +381,11 @@ async function main() { core.info(`Current time: ${formatTimestamp(now)}`); } -await main(); +module.exports = { main }; ``` +**Note:** The script exports `main` but does not call it. The bundler will inject `await main()` when the script is executed inline in GitHub Actions. + ### 5. Build and test: ```bash @@ -389,6 +433,7 @@ Files like `create_issue.cjs`, `add_labels.cjs` that are top-level scripts: - Add to `scripts.go` with `//go:embed` as `xxxSource` variable - Create bundling getter function with `sync.Once` pattern - These scripts can `require()` utilities from `GetJavaScriptSources()` +- **Must export `main` function but NOT call it** - the bundler injects `await main()` during execution ### Pattern 3: Log Parser