home / skills / arcblock / agent-skills / blocklet-pr

blocklet-pr skill

/plugins/blocklet/skills/blocklet-pr

npx playbooks add skill arcblock/agent-skills --skill blocklet-pr

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
15.9 KB
---
name: blocklet-pr
description: Create standardized Pull Requests for blocklet projects. Performs lint checks, unit tests, version updates, and creates PRs following PR templates. Use `/blocklet-pr` or say "help me submit a PR", "create pull request" to trigger.
---

# Blocklet PR

Help developers create standardized Pull Requests for blocklet projects, ensuring code quality and following project PR templates.

## Core Philosophy

**"Quality gates + standardized workflow."**

PRs are not submitted casually. Before submission, code must pass lint and tests, must be on a working branch (never directly on main branch), and PR content must follow project templates. Enforced standardization reduces human oversight errors.

## Prerequisites

- Current directory is a blocklet project (contains `blocklet.yml`)
- Has code changes to commit

## Reference Files

Branch conventions and repository info are read from local reference files (in `blocklet-url-analyzer` skill directory):

- `blocklet-url-analyzer/references/org-arcblock-repos.md` - ArcBlock repos (core infrastructure, SDKs, mobile apps)
- `blocklet-url-analyzer/references/org-blocklet-repos.md` - Blocklet repos (blocklet applications, kits, tools)
- `blocklet-url-analyzer/references/org-aigne-repos.md` - AIGNE repos (AI agent framework, LLM adapters)

### Active Loading Policy (ALP)

> Load reference files on-demand based on repository organization. Do not preload all files.

| Trigger Condition | Load File |
|-------------------|-----------|
| Repository in ArcBlock org | `blocklet-url-analyzer/references/org-arcblock-repos.md` |
| Repository in blocklet org | `blocklet-url-analyzer/references/org-blocklet-repos.md` |
| Repository in AIGNE-io org | `blocklet-url-analyzer/references/org-aigne-repos.md` |
| Uncertain which organization | First read `blocklet-url-analyzer/references/README.md` |

**Loading Strategy:**
1. Determine repository organization from `git remote get-url origin`
2. Load only the reference file for that organization
3. If organization unknown, read README.md first for high-density summary

## Workflow

Execute the following phases in order.

### Phase 1: Workspace Check

**Refer to `blocklet-branch` skill for branch operations**.
Skill location: `blocklet-branch/SKILL.md`

#### 1.1 Confirm Remote Repository

Refer to blocklet-branch section 1.1:

```bash
REMOTE_URL=$(git remote get-url origin)
ORG=$(echo $REMOTE_URL | sed -E 's/.*[:/]([^/]+)\/([^/]+)(\.git)?$/\1/')
REPO=$(echo $REMOTE_URL | sed -E 's/.*[:/]([^/]+)\/([^/]+)(\.git)?$/\2/' | sed 's/\.git$//')
```

#### 1.2 Detect Main Iteration Branch

Read from local reference files to get branch conventions for the repository (following ALP).

**Load reference file based on repository organization** (from 1.1):
- ArcBlock org → `blocklet-url-analyzer/references/org-arcblock-repos.md`
- blocklet org → `blocklet-url-analyzer/references/org-blocklet-repos.md`
- AIGNE-io org → `blocklet-url-analyzer/references/org-aigne-repos.md`
- Unknown → First read `blocklet-url-analyzer/references/README.md`

**Default branch conventions** (if no specific info found in references):

| Organization | Default Main Branch |
|--------------|---------------------|
| ArcBlock | `dev` |
| blocklet | `main` |
| AIGNE-io | `main` |

**Output variables**: `MAIN_BRANCH`, `MAIN_BRANCH_REASON`

#### 1.3 Detect Branch Naming Conventions

Read from local reference files to get branch prefix conventions for the repository.

**Default prefix conventions** (if no specific info found in references):

| Prefix | Usage |
|--------|-------|
| `feat/` or `feature/` | New features |
| `fix/` | Bug fixes |
| `chore/` | Maintenance tasks |
| `docs/` | Documentation |

**Output variables**: `BRANCH_PREFIX_CONVENTION`, `BRANCH_SEPARATOR`

#### 1.4 Branch Check and Creation (Mandatory)

Refer to blocklet-branch sections 6, 7.

