diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..61881ff --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,57 @@ +name: Bug report +description: Report a problem with the ComfyUI-PromptHistoryGallery. +title: "[Bug]: " +labels: + - bug +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to report an issue! Please include enough detail for us to reproduce it inside ComfyUI. + - type: input + id: version + attributes: + label: ComfyUI-PromptHistoryGallery version / commit + description: Include the git commit hash or release tag for this repository. + placeholder: e.g. v0.3.0 or 1a2b3c4 + validations: + required: true + - type: input + id: comfyui_version + attributes: + label: ComfyUI version / commit + description: Include the ComfyUI commit hash or release tag. + placeholder: e.g. v0.6.0 or a1b2c3d + validations: + required: true + - type: input + id: os_details + attributes: + label: Operating system + placeholder: e.g. Ubuntu 24.04, macOS 15.0 beta + - type: textarea + id: steps_to_reproduce + attributes: + label: Steps to reproduce + description: Provide a clear step-by-step guide. + placeholder: | + 1. Go to '...' + 2. Click on '...' + 3. Scroll down to '...' + 4. See error + validations: + required: true + - type: textarea + id: expected_behavior + attributes: + label: Expected behavior + description: What did you expect to happen? + validations: + required: true + - type: textarea + id: actual_behavior + attributes: + label: Actual behavior + description: What actually happened? Include error messages if applicable. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3ba13e0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..ef0113f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,31 @@ +name: Feature request +description: Suggest an improvement or new capability for the Prompt History Gallery extension. +title: "[Feature]: " +labels: + - enhancement +body: + - type: markdown + attributes: + value: | + Thanks for contributing ideas to improve this extension! Share as much detail as you can so we can evaluate and prioritize the request. + - type: textarea + id: problem + attributes: + label: What problem does this solve? + description: Describe the pain point or workflow that would benefit from this change. + placeholder: | + - Who is impacted? + - What is the current limitation? + - Why is a change needed? + validations: + required: true + - type: textarea + id: proposed_solution + attributes: + label: Proposed solution + description: Explain how you would like the feature to work. + placeholder: | + - Describe the desired behavior + - Include UI/UX considerations if relevant + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml new file mode 100644 index 0000000..e260be2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -0,0 +1,39 @@ +name: Question +description: Ask a question about using or configuring the Prompt History Gallery extension. +title: "[Question]: " +labels: + - question +body: + - type: markdown + attributes: + value: | + Thanks for reaching out! Share details so we can help quickly. + - type: input + id: version + attributes: + label: ComfyUI-PromptHistoryGallery version / commit + description: Include the git commit hash or release tag for this repository. + placeholder: e.g. v0.3.0 or 1a2b3c4 + validations: + required: true + - type: textarea + id: question_details + attributes: + label: Details + description: Include the full question, context, and what you've tried so far. + placeholder: | + - What are you trying to achieve? + - What steps have you taken? + - Any error messages or unexpected behavior? + validations: + required: true + - type: input + id: comfyui_version + attributes: + label: ComfyUI version / commit + placeholder: e.g. v0.6.0 or a1b2c3d + - type: input + id: operating_system + attributes: + label: Operating system + placeholder: e.g. macOS 14.6, Windows 11, Ubuntu 24.04 diff --git a/.github/workflows/auto-assign-issues.yml b/.github/workflows/auto-assign-issues.yml new file mode 100644 index 0000000..1d0918c --- /dev/null +++ b/.github/workflows/auto-assign-issues.yml @@ -0,0 +1,24 @@ +name: Auto-assign issues + +permissions: {} + +on: + issues: + types: [opened] + +jobs: + auto-assign: + permissions: + issues: write + runs-on: ubuntu-latest + steps: + - name: Auto-assign issue + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 + with: + script: | + github.rest.issues.addAssignees({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + assignees: ['x0x0b'] + }); diff --git a/.github/workflows/close-inactive-issues.yml b/.github/workflows/close-inactive-issues.yml new file mode 100644 index 0000000..16d272a --- /dev/null +++ b/.github/workflows/close-inactive-issues.yml @@ -0,0 +1,23 @@ +name: Close inactive issues +on: + schedule: + - cron: "0 20 * * *" + +jobs: + close-issues: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # ratchet:actions/stale@v10 + with: + days-before-issue-stale: 7 + days-before-issue-close: 5 + stale-issue-label: "stale" + exempt-issue-labels: "author:maintainer" + stale-issue-message: "This issue is stale because it has been open for 7 days with no activity. It will be closed in 5 days if no further activity occurs." + close-issue-message: "This issue was closed because it has been inactive for 5 days since being marked as stale." + days-before-pr-stale: -1 + days-before-pr-close: -1 + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/enforce-author-label.yml b/.github/workflows/enforce-author-label.yml new file mode 100644 index 0000000..7249d13 --- /dev/null +++ b/.github/workflows/enforce-author-label.yml @@ -0,0 +1,140 @@ +name: Enforce author label + +on: + schedule: + - cron: "45 19 * * *" + workflow_dispatch: + issues: + types: [opened, labeled] + +jobs: + enforce: + if: github.event_name != 'issues' || github.event.action == 'opened' || (github.event.action == 'labeled' && github.event.label.name == 'author:maintainer') + permissions: + issues: write + runs-on: ubuntu-latest + steps: + - name: Enforce author label usage + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 + with: + script: | + const labelName = 'author:maintainer'; + const { owner, repo } = context.repo; + + const ensureLabelExists = async () => { + try { + await github.rest.issues.getLabel({ + owner, + repo, + name: labelName + }); + } catch (error) { + if (error.status === 404) { + await github.rest.issues.createLabel({ + owner, + repo, + name: labelName, + color: 'ededed', + description: 'Issues opened by repository maintainers remain active' + }); + core.info(`Created label ${labelName}.`); + } else { + throw error; + } + } + }; + + const addLabel = async (issueNumber) => { + await ensureLabelExists(); + await github.rest.issues.addLabels({ + owner, + repo, + issue_number: issueNumber, + labels: [labelName] + }); + core.info(`Ensured ${labelName} on issue #${issueNumber}.`); + }; + + const shouldRemoveLabel = (issue) => { + if (!issue || issue.pull_request) { + return false; + } + return issue.user?.login !== 'x0x0b'; + }; + + const removeLabel = async (issueNumber) => { + try { + await github.rest.issues.removeLabel({ + owner, + repo, + issue_number: issueNumber, + name: labelName + }); + core.info(`Removed ${labelName} from issue #${issueNumber}.`); + } catch (error) { + if (error.status !== 404) { + throw error; + } + } + }; + + if (context.eventName === 'issues') { + const issue = context.payload.issue; + const action = context.payload.action; + const author = issue?.user?.login ?? 'unknown'; + + if (!issue || issue.pull_request) { + core.info('Ignoring pull request event.'); + return; + } + + if (action === 'opened') { + if (issue.user?.login === 'x0x0b') { + core.info(`Issue #${issue.number} opened by ${author}; ensuring ${labelName}.`); + await addLabel(issue.number); + } else { + core.info(`Issue #${issue.number} opened by ${author}; removing ${labelName} if present.`); + await removeLabel(issue.number); + } + return; + } + + if (action === 'labeled' && shouldRemoveLabel(issue)) { + core.info(`Issue #${issue.number} labeled event by ${author}; label should be removed.`); + await removeLabel(issue.number); + } else { + core.info(`No action needed for issue #${issue.number} (author: ${author}).`); + } + + return; + } + + core.info(`Auditing usage of ${labelName}.`); + + const issues = await github.paginate(github.rest.issues.listForRepo, { + owner, + repo, + state: 'all', + per_page: 100 + }); + + for (const issue of issues) { + const author = issue.user?.login ?? 'unknown'; + if (issue.pull_request) { + core.info(`Skipping pull request #${issue.number} by ${author}.`); + continue; + } + const hasLabel = issue.labels?.some(label => label.name === labelName) ?? false; + if (author === 'x0x0b' && !hasLabel) { + core.info(`Issue #${issue.number} by ${author} missing ${labelName}; adding.`); + await addLabel(issue.number); + continue; + } + const remove = shouldRemoveLabel(issue) && hasLabel; + core.info( + `Issue #${issue.number} by ${author}: ${remove ? 'label will be removed' : hasLabel ? 'label remains' : 'label not present'}.` + ); + if (remove) { + await removeLabel(issue.number); + } + }