Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions .github/actions/issues-helper/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ inputs:
description: Comment body. Required for `create-comment`.
inactive-day:
required: false
description: Close issues with no activity for at least this many days. Required for `close-issues`.
description: Close issues whose matching label was added at least this many days ago. Required for `close-issues`.

runs:
using: composite
Expand Down Expand Up @@ -68,6 +68,7 @@ runs:
const labels = process.env.INPUT_LABELS
const inactiveDay = Number(process.env.INPUT_INACTIVE_DAY)
const cutoff = new Date(Date.now() - inactiveDay * 24 * 60 * 60 * 1000)
const labelSet = new Set(labels.split(',').map(l => l.trim()))

const issues = await github.paginate(github.rest.issues.listForRepo, {
owner: context.repo.owner,
Expand All @@ -77,20 +78,30 @@ runs:
per_page: 100,
})

const stale = issues.filter(issue =>
!issue.pull_request && new Date(issue.updated_at) <= cutoff
)
let closed = 0
for (const issue of issues) {
const events = await github.paginate(github.rest.issues.listEvents, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
per_page: 100,
})
const labeledAt = events
.filter(e => e.event === 'labeled' && labelSet.has(e.label?.name))
.at(-1)?.created_at

if (!labeledAt || new Date(labeledAt) > cutoff) continue

for (const issue of stale) {
console.log(`Closing issue #${issue.number}, last updated at ${issue.updated_at}`)
console.log(`Closing #${issue.number}, labeled at ${labeledAt}`)
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
state: 'closed',
})
closed++
}

if (stale.length === 0) {
console.log(`No inactive issues with label "${labels}" found`)
if (closed === 0) {
console.log(`No stale items with label "${labels}" found`)
}
44 changes: 3 additions & 41 deletions .github/workflows/issue-close-require.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ on:
permissions: {}

jobs:
close-issues:
close-stale:
runs-on: ubuntu-slim
name: Close Marked Issues
name: Close Marked Issues and PRs
permissions:
contents: read # to check out the repo for local actions
issues: write # to close issues
pull-requests: write # to close pull requests
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
Expand All @@ -32,42 +33,3 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
labels: maybe automated
inactive-day: 3

close-prs:
runs-on: ubuntu-slim
name: Close Marked PRs
permissions:
issues: read # to query PRs by label via the issues API
pull-requests: write # to close pull requests
steps:
- name: maybe automated PRs
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const cutoff = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000)

const issues = await github.paginate(github.rest.issues.listForRepo, {
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'maybe automated',
per_page: 100,
})

const prs = issues.filter(issue =>
issue.pull_request && new Date(issue.updated_at) <= cutoff
)

for (const pr of prs) {
console.log(`Closing PR #${pr.number}, last updated at ${pr.updated_at}`)
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
state: 'closed',
})
}

if (prs.length === 0) {
console.log('No inactive maybe automated PRs found')
}
1 change: 1 addition & 0 deletions .github/workflows/lock-closed-issues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
name: Lock Closed Issues
permissions:
issues: write # to lock issue
pull-requests: write # to lock prs
steps:
- uses: dessant/lock-threads@7266a7ce5c1df01b1c6db85bf8cd86c737dadbe7 # v6.0.0
with:
Expand Down
43 changes: 43 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,49 @@ These measures help reduce maintenance burden and keep the team's work efficient

> The following section is mostly for maintainers who have commit access, but it's helpful to go through if you intend to make non-trivial contributions to the codebase.

### Release Branches

Public support ranges are documented in [Releases](./docs/releases.md). This section describes how maintainers map those ranges to Git branches for releases and backports. These names refer to branches, not release tags; release tags always include the full version, for example `v4.1.8`.

- `main` is the active development branch for the next release line.
- `vN` is the latest maintained minor line for non-main major version `N`.
- `vN.M` is an older minor line for major version `N`, kept when that exact minor still needs releases or backports.

As a hypothetical example, if `v5.1.2` is the latest Vitest release, and the latest releases for older majors are `v4.1.7` and `v3.2.4`, the branch shape can be:

- `main` is the active development branch for `5.1.x`.
- `v5.0` is an older minor line for Vitest 5.
- `v4` is the latest maintained minor line for Vitest 4, so it is the `4.1.x` line.
- `v4.0` is an older minor line for Vitest 4.
- `v3` is the latest maintained minor line for Vitest 3, so it is the `3.2.x` line.
- `v3.1` and `v3.0` are older minor lines for Vitest 3.

The `v5` branch does not exist yet. It will be created from the latest v5 minor only after `main` moves on to a newer release line, such as `6.0.0` or often `6.0.0-beta.x`.

For backports, first use the public support policy to decide which version ranges are supported, then map them to branches:

- Changes can land as usual on the `main` branch first.
- If the fix targets the latest maintained minor of major version `N`, target `vN`. This is the default backport target for a supported non-main major.
- If the fix also needs an older maintained minor `N.M`, target `vN.M`.

For example, using the hypothetical `v5.1.2` release above, the public support policy covers regular fixes for `5.1.x` and important fixes or security patches for `5.0.x` and `4.1.x`:

- fixes for `5.1.x` target `main`
- backports to `5.0.x` target `v5.0`
- backports to `4.1.x` target `v4`

No backport is made to `v3` unless the support policy changes or maintainers decide on an explicit exception.

Backport PR titles should include the target branch in a `[backport to x]` marker, for example `fix: [backport to v5.0] ...` or `fix: [backport to v4] ...`. Branch names never include patch versions.

#### Documentation Branches

The release branches are also linked with the documentation site releases:

- `main` is the source for unreleased documentation at <https://main.vitest.dev/>.
- `release` points to the latest stable release line used for <https://vitest.dev/>. Release managers update it manually for non-beta releases from `main`; it is not moved for older-line backports.
- `vN` branches are used for old major documentation sites. For example, <https://v3.vitest.dev/> uses `v3`.

### Issue Triaging Workflow

```mermaid
Expand Down
Loading