Fix stale-approval bypass in BCR PR reviewer's review-freshness check (#2764)

## Summary

`actions/bcr-pr-reviewer/index.js`'s `getPrApprovers()` decides whether
an existing GitHub review is still valid by comparing its `submitted_at`
against the timestamp of "the latest commit" -- but it computes that
timestamp only from commits whose `parents.length === 1`, explicitly
filtering out merge commits:

```js
// Filter out the merge commits whose parents length is larger than 1
const nonMergeCommits = commits.filter(commit => commit.parents.length === 1);
const latestCommit = nonMergeCommits[nonMergeCommits.length - 1];
const latestCommitTime = new Date(latestCommit.commit.author.date);
...
reviewEvents.forEach(review => {
  if (new Date(review.submitted_at) < latestCommitTime) {
    return; // review is stale, ignore it
  }
  ...
});
```

A merge commit can itself carry diff content -- conflict resolution, or
content brought in from whatever was merged -- so excluding it from "the
latest commit" means a review submitted *before* that merge commit still
counts as approving the PR's *current* head, even though the reviewer
never saw the merge commit's content.

Concretely: a contributor gets an early, innocuous commit approved by a
maintainer, then pushes a merge commit that changes the PR's actual
content. `getPrApprovers()` still returns that maintainer as a current
approver, because the merge commit is invisible to its freshness
calculation.

`reviewPR()` (in the same file) uses `getPrApprovers()`'s output to
decide whether to submit its own `APPROVE` review and call
`pulls.merge()`:

```js
if (allModulesApproved && !hasSensitiveMetadataChange) {
  if (!approvers.has(myLogin)) {
    await octokit.rest.pulls.createReview({ ..., event: 'APPROVE', ... });
  }
  await octokit.rest.pulls.merge({ ... });
  ...
}
```

So this bug lets the bot submit its own fresh `APPROVE` review and merge
a PR based on a maintainer's approval of content that is no longer
what's actually being merged.

**Why this is the sole gate, not defense-in-depth:**
`bazel-central-registry`'s `CODEOWNERS` file explicitly excludes
`modules/` from GitHub's native code-owner review requirement:
```
*          @bazelbuild/bcr-maintainers
/modules/
```
with the comment "which has a bot that manages review requests" -- i.e.
this bot's own approval decision is the *only* review gate for module
changes, there's no redundant native check backing it up for that path.

I verified the mechanics with a standalone script (not just by reading
the source) that reproduces `getPrApprovers()`'s exact logic against
fabricated commit/review data shaped like the real GitHub API responses:
a review approving commit C1, followed by a 2-parent merge commit C2 as
the new PR head, still returns the reviewer as an approver of C2's
content.

## Fix

Use the PR's actual last commit (`commits[commits.length - 1]`) as the
freshness cutoff, without excluding merge commits. `pulls.listCommits`
already returns commits in chronological order, so the last entry is
always the true current PR head regardless of its parent count --
there's no need to special-case merge commits at all.

Also fixed two accidentally-undeclared variables (`existingSubmittedAt`,
`submittedAt`) in the same block (missing `const`, silently created
implicit globals in this non-strict-mode script).

## Test plan

- `node -c index.js`: parses cleanly.
- Added `index.test.js` (Node's built-in `node:test` runner, zero new
dependencies -- this action's `package.json` had no test setup at all
before this) with a fake `octokit` object supplying fabricated
`listCommits`/`listReviews` data directly, covering:
1. The bypass scenario above -- asserts the stale approval no longer
counts.
2. A review genuinely submitted *after* a merge commit -- asserts it
still counts (no regression for the legitimate "approve after syncing
with main" case).
  3. The plain no-merge-commits case -- asserts unaffected.
- `npm test` (updated from the placeholder `"no test specified"` script
to `node --test`): all 3 pass.

Independent from, and a different root cause than, my two earlier fixes
in this file's sibling
(`buildkite/bazel-central-registry/bcr_presubmit.py`, #2739 and #2759)
-- this one's in the PR-reviewer bot's own approval logic, not the
presubmit command/Starlark generation.
3 files changed