Skip to content

[Docs] Automate contributor recognition - #2395

Open
Michael Flanakin (flanakin) wants to merge 11 commits into
devfrom
flanakin/update-contributors
Open

Michael Flanakin (flanakin) wants to merge 11 commits into
devfrom
flanakin/update-contributors

Conversation

@flanakin

Copy link
Copy Markdown
Collaborator

Stacked on #2391. This branch is based on flanakin/release-contributor-order, so the diff here is only the automation. Retarget this PR to dev after #2391 merges. It documents the contribution types from #2391 ("Recognizing contributors" in CONTRIBUTING.md), so it should not merge first.

Summary

Contributors were missed in v15 because crediting them was a manual, per-person step in the release checklist. This adds a script that finds who is missing and a weekly workflow that opens a PR to add them, so nobody is missed.

src/scripts/Update-Contributors.ps1 (PowerShell 7, Windows and Linux)

Uses the gh CLI to collect contributions for -Since <date> and/or -Milestone <name> and compares them with .all-contributorsrc (logins compared case-insensitively):

Credit Inferred from
code Author of a merged PR that changed any file outside the docs paths
doc Author of a merged PR that changed a file in docs/, docs-mslearn/, docs-wiki/, or any *.md
review Human who approved, requested changes, or commented on a merged PR (not on their own PR)
bug Author of a Type: Bug issue that was fixed or accepted
ideas Author of a Type: Feature issue that was implemented or accepted
  • Bots and apps are skipped ([bot], app/..., dependabot, copilot, github-actions, allcontributors, OssSecurityBot). Nobody else is skipped, so maintainers who are missing a type are credited too.
  • Dry run is the default. It prints a table of what is missing. -Apply runs the repo's all-contributors-cli once per login (npm ci --ignore-scripts first). -WhatIf is honored with -Apply.
  • The CLI runs .all-contributorsrc through prettier, which collapses "contributions": [...] onto one line and turns a ~20 line change into a ~500 line diff. After the CLI runs, the script expands the arrays again (keeping CRLF/LF and the trailing blank line), then verifies the result: same contributors in the same order, no credits removed, other settings unchanged, and a text diff with only additions. If that fails, it restores the original files and errors.
  • Idempotent: a second run finds nothing and changes nothing.
  • Clear errors for missing gh, missing gh auth, rate limits (with the reset time, and a pre-check before the per-PR calls), and transient 5xx (retried).
  • Types it cannot infer (question, design, security, mentoring, promotion, leader) are left to humans.

Judgment calls worth a look:

  • Changelog entries do not count as doc. Nearly every code PR edits docs-mslearn/toolkit/changelog.md, which would credit doc to everyone. .all-contributorsrc itself is ignored too.
  • A label alone does not earn bug or ideas. CONTRIBUTING.md says "confirmed or fixed", so the issue must be closed as completed or assigned to a milestone, and not closed as not planned or duplicate, or labeled Resolution: Duplicate, Won't fix, Can't repro, No activity, External, or Support request. Without this, a plain -Since run credits reporters of duplicates and abandoned issues.
  • Issue authors with no Type: label are listed for a human, not credited (for example, the v15 milestone issues from haflidif, josesarsa, and sharmilamusunuru have no type label). They appear in the console, in -SummaryPath, and in the PR body.

.github/workflows/update-contributors.yml

  • Weekly (Mondays 07:00 UTC) plus workflow_dispatch with a since input. Default window is 60 days, which is safe because the script only adds what is missing, and it lets an unmerged PR keep its entries when the branch is rebuilt.
  • Runs only in microsoft/finops-toolkit and only from dev. Permissions are contents: write and pull-requests: write. Uses only the actions/checkout SHA already pinned elsewhere; everything else is gh, npm ci --ignore-scripts, and shell/pwsh.
  • Applies, then (if .all-contributorsrc, README.md, or docs/README.md changed) force-pushes automation/update-contributors from dev, and opens or updates a PR to dev with gh pr create/gh pr edit using GITHUB_TOKEN. The PR body is the table of what was added.
  • If PR creation is blocked, the branch is still pushed and the job summary has the "create pull request" link, like the open data workflows (their comments say Actions cannot open PRs in this org).
  • A failure for one login does not discard the others; the job fails at the end so it is visible.

Docs

