Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions packages/gittensory-miner/lib/loop-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,17 @@ export async function runLoop(args, options = {}) {
const buildLoopClosureSummaryFn = options.buildLoopClosureSummary ?? buildLoopClosureSummary;
const attemptLoopReentryFn = options.attemptLoopReentry ?? attemptLoopReentry;

// Resolved ONCE, at the CLI-entrypoint layer, mirroring manage-poll.js's own runManagePoll (its
// recordManagePollSnapshot callee has no env fallback of its own either -- the top-level CLI function is
// where `process.env.GITHUB_TOKEN` gets read, then threaded down explicitly to every real GitHub caller).
// pollPrDisposition (unlike runDiscover, which falls back to process.env.GITHUB_TOKEN internally) has NO
// such fallback -- an unresolved githubToken here would silently poll unauthenticated.
const githubToken = options.githubToken ?? env.GITHUB_TOKEN ?? "";

async function runDiscoveryOnce() {
await runDiscoverFn(discoverArgv(parsed), {
initPortfolioQueue: () => portfolioQueue,
githubToken: options.githubToken,
githubToken,
apiBaseUrl: options.apiBaseUrl,
nowMs: nowMsFn(),
});
Expand Down Expand Up @@ -377,7 +384,11 @@ export async function runLoop(args, options = {}) {
if (submitted) {
prNumber = parsePrNumberFromExecResult(lastResult?.execResult, claimed.repoFullName);
if (prNumber !== null) {
prDisposition = await pollPrDispositionFn(claimed.repoFullName, prNumber, options.prDispositionOptions ?? {});
prDisposition = await pollPrDispositionFn(claimed.repoFullName, prNumber, {
githubToken,
apiBaseUrl: options.apiBaseUrl,
...(options.prDispositionOptions ?? {}),
});
if (prDisposition.state === "closed") {
recordPrOutcomeSnapshotFn(
{
Expand Down
6 changes: 5 additions & 1 deletion test/unit/miner-loop-cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ describe("runLoop (#5135)", () => {
const pollPrDispositionSpy = vi.fn().mockResolvedValue({ state: "closed", merged: true, closedAt: "2026-07-12T00:00:00Z", attempts: 1 });

const exitCode = await runLoop(["acme/widgets", "--miner-login", "alice", "--max-cycles", "2", "--json"], {
env: { GITHUB_TOKEN: "ghp_loop_test" },
openGovernorState: () => governorState,
initEventLedger: () => eventLedger,
initGovernorLedger: () => governorLedger,
Expand All @@ -233,7 +234,10 @@ describe("runLoop (#5135)", () => {
const [attemptArgv] = runAttemptSpy.mock.calls[0]!;
expect(attemptArgv).toEqual(["acme/widgets", "7", "--miner-login", "alice", "--base", "main"]);

expect(pollPrDispositionSpy).toHaveBeenCalledWith("acme/widgets", 123, expect.anything());
// REGRESSION: the real githubToken (resolved from env.GITHUB_TOKEN, same as runDiscover's own call) must
// reach the poller -- an unauthenticated poll would silently hit GitHub's much lower rate limit or fail
// outright against a private repo.
expect(pollPrDispositionSpy).toHaveBeenCalledWith("acme/widgets", 123, expect.objectContaining({ githubToken: "ghp_loop_test" }));

const after = reopenAfterRun(paths);

Expand Down