ci: clean up the issue and pull request workflows

- name the files and workflows like the release workflows and every step after what it does
- run all workflows without the GitHub Actions cache like the release workflow
This commit is contained in:
peaklabs-dev authored and GitHub committed 2026-11-02 00:06:15 +01:00
1 parent 79fd5a8f7e
commit c38ce3caef
8 files changed
+91 -287

No files matched your search

+5 -12
View File
@@ -8,16 +8,11 @@ workflows:
- 'actions/upload-artifact@v7.0.2'
- 'docker/build-push-action@v7.4.0'
- 'docker/setup-buildx-action@v4.4.1'
'.github/workflows/chore-lock-closed-issues-discussions-and-prs.yml':
- 'dessant/lock-threads@v6.0.2'
'.github/workflows/chore-manage-pr-branch.yaml':
- 'actions/github-script@v9.0.0'
'.github/workflows/chore-manage-stale-issues-and-prs.yml':
- 'actions/stale@v11.0.0'
'.github/workflows/chore-pr-comments.yml': []
'.github/workflows/clean-manifests.yaml':
- 'actions/checkout@v7.0.1'
- 'actions/upload-artifact@v7.0.2'
'.github/workflows/lock-threads.yaml':
- 'dessant/lock-threads@v6.0.2'
'.github/workflows/main.yaml':
- 'actions/checkout@v7.0.1'
- 'actions/download-artifact@v8.0.2'
@@ -37,6 +32,9 @@ workflows:
- 'actions/checkout@v7.0.1'
- 'actions/download-artifact@v8.0.2'
- 'docker/login-action@v4.7.0'
'.github/workflows/request-docs-update.yaml': []
'.github/workflows/stale.yaml':
- 'actions/stale@v11.0.0'
dependencies:
'actions/checkout@v7.0.1':
ref: 'v7.0.1'
@@ -48,11 +46,6 @@ dependencies:
commit: 'sha1-9000827ccba6bdab643e8b6fd33ac0654aef8333'
owner_id: 44036562
repo_id: 192626254
'actions/github-script@v9.0.0':
ref: 'v9.0.0'
commit: 'sha1-3a2844b7e9c422d3c10d287c895573f7108da1b3'
owner_id: 44036562
repo_id: 205262760
'actions/stale@v11.0.0':
ref: 'v11.0.0'
commit: 'sha1-4391f3da665fdf50b6810c1a66712fb9ba21aa93'
@@ -1,29 +0,0 @@
name: Lock closed Issues, Discussions, and PRs
on:
schedule:
- cron: '0 1 * * *'
permissions: {}
concurrency:
group: lock-threads
cancel-in-progress: false
jobs:
lock-threads:
name: Lock inactive threads
permissions:
issues: write # lock the inactive issues
discussions: write # lock the inactive discussions
pull-requests: write # lock the inactive pull requests
runs-on: ubuntu-26.04 # https://github.com/actions/runner-images
timeout-minutes: 10
steps:
- name: Lock threads after 30 days of inactivity
uses: dessant/lock-threads@v6.0.2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
issue-inactive-days: '30'
discussion-inactive-days: '30'
pr-inactive-days: '30'
@@ -1,187 +0,0 @@
name: Manage PR Branch
# Runs *after* the "PR Quality" workflow finishes. This is required because
# PR Quality may close a PR that fails its checks, so we must wait for it to
# complete before deciding whether to retarget the PR's base branch.
on:
# Only reads the PR Quality run and the pull request through the API, it checks out and runs no code of the pull request
# jactionlint ignore=dangerous-triggers
workflow_run:
workflows: ["PR Quality"]
types:
- completed
permissions: {}
concurrency:
group: manage-pr-branch-${{ github.event.workflow_run.head_sha }}
cancel-in-progress: true
jobs:
manage-branch:
name: Retarget the pull request
permissions:
contents: read # read the branches of the repository
pull-requests: write # change the base branch of the pull request and comment on it
runs-on: ubuntu-26.04 # https://github.com/actions/runner-images
timeout-minutes: 10
steps:
- name: Retarget PR base branch based on category
uses: actions/github-script@v9.0.0
with:
script: |
const run = context.payload.workflow_run;
// Branch routing based on the "Category" section of the PR body.
// Bug fixes and one-click service changes ship in patch releases -> main.
// Everything else (features, improvements) -> next.
const MAIN_BRANCH = 'main';
const NEXT_BRANCH = 'next';
// Maintainers/collaborators are trusted to pick their own base branch.
const EXEMPT_ASSOCIATIONS = new Set(['OWNER', 'MEMBER', 'COLLABORATOR']);
// Resolve the open PR from the triggering run.
//
// PR Quality runs on `pull_request_target`, so `run.head_sha` is the
// *base* branch tip, not the PR head — a commit-based lookup finds
// nothing. Instead match on the source branch (`head_branch`) and its
// owner (`head_repository.owner.login`), which uniquely identify the PR
// via the `owner:branch` head filter. This also works for forked PRs,
// where `workflow_run.pull_requests` is empty.
const headOwner = run.head_repository?.owner?.login;
const headBranch = run.head_branch;
let prRef;
if (headOwner && headBranch) {
const { data: openPrs } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
head: `${headOwner}:${headBranch}`,
per_page: 100,
});
prRef = openPrs[0];
}
// Fallback: same-repo PRs may also be resolvable by commit association.
if (!prRef) {
const { data: associated } = await github.rest.repos.listPullRequestsAssociatedWithCommit({
owner: context.repo.owner,
repo: context.repo.repo,
commit_sha: run.head_sha,
});
prRef = associated.find(pr => pr.state === 'open');
}
if (!prRef) {
core.info('No open PR associated with this run (possibly closed by PR Quality). Skipping.');
return;
}
// Fetch the full PR to get an up-to-date body, base ref, and state.
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prRef.number,
});
if (pr.state !== 'open') {
core.info(`PR #${pr.number} is not open. Skipping.`);
return;
}
// Skip PRs opened by owners/members/collaborators — they choose their own base.
if (EXEMPT_ASSOCIATIONS.has(pr.author_association)) {
core.info(`PR #${pr.number} author association is ${pr.author_association}. Skipping.`);
return;
}
// Skip if a maintainer has already changed the base branch manually.
const timeline = await github.paginate(github.rest.issues.listEventsForTimeline, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
per_page: 100,
});
const baseChanges = timeline.filter(e => e.event === 'base_ref_changed');
for (const change of baseChanges) {
const actor = change.actor?.login;
if (!actor) {
continue;
}
try {
const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: actor,
});
// admin/maintain/write => trusted maintainer.
if (['admin', 'maintain', 'write'].includes(perm.permission)) {
core.info(`Base branch was changed manually by ${actor} (${perm.permission}). Skipping.`);
return;
}
} catch (error) {
core.info(`Could not resolve permission for ${actor}: ${error.message}`);
}
}
// Parse the checked category checkboxes from the PR body.
const body = pr.body ?? '';
const checked = [];
const checkboxRegex = /^\s*-\s*\[([ xX])\]\s*(.+?)\s*$/gm;
let match;
while ((match = checkboxRegex.exec(body)) !== null) {
if (match[1].toLowerCase() === 'x') {
checked.push(match[2].toLowerCase());
}
}
const includesAny = (labels) => labels.some(label => checked.some(c => c.includes(label)));
const mainCategories = ['bug fix', 'adding new one click service', 'fixing or updating existing one click service'];
const nextCategories = ['improvement', 'new feature'];
const wantsMain = includesAny(mainCategories);
const wantsNext = includesAny(nextCategories);
if (!wantsMain && !wantsNext) {
core.info('No category selected in the PR body. Skipping.');
return;
}
// If categories from both groups are checked, prefer next: features and
// improvements can only be released from the development branch.
const targetBranch = wantsNext ? NEXT_BRANCH : MAIN_BRANCH;
if (pr.base.ref === targetBranch) {
core.info(`PR #${pr.number} already targets ${targetBranch}. Nothing to do.`);
return;
}
const previousBranch = pr.base.ref;
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
base: targetBranch,
});
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: [
`Based on the selected category, this PR's base branch was automatically changed from \`${previousBranch}\` to \`${targetBranch}\`.`,
'',
targetBranch === MAIN_BRANCH
? 'Bug fixes and one-click service changes target `main`.'
: 'New features and improvements target `next`.',
'',
'If you believe this is incorrect, please let a maintainer know.',
].join('\n'),
});
core.info(`Retargeted PR #${pr.number}: ${previousBranch} -> ${targetBranch}.`);
@@ -1,39 +0,0 @@
name: Manage Stale Issues and PRs
on:
schedule:
- cron: '0 2 * * *'
permissions: {}
concurrency:
group: manage-stale
cancel-in-progress: false
jobs:
manage-stale:
name: Manage stale issues and PRs
permissions:
issues: write # label, comment on and close the stale issues
pull-requests: write # label, comment on and close the stale pull requests
runs-on: ubuntu-26.04 # https://github.com/actions/runner-images
timeout-minutes: 10
steps:
- name: Manage stale issues and PRs
uses: actions/stale@v11.0.0
id: stale
with:
stale-issue-message: 'This issue will be automatically closed in a few days if no response is received. Please provide an update with the requested information.'
stale-pr-message: 'This pull request requires attention. If no changes or response is received within the next few days, it will be automatically closed. Please update your PR or leave a comment with the requested information.'
close-issue-message: 'This issue has been automatically closed due to inactivity.'
close-pr-message: 'Thank you for your contribution. Due to inactivity, this PR was automatically closed. If you would like to continue working on this change in the future, feel free to reopen this PR or submit a new one.'
days-before-stale: 14
days-before-close: 7
stale-issue-label: '⏱︎ Stale'
stale-pr-label: '⏱︎ Stale'
only-labels: '💤 Waiting for feedback, 💤 Waiting for changes'
remove-stale-when-updated: true
operations-per-run: 100
labels-to-remove-when-unstale: '⏱︎ Stale, 💤 Waiting for feedback, 💤 Waiting for changes'
close-issue-reason: 'not_planned'
exempt-all-milestones: false
+30
View File
@@ -0,0 +1,30 @@
name: Lock threads
on:
schedule:
- cron: "0 1 * * *"
permissions: {}
cache-mode: none
concurrency:
group: lock-threads
cancel-in-progress: false
jobs:
lock:
name: Lock threads
permissions:
issues: write # lock the closed issues
discussions: write # lock the closed discussions
pull-requests: write # lock the closed pull requests
runs-on: ubuntu-26.04 # https://github.com/actions/runner-images
timeout-minutes: 10
steps:
- name: Lock closed threads that were inactive for the last 30 days
uses: dessant/lock-threads@v6.0.2
with:
issue-inactive-days: 30
discussion-inactive-days: 30
pr-inactive-days: 30
+9 -6
View File
@@ -1,4 +1,4 @@
name: PR Quality
name: PR quality
on:
# Checks pull requests from forks too, it checks out and runs no code of the pull request
@@ -8,21 +8,24 @@ on:
permissions: {}
cache-mode: none
concurrency:
group: pr-quality-${{ github.event.pull_request.number }}
cancel-in-progress: false
jobs:
pr-quality:
name: Check the pull request
check:
name: Check pull request
permissions:
contents: read # read the commits and files of the pull request
contents: read
issues: read # read the linked issues
pull-requests: write # comment on, label and close the pull request
runs-on: ubuntu-26.04 # https://github.com/actions/runner-images
timeout-minutes: 10
steps:
- uses: peakoss/anti-slop@v0.3.0
- name: Check the pull request
uses: peakoss/anti-slop@v0.3.0
with:
# General Settings
max-failures: 4
@@ -46,7 +49,7 @@ jobs:
max-emoji-count: 2
max-code-references: 5
require-linked-issue: false
blocked-terms: |
blocked-terms: |
STRAWBERRY
🤖 Generated with Claude Code
Generated with Claude Code
@@ -1,16 +1,17 @@
name: Add comment based on label
name: Request docs update
on:
# Comments on pull requests from forks too, it checks out and runs no code of the pull request
# jactionlint ignore=dangerous-triggers
pull_request_target:
types:
- labeled
types: [labeled]
permissions: {}
cache-mode: none
concurrency:
group: pr-comments-${{ github.event.pull_request.number }}
group: request-docs-update-${{ github.event.pull_request.number }}
cancel-in-progress: false
defaults:
@@ -18,8 +19,8 @@ defaults:
shell: bash
jobs:
add-comment:
name: Ask for the docs of ${{ matrix.label }}
comment:
name: Request docs update (${{ matrix.label }})
permissions:
pull-requests: write # comment on the pull request
runs-on: ubuntu-26.04 # https://github.com/actions/runner-images
@@ -47,20 +48,15 @@ jobs:
Coolify Docs Repository: https://github.com/coollabsio/coolify-docs
How to Contribute to the Docs: https://coolify.io/docs/get-started/contribute/documentation
# - label: "✨ Enhancement"
# body: |
# It appears to us that you are making an enhancement to Coolify.
# We kindly ask you to also review and update the Coolify Documentation to include information about this enhancement if applicable.
# This will help ensure that our documentation remains accurate and up-to-date for all users.
steps:
- name: Add comment
- name: Comment on the pull request
if: >-
${{ (github.event.label.name == matrix.label || github.event.label.name == '📑 Waiting for Docs PR')
&& contains(github.event.pull_request.labels.*.name, matrix.label)
&& contains(github.event.pull_request.labels.*.name, '📑 Waiting for Docs PR') }}
run: gh pr comment "$NUMBER" --body "$BODY"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.pull_request.number }}
BODY: ${{ matrix.body }}
run: gh pr comment "$NUMBER" --body "$BODY"
+37
View File
@@ -0,0 +1,37 @@
name: Stale
on:
schedule:
- cron: "0 2 * * *"
permissions: {}
cache-mode: none
concurrency:
group: stale
cancel-in-progress: false
jobs:
stale:
name: Close stale issues and pull requests
permissions:
issues: write # label, comment on and close the stale issues
pull-requests: write # label, comment on and close the stale pull requests
runs-on: ubuntu-26.04 # https://github.com/actions/runner-images
timeout-minutes: 10
steps:
- name: Close the issues and pull requests that wait for feedback or changes
uses: actions/stale@v11.0.0
with:
only-labels: "💤 Waiting for feedback, 💤 Waiting for changes"
days-before-stale: 14
days-before-close: 7
stale-issue-label: "⏱︎ Stale"
stale-pr-label: "⏱︎ Stale"
labels-to-remove-when-unstale: "⏱︎ Stale, 💤 Waiting for feedback, 💤 Waiting for changes"
stale-issue-message: This issue will be automatically closed in a few days if no response is received. Please provide an update with the requested information.
stale-pr-message: This pull request requires attention. If no changes or response is received within the next few days, it will be automatically closed. Please update your PR or leave a comment with the requested information.
close-issue-message: This issue has been automatically closed due to inactivity.
close-pr-message: Thank you for your contribution. Due to inactivity, this PR was automatically closed. If you would like to continue working on this change in the future, feel free to reopen this PR or submit a new one.
operations-per-run: 100