From 9c3d08f66dff9023a244f4c7bfe6d11b8e979a20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20de=20Courville?= Date: Wed, 8 Jul 2026 10:52:30 +0200 Subject: [PATCH 1/4] Add workflow to redirect issues to Processing 4 Automatically close and respond to new issues with: > Thanks for your report. Please note that this repository is inactive and only kept for legacy purposes. > > If you're reporting a bug or requesting a feature for Processing 4, please open an issue in **[processing/processing4](https://github.com/processing/processing4/issues/new/choose)** instead.`; > > This issue will be closed automatically. --- .github/workflows/redirect.yml | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/redirect.yml diff --git a/.github/workflows/redirect.yml b/.github/workflows/redirect.yml new file mode 100644 index 0000000000..31aefbf32f --- /dev/null +++ b/.github/workflows/redirect.yml @@ -0,0 +1,37 @@ +name: Redirect issues to Processing 4 + +on: + issues: + types: [opened] + +permissions: + issues: write + +jobs: + redirect: + runs-on: ubuntu-latest + + steps: + - uses: actions/github-script@v9 + with: + script: | + > Thanks for your report. Please note that this repository is inactive and only kept for legacy purposes. + > + > If you're reporting a bug or requesting a feature for Processing 4, please open an issue in **[processing/processing4](https://github.com/processing/processing4/issues/new/choose)** instead.`; + > + > This issue will be closed automatically. + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body + }); + + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + state: "closed", + state_reason: "not_planned" + }); From 18bf13e69835a97939d96b6a9c4188f0cc8ac307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20de=20Courville?= Date: Wed, 8 Jul 2026 10:54:39 +0200 Subject: [PATCH 2/4] Fix comment formatting in redirect.yml --- .github/workflows/redirect.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/redirect.yml b/.github/workflows/redirect.yml index 31aefbf32f..e73b21a177 100644 --- a/.github/workflows/redirect.yml +++ b/.github/workflows/redirect.yml @@ -17,7 +17,7 @@ jobs: script: | > Thanks for your report. Please note that this repository is inactive and only kept for legacy purposes. > - > If you're reporting a bug or requesting a feature for Processing 4, please open an issue in **[processing/processing4](https://github.com/processing/processing4/issues/new/choose)** instead.`; + > If you're reporting a bug or requesting a feature for Processing 4, please open an issue in **[processing/processing4](https://github.com/processing/processing4/issues/new/choose)** instead. > > This issue will be closed automatically. From a83ecb993c3438bf4ec2de8945e10a626440e715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20de=20Courville?= Date: Wed, 8 Jul 2026 11:06:48 +0200 Subject: [PATCH 3/4] fmt --- .github/workflows/redirect.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/redirect.yml b/.github/workflows/redirect.yml index e73b21a177..ff55bb9e64 100644 --- a/.github/workflows/redirect.yml +++ b/.github/workflows/redirect.yml @@ -15,11 +15,11 @@ jobs: - uses: actions/github-script@v9 with: script: | - > Thanks for your report. Please note that this repository is inactive and only kept for legacy purposes. - > - > If you're reporting a bug or requesting a feature for Processing 4, please open an issue in **[processing/processing4](https://github.com/processing/processing4/issues/new/choose)** instead. - > - > This issue will be closed automatically. + const body = `> Thanks for your report. Please note that this repository is inactive and only kept for legacy purposes. + > + > If you're reporting a bug or requesting a feature for Processing 4, please open an issue in **https://github.com/processing/processing4/issues/new/choose** instead. + > + > This issue will be closed automatically.`; await github.rest.issues.createComment({ owner: context.repo.owner, From 9e9732bc184099f8ed3243c062a3cf342abb81b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20de=20Courville?= Date: Thu, 9 Jul 2026 10:27:58 +0200 Subject: [PATCH 4/4] Fix locked issue crash + robustness changes > [!NOTE] > this needs testing against the actual repository. This PR fixes the following issue: `Error: Unhandled error: HttpError: Unable to create comment because issue is locked.` See: https://github.com/processing/processing/actions/runs/29001253630 #### Summary of changes: - Skips commenting/locking on threads that are already locked (fixes the `HttpError: Unable to create comment because issue is locked` crash) - Wraps per-thread processing in try/catch so one failure doesn't abort the whole run - Closes PRs via `pulls.update` instead of `issues.update` - Adds a `concurrency` group to prevent overlapping runs - Handles labels returned as plain strings, not just objects - Breaks out of the loop once a thread is newer than the cutoff (list is already sorted) instead of just `continue` - Builds close messages via array + `join('\n')` instead of a template literal (avoids leading-whitespace indentation in the posted comment) --- .github/workflows/lock.yml | 142 +++++++++++++++++++++++-------------- 1 file changed, 90 insertions(+), 52 deletions(-) diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index 914771c1b5..4a4d2057db 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -5,6 +5,10 @@ on: - cron: '0 6 * * *' workflow_dispatch: +concurrency: + group: close-old-threads + cancel-in-progress: false + permissions: issues: write pull-requests: write @@ -23,23 +27,48 @@ jobs: const cutoff = new Date(); cutoff.setDate(cutoff.getDate() - cutoffDays); - const closeIssueMessage = `This issue has been automatically closed and locked. - - Processing 3.x is no longer actively developed. Since January 2020, development moved to the Processing 4 repository. - - If this issue is still relevant to Processing 4, we'd love to hear from you. Please open a new issue at: - https://github.com/processing/processing4/issues/new/choose - - Thank you for helping improve Processing.`; - - const closePrMessage = `This pull request has been automatically closed and locked. - - Processing 3.x is no longer actively developed. Since January 2020, development moved to the Processing 4 repository. - - If you'd still like to contribute this work, please open an issue in the Processing 4 repository to discuss it first: - https://github.com/processing/processing4/issues/new/choose + const closeIssueMessage = [ + 'This issue has been automatically closed and locked.', + '', + 'Processing 3.x is no longer actively developed. Since January 2020, development moved to the Processing 4 repository.', + '', + "If this issue is still relevant to Processing 4, we'd love to hear from you. Please open a new issue at:", + 'https://github.com/processing/processing4/issues/new/choose', + '', + 'Thank you for helping improve Processing.' + ].join('\n'); + + const closePrMessage = [ + 'This pull request has been automatically closed and locked.', + '', + 'Processing 3.x is no longer actively developed. Since January 2020, development moved to the Processing 4 repository.', + '', + "If you'd still like to contribute this work, please open an issue in the Processing 4 repository to discuss it first:", + 'https://github.com/processing/processing4/issues/new/choose', + '', + 'Thank you for your contribution.' + ].join('\n'); + + async function closeThread(thread) { + const isPr = Boolean(thread.pull_request); - Thank you for your contribution.`; + if (isPr) { + await github.rest.pulls.update({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: thread.number, + state: 'closed' + }); + } else { + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: thread.number, + state: 'closed', + state_reason: 'not_planned' + }); + } + } const threads = await github.paginate(github.rest.issues.listForRepo, { owner: context.repo.owner, @@ -51,41 +80,50 @@ jobs: }); for (const thread of threads) { - const updatedAt = new Date(thread.updated_at); - - if (updatedAt > cutoff) { - continue; - } - - const labels = thread.labels.map(label => label.name); - const isExempt = labels.some(label => exemptLabels.includes(label)); - - if (isExempt) { - continue; + try { + const updatedAt = new Date(thread.updated_at); + + if (updatedAt > cutoff) { + break; + } + + const labels = thread.labels.map(label => + typeof label === 'string' ? label : label.name + ); + + const isExempt = labels.some(label => exemptLabels.includes(label)); + + if (isExempt) { + console.log(`Skipping #${thread.number}: exempt label.`); + continue; + } + + const isPr = Boolean(thread.pull_request); + const body = isPr ? closePrMessage : closeIssueMessage; + + await closeThread(thread); + + if (thread.locked) { + console.log(`Closed #${thread.number}: already locked, so no comment was added.`); + continue; + } + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: thread.number, + body + }); + + await github.rest.issues.lock({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: thread.number, + lock_reason: 'resolved' + }); + + console.log(`Closed and locked #${thread.number}.`); + } catch (error) { + console.log(`Failed on #${thread.number}: ${error.status || 'unknown status'} ${error.message}`); } - - const isPr = Boolean(thread.pull_request); - const body = isPr ? closePrMessage : closeIssueMessage; - - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: thread.number, - body - }); - - await github.rest.issues.update({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: thread.number, - state: 'closed', - state_reason: 'not_planned' - }); - - await github.rest.issues.lock({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: thread.number, - lock_reason: 'resolved' - }); }