**Important**: Before submitting a PR, you **must** ensure you are on a working branch; cannot commit directly on the main iteration branch.

```bash
CURRENT_BRANCH=$(git branch --show-current)

if [ "$CURRENT_BRANCH" = "$MAIN_BRANCH" ]; then
    echo "⚠️ Currently on main iteration branch $MAIN_BRANCH, must create new branch!"
fi
```

| Situation | Handling |
|-----------|----------|
| On main iteration branch | **Must** create new branch (refer to blocklet-branch section 6) |
| On working branch | Check if branch naming follows convention (refer to blocklet-branch section 7.2) |

**If on main iteration branch**, use `AskUserQuestion`:

```
⚠️ Currently on main iteration branch {MAIN_BRANCH}, cannot submit PR directly.

Please select new branch name (will be created based on {MAIN_BRANCH}):

Options:
A. {suggested branch name, generated based on change type and BRANCH_PREFIX_CONVENTION} (Recommended)
B. Enter custom branch name
C. Cancel operation
```

**Create working branch** (refer to blocklet-branch section 6.2):

```bash
git fetch origin $MAIN_BRANCH
git checkout $MAIN_BRANCH
git pull origin $MAIN_BRANCH
git checkout -b $NEW_BRANCH_NAME
```

#### 1.5 Check Uncommitted Changes

```bash
git status --porcelain
```

| Situation | Handling |
|-----------|----------|
| Has unstaged changes | Continue flow, will handle later |
| No changes at all | Prompt no changes to commit, ask user intent |

---

### Phase 2: Code Quality Checks

#### 2.0 Ensure Dependencies Installed

Before running lint or tests, check if `node_modules` exists. If not, ask user whether to install dependencies.

**Important**: Detect and use the project's package manager (check lock files like `pnpm-lock.yaml`, `yarn.lock`, `package-lock.json`, etc.) for all dependency operations.

#### 2.1 Lint Check

Run lint script from `package.json` (e.g., `lint`, `lint:fix`, `check`).

**Handle missing dependency errors**:

If lint fails with `command not found` or `Cannot find module` errors:

1. Extract the missing package name from error message
2. Check if it exists in project's `devDependencies` or `dependencies`
3. If NOT in project dependencies, ask user:
   - Add the package to devDependencies (using project's package manager)
   - Skip lint check
   - Cancel

**Never suggest global installation** - missing packages should be added to the project.

| Result | Handling |
|--------|----------|
| Pass | Continue to next step |
| Fail (auto-fixable) | Try `lint:fix`, then recheck |
| Fail (cannot auto-fix) | **Stop flow**, let user fix |
| No lint command | Skip |

#### 2.2 Unit Tests

Run test script from `package.json` (e.g., `test`, `test:unit`, `test:ci`).

**Handle missing dependency errors**: Same as 2.1 - ask user to add missing package to project, never suggest global installation.

**Regular test results**:

| Result | Handling |
|--------|----------|
| Pass | Continue to next step |
| Fail | **Stop flow**, output failed test cases, let user fix |
| No test command | Skip, continue to next step (suggest adding tests) |

---

### Phase 3: Version Update

**Important**: If the project has a `CHANGELOG.md` file, version bump is **required** for every PR, not optional.

#### 3.1 Check If Version Update Required

First check if `CHANGELOG.md` exists in project root:

```bash
test -f CHANGELOG.md && echo "CHANGELOG exists - version bump required"
```

| Situation | Handling |
|-----------|----------|
| CHANGELOG.md exists | Version bump is **required**, skip option D |
| No CHANGELOG.md | Version bump is optional |

#### 3.2 Ask Version Update Type

Use `AskUserQuestion` to ask:

**If CHANGELOG.md exists**:
```
Project has CHANGELOG.md - version bump is required.

Please select version update type:
Options:
A. Patch version (x.x.X) (Recommended for bug fixes)
B. Minor version (x.X.0)
C. Major version (X.0.0)
```

**If no CHANGELOG.md**:
```
Do you need to update version and create release?

Options:
A. Yes, update patch version (x.x.X) (Recommended for bug fixes)
B. Yes, update minor version (x.X.0)
C. Yes, update major version (X.0.0)
D. No, skip version update
```

#### 3.3 Execute Version Update

If user chooses to update version (or if required due to CHANGELOG.md), **call blocklet-updater skill**:

**blocklet-updater skill location**: `blocklet-updater/SKILL.md`

---

### Phase 4: Git Commit

#### 4.0 Check for Temporary Files (Pre-staging)

Before staging files, check for temporary database files in the **root directory** that should be ignored:

```bash
# Check for .db files in root directory only (not in subdirectories)
ROOT_DB_FILES=$(git status --porcelain | grep -E '^\?\? .*\.db$' | awk '{print $2}' | grep -v '/')

if [ -n "$ROOT_DB_FILES" ]; then
    echo "⚠️ Found temporary database files in root directory:"
    echo "$ROOT_DB_FILES"
fi
```

**If root .db files found**, use `AskUserQuestion`:

```
⚠️ Found temporary database files in root directory:

{list of files found}

These .db files are typically generated by tools and should not be committed.

Options:
A. Add *.db to .gitignore and continue (Recommended)
B. Continue anyway (these files will be committed)
C. Cancel, let me handle this manually
```

**If Option A selected**:

```bash
# Add .db pattern to .gitignore
echo "" >> .gitignore
echo "# Temporary database files" >> .gitignore
echo "*.db" >> .gitignore

git add .gitignore
```

**If Option C selected**: EXIT and let user handle manually.

**Note**: `.aigne/` directories and files in subdirectories are NOT temporary files and should not be flagged.

#### 4.1 Stage Changes

```bash
git add -A
git status
```

Display list of files to be committed, use `AskUserQuestion` to confirm:

```
The following files will be committed:
{file list}

Continue?
A. Yes, commit all changes (Recommended)
B. No, let me select files to commit
C. Cancel
```

#### 4.2 Generate Commit Message

**Generate standardized commit message based on change type**:

Note: Refer to the last 20 commits for the specific prefix, follow historical conventions.

| Change Type | Commit Prefix | Example |
|-------------|---------------|---------|
| New feature | `feat:` | `feat: add video preview support` |
| Bug fix | `fix:` | `fix: resolve duplicate upload issue` |
| Documentation | `docs:` | `docs: update API documentation` |
| Refactoring | `refactor:` | `refactor: simplify auth logic` |
| Testing | `test:` | `test: add unit tests for utils` |
| Build/Chore | `chore:` | `chore: bump dependencies` |

**Analyze changes to automatically infer type**, then use `AskUserQuestion` to confirm:

```
Suggested commit message:

{generated commit message}

Options:
A. Use this message (Recommended)
B. Modify message
C. Cancel
```

#### 4.3 Execute Commit

```bash
git commit -m "$(cat <<'EOF'
{commit_message}

Co-Authored-By: Claude <[email protected]>
EOF
)"
```

---

### Phase 5: Push Branch

#### 5.1 Check Remote Branch

```bash
git ls-remote --heads origin $CURRENT_BRANCH
```

| Situation | Handling |
|-----------|----------|
| Remote branch doesn't exist | Use `-u` to push and set upstream |
| Remote branch exists | Normal push |

#### 5.2 Push

```bash
git push -u origin $CURRENT_BRANCH
```

---

### Phase 6: Create Pull Request

#### 6.1 Check PR Template

```bash
# Find PR template
PR_TEMPLATE=""
if [ -f ".github/PULL_REQUEST_TEMPLATE.md" ]; then
    PR_TEMPLATE=".github/PULL_REQUEST_TEMPLATE.md"
elif [ -f ".github/pull_request_template.md" ]; then
    PR_TEMPLATE=".github/pull_request_template.md"
elif [ -f "docs/PULL_REQUEST_TEMPLATE.md" ]; then
    PR_TEMPLATE="docs/PULL_REQUEST_TEMPLATE.md"
fi
```

**If template found**: Read and parse template structure, fill PR content according to template format.

**If template not found**: Use default PR format.

#### 6.2 Get Target Branch

Use the `MAIN_BRANCH` detected in Phase 1.2 (from reference files).

Use `AskUserQuestion` to confirm target branch:

```
PR target branch:

Options:
A. {MAIN_BRANCH} (Recommended)
B. Other branch
```

#### 6.3 Link Issue (If Applicable)

Use `AskUserQuestion` to ask:

```
Do you need to link an Issue?

Options:
A. No, don't link Issue
B. Yes, link Issue (please enter Issue number)
```

If linking Issue, add to PR description:
- `Closes #123` - Auto-close Issue when merged
- `Fixes #123` - Fix Issue
- `Relates to #123` - Related but don't auto-close

#### 6.4 Generate PR Content

**PR Title**: Generate based on commit message or branch name, keep format concise and clear.

**Important**: PR title must be **all lowercase**. When converting camelCase words, use hyphens between words (e.g., `devDependencies` → `dev-dependencies`). Example: `fix: add lerna to dev-dependencies`

**PR Description** (according to template or default format):

```markdown
## Summary

{Change overview, 2-3 sentences explaining what this PR does}

## Changes

{Specific change list}
- Change 1
- Change 2
- ...

## Related Issues

{If there are linked Issues}
Closes #{issue_number}

## Test Plan

{Verification methods and test points}
- [ ] Verification point 1
- [ ] Verification point 2
- [ ] Unit tests pass
- [ ] Lint check passes

## Screenshots (if applicable)

{If there are UI changes, add screenshots}
```

#### 6.5 Choose PR Creation Method

After generating PR content, use `AskUserQuestion` to ask user:

```
How would you like to create the PR?

Options:
A. Create PR.md file (for manual submission later)
B. Submit PR directly using gh CLI (Recommended)
```

#### 6.5.1 Option A: Create PR.md File

Create a PR.md file in the repository root with the PR content:

```bash
cat > PR.md << 'EOF'
# {pr_title}

**Target Branch**: {TARGET_BRANCH}
**Source Branch**: {CURRENT_BRANCH}

{pr_body}
EOF

echo "✅ PR.md created. You can manually create PR on GitHub using this content."
```

**Output**:
```
===== PR.md Created =====

File: PR.md
Title: {pr_title}
Target Branch: {target_branch}

Next Steps:
1. Open GitHub repository: https://github.com/{ORG}/{REPO}
2. Click "Pull requests" → "New pull request"
3. Select base: {TARGET_BRANCH}, compare: {CURRENT_BRANCH}
4. Copy content from PR.md
```

#### 6.5.2 Option B: Submit PR using gh CLI

**First check gh CLI availability**:

```bash
# Check if gh is installed
if ! command -v gh &> /dev/null; then
    echo "❌ gh CLI is not installed."
    echo ""
    echo "Install gh CLI:"
    echo "  macOS: brew install gh"
    echo "  Linux: see https://cli.github.com/linux"
    echo "  Windows: winget install GitHub.cli"
    echo ""
    echo "After installation, run: gh auth login"
    exit 1
fi

# Check if gh is authenticated
if ! gh auth status &> /dev/null; then
    echo "❌ gh CLI is not authenticated."
    echo ""
    echo "Run: gh auth login"
    echo "Then retry creating PR."
    exit 1
fi
```

| Status | Handling |
|--------|----------|
| gh not installed | Show installation instructions, fallback to PR.md |
| gh not authenticated | Show `gh auth login` instructions, fallback to PR.md |
| gh ready | Create PR |

**Create PR**:

```bash
gh pr create \
  --title "{pr_title}" \
  --body "$(cat <<'EOF'
{pr_body}
EOF
)" \
  --base $TARGET_BRANCH
```

#### 6.6 Output Result

**If PR created via gh**:
```
===== PR Created Successfully =====

PR URL: {pr_url}
Title: {pr_title}
Target Branch: {target_branch}
Linked Issues: {issue_numbers or "None"}

===== Next Steps =====
Wait for Code Review
```

**If PR.md created**:
```
===== PR.md Created =====

File: PR.md
Please manually create PR on GitHub.
```

---

## Error Handling

| Error | Handling |
|-------|----------|
| Lint failed | Show error details, suggest running `pnpm run lint:fix` |
| Tests failed | Show failed test cases, let user fix |
| Push failed | Check permissions, suggest `git pull --rebase` |
| gh not installed | Show installation instructions, offer to create PR.md instead |
| gh not authenticated | Show `gh auth login` instructions, offer to create PR.md instead |
| PR creation failed | Show gh error message, offer to create PR.md instead |
| Same PR already exists | Show existing PR link, ask whether to update |


---

## Relationship with Other Skills

| Skill | Relationship |
|-------|--------------|
| `blocklet-dev-setup` | Development environment setup, use before PR |
| `blocklet-updater` | Version update, optionally called during PR |
| `blocklet-url-analyzer` | Analyze Blocklet URL, locate repository |