Skip to content

Commit 3cd13f3

Browse files
authored
feat(triage): add Sieve to repo (#884)
* feat(triage): add Sieve to repo
1 parent e362749 commit 3cd13f3

21 files changed

Lines changed: 1684 additions & 1 deletion

.github/workflows/issue-triage.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Issue Triage
2+
3+
on:
4+
issues:
5+
types:
6+
- closed
7+
- opened
8+
- labeled
9+
workflow_dispatch:
10+
inputs:
11+
issue_url:
12+
description: GitHub issue URL to triage
13+
required: true
14+
type: string
15+
16+
permissions:
17+
contents: read
18+
issues: read
19+
20+
concurrency:
21+
group: ${{ github.workflow }}-${{ github.event.issue.node_id || inputs.issue_url || github.run_id }}
22+
cancel-in-progress: true
23+
24+
jobs:
25+
trigger:
26+
name: Trigger Miriad triage
27+
if: github.event_name == 'workflow_dispatch' || github.event.action == 'opened' || github.event.action == 'closed' || (github.event.action == 'labeled' && github.event.label.name == 'needs-triage')
28+
runs-on: ubuntu-latest
29+
timeout-minutes: 10
30+
env:
31+
GITHUB_TOKEN: ${{ github.token }}
32+
ISSUE_URL: ${{ github.event_name == 'workflow_dispatch' && inputs.issue_url || github.event.issue.html_url }}
33+
MIRIAD_SPACE_ID: ${{ secrets.MIRIAD_SPACE_ID }}
34+
MIRIAD_TOKEN: ${{ secrets.MIRIAD_TOKEN }}
35+
MIRIAD_URL: ${{ secrets.MIRIAD_URL }}
36+
steps:
37+
- uses: actions/checkout@v6
38+
39+
- uses: actions/setup-node@v6
40+
with:
41+
node-version: lts/*
42+
43+
- name: Trigger issue triage
44+
if: github.event.action != 'closed'
45+
run: node scripts/trigger-triage/src/index.ts --verbose "$ISSUE_URL"
46+
47+
- name: Archive issue triage channel
48+
if: github.event.action == 'closed'
49+
run: node scripts/trigger-triage/src/archive.ts --verbose "$ISSUE_URL"

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
"dev": "pnpm turbo dev --filter=test-studio",
1010
"format": "oxfmt . --no-error-on-unmatched-pattern",
1111
"generate": "turbo gen",
12+
"issue-triage": "node scripts/trigger-triage/src/index.ts",
13+
"issue-triage:archive": "node scripts/trigger-triage/src/archive.ts",
1214
"knip": "knip",
1315
"lint": "pnpm run oxlint",
1416
"lint:fix": "pnpm lint --fix --fix-suggestions",

pnpm-lock.yaml

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ packages:
55
- packages/@sanity/*
66
- plugins/*
77
- plugins/@sanity/*
8+
- scripts/*
89
- turbo/generators
910

1011
catalog:
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# For local issue triage runs get it from miriad workspace.
2+
MIRIAD_URL=
3+
MIRIAD_SPACE_ID=
4+
MIRIAD_TOKEN=
5+
6+
# Optional. Useful locally if anonymous GitHub API requests hit rate limits or if you are testing against a private repository.
7+
GITHUB_TOKEN=

scripts/trigger-triage/README.md

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Issue Triage Trigger
2+
3+
This package triggers the Miriad issue triage workflow for a GitHub issue URL.
4+
It is used by the `sanity-io/plugins` GitHub workflow and can also be run from
5+
the terminal while developing or testing.
6+
7+
The runtime path is dependency-free: the GitHub Action runs the TypeScript file
8+
directly with Node, without `pnpm install` or a build step. Use Node 22.18 or
9+
newer locally.
10+
11+
## How It Works
12+
13+
### On new issues
14+
15+
Given a GitHub issue URL, the default CLI path:
16+
17+
1. Parses the owner, repo, and issue number.
18+
2. Fetches the issue from the GitHub REST API.
19+
3. Ignores noise, including bot authors, dependency dashboards, and issues with
20+
ignored labels.
21+
4. Creates or reuses a Miriad channel named after the repo and issue number.
22+
5. Adds the configured Miriad agents to the channel.
23+
6. Posts a kickoff message tagging `@triager`.
24+
25+
The trigger does not post back to GitHub. It only starts the Miriad workflow.
26+
27+
### On closed issues
28+
29+
A separate archive entrypoint handles closed issues. It fetches the issue to
30+
apply the same ignore filters as triage, derives the expected channel name from
31+
the issue URL, finds that channel in Miriad, and archives it:
32+
33+
```bash
34+
node scripts/trigger-triage/src/archive.ts https://github.com/sanity-io/plugins/issues/725
35+
```
36+
37+
## GitHub Workflow
38+
39+
The workflow that calls this package is:
40+
41+
```text
42+
.github/workflows/issue-triage.yml
43+
```
44+
45+
It runs when:
46+
47+
- A new issue is opened.
48+
- The `needs-triage` label is added to an existing issue.
49+
- An issue is closed, which archives the matching Miriad channel.
50+
- A developer manually runs the workflow from the GitHub Actions UI and provides
51+
an `issue_url` input.
52+
53+
For issue events, the workflow passes `github.event.issue.html_url` to the CLI.
54+
For manual runs, it passes the `issue_url` input instead.
55+
56+
```bash
57+
node scripts/trigger-triage/src/index.ts "$ISSUE_URL"
58+
```
59+
60+
Closed issue events run the archive mode:
61+
62+
```bash
63+
node scripts/trigger-triage/src/archive.ts "$ISSUE_URL"
64+
```
65+
66+
Archive mode calls the Miriad REST API equivalent of:
67+
68+
```bash
69+
curl -X POST "$MIRIAD_URL/channels/$CHANNEL_ID/archive" \
70+
-H "Authorization: Bearer $MIRIAD_TOKEN"
71+
```
72+
73+
To trigger it manually, open the `Issue Triage` workflow in GitHub Actions, click
74+
`Run workflow`, and paste a GitHub issue URL such as
75+
`https://github.com/sanity-io/plugins/issues/725`.
76+
77+
## Local Usage
78+
79+
From the repository root:
80+
81+
```bash
82+
pnpm issue-triage https://github.com/sanity-io/plugins/issues/725
83+
```
84+
85+
Dry-run mode fetches and filters the issue, then prints the Miriad kickoff
86+
message without calling Miriad:
87+
88+
```bash
89+
pnpm issue-triage --dry-run https://github.com/sanity-io/plugins/issues/725
90+
```
91+
92+
Verbose mode prints debug logs:
93+
94+
```bash
95+
pnpm issue-triage --verbose https://github.com/sanity-io/plugins/issues/725
96+
```
97+
98+
Archive the Miriad channel for a closed issue:
99+
100+
```bash
101+
node scripts/trigger-triage/src/archive.ts https://github.com/sanity-io/plugins/issues/725
102+
```
103+
104+
## Required GitHub Actions Secrets
105+
106+
Add these to the target repository's GitHub Actions secrets:
107+
108+
- `MIRIAD_URL` - Miriad REST API base URL.
109+
- `MIRIAD_TOKEN` - Bearer token for the Miriad REST API.
110+
- `MIRIAD_SPACE_ID` - Miriad space short id.
111+
112+
The workflow sets `GITHUB_TOKEN` from GitHub's built-in token:
113+
114+
```yaml
115+
GITHUB_TOKEN: ${{ github.token }}
116+
```
117+
118+
Do not add a custom `GITHUB_TOKEN` repository secret for this workflow.
119+
120+
## Local Environment
121+
122+
For local terminal runs, `GITHUB_TOKEN` is optional. Set it only if anonymous
123+
GitHub API requests hit rate limits or if you are testing against a private
124+
repository.
125+
126+
```bash
127+
GITHUB_TOKEN=ghp_example pnpm issue-triage --dry-run https://github.com/sanity-io/plugins/issues/725
128+
```
129+
130+
The script also loads local `.env` files automatically without any dependencies.
131+
Shell-provided environment variables always win. For local Miriad runs, copy the
132+
example file and fill in the required values:
133+
134+
```bash
135+
cp scripts/trigger-triage/.env.example scripts/trigger-triage/.env
136+
```
137+
138+
The lookup order is:
139+
140+
1. Environment variables already set in the shell or GitHub Actions.
141+
2. `scripts/trigger-triage/.env`.
142+
3. Repository root `.env`.
143+
144+
The script-local `.env` is preferred because it keeps these secrets scoped to
145+
this helper. The root `.env` fallback exists for convenience in this repo.
146+
147+
## Hardcoded Agents
148+
149+
The Miriad agents are intentionally hardcoded in `src/index.ts`:
150+
151+
```ts
152+
const AGENT_NAMES = ['triager', 'squiggler'] as const
153+
```
154+
155+
This keeps the GitHub workflow and repository settings small: agent assignment
156+
is part of the script behavior, not deployment configuration. If another repo or
157+
Miriad workspace uses different callsigns, update `AGENT_NAMES` before copying
158+
or enabling the workflow there.
159+
160+
## Moving This To Another Repo
161+
162+
To reuse this setup in another repository, such as the main `sanity` repo:
163+
164+
1. Copy `scripts/trigger-triage/`.
165+
2. Copy `.github/workflows/issue-triage.yml`.
166+
3. Add the script package to that repository's package manager or workspace
167+
setup.
168+
4. Create a new Miriad workspace. From this workspace you will get:
169+
- `MIRIAD_URL`
170+
- `MIRIAD_TOKEN`
171+
- `MIRIAD_SPACE_ID`
172+
Add these variables to the repository secrets.
173+
5. Review `AGENT_NAMES` in `src/index.ts` and update the callsigns if the target
174+
Miriad workspace uses different agents.
175+
6. Confirm the workflow passes `github.event.issue.html_url` to the CLI.
176+
7. Confirm the manual `workflow_dispatch` input is still named `issue_url`.
177+
8. Run a local dry-run against a real issue URL.
178+
9. Smoke-test the workflow by opening a test issue or adding `needs-triage` to
179+
an existing issue.
180+
10. Close the test issue and confirm the matching Miriad channel is archived.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "@sanity/issue-trigger-triage",
3+
"version": "0.1.0",
4+
"private": true,
5+
"description": "CLI and GitHub Actions helper that triggers the Miriad issue triage workflow for a GitHub issue URL.",
6+
"bin": {
7+
"trigger-triage": "./src/index.ts"
8+
},
9+
"type": "module",
10+
"scripts": {
11+
"dev": "node src/index.ts",
12+
"start": "node src/index.ts",
13+
"test": "vitest run",
14+
"typecheck": "tsc --noEmit -p tsconfig.json"
15+
},
16+
"devDependencies": {
17+
"@types/node": "catalog:",
18+
"typescript": "catalog:",
19+
"vitest": "^4.1.0"
20+
},
21+
"engines": {
22+
"node": ">=22.18"
23+
}
24+
}

0 commit comments

Comments
 (0)