CONTRIBUTING.md ("Recognizing contributors"), .claude/commands/release.md (Contributors bullet), and src/scripts/README.md point to the script. No changelog entry: this is repo tooling, not a product change.

Maintainer settings needed

  • Settings > Actions > General > "Allow GitHub Actions to create and approve pull requests" must be enabled (repo, and org if it is locked at that level). If not, the workflow falls back to pushing the branch and linking the compare page.
  • PRs opened with GITHUB_TOKEN do not trigger other workflows (the dev.yml checks). Close and reopen the PR to run them, or merge as an admin if the changes are only the contributor files.
  • If dev requires status checks on automation/* PRs, the PR will wait on them.

Test plan

Run locally on Windows with PowerShell 7.6 and gh 2.103 (authenticated):

  • Dry run -Milestone v15 against the real config: the only gap is flanakin for bug (issues ADX dashboard: List cost / Commitment savings don't match between Summary and Rate Optimization pages #2315 and Hub redeploys can reset msexports and raw retention #2348, both Type: Bug); nothing is missing for bpurchell, danfiedler-msft, JacobStruiksma, Christopherloof, haflidif, josesarsa, sharmilamusunuru, or xan-archera.
  • Dry run -Since 2026-04-29: same, nothing missing for those people. It also finds other people missing bug/ideas for fixed or milestoned issues since then (for example digitalsb, Elgeario, eltanko, jlwebb-fc, rahalan, santiagoamado0209, shweta25586-ms, t2kx, Vikesh1981; plus arthursilvany, DirkBrinkmann, MSBrett, and bpurchell on existing entries). The first workflow run will propose these, so review that PR.
  • Apply path on a scratch copy (real files untouched): removed bpurchell and danfiedler-msft and JacobStruiksma's bug from the copy, ran -Milestone v15 -Apply. It re-added them plus flanakin's bug, with 21 lines added and 1 removed in .all-contributorsrc (the comma on "promotion"), and a README change of one cell. A second run changed nothing (file hashes identical). -Apply -WhatIf changed nothing. CRLF and the trailing blank line were preserved.
  • With the 5 v15 reporters removed from a scratch copy, the script credits the issue authors it can classify and lists haflidif, josesarsa, and sharmilamusunuru for a human. Christopherloof (Issue connecting to ADF from PowerBI online #1309, closed not planned) and xan-archera (DISP_E_TYPEMISMATCH when loading storage reports with data from March 2025 alongside other #2070, duplicate/external) are not credited by the "confirmed or fixed" rule, so those two v15 credits from docs: credit v15 contributors and document contribution types #2391 remain a human call.
  • New Pester tests: Update-Contributors.Tests.ps1 (64 tests: type inference, bot filtering, array re-expansion including a round trip of the committed .all-contributorsrc, dedupe, issue rules, config verification) and Action.UpdateContributors.Tests.ps1 (11 tests: permissions, fork/branch guard, SHA pins, input handling). All pass.
  • Test-PowerShell.ps1 -Lint (3970 passed) and -Actions pass.
  • Workflow YAML parses (YamlDotNet), the bash steps pass bash -n, and the pwsh step parses. Re-read by hand. actionlint is not installed.
  • The workflow itself was not run (it cannot be triggered from here): schedule, workflow_dispatch, GITHUB_TOKEN access to PR/issue reads with only contents/pull-requests scopes, the force-push, gh pr create, and the fallback link are untested. The first run should be a manual workflow_dispatch from dev.
  • Not tested on Linux (the runner OS). The script avoids Windows-only calls and the workflow shells are standard, but the first run is the real test.

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Adds Christopherloof, haflidif, josesarsa, sharmilamusunuru, and xan-archera, and adds bug for JacobStruiksma. Documents the contrib command in the release instructions.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Adds bpurchell and danfiedler-msft for code, documents every contribution type in CONTRIBUTING.md, and updates the release guidance to credit everyone named in the release notes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Add Update-Contributors.ps1, which finds merged PR authors, PR reviewers, and
reporters of fixed or accepted bugs and feature requests who are missing from
.all-contributorsrc, and adds them with all-contributors-cli while keeping the
diff small. Add a weekly update-contributors workflow that opens a PR with the
result, unit tests, and docs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Comment on lines +15 to +16
schedule:
- cron: '0 7 * * 1' # Every Monday at 07:00 UTC

Copy link
Copy Markdown
Collaborator Author

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)

Copy link
Copy Markdown
Collaborator Author

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.

Copy link
Copy Markdown
Collaborator Author

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.


# 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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The 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 code, issue author for bug (?) (or feature depending on context?), issue commenters for ???

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 [AI][Claude] 🤔 Needs discussion

The script already wraps npm run contrib (-Apply runs the CLI per login and keeps the diff small), so I kept it for detection and dedupe. Mapping: PR author = code/doc, issue author = bug/ideas, PR reviewers = review. I did not credit commenters: comments don't prove a contribution, and question is added by hand (@allcontributors please add @user for question). Want a threshold (e.g. 3+ answered issues) instead?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The 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 npm run contrib directly. Recommendation: keep the script. The CLI alone can't find who is missing or which type applies (PR author = code/doc, issue author = bug/ideas, reviewer = review), and it can't dedupe against the existing list. The script already runs npm run contrib's CLI per login for the actual write. Commenters stay manual.

- Add -PullRequest to Update-Contributors.ps1 to credit one PR's author and reviewers.
- Run it on same-repo pull requests and push the credits to the PR branch.
- Keep the weekly run for fork PRs, bugs, and feature requests.

Co-Authored-By: flanakin <flanakin@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@flanakin

Copy link
Copy Markdown
Collaborator Author

🤖 [AI][Claude] PR Update Summary

Addressed: 2 thread(s)

  • ✅ Implemented: 1 (per-PR credit job + -PullRequest)
  • 🤔 Needs discussion: 1 (commenter credits)

Pester: 77 passed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The design and security posture are sound: no pull_request_target, a fork guard, and no ${{ }} inside run:. The tests pass (77 of 77 locally, and Pester on Linux).

The branch is one commit behind #2391, so it needs a rebase; that also brings in the README anchor fix.

Comment thread src/scripts/Update-Contributors.ps1 Resolved
runs-on: ubuntu-latest
timeout-minutes: 10
# Same-repo pull requests only (forks have a read-only token). Skip the weekly PR, which is already the credit.
if: >-

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Per-PR commits to .all-contributorsrc and the README tables conflict between parallel PRs and with the weekly PR. Should the weekly job also run on push to dev, with no per-PR job?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The 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 .all-contributorsrc and the README tables will conflict between parallel PRs and with the weekly PR, and add an extra head commit per PR that needs checks and approval. Recommendation: drop the per-PR credit-pr job and run the existing weekly job on push to dev (plus the schedule and manual runs). That serves fork PRs too, avoids conflicts, and removes the bot commit on PRs. Trade-off: credits show up in a follow-up PR after merge rather than in the PR itself.

Comment thread src/scripts/Update-Contributors.ps1 Resolved
Comment thread src/scripts/Update-Contributors.ps1 Resolved
Comment thread CONTRIBUTING.md Resolved
@microsoft-github-policy-service microsoft-github-policy-service Bot added Needs: Attention 👋 Issue or PR needs to be reviewed by the author or it will be closed due to no activity and removed Needs: Review 👀 PR that is ready to be reviewed labels Oct 30, 2026
@microsoft-github-policy-service

Copy link
Copy Markdown

@Michael Flanakin (@flanakin): you have some new feedback!

Please review and resolve all comments and I'll let reviewers know by removing the Needs: Attention label. If I miss anything, just reply with #needs-review and I'll update the status.

Co-Authored-By: RolandKrummenacher <RolandKrummenacher@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Skip files the contributor CLI rewrites when crediting doc, retry the push after rebasing, set permissions per job, restore PRIVATE_TOKEN, build the summary after -Apply, check multi-line run blocks in the test, set up Node 22.22, and fix the multi-type syntax in CONTRIBUTING.md.

Co-Authored-By: RolandKrummenacher <RolandKrummenacher@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@microsoft-github-policy-service microsoft-github-policy-service Bot added Needs: Review 👀 PR that is ready to be reviewed and removed Needs: Attention 👋 Issue or PR needs to be reviewed by the author or it will be closed due to no activity labels Oct 30, 2026
Co-Authored-By: RolandKrummenacher <RolandKrummenacher@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Base automatically changed from flanakin/release-contributor-order to dev October 30, 2026 19:06

This branch has not been deployed

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

Labels

Needs: Review 👀 PR that is ready to be reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants