Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
9793762
bump version to 1.0.0 in package.json
devfrankduah Jun 8, 2026
91f4460
add releasing guidelines to RELEASING.md
devfrankduah Jun 8, 2026
f81ed74
add auto-merge workflow for pull requests from development to main
devfrankduah Jun 8, 2026
3b0403c
add semantic versioning check workflow for pull requests
devfrankduah Jun 8, 2026
81b5d1d
add workflow to create and manage draft releases on GitHub
devfrankduah Jun 8, 2026
040b55b
add workflow for managing draft pull requests and version bumping
devfrankduah Jun 8, 2026
ddd44af
add workflow for release publishing with verification and draft rever…
devfrankduah Jun 8, 2026
f928cd1
add CI workflow for running tests and verifying distribution consistency
devfrankduah Jun 8, 2026
99eda56
add workflow for automated PR review and approval process
devfrankduah Jun 8, 2026
cc02a26
add workflow for bot response to issue comments
devfrankduah Jun 8, 2026
83eb6c2
add workflow for updating open PRs targeting development
devfrankduah Jun 8, 2026
eb43e43
refactor RELEASING.md for improved formatting and readability
devfrankduah Jun 8, 2026
5252bcd
refactor create-draft-release workflow for improved clarity and error…
devfrankduah Jun 8, 2026
25e6eba
Merge pull request #2 from llm-exe/chore/release-workflows
gregreindel Jun 9, 2026
d46b529
update Node.js setup action to version 6 for improved performance and…
devfrankduah Jun 9, 2026
387f09f
update Node.js setup action to version 6 for improved performance and…
devfrankduah Jun 9, 2026
585cff2
update Node.js setup action to version 6 for improved performance and…
devfrankduah Jun 9, 2026
07e83d3
update Node.js setup action to version 6 for improved performance and…
devfrankduah Jun 9, 2026
f0cd841
update Node.js version in agent-review-pr workflow to 24.x for enhanc…
devfrankduah Jun 9, 2026
f6c01c2
update Node.js version in bot-respond workflow to 24 for enhanced com…
devfrankduah Jun 9, 2026
a2c6fbd
update Node.js version in publish-release workflow to 24.x for enhanc…
devfrankduah Jun 9, 2026
aec5b67
update Node.js version in tests workflow to include 24.x for enhanced…
devfrankduah Jun 9, 2026
90f06f6
Merge pull request #4 from llm-exe/chore/release-workflows
gregreindel Jun 9, 2026
dfd14c8
update actions/checkout and actions/create-github-app-token versions …
devfrankduah Jun 18, 2026
89e8a7e
update actions/checkout and actions/create-github-app-token versions …
devfrankduah Jun 18, 2026
66d205f
update actions/create-github-app-token to v3 and actions/checkout to …
devfrankduah Jun 18, 2026
58908fe
update actions/checkout to v6 for improved functionality
devfrankduah Jun 18, 2026
f93acb5
update actions/checkout to v6 and refine release notes cleanup process
devfrankduah Jun 18, 2026
1045f40
update actions/checkout to v6 and actions/create-github-app-token to …
devfrankduah Jun 18, 2026
253322c
update actions/checkout to v6 and actions/create-github-app-token to …
devfrankduah Jun 18, 2026
97e0dc1
update actions/checkout to v6 for consistency across jobs
devfrankduah Jun 18, 2026
4dbe9f7
update actions/create-github-app-token to v3 and actions/checkout to …
devfrankduah Jun 18, 2026
8efbd59
fix: remove extra space in client-id variable for create-github-app-t…
devfrankduah Jun 18, 2026
124008f
fix: update git user email configuration to use APP_BOT_USER_ID variable
devfrankduah Jun 18, 2026
3464a9f
Merge pull request #5 from llm-exe/chore/release-workflows
gregreindel Jun 19, 2026
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
194 changes: 194 additions & 0 deletions .github/workflows/agent-review-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
name: Agent / Review PR

on:
pull_request:
types: [opened, synchronize]
branches: [main, development]

workflow_dispatch:
inputs:
pr_number:
description: "PR number to review"
required: true
type: string
base_ref:
description: "Base branch of the PR (e.g. development)"
required: true
type: string
head_ref:
description: "Head branch of the PR"
required: true
type: string

permissions:
contents: read
pull-requests: write
issues: write
id-token: write

jobs:
tests:
if: github.base_ref == 'development' || (github.event_name == 'workflow_dispatch' && inputs.base_ref == 'development')
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
node-version: [20.x, 22.x, 24.x]

steps:
- uses: actions/checkout@v6

- name: Checkout PR (workflow_dispatch)
if: github.event_name == 'workflow_dispatch'
run: gh pr checkout ${{ inputs.pr_number }}
env:
GH_TOKEN: ${{ github.token }}

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
cache: "npm"

- name: Install dependencies
run: npm ci

- name: Verify (format, typecheck, test)
run: npm run verify

review:
if: (github.base_ref == 'development' && github.event.action == 'opened') || (github.event_name == 'workflow_dispatch' && inputs.base_ref == 'development')
runs-on: ubuntu-latest
timeout-minutes: 15
outputs:
verdict: ${{ steps.verdict.outputs.verdict }}

steps:
- name: Generate review bot token
id: review-bot-token
uses: actions/create-github-app-token@v3
with:
client-id: ${{ vars.LLM_EXE_REVIEW_BOT_CLIENT_ID }}
private-key: ${{ secrets.LLM_EXE_REVIEW_BOT_PRIVATE_KEY }}

- uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ steps.review-bot-token.outputs.token }}

- uses: actions/setup-node@v6
with:
node-version: 24
cache: npm

- name: Install dependencies
run: npm ci

- name: Review PR
env:
PR_NUMBER: ${{ github.event.pull_request.number || inputs.pr_number }}
HEAD_REF: ${{ github.event.pull_request.head.ref || inputs.head_ref }}
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ steps.review-bot-token.outputs.token }}
display_report: "false"
allowed_bots: "llm-exe-bot[bot]"
prompt: |
You are a senior engineer reviewing PR #${{ env.PR_NUMBER }} on the llm-exe GitHub Action repository.

This repo is a GitHub Action wrapper around the llm-exe SDK. It runs committed dist/index.js
(not src/) so every code change must be accompanied by a rebuilt dist/. The action exposes
inputs/outputs defined in action.yml and is consumed by other GitHub workflows via
`uses: llm-exe/github-action@v1`.

## Your task

1. Read CLAUDE.md for project context.
2. Fetch the PR diff: `gh pr diff ${{ env.PR_NUMBER }}`
3. Read any changed source files in full.
4. Check that dist/ was rebuilt if src/ changed: look for dist/ changes alongside src/ changes.
5. Review for: correctness, security, type safety, action.yml contract changes, and dist freshness.

## Verdict

After your review, post a PR comment with your findings. Then write your verdict to
/tmp/review-verdict.txt — one word only:
- `approve` — code is correct, dist is fresh (if src changed), no blocking issues
- `request-changes` — there are issues that must be fixed before merging
- `comment` — minor notes only, no blocking issues but not ready to formally approve

If the branch name starts with `agent/` note that this is bot-authored code — hold it
to the same standards but expect mechanical patterns.
claude_args: |
--allowedTools "Bash,Read,Glob,Grep,WebFetch"
--max-turns 30
--model ${{ vars.ANTHROPIC_OPUS_LATEST || 'claude-opus-4-6' }}

- name: Read verdict
id: verdict
if: always()
run: |
if [ -f /tmp/review-verdict.txt ]; then
v=$(cat /tmp/review-verdict.txt | tr -d '[:space:]')
else
v="no-verdict"
fi
echo "verdict=$v" >> "$GITHUB_OUTPUT"

decide:
needs: [tests, review]
if: always() && (github.base_ref == 'development' || (github.event_name == 'workflow_dispatch' && inputs.base_ref == 'development'))
runs-on: ubuntu-latest
timeout-minutes: 5

steps:
- name: Generate review bot token
id: review-bot-token
uses: actions/create-github-app-token@v3
with:
client-id: ${{ vars.LLM_EXE_REVIEW_BOT_CLIENT_ID }}
private-key: ${{ secrets.LLM_EXE_REVIEW_BOT_PRIVATE_KEY }}

- name: Generate bot token
id: bot-token
uses: actions/create-github-app-token@v3
with:
client-id: ${{ vars.APP_CLIENT_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Approve or skip
env:
GH_TOKEN: ${{ steps.review-bot-token.outputs.token }}
BOT_TOKEN: ${{ steps.bot-token.outputs.token }}
PR_NUMBER: ${{ github.event.pull_request.number || inputs.pr_number }}
HEAD_REF: ${{ github.event.pull_request.head.ref || inputs.head_ref }}
REPOSITORY: ${{ github.repository }}
run: |
verdict="${{ needs.review.outputs.verdict }}"
tests_result="${{ needs.tests.result }}"

echo "Review verdict : $verdict"
echo "Tests result : $tests_result"

if [ "$verdict" = "approve" ] && [ "$tests_result" = "success" ]; then
gh pr review "$PR_NUMBER" \
--approve \
--body "Approved by reviewer agent (tests passing)." \
--repo "$REPOSITORY"

if echo "$HEAD_REF" | grep -q '^agent/'; then
IS_DRAFT=$(gh pr view "$PR_NUMBER" \
--json isDraft --jq '.isDraft' \
--repo "$REPOSITORY")
if [ "$IS_DRAFT" = "true" ]; then
GH_TOKEN="$BOT_TOKEN" gh pr ready "$PR_NUMBER" --repo "$REPOSITORY"
echo "PR marked as ready for review."
fi
fi

echo "PR #$PR_NUMBER approved."
else
echo "No approval submitted: verdict='$verdict', tests='$tests_result'."
fi
88 changes: 88 additions & 0 deletions .github/workflows/auto-merge-main-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: Release / Auto Merge

on:
workflow_run:
workflows:
- "Release / Check Semver"
types:
- completed
pull_request:
types:
- ready_for_review
- synchronize
branches:
- main

permissions:
id-token: write
checks: write
contents: write
pull-requests: write
actions: write

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
auto-merge:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'development' || github.event_name == 'pull_request' }}

steps:
- uses: actions/checkout@v6

- name: Generate bot token
id: bot-token
uses: actions/create-github-app-token@v3
with:
client-id: ${{ vars.APP_CLIENT_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Get PR number for development to main
run: |
PR_INFO=$(gh pr list --base main --head development --state open --json number,isDraft --jq '.[] | select(.isDraft == false) | .number')
echo "PR_NUMBER=$PR_INFO" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ steps.bot-token.outputs.token }}
GITHUB_TOKEN: ${{ steps.bot-token.outputs.token }}

- name: Wait for all checks to complete
if: env.PR_NUMBER != ''
run: |
MAX_ATTEMPTS=10
ATTEMPT=0
while [[ $ATTEMPT -lt $MAX_ATTEMPTS ]]; do
CHECKS_IN_PROGRESS=$(gh pr checks ${{ env.PR_NUMBER }} --json name,state --jq '[.[] | select(.name != "auto-merge") | select(.state == "IN_PROGRESS")] | length')
if [[ "$CHECKS_IN_PROGRESS" -eq "0" ]]; then
echo "All checks complete."
break
fi
echo "Checks still in progress... attempt $ATTEMPT/$MAX_ATTEMPTS"
ATTEMPT=$((ATTEMPT + 1))
sleep 30
done
env:
GH_TOKEN: ${{ steps.bot-token.outputs.token }}
GITHUB_TOKEN: ${{ steps.bot-token.outputs.token }}

- name: Verify all checks passed
if: env.PR_NUMBER != ''
run: |
FAILED_CHECKS=$(gh pr checks ${{ env.PR_NUMBER }} --json name,state --jq '[.[] | select(.name != "auto-merge") | select(.state == "FAILURE")] | length')
if [[ "$FAILED_CHECKS" -gt "0" ]]; then
echo "Some checks failed — aborting auto-merge."
exit 1
fi
echo "All checks passed."
env:
GH_TOKEN: ${{ steps.bot-token.outputs.token }}
GITHUB_TOKEN: ${{ steps.bot-token.outputs.token }}

- name: Merge PR to main
if: env.PR_NUMBER != ''
run: |
gh pr merge ${{ env.PR_NUMBER }} --merge --admin --repo ${{ github.repository }}
env:
GH_TOKEN: ${{ steps.bot-token.outputs.token }}
GITHUB_TOKEN: ${{ steps.bot-token.outputs.token }}
114 changes: 114 additions & 0 deletions .github/workflows/bot-respond.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: Agent / Bot Respond

on:
issue_comment:
types: [created]

permissions:
contents: write
issues: write
pull-requests: write
id-token: write

jobs:
respond:
if: |
contains(github.event.comment.body, '@llm-exe-bot') &&
github.event.comment.user.login != 'llm-exe-bot[bot]' &&
(
github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR'
)
runs-on: ubuntu-latest
timeout-minutes: 20

steps:
- name: Generate bot token
id: bot-token
uses: actions/create-github-app-token@v3
with:
client-id: ${{ vars.APP_CLIENT_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Configure git
run: |
git config --global user.name "llm-exe-bot[bot]"
git config --global user.email "${{ vars.APP_BOT_USER_ID }}+llm-exe-bot[bot]@users.noreply.github.com"

- uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ steps.bot-token.outputs.token }}

- uses: actions/setup-node@v6
with:
node-version: 24
cache: npm

- name: Install dependencies
run: npm ci

- name: Respond
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ steps.bot-token.outputs.token }}
prompt: |
You are llm-exe-bot, a helpful assistant for the llm-exe GitHub Action repository.
You've been mentioned in a GitHub issue or PR comment by a maintainer or collaborator.

Read CLAUDE.md for project context. This repo is a GitHub Action wrapper around the
llm-exe SDK. It runs committed dist/index.js (not src/) so code changes must include
a rebuilt dist/.

## Determine what's being asked

Read the comment that mentioned you carefully. Decide which of the following applies:

### 1. PR review requested
If the maintainer wants you to review a pull request — any phrasing like "review this",
"re-review", "take another look", "check the PR", "can you review", etc. — AND the
comment is on a pull request:
- Fetch the PR's base and head branch:
`gh pr view ${{ github.event.issue.number }} --repo ${{ github.repository }} --json baseRefName,headRefName`
- Dispatch the review pipeline:
`gh workflow run agent-review-pr.yml \
--repo ${{ github.repository }} \
-f pr_number="${{ github.event.issue.number }}" \
-f base_ref="<base_ref from above>" \
-f head_ref="<head_ref from above>"`
- Post a brief acknowledgment, e.g.:
"Review pipeline started — tests + agent review + approval will run shortly."
- Stop here. Do not also do a manual review.

### 2. Answer questions (read-only)
If the maintainer is asking a question or wants your opinion on something:
- Read any relevant source code
- Use `gh pr diff` or `gh pr view` to understand PR context
- Run `npm run verify` if needed to check the current state
- Reply with a concise, specific answer

### 3. Make changes (write mode)
If the maintainer is asking you to fix something, revise a PR, address review feedback,
or make code changes:
- If you're on a PR, check out the PR branch: `gh pr checkout <number>`
- Read the PR diff and any feedback
- Make the requested changes
- If you changed src/, rebuild dist/: `npm run build`
- Run `npm run verify` — everything must pass
- Commit with a descriptive message (do NOT add Co-Authored-By lines)
- Push to the existing PR branch
- Reply with a summary of what you changed

## Rules
- ONLY make changes when the maintainer explicitly asks you to
- If the request is ambiguous, ask for clarification — don't guess
- Stay scoped to what's asked. Don't refactor unrelated things.
- Do NOT create new PRs or branches — work on the existing PR branch
- Do NOT close issues or PRs unless explicitly told to
- Be conversational and concise. Reference actual code (file paths, line numbers) when relevant.
claude_args: |
--allowedTools "Bash,Read,Write,Edit,Glob,Grep,WebFetch,WebSearch"
--max-turns 90
--model ${{ vars.ANTHROPIC_OPUS_LATEST || 'claude-opus-4-6' }}
Loading