Compare commits
3 Commits
0.2.0
...
cac2903807
| Author | SHA1 | Date | |
|---|---|---|---|
| cac2903807 | |||
|
|
210118bf9a | ||
| 9a78ebd9b0 |
94
.claude/skills/merge-pr/SKILL.md
Normal file
94
.claude/skills/merge-pr/SKILL.md
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
---
|
||||||
|
name: merge-pr
|
||||||
|
description: Create a Gitea pull request, monitor CI pipeline status, and merge when green. Use this skill when the user asks to "create a PR", "merge the PR", "ship it", "make it ready to merge", or when you need to open a pull request and wait for CI before merging. Also use when asked to check CI/PR status on Gitea.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Merge PR
|
||||||
|
|
||||||
|
Create a pull request on Gitea, monitor the CI pipeline via the Actions API, and merge once all jobs pass.
|
||||||
|
|
||||||
|
## Why this skill exists
|
||||||
|
|
||||||
|
The Gitea MCP pull request API does not return CI status directly. To know if a PR is ready to merge, you must cross-reference the PR's `head.sha` with the Actions runs API, find the matching run, and check job conclusions. This skill encodes that workflow so it doesn't have to be rediscovered.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
The Gitea MCP tools must be available. The key tools are:
|
||||||
|
|
||||||
|
- `mcp__gitea__pull_request_write` (method: `create`, `merge`)
|
||||||
|
- `mcp__gitea__pull_request_read` (method: `get`)
|
||||||
|
- `mcp__gitea__actions_run_read` (methods: `list_runs`, `list_run_jobs`)
|
||||||
|
|
||||||
|
If these tools are not yet loaded, use ToolSearch to discover and load them before proceeding.
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
### 1. Create the PR
|
||||||
|
|
||||||
|
Use `mcp__gitea__pull_request_write` with method `create`. Include a clear title, body with summary and test plan, head branch, and base branch (usually `master`).
|
||||||
|
|
||||||
|
Save the returned `head.sha` — you need it to find the CI run.
|
||||||
|
|
||||||
|
### 2. Find the CI run for the PR
|
||||||
|
|
||||||
|
The Actions API has no direct "get CI status for PR" call. Instead:
|
||||||
|
|
||||||
|
```
|
||||||
|
mcp__gitea__actions_run_read(method: "list_runs", owner, repo, perPage: 5)
|
||||||
|
```
|
||||||
|
|
||||||
|
Find the run whose `head_sha` matches the PR's `head.sha`. This is the CI run triggered by the push that the PR points to. If the branch was force-pushed or new commits were added, always match against the latest `head.sha` from a fresh `get` on the PR.
|
||||||
|
|
||||||
|
### 3. Monitor job status
|
||||||
|
|
||||||
|
Once you have the run ID:
|
||||||
|
|
||||||
|
```
|
||||||
|
mcp__gitea__actions_run_read(method: "list_run_jobs", owner, repo, run_id: <id>)
|
||||||
|
```
|
||||||
|
|
||||||
|
This returns all jobs with their `status` (queued/in_progress/completed) and `conclusion` (success/failure/skipped/null).
|
||||||
|
|
||||||
|
Present a status table to the user:
|
||||||
|
|
||||||
|
| Job | Status |
|
||||||
|
|-----|--------|
|
||||||
|
| backend-test | success |
|
||||||
|
| frontend-test | in_progress |
|
||||||
|
| frontend-e2e | queued |
|
||||||
|
|
||||||
|
If jobs are still running, wait ~30 seconds and check again. Don't poll in a tight loop.
|
||||||
|
|
||||||
|
### 4. Handle failures
|
||||||
|
|
||||||
|
If any job has `conclusion: failure`:
|
||||||
|
- Use `mcp__gitea__actions_run_read` with method `get_job_log_preview` to fetch the failing job's log
|
||||||
|
- Report the failure to the user with relevant log output
|
||||||
|
- Do NOT attempt to merge
|
||||||
|
|
||||||
|
### 5. Merge when green
|
||||||
|
|
||||||
|
Once all jobs show `conclusion: success` (or `skipped` for conditional jobs like `build-and-publish`):
|
||||||
|
|
||||||
|
```
|
||||||
|
mcp__gitea__pull_request_write(
|
||||||
|
method: "merge",
|
||||||
|
owner, repo,
|
||||||
|
index: <pr_number>,
|
||||||
|
merge_style: "merge",
|
||||||
|
delete_branch: true
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Ask the user for confirmation before merging. They may want to review the PR in the web UI first.
|
||||||
|
|
||||||
|
### 6. Post-merge cleanup
|
||||||
|
|
||||||
|
After a successful merge, suggest:
|
||||||
|
- `git checkout master && git pull origin master`
|
||||||
|
- `git branch -d <feature-branch>` (local cleanup)
|
||||||
|
- Tagging a release if appropriate (see `/release` skill)
|
||||||
|
|
||||||
|
## Abbreviated flow
|
||||||
|
|
||||||
|
When the user just wants a quick status check (e.g. "how's the PR?"), skip straight to steps 2-3: find the run by SHA, show the job status table.
|
||||||
52
frontend/package-lock.json
generated
52
frontend/package-lock.json
generated
@@ -1201,15 +1201,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/config-array": {
|
"node_modules/@eslint/config-array": {
|
||||||
"version": "0.23.2",
|
"version": "0.23.3",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.2.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.3.tgz",
|
||||||
"integrity": "sha512-YF+fE6LV4v5MGWRGj7G404/OZzGNepVF8fxk7jqmqo3lrza7a0uUcDnROGRBG1WFC1omYUS/Wp1f42i0M+3Q3A==",
|
"integrity": "sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/object-schema": "^3.0.2",
|
"@eslint/object-schema": "^3.0.3",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"minimatch": "^10.2.1"
|
"minimatch": "^10.2.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || ^22.13.0 || >=24"
|
"node": "^20.19.0 || ^22.13.0 || >=24"
|
||||||
@@ -1229,9 +1229,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/core": {
|
"node_modules/@eslint/core": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.1.tgz",
|
||||||
"integrity": "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==",
|
"integrity": "sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1242,9 +1242,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/object-schema": {
|
"node_modules/@eslint/object-schema": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.3.tgz",
|
||||||
"integrity": "sha512-HOy56KJt48Bx8KmJ+XGQNSUMT/6dZee/M54XyUyuvTvPXJmsERRvBchsUVx1UMe1WwIH49XLAczNC7V2INsuUw==",
|
"integrity": "sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1252,13 +1252,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/plugin-kit": {
|
"node_modules/@eslint/plugin-kit": {
|
||||||
"version": "0.6.0",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz",
|
||||||
"integrity": "sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==",
|
"integrity": "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/core": "^1.1.0",
|
"@eslint/core": "^1.1.1",
|
||||||
"levn": "^0.4.1"
|
"levn": "^0.4.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -4304,18 +4304,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint": {
|
"node_modules/eslint": {
|
||||||
"version": "10.0.2",
|
"version": "10.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.3.tgz",
|
||||||
"integrity": "sha512-uYixubwmqJZH+KLVYIVKY1JQt7tysXhtj21WSvjcSmU5SVNzMus1bgLe+pAt816yQ8opKfheVVoPLqvVMGejYw==",
|
"integrity": "sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.8.0",
|
"@eslint-community/eslint-utils": "^4.8.0",
|
||||||
"@eslint-community/regexpp": "^4.12.2",
|
"@eslint-community/regexpp": "^4.12.2",
|
||||||
"@eslint/config-array": "^0.23.2",
|
"@eslint/config-array": "^0.23.3",
|
||||||
"@eslint/config-helpers": "^0.5.2",
|
"@eslint/config-helpers": "^0.5.2",
|
||||||
"@eslint/core": "^1.1.0",
|
"@eslint/core": "^1.1.1",
|
||||||
"@eslint/plugin-kit": "^0.6.0",
|
"@eslint/plugin-kit": "^0.6.1",
|
||||||
"@humanfs/node": "^0.16.6",
|
"@humanfs/node": "^0.16.6",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
"@humanwhocodes/retry": "^0.4.2",
|
"@humanwhocodes/retry": "^0.4.2",
|
||||||
@@ -4324,7 +4324,7 @@
|
|||||||
"cross-spawn": "^7.0.6",
|
"cross-spawn": "^7.0.6",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
"eslint-scope": "^9.1.1",
|
"eslint-scope": "^9.1.2",
|
||||||
"eslint-visitor-keys": "^5.0.1",
|
"eslint-visitor-keys": "^5.0.1",
|
||||||
"espree": "^11.1.1",
|
"espree": "^11.1.1",
|
||||||
"esquery": "^1.7.0",
|
"esquery": "^1.7.0",
|
||||||
@@ -4337,7 +4337,7 @@
|
|||||||
"imurmurhash": "^0.1.4",
|
"imurmurhash": "^0.1.4",
|
||||||
"is-glob": "^4.0.0",
|
"is-glob": "^4.0.0",
|
||||||
"json-stable-stringify-without-jsonify": "^1.0.1",
|
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||||
"minimatch": "^10.2.1",
|
"minimatch": "^10.2.4",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
"optionator": "^0.9.3"
|
"optionator": "^0.9.3"
|
||||||
},
|
},
|
||||||
@@ -4418,9 +4418,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-scope": {
|
"node_modules/eslint-scope": {
|
||||||
"version": "9.1.1",
|
"version": "9.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz",
|
||||||
"integrity": "sha512-GaUN0sWim5qc8KVErfPBWmc31LEsOkrUJbvJZV+xuL3u2phMUK4HIvXlWAakfC8W4nzlK+chPEAkYOYb5ZScIw==",
|
"integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
Reference in New Issue
Block a user