Download .github/workflows/compliance-close.yml from SaylorTwift/opencode: direct link, hf CLI and curl.
- Browser
- Download file 5.06 kB
-
https://huggingface.co/SaylorTwift/opencode/resolve/main/.github/workflows/compliance-close.yml
- Command line
-
hf download hf://SaylorTwift/opencode/.github/workflows/compliance-close.yml
-
curl -L -o compliance-close.yml https://huggingface.co/SaylorTwift/opencode/resolve/main/.github/workflows/compliance-close.yml
5.06 kB
| name: compliance-close | |
| on: | |
| schedule: | |
| # Run every 30 minutes to check for expired compliance windows | |
| - cron: "*/30 * * * *" | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| issues: write | |
| pull-requests: write | |
| jobs: | |
| close-non-compliant: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Close non-compliant issues and PRs after 2 hours | |
| uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 | |
| with: | |
| script: | | |
| const { data: items } = await github.rest.issues.listForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| labels: 'needs:compliance', | |
| state: 'open', | |
| per_page: 100, | |
| }); | |
| if (items.length === 0) { | |
| core.info('No open issues/PRs with needs:compliance label'); | |
| return; | |
| } | |
| const now = Date.now(); | |
| const twoHours = 2 * 60 * 60 * 1000; | |
| const orgMemberAssociations = new Set(['OWNER', 'MEMBER']); | |
| const agentLogin = 'opencode-agent[bot]'; | |
| const { data: file } = await github.rest.repos.getContent({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| path: '.github/TEAM_MEMBERS', | |
| ref: 'dev', | |
| }); | |
| const teamMembers = new Set( | |
| Buffer.from(file.content, 'base64') | |
| .toString() | |
| .split('\n') | |
| .map((line) => line.trim().toLowerCase()) | |
| .filter(Boolean) | |
| ); | |
| function isExempt(item) { | |
| const login = item.user?.login?.toLowerCase(); | |
| return ( | |
| login === agentLogin || | |
| orgMemberAssociations.has(item.author_association) || | |
| (login && teamMembers.has(login)) | |
| ); | |
| } | |
| for (const item of items) { | |
| const isPR = !!item.pull_request; | |
| const kind = isPR ? 'PR' : 'issue'; | |
| const login = item.user?.login; | |
| if (isExempt(item)) { | |
| core.info(`Skipping ${kind} #${item.number}; author ${login || 'unknown'} is exempt`); | |
| try { | |
| await github.rest.issues.removeLabel({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: item.number, | |
| name: 'needs:compliance', | |
| }); | |
| } catch (e) {} | |
| continue; | |
| } | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: item.number, | |
| }); | |
| const complianceComment = comments.find(c => c.body.includes('<!-- issue-compliance -->')); | |
| if (!complianceComment) continue; | |
| const commentAge = now - new Date(complianceComment.created_at).getTime(); | |
| if (commentAge < twoHours) { | |
| core.info(`${kind} #${item.number} still within 2-hour window (${Math.round(commentAge / 60000)}m elapsed)`); | |
| continue; | |
| } | |
| const closeMessage = isPR | |
| ? 'This pull request has been automatically closed because it was not updated to meet our [contributing guidelines](../blob/dev/CONTRIBUTING.md) within the 2-hour window.\n\nFeel free to open a new pull request that follows our guidelines.' | |
| : 'This issue has been automatically closed because it was not updated to meet our [contributing guidelines](../blob/dev/CONTRIBUTING.md) within the 2-hour window.\n\nFeel free to open a new issue that follows our issue templates.'; | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: item.number, | |
| body: closeMessage, | |
| }); | |
| try { | |
| await github.rest.issues.removeLabel({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: item.number, | |
| name: 'needs:compliance', | |
| }); | |
| } catch (e) {} | |
| if (isPR) { | |
| await github.rest.pulls.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: item.number, | |
| state: 'closed', | |
| }); | |
| } else { | |
| await github.rest.issues.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: item.number, | |
| state: 'closed', | |
| state_reason: 'not_planned', | |
| }); | |
| } | |
| core.info(`Closed non-compliant ${kind} #${item.number} after 2-hour window`); | |
| } | |