content(plugins): add CentricMem #46
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # §8.6 — the merge gate. Fails CLOSED: an unlabelled or unverified PR never merges. | |
| # Every PR is a community submission (see labeler.yml). The gate requires: the `community` | |
| # label is present, the PR only ADDs new files under content/, a maintainer has cleared | |
| # `needs-verification`, and there is a fresh approval against the current head SHA. | |
| name: merge-gate | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, labeled, unlabeled] | |
| pull_request_review: | |
| types: [submitted, dismissed] | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| jobs: | |
| gate: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: { fetch-depth: 0 } | |
| - uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const pr = context.payload.pull_request; | |
| const labels = pr.labels.map((l) => l.name); | |
| const author = pr.user.login; | |
| // Unlabelled → fail closed. | |
| if (!labels.includes('community')) { | |
| core.setFailed('unlabelled PR — the community label must be present (the labeler applies it)'); | |
| return; | |
| } | |
| const files = await github.paginate(github.rest.pulls.listFiles, { | |
| owner: context.repo.owner, repo: context.repo.repo, pull_number: pr.number, | |
| }); | |
| const isContent = (f) => f.filename.startsWith('content/'); | |
| // Community PRs may only ADD new files under content/. Anything else — edits, | |
| // deletes, integrations, or code — needs a maintainer (open an issue). | |
| const codeScope = files.filter((f) => !isContent(f)); | |
| const mutated = files.filter((f) => isContent(f) && f.status !== 'added'); | |
| if (codeScope.length || mutated.length) { | |
| core.setFailed( | |
| 'community PRs may only ADD new files under content/ — edits, deletes, integrations and code changes need a maintainer (open an issue)' | |
| ); | |
| return; | |
| } | |
| if (labels.includes('needs-verification')) { | |
| core.setFailed('needs-verification is still applied — a maintainer must verify this entry (§10.1)'); | |
| return; | |
| } | |
| // An approval only counts if it is against the CURRENT head SHA. | |
| const reviews = await github.paginate(github.rest.pulls.listReviews, { | |
| owner: context.repo.owner, repo: context.repo.repo, pull_number: pr.number, | |
| }); | |
| const fresh = reviews.some((r) => r.state === 'APPROVED' && r.commit_id === pr.head.sha); | |
| if (!fresh) { | |
| core.setFailed('no maintainer approval against the current head SHA (a stale approval does not count)'); | |
| return; | |
| } | |
| core.info(`community path (${author}): content-only ADDs, verified, fresh approval — gate passes`); |