Skip to content

fix: include private contributor statistics safely - #11

Open
garmoths wants to merge 1 commit into
HappyHackingSpace:mainfrom
garmoths:fix/private-contributor-stats
Open

fix: include private contributor statistics safely#11
garmoths wants to merge 1 commit into
HappyHackingSpace:mainfrom
garmoths:fix/private-contributor-stats

Conversation

@garmoths

@garmoths garmoths commented Aug 2, 2026

Copy link
Copy Markdown
Member

Summary

This PR allows the contributor leaderboard to include activity from authorized private repositories without exposing private repository details in the public organization profile.

Changes

  • Fetches all repositories accessible to the statistics token.
  • Keeps private repositories out of the public projects table.
  • Includes private repository commits, issues, and pull requests only in aggregated contributor totals.
  • Uses ORG_STATS_TOKEN when configured and falls back to the default GitHub token otherwise.
  • Stops the workflow on API or permission errors instead of publishing incomplete statistics.
  • Avoids exposing private repository names in error messages.
  • Adds dependency verification and Go tests before updating the README.
  • Aligns the workflow with Go 1.26.
  • Adds workflow timeout and concurrency protection.
  • Pins GitHub Actions to immutable commit SHAs.
  • Limits the default workflow permission to contents: write.

Required configuration

An organization administrator must add an ORG_STATS_TOKEN Actions secret to the upstream .github repository.

The token should have read-only access to the selected repositories with only:

  • Metadata: Read
  • Contents: Read
  • Issues: Read
  • Pull requests: Read

No token value or private repository information is included in this PR.

Security

Private repository names, URLs, project statistics, commit messages, and source code are never written to the public README. Only aggregated contributor counts are published.

Summary by CodeRabbit

  • Bug Fixes

    • Improved project statistics updates by reporting API failures instead of silently producing incomplete results.
    • Ensured all available repositories are considered while excluding private repositories from public project listings.
  • Reliability

    • Strengthened automated update runs with controlled execution time, serialized runs, verified dependencies, and safer authentication handling.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The project statistics workflow now uses pinned actions, Go 1.26, explicit dependency validation, repository write access, and controlled authentication. The Go script includes private-repository filtering and propagates contributor API errors to main.

Changes

Project statistics update

Layer / File(s) Summary
Contributor fetch error propagation
scripts/update_projects.go
fetchContributors returns errors from commit, issue, and pull-request requests. main stops when contributor collection fails.
Repository scope and publication filtering
scripts/update_projects.go
Repository listing includes all repository types. Private and excluded repositories are skipped before statistics are published.
Workflow execution and authentication
.github/workflows/update-projects.yml
The workflow grants write access, serializes runs, sets a timeout, pins actions, uses Go 1.26, validates dependencies, selects the organization token, and scopes Git identity locally.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant main
  participant fetchContributors
  participant GitHubAPI
  main->>fetchContributors: collect contributor statistics
  fetchContributors->>GitHubAPI: fetch commits, issues, and pull requests
  GitHubAPI-->>fetchContributors: data or API error
  fetchContributors-->>main: contributors or error
  main->>main: terminate on contributor-fetch error
Loading

Poem

I hopped through commits beneath the moon,
Checked issues and pull requests too.
Errors now raise a clear alarm,
Private projects stay out of harm.
The workflow runs with steady cheer—
A tidy burrow, year by year.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: safely including aggregated contributor statistics from private repositories.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/update-projects.yml:
- Line 20: Update the actions/checkout step in the update-projects workflow to
set persist-credentials to false, preventing the GitHub token from being stored
in local Git configuration. If the final push step requires authentication,
provide the token directly to that push command rather than relying on checkout
persistence.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f870d70f-1a38-4c77-9ff4-b24ecb4a34db

📥 Commits

Reviewing files that changed from the base of the PR and between fb01166 and 1fe835e.

📒 Files selected for processing (2)
  • .github/workflows/update-projects.yml
  • scripts/update_projects.go

timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow excerpt =="
cat -n .github/workflows/update-projects.yml | sed -n '1,180p'

echo
echo "== relevant GHA checkout references =="
rg -n "actions/checkout|persist-credentials|github\.token|git push|go test|update_projects" .github/workflows/update-projects.yml

echo
echo "== repository-controlled Go files paths/stat =="
git ls -l -- . | head -20
git ls-files scripts update_projects.go | head -50

echo
echo "== file sizes if relevant scripts exist =="
for f in $(git ls-files scripts/update_projects.go 2>/dev/null | tr '\n' ' ') scripts/update_projects.go; do
  [ -f "$f" ] && echo "--- $f" && wc -l "$f"
done

Repository: HappyHackingSpace/.github

