Repository navigation
[Docs] Automate contributor recognition #2395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
b8c1926
390ed07
fcbd2db
4ca1b03
1066816
70a91ba
e758ff5
82602ba
a52d8b0
5d419f2
9d24830
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,198 @@ | ||
| name: Update contributors | ||
|
|
||
| # Finds contributors who are missing from .all-contributorsrc (merged PR authors, PR reviewers, and the reporters of | ||
| # fixed or accepted bugs and feature requests) and opens a pull request that adds them. Only contribution types that | ||
| # GitHub data can prove are handled; everything else (question, design, security, mentoring, promotion, leader) is | ||
| # left to humans. See "Recognizing contributors" in CONTRIBUTING.md and src/scripts/Update-Contributors.ps1. | ||
| # | ||
| # Requires the repo setting "Allow GitHub Actions to create and approve pull requests" (Settings > Actions > | ||
| # General). If it is off, or the org blocks it, the branch is still pushed and the job summary links to the | ||
| # "create pull request" page, like the open data workflows. | ||
| # | ||
| # Pull requests opened with GITHUB_TOKEN don't start other workflows, so close and reopen the PR to run its checks. | ||
| # | ||
| # Two ways to run: | ||
| # - On every pull request from this repo, the author (code, doc) and reviewers (review) of that PR are credited with a | ||
| # commit on the PR branch, like the ms.date workflow. Pull requests from forks can't be pushed to, so they are | ||
| # skipped here. | ||
| # - Weekly (and on demand), everything from the last 60 days is checked, which catches fork PRs, reviews added after | ||
| # the PR was last updated, and fixed or accepted bugs and feature requests. | ||
|
|
||
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened] | ||
| schedule: | ||
| - cron: '0 7 * * 1' # Every Monday at 07:00 UTC | ||
| workflow_dispatch: | ||
| inputs: | ||
| since: | ||
| description: 'Credit contributions since this date (YYYY-MM-DD). Default is 60 days ago.' | ||
| required: false | ||
| type: string | ||
|
|
||
| # Each job asks for only what it needs | ||
| permissions: {} | ||
|
|
||
| jobs: | ||
| credit-pr: | ||
| name: Credit pull request contributors | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| permissions: | ||
| contents: write | ||
|
flanakin marked this conversation as resolved.
Resolved
|
||
| # Same-repo pull requests only (forks have a read-only token). Skip the weekly PR, which is already the credit. | ||
| if: >- | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per-PR commits to
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 [AI][Claude] ❓ Question Escalating to Michael Flanakin (@flanakin): this is a design decision, so I'm not changing it yet. Per-PR commits to |
||
| github.event_name == 'pull_request' | ||
| && github.event.pull_request.head.repo.full_name == github.repository | ||
| && github.head_ref != 'automation/update-contributors' | ||
| concurrency: | ||
| group: update-contributors-pr-${{ github.event.pull_request.number }} | ||
| cancel-in-progress: true | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| steps: | ||
| - name: Checkout PR branch | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| ref: ${{ github.head_ref }} | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| # all-contributors-cli needs Node 22.22 or later | ||
| - name: Set up Node.js | ||
| uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 | ||
| with: | ||
| node-version: '22.22' | ||
|
flanakin marked this conversation as resolved.
Resolved
|
||
|
|
||
| - name: Install all-contributors-cli | ||
|
flanakin marked this conversation as resolved.
Resolved
|
||
| run: npm ci --ignore-scripts | ||
|
|
||
| - name: Add missing credits for this pull request | ||
| shell: pwsh | ||
| env: | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| run: ./src/scripts/Update-Contributors.ps1 -PullRequest ([int]$env:PR_NUMBER) -Apply | ||
|
|
||
| - name: Commit and push changes | ||
| env: | ||
| HEAD_REF: ${{ github.head_ref }} | ||
| run: | | ||
| if git diff --quiet -- .all-contributorsrc README.md docs/README.md; then | ||
| echo "No missing credits." | ||
| exit 0 | ||
| fi | ||
| git config --local user.email "github-actions[bot]@users.noreply.github.com" | ||
| git config --local user.name "github-actions[bot]" | ||
| git add .all-contributorsrc README.md docs/README.md | ||
| git commit -m "docs: Credit contributors" | ||
|
|
||
| # Other workflows (like ms.date) push to the same branch on the same event, so rebase onto theirs and retry | ||
| for attempt in 1 2 3 4; do | ||
| if git push; then exit 0; fi | ||
| echo "Push failed (attempt $attempt). Rebasing onto the remote branch and retrying." | ||
| sleep $((attempt * 5)) | ||
| git pull --rebase origin "$HEAD_REF" | ||
|
flanakin marked this conversation as resolved.
Resolved
|
||
| done | ||
| echo "::error::Could not push the contributor credits after 4 attempts." | ||
| exit 1 | ||
|
|
||
| update: | ||
| name: Credit new contributors | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 30 | ||
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
| concurrency: | ||
| group: update-contributors | ||
| cancel-in-progress: false | ||
| # Scheduled workflows also run in forks, where there is nothing to credit and no permission to push. Only run in | ||
| # the upstream repo, from dev, so manual runs from other branches can't push their commits into the PR. | ||
| if: github.repository == 'microsoft/finops-toolkit' && github.ref == 'refs/heads/dev' | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| BRANCH: automation/update-contributors | ||
| steps: | ||
| - name: Checkout dev | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
|
|
||
| # The repo's own devDependency (all-contributors-cli). Scripts are not run during install. | ||
| # all-contributors-cli needs Node 22.22 or later | ||
| - name: Set up Node.js | ||
| uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 | ||
| with: | ||
| node-version: '22.22' | ||
|
|
||
| - name: Install all-contributors-cli | ||
| run: npm ci --ignore-scripts | ||
|
|
||
| # The default window is long on purpose: the script only adds what is missing, so re-checking recent work is | ||
| # harmless, and an unmerged PR from a previous week keeps its entries when the branch is rebuilt from dev. | ||
| - name: Add missing contributors | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we just use npm run contrib directly? PR author can be for
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 [AI][Claude] 🤔 Needs discussion The script already wraps
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 [AI][Claude] ❓ Question Your call on whether the script should stay or the workflow should call |
||
| id: update | ||
| shell: pwsh | ||
| env: | ||
| SINCE_INPUT: ${{ inputs.since }} | ||
| run: | | ||
| $since = if ($env:SINCE_INPUT) { $env:SINCE_INPUT } else { (Get-Date).AddDays(-60).ToString('yyyy-MM-dd') } | ||
| "since=$since" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | ||
| ./src/scripts/Update-Contributors.ps1 -Since $since -Apply -SummaryPath "$env:RUNNER_TEMP/contributors.md" | ||
| # A failure for one login shouldn't lose the credits that worked. The last step fails the job afterwards. | ||
| continue-on-error: true | ||
|
|
||
| - name: Check for changes | ||
| id: changes | ||
| run: | | ||
| if git diff --quiet -- .all-contributorsrc README.md docs/README.md; then | ||
| echo "changed=false" >> "$GITHUB_OUTPUT" | ||
| echo "No missing contributors." | ||
| else | ||
| echo "changed=true" >> "$GITHUB_OUTPUT" | ||
| git diff --stat -- .all-contributorsrc README.md docs/README.md | ||
| fi | ||
|
|
||
| - name: Push branch and open pull request | ||
| if: steps.changes.outputs.changed == 'true' | ||
| env: | ||
| SINCE: ${{ steps.update.outputs.since }} | ||
| run: | | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||
| git checkout -b "$BRANCH" | ||
| git add .all-contributorsrc README.md docs/README.md | ||
| git commit -m "docs: Credit new contributors" | ||
|
|
||
| # The branch is rebuilt from dev every run, so an open PR is updated in place | ||
| git push --force origin "$BRANCH" | ||
|
|
||
| { | ||
| echo "Adds contributor credits found by [\`Update-Contributors.ps1\`](https://github.com/${GITHUB_REPOSITORY}/blob/dev/src/scripts/Update-Contributors.ps1) for work since $SINCE." | ||
| echo "" | ||
| cat "$RUNNER_TEMP/contributors.md" | ||
| echo "" | ||
| echo "Review before merging: credits come from GitHub data only (merged PRs, reviews, and fixed or accepted bugs and feature requests). Other types, like question, design, security, mentoring, and promotion, are added by hand. See [Recognizing contributors](https://github.com/${GITHUB_REPOSITORY}/blob/dev/CONTRIBUTING.md#-recognizing-contributors)." | ||
| echo "" | ||
| echo "_Opened by the [Update contributors](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}) workflow. Close and reopen this PR to run its checks._" | ||
| } > "$RUNNER_TEMP/pr-body.md" | ||
| cat "$RUNNER_TEMP/pr-body.md" >> "$GITHUB_STEP_SUMMARY" | ||
|
|
||
| PR_NUMBER=$(gh pr list --head "$BRANCH" --base dev --state open --json number --jq '.[0].number // empty') | ||
| if [ -n "$PR_NUMBER" ]; then | ||
| gh pr edit "$PR_NUMBER" --body-file "$RUNNER_TEMP/pr-body.md" | ||
| echo "Updated PR #$PR_NUMBER" | ||
| elif ! gh pr create --base dev --head "$BRANCH" --title "[Docs] Credit new contributors" --body-file "$RUNNER_TEMP/pr-body.md"; then | ||
| # Creating PRs from Actions is a repo/org setting. Don't lose the work if it is off. | ||
| PR_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/compare/dev...${BRANCH}?expand=1" | ||
| echo "::warning::Could not open the pull request (is \"Allow GitHub Actions to create and approve pull requests\" off?). The branch $BRANCH was pushed." | ||
| { | ||
| echo "" | ||
| echo "GitHub Actions could not open the pull request. Branch \`$BRANCH\` was pushed, so open it manually:" | ||
| echo "" | ||
| echo "[**Create pull request**]($PR_URL)" | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
| fi | ||
|
|
||
| - name: Fail if credits could not be added | ||
| if: steps.update.outcome == 'failure' | ||
| run: | | ||
| echo "::error::Update-Contributors.ps1 failed. See the 'Add missing contributors' step." | ||
| exit 1 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better would be per PR, so on PR open or update, if we want to account for reviewers (which is rare)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 [AI][Claude] ✅ Implemented
Added a per-PR job: on open/update of a same-repo PR it credits the author and reviewers with a commit on the PR branch (like the ms.date workflow). Kept the weekly run as a catch-all, because fork PRs (most external contributors) can't be pushed to, and it covers bugs and feature requests. Note: two open PRs crediting different people can conflict in
.all-contributorsrc.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 [AI][Claude] ❓ Question
Related to Roland's thread above (conflicts and extra commits from per-PR commits). Which do you want: per-PR commits or a weekly/on-push-to-dev job only? Recommendation: on-push-to-dev plus the weekly schedule, no per-PR job.