fix(release): use GitHub API logins for contributors deduplication#205
fix(release): use GitHub API logins for contributors deduplication#205ymkiux wants to merge 2 commits into
Conversation
📝 WalkthroughWalkthroughA new GitHub Actions step fetches PR author logins via the ChangesExternal Contributor Injection into Release Changelog
Vietnamese Locale String Cleanup
Sequence Diagram(s)sequenceDiagram
participant Job as release.yml job
participant gh as gh CLI
participant File as release-contributors.txt
participant Script as changelog.js
alt No LATEST_TAG
Job->>Job: skip contributor fetch
else Has LATEST_TAG
Job->>gh: gh pr list (LATEST_TAG...RELEASE_TAG)
gh-->>Job: PR author logins
Job->>File: write logins (newline-separated)
end
Job->>Script: invoke with CONTRIBUTORS_FILE env var
Script->>File: read & trim logins → externalLogins[]
Script->>Script: listContributors(commits, externalLogins)
Script->>Script: formatChangelog({ externalLogins })
Script-->>Job: changelog with merged Contributors section
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release.yml:
- Around line 198-199: The LATEST_TAG environment variable is set to
steps.resolve.outputs.latest_tag, but this baseline differs from what the
changelog generation uses for deriving the target release, causing a mismatch in
the contributor data range. Update the LATEST_TAG assignment to use the same
baseline tag that the changelog generation process uses (the previous semver tag
for the target release) instead of steps.resolve.outputs.latest_tag, ensuring
both operations work with the same tag range.
- Around line 216-220: The fallback mechanism around lines 235-236 injects
unscoped contributors from the gh pr list command into the release contributors
list when the primary range-scoped extraction (from git log in lines 227-234)
finds no results. Instead of using the unscoped gh pr list output as a fallback,
modify the fallback logic to keep the contributor list empty or add a notice
indicating that no contributors were found within the intended range. This
ensures data accuracy by preventing contributors outside the target range from
being included in the release.
In `@tools/release/changelog.js`:
- Around line 143-154: The deduplication logic uses case-sensitive keys when
checking and adding to the seen Set, which allows the same GitHub login to
appear multiple times with different casing (e.g., "GitHub" vs "github").
Normalize the login values to lowercase before performing any deduplication
checks. In the first loop where externalLogins are processed, convert safeLogin
to lowercase before the seen.has() check and before seen.add(). In the second
loop where commits are processed, convert login to lowercase before the
seen.has() check and before seen.add(). Ensure the normalized lowercase value is
used consistently for deduplication while preserving the original casing for the
displayName property.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: f9dd0426-0ee5-422b-8cd9-4bfcd6a4a548
📒 Files selected for processing (2)
.github/workflows/release.ymltools/release/changelog.js
📜 Review details
🔇 Additional comments (2)
tools/release/changelog.js (1)
120-130: LGTM!Also applies to: 197-197, 235-235, 267-286
.github/workflows/release.yml (1)
241-246: LGTM!
| LATEST_TAG: ${{ steps.resolve.outputs.latest_tag }} | ||
| CONTRIBUTORS_FILE: release-contributors.txt |
There was a problem hiding this comment.
Use the same baseline tag as changelog generation.
Line 224 derives PRs from LATEST_TAG...RELEASE_TAG, but changelog generation uses the previous semver tag for the target release. This mismatch can produce contributor data for a different range.
Also applies to: 224-224
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 198 - 199, The LATEST_TAG
environment variable is set to steps.resolve.outputs.latest_tag, but this
baseline differs from what the changelog generation uses for deriving the target
release, causing a mismatch in the contributor data range. Update the LATEST_TAG
assignment to use the same baseline tag that the changelog generation process
uses (the previous semver tag for the target release) instead of
steps.resolve.outputs.latest_tag, ensuring both operations work with the same
tag range.
| gh pr list \ | ||
| --repo "${GITHUB_REPOSITORY}" \ | ||
| --limit 500 \ | ||
| --json author \ | ||
| --jq '.[].author.login' 2>/dev/null | sort -u > "${tmp_logins}" || true |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
What are the default filters for gh pr list (state, scope), and does this command support constraining results to commits between two git tags?
💡 Result:
The default state for the gh pr list command is open [1][2][3]. Regarding your specific questions: Default Filters: The gh pr list command filters by state, and its default value is open [1][2][4]. The available states you can filter by are open, closed, merged, and all [1][3][4]. There is no scope parameter in the command itself; however, you can constrain results to a specific repository using the -R or --repo flag [2][3]. Constraint by Git Tags: The gh pr list command does not natively support constraining results to commits between two git tags [1][2][4]. While you can use the --search flag to pass advanced GitHub search queries—such as searching by a specific commit SHA—it does not support range-based filtering using git tags directly [2][5][4]. To filter pull requests based on commits or time ranges associated with tags, you would typically need to identify the commit SHAs corresponding to your tags (using standard git commands like git rev-list or git show) and then use those SHAs or the associated dates within a --search query [2][4][6]. For example, if you have the commit SHAs, you might use the search syntax within the -S flag, though this requires manual translation of your git tags into inputs the search API accepts [2][4].
Citations:
- 1: https://cli.github.com/manual/gh_pr_list
- 2: https://manpages.debian.org/trixie/gh/gh-pr-list.1.en.html
- 3: https://manpages.ubuntu.com/manpages/jammy/man1/gh-pr-list.1.html
- 4: https://www.gsp.com/cgi-bin/man.cgi?topic=GH-PR-LIST
- 5: Filtering options for issues and pull requests cli/cli#641
- 6: Incorrect PR list when using date ranges cli/cli#3677
🏁 Script executed:
sed -n '200,250p' .github/workflows/release.ymlRepository: SakuraByteCore/codexmate
Length of output: 2220
Fix the unscoped contributor fallback in release workflow.
The gh pr list call on line 216 lacks range filtering and defaults to all open PRs in the repository. When the primary range-scoped mechanism (lines 227-234, which extracts PR numbers from git log) finds no PRs, the fallback on lines 235-236 injects these unscoped contributors into the release contributors list, compromising data accuracy.
Replace the fallback to keep the contributor list empty with a notice instead:
Suggested patch
- elif [ -s "${tmp_logins}" ]; then
- cat "${tmp_logins}" > "${CONTRIBUTORS_FILE}"
+ elif [ -s "${tmp_logins}" ]; then
+ echo "::notice title=No range-scoped PR contributors::Using empty contributor list."
+ : > "${CONTRIBUTORS_FILE}"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 216 - 220, The fallback mechanism
around lines 235-236 injects unscoped contributors from the gh pr list command
into the release contributors list when the primary range-scoped extraction
(from git log in lines 227-234) finds no results. Instead of using the unscoped
gh pr list output as a fallback, modify the fallback logic to keep the
contributor list empty or add a notice indicating that no contributors were
found within the intended range. This ensures data accuracy by preventing
contributors outside the target range from being included in the release.
| for (const login of externalLogins) { | ||
| const safeLogin = String(login || '').trim(); | ||
| if (!safeLogin || seen.has(safeLogin)) continue; | ||
| seen.add(safeLogin); | ||
| contributors.push({ login: safeLogin, displayName: safeLogin }); | ||
| } | ||
|
|
||
| // Fallback to commit authors for missing entries | ||
| for (const commit of commits) { | ||
| const contributor = formatContributorName(commit.author); | ||
| const key = contributor.toLowerCase(); | ||
| if (seen.has(key)) continue; | ||
| seen.add(key); | ||
| contributors.push(contributor); | ||
| const { login, displayName } = contributorProfile(commit.author); | ||
| if (!login || seen.has(login)) continue; | ||
| seen.add(login); |
There was a problem hiding this comment.
Normalize login keys before deduplication.
On Line 145 and Line 153, dedupe uses case-sensitive keys. This can still emit duplicates when the same GitHub login appears with different casing across sources.
Suggested patch
for (const login of externalLogins) {
const safeLogin = String(login || '').trim();
- if (!safeLogin || seen.has(safeLogin)) continue;
- seen.add(safeLogin);
+ const loginKey = safeLogin.toLowerCase();
+ if (!safeLogin || seen.has(loginKey)) continue;
+ seen.add(loginKey);
contributors.push({ login: safeLogin, displayName: safeLogin });
}
...
for (const commit of commits) {
const { login, displayName } = contributorProfile(commit.author);
- if (!login || seen.has(login)) continue;
- seen.add(login);
+ const loginKey = String(login || '').toLowerCase();
+ if (!login || seen.has(loginKey)) continue;
+ seen.add(loginKey);
contributors.push({ login, displayName });
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tools/release/changelog.js` around lines 143 - 154, The deduplication logic
uses case-sensitive keys when checking and adding to the seen Set, which allows
the same GitHub login to appear multiple times with different casing (e.g.,
"GitHub" vs "github"). Normalize the login values to lowercase before performing
any deduplication checks. In the first loop where externalLogins are processed,
convert safeLogin to lowercase before the seen.has() check and before
seen.add(). In the second loop where commits are processed, convert login to
lowercase before the seen.has() check and before seen.add(). Ensure the
normalized lowercase value is used consistently for deduplication while
preserving the original casing for the displayName property.
- Add "Fetch contributors from GitHub API" step in release workflow to get PR authors' GitHub logins via gh CLI - Modify listContributors to accept externalLogins from GitHub API - Change deduplication key from author name to GitHub login (prevents awsl/awsl233777 from appearing as separate contributors) - Update formatContributorCard to support object parameter - Ensure circular avatars via wsrv.nl mask=circle (no CSS dependency)
…icate keys
- Update listContributors test to expect { login, displayName } objects
- Remove duplicate settings.sharePrefix.* keys in vi locale
- Remove duplicate settings.trashConfig.* keys in vi locale
0df9e7b to
de36813
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release.yml:
- Around line 224-231: The git log command using the commit range
"${LATEST_TAG}...${RELEASE_TAG}" fails when RELEASE_TAG hasn't been created yet
in a new release flow. Since the failure is silently handled by the || true
operator, tmp_merged becomes empty, causing incorrect contributor data
downstream. Replace ${RELEASE_TAG} in the git log command with an existing ref
that is guaranteed to be present (such as HEAD or the target branch reference)
to ensure the command succeeds regardless of whether the release tag has been
created yet.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: efbd84b6-d125-4870-a2f9-41de947ba1b2
📒 Files selected for processing (4)
.github/workflows/release.ymltests/unit/release-changelog.test.mjstools/release/changelog.jsweb-ui/modules/i18n/locales/vi.mjs
💤 Files with no reviewable changes (1)
- web-ui/modules/i18n/locales/vi.mjs
🚧 Files skipped from review as they are similar to previous changes (2)
- tests/unit/release-changelog.test.mjs
- tools/release/changelog.js
📜 Review details
🔇 Additional comments (1)
.github/workflows/release.yml (1)
216-220: Unscopedgh pr listfallback remains in place.This still falls back to unscoped
gh pr listauthors whentmp_mergedis empty, which can inject contributors outside the intended release range.Also applies to: 235-236
| git log "${LATEST_TAG}...${RELEASE_TAG}" --pretty=format:%s \ | ||
| | grep -oE '#[0-9]+' \ | ||
| | sed 's/^#//' \ | ||
| | sort -u \ | ||
| | while read -r pr_number; do | ||
| gh pr view "${pr_number}" --repo "${GITHUB_REPOSITORY}" --json author --jq '.author.login' 2>/dev/null || true | ||
| done \ | ||
| | sort -u > "${tmp_merged}" || true |
There was a problem hiding this comment.
Use an existing ref for the commit-range upper bound.
On Line 224, git log "${LATEST_TAG}...${RELEASE_TAG}" can fail when ${RELEASE_TAG} hasn’t been created yet (new release flow). Because the pipeline ends with || true, this silently empties tmp_merged and skews contributors downstream.
Suggested fix
+ range_head="${RELEASE_TAG}"
+ if ! git rev-parse --verify --quiet "refs/tags/${RELEASE_TAG}" >/dev/null; then
+ range_head="HEAD"
+ fi
+
- git log "${LATEST_TAG}...${RELEASE_TAG}" --pretty=format:%s \
+ git log "${LATEST_TAG}...${range_head}" --pretty=format:%s \
| grep -oE '#[0-9]+' \
| sed 's/^`#//`' \
| sort -u \
| while read -r pr_number; do
gh pr view "${pr_number}" --repo "${GITHUB_REPOSITORY}" --json author --jq '.author.login' 2>/dev/null || true
done \
| sort -u > "${tmp_merged}" || true📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| git log "${LATEST_TAG}...${RELEASE_TAG}" --pretty=format:%s \ | |
| | grep -oE '#[0-9]+' \ | |
| | sed 's/^#//' \ | |
| | sort -u \ | |
| | while read -r pr_number; do | |
| gh pr view "${pr_number}" --repo "${GITHUB_REPOSITORY}" --json author --jq '.author.login' 2>/dev/null || true | |
| done \ | |
| | sort -u > "${tmp_merged}" || true | |
| range_head="${RELEASE_TAG}" | |
| if ! git rev-parse --verify --quiet "refs/tags/${RELEASE_TAG}" >/dev/null; then | |
| range_head="HEAD" | |
| fi | |
| git log "${LATEST_TAG}...${range_head}" --pretty=format:%s \ | |
| | grep -oE '#[0-9]+' \ | |
| | sed 's/^`#//`' \ | |
| | sort -u \ | |
| | while read -r pr_number; do | |
| gh pr view "${pr_number}" --repo "${GITHUB_REPOSITORY}" --json author --jq '.author.login' 2>/dev/null || true | |
| done \ | |
| | sort -u > "${tmp_merged}" || true |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 224 - 231, The git log command
using the commit range "${LATEST_TAG}...${RELEASE_TAG}" fails when RELEASE_TAG
hasn't been created yet in a new release flow. Since the failure is silently
handled by the || true operator, tmp_merged becomes empty, causing incorrect
contributor data downstream. Replace ${RELEASE_TAG} in the git log command with
an existing ref that is guaranteed to be present (such as HEAD or the target
branch reference) to ensure the command succeeds regardless of whether the
release tag has been created yet.
Summary
Changes
to get PR authors' GitHub logins via gh CLI
listContributorsto acceptexternalLoginsfrom GitHub APIformatContributorCardto support object parameterTest plan
🤖 Generated with Claude Code
Summary by CodeRabbit