Skip to content

Commit

Permalink
add files to check issues for reproduction repository and maintainer …
Browse files Browse the repository at this point in the history
…access
  • Loading branch information
joelbutcher committed Dec 6, 2023
1 parent 9d3e191 commit f9643ab
Show file tree
Hide file tree
Showing 2 changed files with 264 additions and 0 deletions.
67 changes: 67 additions & 0 deletions .github/workflows/check-pr-maintainer-access.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: check-pr-maintainer-access

on:
pull_request_target:
types:
- opened

permissions:
pull-requests: write

jobs:
notify-when-maintainers-cannot-edit:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v3
with:
script: |
const query = `
query($number: Int!) {
repository(owner: "joelbutcher", name: "socialstream") {
pullRequest(number: $number) {
headRepositoryOwner {
login
}
maintainerCanModify
}
}
}
`
const pullNumber = context.issue.number
const variables = { number: pullNumber }
try {
console.log(`Check #${pullNumber} for maintainer edit access...`)
const result = await github.graphql(query, variables)
console.log(JSON.stringify(result, null, 2))
const pullRequest = result.repository.pullRequest
if (pullRequest.headRepositoryOwner.login === 'joelbutcher') {
console.log('PR owned by joelbutcher')
return
}
if (! pullRequest.maintainerCanModify) {
console.log('PR not owned by joelbutcher and does not have maintainer edits enabled')
await github.issues.createComment({
issue_number: pullNumber,
owner: 'joelbutcher',
repo: 'socialstream',
body: 'Thanks for submitting a PR!\n\nIn order to review and merge PRs most efficiently, we require that all PRs grant maintainer edit access before we review them. If your fork belongs to a GitHub organization, please move the repository to your personal account and try again. If you\'re already using a personal fork, you can learn how to enable maintainer access [in the GitHub documentation](https://docs.github.com/en/github/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork).'
})
await github.issues.update({
issue_number: pullNumber,
owner: 'joelbutcher',
repo: context.repo.repo,
state: 'closed'
})
}
} catch(error) {
console.log(error)
}
197 changes: 197 additions & 0 deletions .github/workflows/manage-issue.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
name: manage-issue

on:
issues:
types: [opened, edited]

jobs:
check-repro:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v3
with:
script: |
const URL_REGEXP = /### Reproduction repository[\r\n]+([^#]+)###/m
const REPRO_STEPS_REGEXP = /### Steps to reproduce[\r\n]+([^#]+)###/m
const LABEL_NEEDS_MORE_INFORMATION = 'needs more info'
const LABEL_UNCONFIRMED = 'unconfirmed'
function debug(...args) {
core.info(args.map(JSON.stringify).join(' '))
}
if (context.payload.comment) {
debug('Ignoring comment update.')
return
}
const user = context.payload.sender.login
const issue = context.payload.issue
const body = issue.body
const urlMatch = body.match(URL_REGEXP)
const reproStepsMatch = body.match(REPRO_STEPS_REGEXP)
const url = urlMatch !== null ? urlMatch[1].trim() : null
const reproSteps = reproStepsMatch !== null ? reproStepsMatch[1].trim() : null
debug(`Found URL '${url}'`)
debug(`Found repro steps '${reproSteps}'`)
async function createComment(comment) {
comment = comment
.split('\n')
.map((line) => line.trim())
.join('\n')
.trim()
await github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment,
})
}
async function getGitHubActionComments() {
debug(`Loading existing comments...`)
const comments = await github.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
})
return comments.data.filter(comment => {
debug(`comment by user: '${comment.user.login}'`)
return comment.user.login === 'github-actions[bot]'
})
}
async function getIssueLabels() {
const issues = await github.issues.listLabelsOnIssue({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
})
return issues.data
}
async function updateIssue(state, state_reason = null) {
await github.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
state,
state_reason,
})
}
async function closeWithComment(comment) {
if (issue.state !== 'open') {
debug(`Issue is not open`)
return
}
const comments = await getGitHubActionComments()
if (comments.length > 0) {
debug(`Already commented on issue won't comment again`)
return
}
debug(`Missing required information`)
await github.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: [LABEL_NEEDS_MORE_INFORMATION],
})
await createComment(comment)
await updateIssue('closed', 'not_planned')
}
async function openWithComment(comment) {
if (issue.state !== 'closed') {
debug(`Issue is already open`)
return
}
const labels = await getIssueLabels()
const label = labels.find(label => label.name === LABEL_NEEDS_MORE_INFORMATION)
if (! label) {
debug(`Issue was not tagged as needs information`)
return
}
const comments = await getGitHubActionComments()
if (comments.length === 0) {
debug(`Issue was closed by someone else, won't reopen`)
return
}
debug(`Reopening closed issue`)
await github.issues.removeLabel({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
name: LABEL_NEEDS_MORE_INFORMATION,
})
await createComment(comment)
await updateIssue('open')
}
const COMMENT_HEADER = `
Hey @${user}! We're sorry to hear that you've hit this issue. 💛
`.trim()
const NO_REPRO_URL = ((! url) || (! url.includes('https://github.com/')) || (url.includes('https://github.com/joelbutcher') && (! url.includes('https://github.com/joelbutcher/socialstream-demo'))))
const NO_REPRO_STEPS = reproSteps.length < 25
if (NO_REPRO_URL || NO_REPRO_STEPS) {
let comment = `
${COMMENT_HEADER}
`
if (NO_REPRO_URL) {
comment += `
However, it looks like you forgot to fill in the reproduction repository URL. Can you edit your original post and then we'll look at your issue?
We need a public GitHub repository which contains a Laravel app with the minimal amount of Socialstream code to reproduce the problem. **Please do not link to your actual project**, what we need instead is a _minimal_ reproduction in a fresh project without any unnecessary code. This means it doesn\'t matter if your real project is private / confidential, since we want a link to a separate, isolated reproduction. That would allow us to download it and review your bug much easier, so it can be fixed quicker. Please make sure to include a database seeder with everything we need to set the app up quickly.
`
}
if (NO_REPRO_URL && NO_REPRO_STEPS) {
comment += `
Also, `
} else if (NO_REPRO_STEPS) {
comment += `
However, `
}
if (NO_REPRO_STEPS) {
comment += `it doesn't look like you've provided much information on how to replicate the issue. Please edit your original post with clear steps we need to take.`
}
closeWithComment(comment)
} else {
openWithComment(`
Thank you for providing reproduction steps! Reopening the issue now.
`)
}

0 comments on commit f9643ab

Please sign in to comment.