diff --git a/.github/workflows/add-coauthors.yml b/.github/workflows/add-coauthors.yml new file mode 100644 index 00000000..81c1d75b --- /dev/null +++ b/.github/workflows/add-coauthors.yml @@ -0,0 +1,85 @@ +name: Add Co-Authors +on: + pull_request: + types: [closed] + pull_request_review: + types: [submitted] + +jobs: + check-approval: + runs-on: ubuntu-latest + if: github.event.review.state == 'approved' + steps: + - name: Add approval status comment + uses: actions/github-script@v6 + with: + script: | + const { owner, repo, number } = context.issue; + await github.rest.issues.createComment({ + owner, + repo, + issue_number: number, + body: `✅ PR has been approved! CI process initiated.\nCI Run: ${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}` + }); + + add-coauthors: + needs: check-approval + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup Git + run: | + git config --global user.name "GitHub Actions" + git config --global user.email "noreply@github.com" + + - name: Add co-authors + run: | + # Get the merge commit SHA + MERGE_COMMIT_SHA=$(git rev-parse HEAD) + + # Get the base branch (target of PR) + BASE_BRANCH="${{ github.event.pull_request.base.ref }}" + + # Find merge base + MERGE_BASE=$(git merge-base HEAD $BASE_BRANCH) + + # Get list of commits in PR + COMMITS=$(git log --format="%H" $MERGE_BASE..$MERGE_COMMIT_SHA) + + # Initialize co-authors list + CO_AUTHORS="" + + # Loop through commits + for commit in $COMMITS; do + # Get commit author email and name + AUTHOR_EMAIL=$(git log -1 --format="%ae" $commit) + AUTHOR_NAME=$(git log -1 --format="%an" $commit) + + # Add to co-authors if not already present + AUTHOR_LINE="Co-authored-by: $AUTHOR_NAME <$AUTHOR_EMAIL>" + if [[ ! $CO_AUTHORS =~ $AUTHOR_LINE ]]; then + CO_AUTHORS="$CO_AUTHORS\n$AUTHOR_LINE" + fi + done + + # Amend the merge commit with co-authors + if [ ! -z "$CO_AUTHORS" ]; then + git fetch origin $BASE_BRANCH + git checkout $BASE_BRANCH + git pull origin $BASE_BRANCH + echo -e "\n$CO_AUTHORS" | git commit --amend -F - + git push origin $BASE_BRANCH + + # Add comment to PR + gh pr comment ${{ github.event.pull_request.number }} --body "✨ Added co-authors to merge commit.\nCI Status: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + fi + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a9f3ab1b..5e1406e6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -199,3 +199,17 @@ Before submitting a PR: - Ask for help when needed The project maintainers reserve the right to reject any contribution that doesn't meet these guidelines or align with the project's goals. + +## Git Co-Authors Feature +This repository includes an automated GitHub Action that preserves contributor attribution when PRs are squashed and merged. The workflow automatically adds `Co-authored-by` lines to the squashed commit message, ensuring that all contributors get proper credit for their work. +### How it works +1. When a PR is merged, the GitHub Action triggers automatically +2. It identifies all unique contributors who made commits in the PR +3. It adds their names and emails as `Co-authored-by` lines to the final squashed commit message +### Example co-authored commit message: +``` +feat: Add new feature +Co-authored-by: John Doe +Co-authored-by: Jane Smith +``` +The workflow is configured in `.github/workflows/add-coauthors.yml`.