diff --git a/.changeset/fix-cross-repo-closer-require.md b/.changeset/fix-cross-repo-closer-require.md new file mode 100644 index 0000000000..990b00b01c --- /dev/null +++ b/.changeset/fix-cross-repo-closer-require.md @@ -0,0 +1,23 @@ +--- +--- + +fix(ci): hand the cross-repo token to github-script instead of requiring @actions/github + +Release-nothing: touches `.github/workflows/cross-repo-issue-closer.yml` only. + +`require('@actions/github')` is not resolvable from a github-script `script:` +block — the action bundles its dependencies, so the call fails at runtime with +`MODULE_NOT_FOUND`. The token is now handed to the action itself +(`github-token:`), which makes the injected `github` client the cross-repo one, +with `secrets.GITHUB_TOKEN` as the fallback so the report path can still +comment on the pull request when no cross-repo credential is configured. + +Observed in objectui, whose copy of this workflow reached that line first. Its +run also confirmed the credential logging added alongside works, printing +`CROSS_REPO_ISSUE_TOKEN: configured` before failing at the require. + +This supersedes #4573, which renamed the second client without removing it — +the rename fixed the identifier collision that aborted parsing, and only then +did the run get far enough to hit the unresolvable module. Three failures in +three consecutive runs, each one further down the same script: parse, resolve, +then (expected next) the API calls themselves. diff --git a/.github/workflows/cross-repo-issue-closer.yml b/.github/workflows/cross-repo-issue-closer.yml index dadaaf4282..03e7c90842 100644 --- a/.github/workflows/cross-repo-issue-closer.yml +++ b/.github/workflows/cross-repo-issue-closer.yml @@ -46,6 +46,12 @@ jobs: # to the repository running the workflow, which is the whole problem. CROSS_REPO_TOKEN: ${{ secrets.CROSS_REPO_ISSUE_TOKEN }} with: + # Hand the cross-repo token to the action itself, so `github` IS the + # cross-repo client. `require('@actions/github')` does NOT work here: + # github-script bundles its dependencies and the module is not + # resolvable from the script scope (`MODULE_NOT_FOUND`). Falling back + # to GITHUB_TOKEN keeps the report path able to comment on this PR. + github-token: ${{ secrets.CROSS_REPO_ISSUE_TOKEN || secrets.GITHUB_TOKEN }} script: | const body = context.payload.pull_request.body || ''; const prUrl = context.payload.pull_request.html_url; @@ -109,27 +115,23 @@ jobs: return; } - // A second client: `github` is bound to GITHUB_TOKEN, which has no - // write access outside this repository. - const crossRepo = require('@actions/github').getOctokit(token); - for (const [key, t] of targets) { try { - const { data: issue } = await crossRepo.rest.issues.get({ + const { data: issue } = await github.rest.issues.get({ owner: t.owner, repo: t.repo, issue_number: t.number, }); if (issue.state === 'closed') { core.info(`${key} is already closed — skipping.`); continue; } - await crossRepo.rest.issues.createComment({ + await github.rest.issues.createComment({ owner: t.owner, repo: t.repo, issue_number: t.number, body: `已由 ${thisRepo} 的 ${prUrl} 修复并合并。\n\n` + `(跨仓库的关闭关键字不会自动生效,本条由 \`cross-repo-issue-closer\` 工作流代为收口。)\n\n` + `---\n_Generated by [Claude Code](https://claude.ai/code)_`, }); - await crossRepo.rest.issues.update({ + await github.rest.issues.update({ owner: t.owner, repo: t.repo, issue_number: t.number, state: 'closed', state_reason: 'completed', });