Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions .github/actions/claude-code-action/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM node:20-alpine

RUN npm install -g @anthropic-ai/claude-code

WORKDIR /app
COPY entrypoint.sh .
RUN chmod +x entrypoint.sh

ENTRYPOINT ["/app/entrypoint.sh"]
17 changes: 17 additions & 0 deletions .github/actions/claude-code-action/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: "Claude Code Action"
description: "Custom Claude Code runner for PraisonAI"

inputs:
anthropic_api_key:
required: true
description: "Anthropic API key"
github_token:
required: true
description: "GitHub token for repo access"

runs:
using: "docker"
image: "ghcr.io/mervinpraison/praisonai-claude-code:latest"
args:
- "--anthropic-api-key=${{ inputs.anthropic_api_key }}"
- "--github-token=${{ inputs.github_token }}"
15 changes: 15 additions & 0 deletions .github/actions/claude-code-action/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

set -e

echo "Running Claude Code in CI mode..."

# Extract GitHub context and create a smart prompt
PROMPT="Analyse the GitHub issue or PR context and generate a smart response based on the repository context."

# Set environment variables
export ANTHROPIC_API_KEY="$1"
export GITHUB_TOKEN="$2"

# Run Claude with the prompt
claude -p "$PROMPT"
117 changes: 117 additions & 0 deletions .github/actions/claude-code/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
name: "Claude Code Action"
description: "Run Claude Code in GitHub Actions workflows"

inputs:
github_token:
description: "GitHub token with repo and issues permissions"
required: true
anthropic_api_key:
description: "Anthropic API key"
required: true
prompt:
description: "The prompt to send to Claude Code"
required: false
default: ""
prompt_file:
description: "Path to a file containing the prompt to send to Claude Code"
required: false
default: ""
allowed_tools:
description: "Comma-separated list of allowed tools for Claude Code to use"
required: false
default: ""
output_file:
description: "File to save Claude Code output to (optional)"
required: false
default: ""
timeout_minutes:
description: "Timeout in minutes for Claude Code execution"
required: false
default: "10"
install_github_mcp:
description: "Whether to install the GitHub MCP server"
required: false
default: "false"

runs:
using: "composite"
steps:
- name: Install Claude Code
shell: bash
run: npm install -g @anthropic-ai/claude-code

- name: Install GitHub MCP Server
if: inputs.install_github_mcp == 'true'
shell: bash
run: |
claude mcp add-json github '{
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:sha-ff3036d"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${{ inputs.GITHUB_TOKEN }}"
}
}'

- name: Prepare Prompt File
shell: bash
id: prepare_prompt
run: |
if [ -z "${{ inputs.prompt }}" ] && [ -z "${{ inputs.prompt_file }}" ]; then
echo "::error::Neither 'prompt' nor 'prompt_file' was provided. At least one is required."
exit 1
fi

if [ ! -z "${{ inputs.prompt_file }}" ]; then
if [ ! -f "${{ inputs.prompt_file }}" ]; then
echo "::error::Prompt file '${{ inputs.prompt_file }}' does not exist."
exit 1
fi
PROMPT_PATH="${{ inputs.prompt_file }}"
else
mkdir -p /tmp/claude-action
PROMPT_PATH="/tmp/claude-action/prompt.txt"
echo "${{ inputs.prompt }}" > "$PROMPT_PATH"
fi

if [ ! -s "$PROMPT_PATH" ]; then
echo "::error::Prompt is empty. Please provide a non-empty prompt."
exit 1
fi

echo "PROMPT_PATH=$PROMPT_PATH" >> $GITHUB_ENV

- name: Run Claude Code
shell: bash
id: run_claude
run: |
timeout_seconds=$((${{ inputs.timeout_minutes }} * 60))

if [ -z "${{ inputs.output_file }}" ]; then
timeout $timeout_seconds claude \
-p \
--verbose \
--output-format stream-json \
"$(cat ${{ env.PROMPT_PATH }})" \
${{ inputs.allowed_tools != '' && format('--allowedTools "{0}"', inputs.allowed_tools) || '' }}
else
timeout $timeout_seconds claude \
-p \
--verbose \
--output-format stream-json \
"$(cat ${{ env.PROMPT_PATH }})" \
${{ inputs.allowed_tools != '' && format('--allowedTools "{0}"', inputs.allowed_tools) || '' }} | tee output.txt

jq -s '.' output.txt > output.json
jq -r '.[-1].result' output.json > "${{ inputs.output_file }}"
echo "Complete output saved to output.json, final response saved to ${{ inputs.output_file }}"
fi
env:
ANTHROPIC_API_KEY: ${{ inputs.anthropic_api_key }}
GITHUB_TOKEN: ${{ inputs.github_token }}
3 changes: 2 additions & 1 deletion .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ jobs:

- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@beta
uses: docker://ghcr.io/mervinpraison/praisonai-claudecode:latest
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GH_TOKEN }}

Loading