diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-17 03:59:59 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-17 03:59:59 +0300 |
| commit | db6f9afad27142248150096aa886f1057c1ebcd6 (patch) | |
| tree | 59ab5c506ad506a5461d5669878841d9ba7f2b62 | |
| parent | d743b39a2b922aa9f7c4365a0b6e53a8be68b9e6 (diff) | |
chore: add contributor intent issue form
| -rw-r--r-- | .github/ISSUE_TEMPLATE/config.yml | 2 | ||||
| -rw-r--r-- | .github/ISSUE_TEMPLATE/proposal.yml | 59 | ||||
| -rw-r--r-- | .github/workflows/label-intends-to-pr.yml | 91 | ||||
| -rw-r--r-- | CONTRIBUTING.md | 4 |
4 files changed, 154 insertions, 2 deletions
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..64eb98dc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,2 @@ +blank_issues_enabled: true +contact_links: [] diff --git a/.github/ISSUE_TEMPLATE/proposal.yml b/.github/ISSUE_TEMPLATE/proposal.yml new file mode 100644 index 00000000..01080b6e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/proposal.yml @@ -0,0 +1,59 @@ +name: Change proposal +description: Propose a bug fix, feature, workflow change, or first-time contribution. +title: "[proposal]: " +body: + - type: markdown + attributes: + value: | + Before opening your first PR, describe the change here and wait for maintainer approval. + + - type: textarea + id: current-behavior + attributes: + label: Current behavior + description: What does herdr do today? + validations: + required: true + + - type: textarea + id: proposed-change + attributes: + label: Proposed change + description: What do you want to change? + validations: + required: true + + - type: textarea + id: why-herdr + attributes: + label: Why this belongs in herdr + description: Explain why this fits herdr's direction. + validations: + required: true + + - type: dropdown + id: product-impact + attributes: + label: Does this change UI, interaction, workflow, or product direction? + options: + - "No" + - "Yes" + - "Not sure" + validations: + required: true + + - type: textarea + id: product-impact-details + attributes: + label: Impact details + description: If yes or not sure, explain what changes for users. + + - type: checkboxes + id: contribution-intent + attributes: + label: Contribution intent + options: + - label: I intend to open a PR for this change. + required: false + - label: I understand this does not mean the change is approved. + required: false diff --git a/.github/workflows/label-intends-to-pr.yml b/.github/workflows/label-intends-to-pr.yml new file mode 100644 index 00000000..11136ec3 --- /dev/null +++ b/.github/workflows/label-intends-to-pr.yml @@ -0,0 +1,91 @@ +name: Label contributor intent + +on: + issues: + types: [opened, edited] + +permissions: + issues: write + +env: + INTENDS_TO_PR_LABEL: intends-to-pr + +jobs: + label: + if: ${{ !github.event.issue.pull_request }} + runs-on: ubuntu-latest + + steps: + - name: Sync intends-to-pr label + uses: actions/github-script@v7 + with: + script: | + const label = process.env.INTENDS_TO_PR_LABEL; + const body = context.payload.issue.body || ''; + const issueNumber = context.payload.issue.number; + const { owner, repo } = context.repo; + const checkedIntentPattern = /^\s*-\s*\[[xX]\]\s*I intend to open a PR for this change\.\s*$/m; + const uncheckedIntentPattern = /^\s*-\s*\[ \]\s*I intend to open a PR for this change\.\s*$/m; + const shouldAddLabel = checkedIntentPattern.test(body); + const shouldRemoveLabel = uncheckedIntentPattern.test(body); + const labels = context.payload.issue.labels.map((item) => + typeof item === 'string' ? item : item.name, + ); + const hasLabel = labels.includes(label); + + if (shouldAddLabel && hasLabel) { + console.log(`${label} is already present on #${issueNumber}.`); + return; + } + + if (shouldRemoveLabel && !hasLabel) { + console.log(`${label} is already absent from #${issueNumber}.`); + return; + } + + if (!shouldAddLabel && !shouldRemoveLabel) { + console.log(`No contribution intent checkbox found for #${issueNumber}.`); + return; + } + + if (shouldAddLabel) { + try { + await github.rest.issues.getLabel({ owner, repo, name: label }); + } catch (error) { + if (error.status !== 404) { + throw error; + } + + await github.rest.issues.createLabel({ + owner, + repo, + name: label, + color: '0E8A16', + description: 'Contributor intends to open a PR for this issue.', + }); + } + + await github.rest.issues.addLabels({ + owner, + repo, + issue_number: issueNumber, + labels: [label], + }); + console.log(`Added ${label} to #${issueNumber}.`); + return; + } + + try { + await github.rest.issues.removeLabel({ + owner, + repo, + issue_number: issueNumber, + name: label, + }); + console.log(`Removed ${label} from #${issueNumber}.`); + } catch (error) { + if (error.status !== 404) { + throw error; + } + console.log(`${label} was already absent from #${issueNumber}.`); + } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 31f0ba02..0837c008 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ If you have a suggestion, disagreement, or contradiction with the current produc We use an approval gate for new contributors. -Before opening your first PR, open an issue describing what you want to change and why. Keep it short. Write in your own voice. If you intend to implement it yourself, add the `intends-to-pr` label. A maintainer will comment `/approve` if the direction is approved. Once approved, you can open PRs. +Before opening your first PR, open an issue describing what you want to change and why. Keep it short. Write in your own voice. If you intend to implement it yourself, check the contribution intent box in the issue form. The `intends-to-pr` label will be added automatically. A maintainer will comment `/approve` if the direction is approved. Once approved, you can open PRs. This exists because AI makes it trivial to generate plausible-looking contributions that do not fit the app. @@ -44,7 +44,7 @@ If your proposal changes the visual language, interaction model, or overall prod If your issue does not make the direction clear, it will likely be closed. -If you plan to implement the change yourself, say that directly in the issue and use the `intends-to-pr` label. That signals intent. It is not approval. +If you plan to implement the change yourself, say that directly in the issue and check the contribution intent box. That adds the `intends-to-pr` label automatically, signals intent, and does not mean the change is approved. ## Documentation for unreleased changes |
