diff --git a/.github/workflows/sign-off.yml b/.github/workflows/sign-off.yml new file mode 100644 index 00000000..68846aea --- /dev/null +++ b/.github/workflows/sign-off.yml @@ -0,0 +1,59 @@ +# Copyright 2024 Catalan Lover +# Copyright 2022 - 2024 The Matrix.org Foundation C.I.C. +# +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileAttributionText: +# This modified file incorporates work from matrix-org/backend-meta +# https://github.com/matrix-org/backend-meta +# +name: Contribution requirements + +on: + pull_request: + types: [opened, edited, synchronize] + workflow_call: + +jobs: + signoff: + runs-on: ubuntu-latest + steps: + - name: Check PR for sign-off text + uses: actions/github-script@v6 + with: + script: | + // We don't require owners or members of the org to sign off. + const authorAssociation = context.payload.pull_request.author_association; + if (['OWNER', 'MEMBER'].includes(authorAssociation) || + // GitHub sometimes mislables users as 'CONTRIBUTOR'/'COLLABORATOR', + // so check that the user created the PR on the base project to check they have write access. + context.payload.pull_request.head.user.login === context.repo.owner) { + core.notice('Pull request does not require sign-off.'); + return; + } + + // This regex is intentionally left lenient. + const signOffRegex = /signed[_\- ]off[_\- ]by: [\S ]+ ?/i; + + if (signOffRegex.test(context.payload.pull_request.body ?? "")) { + core.notice('Pull request body contains a sign-off notice'); + return; + } + + const commits = await github.rest.pulls.listCommits({ + pull_number: context.payload.pull_request.number, + owner: context.repo.owner, + repo: context.repo.repo, + // It's *possible* the author has buried the sign-off 101 commits down, but + // we don't want to max out the API searching for it. + per_page: 100, + }); + + const commit = commits.data.find(c => signOffRegex.test(c.commit.message)); + if (commit) { + core.notice(`Commit '${commit.id}' contains a sign-off notice`); + return; + } + + core.setFailed('No sign off found. Please ensure you have signed off following the advice in https://the-draupnir-project.github.io/draupnir-documentation/docs/contributing#sign-off .') + core.notice('Ensure you have matched the format `Signed-off-by: Your Name `')