Length of output: 2253


🌐 Web query:

actions/checkout persist-credentials default true github.token local git config

💡 Result:

In the actions/checkout GitHub Action, the persist-credentials input determines whether the authentication token (typically the GITHUB_TOKEN or a provided Personal Access Token) is configured for use with Git [1][2]. When persist-credentials is set to true (which is the default value) [1][2], the action configures the provided credentials so that subsequent steps in the workflow can run authenticated Git commands [1][3]. Regarding how these credentials are stored: - In older versions of actions/checkout, the token was persisted directly in the local.git/config file [4][5]. - As of version 6.0.0 and later, the action has been updated to store these credentials in a separate file located under $RUNNER_TEMP, rather than directly in the local git config [4][6]. This change helps improve security by keeping the credentials out of the local Git configuration file [4][5]. The action automatically removes these credentials during the post-job cleanup phase [1][3]. If you prefer to disable this behavior for security reasons, you can set persist-credentials: false in your workflow step [1][7].

Citations:


🌐 Web query:

actions/checkout v4 persist-credentials default github.token local git config

💡 Result:

In actions/checkout v4, the persist-credentials input defaults to true [1][2][3]. When set to true, the action automatically configures the local git repository's configuration (stored in.git/config) with the authentication token provided to the action [1][4][5]. If you do not specify a custom token, the action defaults to using the GitHub token (typically secrets.GITHUB_TOKEN) [6][7]. By persisting this token into the local git config, the action enables your workflow scripts to run authenticated git commands (such as git push or git pull) directly within the workspace [1][4][5]. To opt-out of this behavior—which is often recommended for security to prevent the token from being accessible to other processes or potentially leaked through artifacts—you must explicitly set persist-credentials to false [1][5][7]: - uses: actions/checkout@v4 with: persist-credentials: false When persist-credentials is set to false, the action does not write the token into the local git configuration [1][5]. Any subsequent git commands that require authentication will need to be configured separately (e.g., using a credential helper or by manually configuring the git url with credentials) [8]. The token used by the action is automatically removed during the post-job cleanup process in either case [1][4][5].

Citations:


🌐 Web query:

GitHub Actions GITHUB_TOKEN contents: write permissions git push token permissions contents read

💡 Result:

The GITHUB_TOKEN is a powerful, repository-scoped token automatically provided by GitHub Actions to authenticate on behalf of the GitHub App installed on your repository [1]. By default, it often has only read access to repository contents, meaning workflows attempting to push commits, create branches, or delete files will fail with a "permission denied" error unless permissions are explicitly elevated [2][3]. To allow a workflow to perform write operations like git push, you must grant the contents: write permission in your workflow file [2][4]. How to grant write permissions: You can define permissions at either the workflow level (for all jobs) or the job level (for a specific job) [5][4]. Specifying the permissions key will override the repository's default token permissions [2][4]. Example configuration: jobs: build: runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/checkout@v4 # Now you can commit and push changes - run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git commit -am "Update via GITHUB_TOKEN" git push Important considerations: 1. Explicit Override: When you define a permissions block, any permissions not explicitly listed are set to none [4]. If your workflow requires other actions (such as reading metadata or interacting with issues), ensure they are included in the permissions block [4]. 2. Scope: The GITHUB_TOKEN is strictly scoped to the repository containing the workflow [1][6]. It cannot be used to push to other repositories, even if those repositories are under the same organization [6][7]. To push to a different repository, you must use a Personal Access Token (PAT) or a GitHub App installation token stored as a secret [1][7]. 3. Security: Always follow the principle of least privilege [5][2]. Only grant contents: write if the workflow genuinely needs to modify the repository [5][2]. 4. Recursive Workflows: When a workflow uses the GITHUB_TOKEN to push code, it generally does not trigger new workflow runs, which prevents infinite loops [1]. Exceptions exist for certain pull_request events, which may create workflow runs in an "approval-required" state [1].

Citations:


Disable checked-out token persistence.

actions/checkout@v4 persists github.token in the local Git config by default, and this job runs repository-controlled Go code before git push. Set persist-credentials: false on checkout and pass the token directly to the push command only if the final step needs it.

🧰 Tools
🪛 zizmor (1.28.0)

[warning] 20-20: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/update-projects.yml at line 20, Update the
actions/checkout step in the update-projects workflow to set persist-credentials
to false, preventing the GitHub token from being stored in local Git
configuration. If the final push step requires authentication, provide the token
directly to that push command rather than relying on checkout persistence.

Source: Linters/SAST tools

@garmoths

garmoths commented Aug 8, 2026

Copy link
Copy Markdown
Member Author

@dogancanbakir review pls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant