diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 000000000..237dec9ac --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,27 @@ +docs: +- changed-files: + - any-glob-to-any-file: + - 'docs/**/*' +comp:sdk: +- changed-files: + - any-glob-to-any-file: + - 'sdk/**/*' +comp:ci: +- changed-files: + - any-glob-to-any-file: + - '.github/**/*' +comp:db: +- changed-files: + - any-glob-to-any-file: + - 'service/policy/db/**/*' +comp:kas: +- changed-files: + - any-glob-to-any-file: + - 'service/kas/**' +comp:policy: +- all: + - changed-files: + - any-glob-to-any-file: + - 'service/policy/**/*' + - all-globs-to-all-files: + - '!service/policy/db/**/*' diff --git a/.github/workflows/label.yaml b/.github/workflows/label.yaml new file mode 100644 index 000000000..4eef70f55 --- /dev/null +++ b/.github/workflows/label.yaml @@ -0,0 +1,90 @@ +name: Label Pull Requests + +on: + pull_request_target: + types: + - opened + - reopened + - unlabeled + +permissions: {} + +jobs: + labeler: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0 + + external-contributor: + permissions: + pull-requests: write + runs-on: ubuntu-latest + steps: + - name: Check Author Association and Label PR + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const pr = context.payload.pull_request; + if (!pr) { + core.error("Could not get PR from context"); + return; + } + + // Define associations considered "internal" + const internalAssociations = ["MEMBER"]; + + // Label to add if the author is external + const externalLabel = "external-contributor"; + + const authorAssociation = pr.author_association; + const isExternal = !internalAssociations.includes(authorAssociation); + + const prLabels = pr.labels.map(label => label.name); + const hasExternalLabel = prLabels.includes(externalLabel); + + core.info(`Event: ${context.eventName}, Action: ${context.payload.action}`); + core.info(`Author: ${pr.user.login}, Association: ${authorAssociation}, Is External: ${isExternal}`); + core.info(`Current PR Labels: ${prLabels.join(', ')}`); + + // Logic for 'unlabeled' event: only re-add if *our* label was removed and author is still external + if (context.eventName === 'pull_request_target' && context.payload.action === 'unlabeled') { + const removedLabel = context.payload.label.name; + core.info(`Label removed: ${removedLabel}`); + if (removedLabel === externalLabel && isExternal) { + core.info(`External label was removed, author is still external. Re-adding label: ${externalLabel}`); + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + labels: [externalLabel] + }); + core.info(`Label "${externalLabel}" re-added successfully.`); + } else { + core.info(`Removed label was not the external label or author is not external. No action needed for unlabeled event.`); + } + } + // Logic for 'opened' or 'reopened' events: add label if external and not already present + else if (['opened', 'reopened'].includes(context.payload.action)) { + if (isExternal && !hasExternalLabel) { + core.info(`Author association "${authorAssociation}" is external and label is missing. Adding label: ${externalLabel}`); + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + labels: [externalLabel] + }); + core.info(`Label "${externalLabel}" added successfully.`); + } else if (isExternal && hasExternalLabel) { + core.info(`Author is external, but label "${externalLabel}" is already present.`); + } else { + if (hasExternalLabel) { + core.warning(`Author association "${authorAssociation}" is internal. However, external contributor label is present.`) + } else { + core.info(`Author association "${authorAssociation}" is internal. No label added.`) + } + } + }