fix: add .dockerignore to reduce build context size #20
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
| name: Approved PRs Only | |
| on: | |
| pull_request_target: | |
| types: [opened, reopened] | |
| permissions: | |
| pull-requests: write | |
| issues: write | |
| contents: read | |
| env: | |
| UNAPPROVED_LABEL: unapproved | |
| UNAPPROVED_PR_COMMENT: "This repository is invite-only. Pull requests from unapproved actors or forks are automatically closed." | |
| APPROVED_ACTORS_FILE: .github/approved-actors.yml | |
| jobs: | |
| enforce-approved-prs: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Enforce invite-only PR participation | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| const pull_number = context.payload.pull_request.number; | |
| const opener = context.payload.pull_request.user.login; | |
| const fromFork = context.payload.pull_request.head.repo.full_name !== `${owner}/${repo}`; | |
| const label = process.env.UNAPPROVED_LABEL; | |
| const comment = process.env.UNAPPROVED_PR_COMMENT; | |
| const whitelistPath = process.env.APPROVED_ACTORS_FILE; | |
| async function loadWhitelist() { | |
| try { | |
| const { data } = await github.request( | |
| "GET /repos/{owner}/{repo}/contents/{path}", | |
| { owner, repo, path: whitelistPath } | |
| ); | |
| if (!data?.content) return new Set(); | |
| const text = Buffer.from(data.content, "base64").toString("utf8"); | |
| const users = []; | |
| let inUsers = false; | |
| for (const raw of text.split(/\r?\n/)) { | |
| const line = raw.trim(); | |
| if (!line || line.startsWith("#")) continue; | |
| if (line === "users:" || line.startsWith("users:")) { | |
| inUsers = true; | |
| continue; | |
| } | |
| if (inUsers && line.startsWith("- ")) { | |
| users.push(line.slice(2).trim()); | |
| continue; | |
| } | |
| if (inUsers && !line.startsWith("- ")) { | |
| break; | |
| } | |
| } | |
| return new Set(users); | |
| } catch (error) { | |
| core.warning(`Unable to read ${whitelistPath}: ${error.message}`); | |
| return new Set(); | |
| } | |
| } | |
| const whitelist = await loadWhitelist(); | |
| const whitelisted = whitelist.has(opener); | |
| let collaborator = false; | |
| try { | |
| const resp = await github.request( | |
| "GET /repos/{owner}/{repo}/collaborators/{username}", | |
| { owner, repo, username: opener } | |
| ); | |
| collaborator = resp.status === 204; | |
| } catch (error) { | |
| if (error.status !== 404) { | |
| core.warning(`Collaborator check returned ${error.status}: ${error.message}`); | |
| } | |
| collaborator = false; | |
| } | |
| // Fork PRs are only approved for collaborators. | |
| const approved = collaborator || (whitelisted && !fromFork); | |
| if (approved) { | |
| core.info(`${opener} is approved (collaborator=${collaborator}, whitelisted=${whitelisted}, fromFork=${fromFork}); no action needed.`); | |
| return; | |
| } | |
| try { | |
| await github.request("GET /repos/{owner}/{repo}/labels/{name}", { | |
| owner, | |
| repo, | |
| name: label, | |
| }); | |
| } catch (error) { | |
| if (error.status === 404) { | |
| try { | |
| await github.request("POST /repos/{owner}/{repo}/labels", { | |
| owner, | |
| repo, | |
| name: label, | |
| color: "B60205", | |
| description: "Issue or PR opened by a non-collaborator in invite-only participation mode", | |
| }); | |
| } catch (createError) { | |
| if (createError.status !== 422) { | |
| throw createError; | |
| } | |
| } | |
| } else { | |
| throw error; | |
| } | |
| } | |
| await github.request("POST /repos/{owner}/{repo}/issues/{issue_number}/labels", { | |
| owner, | |
| repo, | |
| issue_number: pull_number, | |
| labels: [label], | |
| }); | |
| await github.request("POST /repos/{owner}/{repo}/issues/{issue_number}/comments", { | |
| owner, | |
| repo, | |
| issue_number: pull_number, | |
| body: comment, | |
| }); | |
| await github.request("PATCH /repos/{owner}/{repo}/pulls/{pull_number}", { | |
| owner, | |
| repo, | |
| pull_number, | |
| state: "closed", | |
| }); |