Files
DeepSeek-Reasonix/.github/workflows/issue-version-label.yml
T
yhh 4fe5caf8ce docs(repo): studio is the 2.x line, ready to be the default branch
The repository now describes the two lines the version roadmap announced
(discussions/10748): 2.x on studio, 1.x on main-v2 in maintenance.

- README (en, zh-CN): a Versions section and a Studio 2.x release badge.
  Install leads with Reasonix Studio 2.x from the studio-v* pre-releases,
  with the 1.x CLI and desktop app beside it as the stable line. The
  zh-CN build-from-source section gains the Studio build it lacked.
- Issue forms offer 2.x / 1.x / 0.x, and the labeler maps them to v3 /
  v2 / v1, with the pasted version still overriding the dropdown. The
  forms link the roadmap. The PR template and CONTRIBUTING say which
  branch takes which changes.

Issue forms, schedules and Dependabot are read from the default branch
only, so these take effect when studio becomes it:
- CodeQL scans pushes and PRs on both lines, and the weekly scan checks
  out each line and files results under its own ref, so 1.x keeps its
  security scanning.
- v1-maintenance-schedule starts main-v2's nightly app-memory and
  diagnostic-overhead monitors, which measure the 1.x desktop app, on
  main-v2.
- Dependabot drops /desktop/frontend and /site, which do not exist on
  studio, and covers /desktop/frontend-next and /desktop/electron. It
  also names main-v2 as a target for patch updates only.
2026-09-24 20:21:38 -07:00

65 lines
2.5 KiB
YAML

name: Label issue version
# Issue forms can't let a reporter set a label directly (that needs triage rights),
# so the bug/feature forms carry a "Version line" dropdown and this workflow reads
# the submitted value and applies the matching label on their behalf:
# 0.x -> v1 (TypeScript), 1.x -> v2 (main-v2), 2.x -> v3 (studio).
on:
issues:
types: [opened, edited]
permissions:
issues: write
concurrency:
group: issue-version-${{ github.event.issue.number }}
cancel-in-progress: true
jobs:
label:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v9
with:
script: |
const body = context.payload.issue.body || '';
const sectionOf = (name) =>
body.split(/^###\s+/m).find((s) => new RegExp(`^${name}`, 'i').test(s)) || '';
const labelOf = (major) => ({ 0: 'v1', 1: 'v2', 2: 'v3' })[major];
const m = sectionOf('Version line').match(/\b([012])\.x\b/);
if (!m) {
core.info('No version line found; nothing to label.');
return;
}
let choice = labelOf(Number(m[1]));
// The dropdown is a choice, and its first entry gets picked by
// reporters who never looked. `Exact version` is pasted from
// `reasonix --version` or Studio, so when it parses it is the better
// evidence. Anything that does not parse (a commit sha, a branch
// name) or names no known line leaves the dropdown to decide.
const exact = sectionOf('Exact version').match(/\b(\d+)\.(\d+)\.(\d+)/);
const fromVersion = exact && labelOf(Number(exact[1]));
if (fromVersion && fromVersion !== choice) {
core.info(`Version line says ${choice} but ${exact[0]} says ${fromVersion}; trusting the version.`);
choice = fromVersion;
}
await github.rest.issues.addLabels({
...context.repo,
issue_number: context.issue.number,
labels: [choice],
});
// Keep the line labels mutually exclusive in case an edit flipped the choice.
for (const other of ['v1', 'v2', 'v3'].filter((l) => l !== choice)) {
try {
await github.rest.issues.removeLabel({
...context.repo,
issue_number: context.issue.number,
name: other,
});
} catch (e) {
core.info(`No ${other} label to remove.`);
}
}