yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
2d775b54d
master
1name : "Claude Code Runner" 2description : "Complete Claude Code execution with authentication, setup, execution, and results handling" 3inputs : 4# Authentication inputs 5llmgw-id : 6description : "LLMGW ID for token generation" 7required : true 8llmgw-secret : 9description : "LLMGW secret for token generation" 10required : true 11llmgw-token-url : 12description : "LLMGW token URL for authentication" 13required : true 14github-token-fallback : 15description : "Fallback GitHub token if App token fails" 16required : false 17default : "" 18 19# Claude configuration 20model : 21description : "Anthropic model to use" 22required : false 23default : "claude-3-5-sonnet-20241022" 24max-turns : 25description : "Maximum number of turns for Claude" 26required : false 27default : "50000" 28timeout-minutes : 29description : "Timeout for Claude action in minutes" 30required : false 31default : "600" 32trigger-phrase : 33description : "Trigger phrase to activate Claude" 34required : false 35default : "@claude" 36assignee-trigger : 37description : "Assignee trigger name" 38required : false 39default : "claude" 40 41# Environment and setup 42custom-instructions : 43description : "Custom instructions for Claude" 44required : true 45mcp-config : 46description : "MCP server configuration JSON" 47required : false 48default : "" 49allowed-tools : 50description : "Comma-separated list of allowed tools" 51required : false 52default : "Bash,View,GlobTool,GrepTool,BatchTool,Write" 53setup-commands : 54description : "Setup commands to run before Claude (multiline string)" 55required : false 56default : "" 57continue-on-setup-error : 58description : "Continue if setup commands fail" 59required : false 60default : "false" 61 62# AWS/Bedrock configuration 63use-bedrock : 64description : "Use AWS Bedrock for Claude" 65required : false 66default : "true" 67aws-region : 68description : "AWS region" 69required : false 70default : "" 71bedrock-base-url : 72description : "Anthropic Bedrock base URL" 73required : false 74default : "" 75small-fast-model : 76description : "Small fast model for Anthropic" 77required : false 78default : "" 79 80outputs : 81auth-token : 82description : "Generated authentication token" 83value : ${{ steps.auth-token.outputs.token }} 84github-token : 85description : "Final GitHub token (App or fallback)" 86value : ${{ steps.auth-config.outputs.github-token }} 87token-expires : 88description : "Token expiration time (if available)" 89value : ${{ steps.auth-token.outputs.token-expires }} 90github-app-token-outcome : 91description : "Outcome of GitHub App token generation" 92value : ${{ steps.github-app-token.outcome }} 93claude-outcome : 94description : "Outcome of Claude Code execution" 95value : ${{ steps.claude-action.outcome }} 96 97runs : 98using : "composite" 99steps : 100# Validate environment and inputs 101- name : Validate Environment 102shell : bash 103run : | 104set -euo pipefail 105 106# Check required secrets 107if [ -z "${{ inputs.llmgw-id }}" ] || [ -z "${{ inputs.llmgw-secret }}" ] || [ -z "${{ inputs.llmgw-token-url }}" ]; then 108echo "::error::Missing required secrets: LLMGW_ID or LLMGW_SECRET or LLMGW_TOKEN_URL" 109exit 1 110fi 111 112# Install required tools 113command -v jq >/dev/null 2>&1 || { echo "::error::jq is required but not installed"; exit 1; } 114command -v curl >/dev/null 2>&1 || { echo "::error::curl is required but not installed"; exit 1; } 115 116echo "โ Environment validation passed" 117 118# Generate custom auth token 119- name : Generate Custom Auth Token 120id : auth-token 121shell : bash 122run : | 123set -euo pipefail 124 125echo "๐ Generating authentication token..." 126 127# Set up error handling 128cleanup() { 129local exit_code=$? 130echo "๐งน Cleaning up temporary files..." 131rm -f /tmp/token_response.json 2>/dev/null || true 132if [ $exit_code -ne 0 ]; then 133echo "::error::Authentication failed - check your credentials and endpoint" 134fi 135exit $exit_code 136} 137trap cleanup EXIT 138 139# Generate token with comprehensive error handling (using Basic auth like original) 140HTTP_CODE=$(curl -s -w "%{http_code}" -o /tmp/token_response.json --fail-with-body \ 141--max-time 30 \ 142--retry 3 \ 143--retry-delay 2 \ 144--location "${{ inputs.llmgw-token-url }}" \ 145--header 'Content-Type: application/x-www-form-urlencoded' \ 146--header "Authorization: Basic $(echo -n ${{ inputs.llmgw-id }}:${{ inputs.llmgw-secret }} | base64 -w0)" \ 147--data-urlencode 'grant_type=client_credentials' \ 148--data-urlencode 'scope=awsanthropic-readwrite azureopenai-readwrite' \ 1492>/dev/null) 150 151# Check HTTP response code 152if [ "$HTTP_CODE" -ne 200 ]; then 153echo "::error::Authentication failed with HTTP code: $HTTP_CODE" 154if [ -f /tmp/token_response.json ]; then 155echo "::error::Response: $(cat /tmp/token_response.json | head -c 200)" 156fi 157exit 1 158fi 159 160# Extract and validate token 161if [ ! -f /tmp/token_response.json ]; then 162echo "::error::No response file generated" 163exit 1 164fi 165 166ANTHROPIC_AUTH_TOKEN=$(jq -r '.access_token // empty' /tmp/token_response.json 2>/dev/null) 167 168# Validate token format and length 169if [ -z "$ANTHROPIC_AUTH_TOKEN" ] || [ "$ANTHROPIC_AUTH_TOKEN" = "null" ]; then 170echo "::error::Failed to extract access token from response" 171exit 1 172fi 173 174# Basic token validation 175if [ ${#ANTHROPIC_AUTH_TOKEN} -lt 10 ]; then 176echo "::error::Token appears to be too short (${#ANTHROPIC_AUTH_TOKEN} characters)" 177exit 1 178fi 179 180# CRITICAL: Mask the token BEFORE any output 181echo "::add-mask::$ANTHROPIC_AUTH_TOKEN" 182 183# Set outputs 184echo "token=$ANTHROPIC_AUTH_TOKEN" >> $GITHUB_OUTPUT 185 186# Set token expiry if available 187TOKEN_EXPIRES=$(jq -r '.expires_in // empty' /tmp/token_response.json 2>/dev/null) 188if [ -n "$TOKEN_EXPIRES" ]; then 189echo "::add-mask::$TOKEN_EXPIRES" 190echo "token-expires=$TOKEN_EXPIRES" >> $GITHUB_OUTPUT 191fi 192 193echo "โ Authentication token generated and masked successfully" 194 195# Clean up response file 196rm -f /tmp/token_response.json 197 198# Configure authentication 199- name : Configure Authentication 200id : auth-config 201shell : bash 202run : | 203set -euo pipefail 204 205# Use GitHub App token if available, otherwise use GITHUB_TOKEN 206if [ -n "${{ steps.github-app-token.outputs.token }}" ]; then 207echo "github-token=${{ steps.github-app-token.outputs.token }}" >> $GITHUB_OUTPUT 208echo "โ Using GitHub App authentication" 209else 210echo "github-token=${{ inputs.github-token-fallback }}" >> $GITHUB_OUTPUT 211echo "โ ๏ธ Using fallback GITHUB_TOKEN authentication" 212fi 213 214# Run setup commands if provided 215- name : Run setup commands 216id : setup-commands 217if : inputs.setup-commands != '' 218shell : bash 219continue-on-error : ${{ inputs.continue-on-setup-error == 'true' }} 220run : ${{ inputs.setup-commands }} 221 222# Security cleanup 223- name : Security Cleanup 224if : always() 225shell : bash 226run : | 227set -euo pipefail 228 229echo "๐งน Performing security cleanup..." 230 231# Clear any temporary files that might contain sensitive data 232find /tmp -name "*token*" -type f -delete 2>/dev/null || true 233find /tmp -name "*auth*" -type f -delete 2>/dev/null || true 234find /tmp -name "*response*" -type f -delete 2>/dev/null || true 235 236# Clear environment variables (belt and suspenders approach) 237unset ANTHROPIC_API_KEY 2>/dev/null || true 238unset ANTHROPIC_AUTH_TOKEN 2>/dev/null || true 239 240echo "โ Security cleanup completed" 241 242# Workflow summary 243- name : Generate Workflow Summary 244if : always() 245shell : bash 246run : | 247echo "## Claude Code Runner Summary" >> $GITHUB_STEP_SUMMARY 248echo "" >> $GITHUB_STEP_SUMMARY 249echo "### Authentication" >> $GITHUB_STEP_SUMMARY 250echo "- **Auth Token**: โ Generated" >> $GITHUB_STEP_SUMMARY 251echo "- **Token Expiry**: ${{ steps.auth-token.outputs.token-expires || 'Not provided' }}" >> $GITHUB_STEP_SUMMARY 252echo "- **GitHub Token**: ${{ steps.github-app-token.outcome == 'success' && 'โ GitHub App' || 'โ ๏ธ Fallback' }}" >> $GITHUB_STEP_SUMMARY 253echo "" >> $GITHUB_STEP_SUMMARY 254echo "### Configuration" >> $GITHUB_STEP_SUMMARY 255echo "- **Model**: ${{ inputs.model }}" >> $GITHUB_STEP_SUMMARY 256echo "- **Max Turns**: ${{ inputs.max-turns }}" >> $GITHUB_STEP_SUMMARY 257echo "- **Timeout**: ${{ inputs.timeout-minutes }} minutes" >> $GITHUB_STEP_SUMMARY 258echo "- **Bedrock**: ${{ inputs.use-bedrock == 'true' && 'โ Enabled' || 'โ Disabled' }}" >> $GITHUB_STEP_SUMMARY 259if [ "${{ inputs.use-bedrock }}" = "true" ]; then 260echo "- **AWS Region**: ${{ inputs.aws-region || 'Default' }}" >> $GITHUB_STEP_SUMMARY 261fi 262echo "" >> $GITHUB_STEP_SUMMARY 263echo "### Setup" >> $GITHUB_STEP_SUMMARY 264echo "- **Setup Commands**: ${{ inputs.setup-commands != '' && 'โ Executed' || 'โญ๏ธ Skipped' }}" >> $GITHUB_STEP_SUMMARY 265if [ "${{ inputs.setup-commands }}" != "" ]; then 266echo "- **Setup Result**: ${{ steps.setup-commands.outcome || 'Unknown' }}" >> $GITHUB_STEP_SUMMARY 267fi 268echo "- **Security Cleanup**: โ Completed" >> $GITHUB_STEP_SUMMARY 269 270# Execute Claude Code Action 271- name : Execute Claude Code Action 272id : claude-action 273uses : anthropics/claude-code-action@beta 274with : 275custom_instructions : ${{ inputs.custom-instructions }} 276mcp_config : ${{ inputs.mcp-config }} 277allowed_tools : ${{ inputs.allowed-tools }} 278trigger_phrase : ${{ inputs.trigger-phrase }} 279assignee_trigger : ${{ inputs.assignee-trigger }} 280timeout_minutes : ${{ inputs.timeout-minutes }} 281github_token : ${{ steps.auth-config.outputs.github-token }} 282use_bedrock : ${{ inputs.use-bedrock }} 283model : ${{ inputs.model }} 284max_turns : ${{ inputs.max-turns }} 285# Use claude_env for custom environment variables 286claude_env : | 287ANTHROPIC_BEDROCK_BASE_URL: ${{ inputs.bedrock-base-url }} 288ANTHROPIC_SMALL_FAST_MODEL: ${{ inputs.small-fast-model }} 289AWS_REGION: ${{ inputs.aws-region }} 290GITHUB_REPOSITORY: ${{ github.repository }} 291GITHUB_EVENT_NAME: ${{ github.event_name }} 292GITHUB_ACTOR: ${{ github.actor }} 293ANTHROPIC_AUTH_TOKEN: ${{ steps.auth-token.outputs.token }} 294DISABLE_TELEMETRY: 1 295continue-on-error : true 296 297# Handle Claude results 298- name : Handle Claude Results 299if : always() 300shell : bash 301run : | 302set -euo pipefail 303 304echo "๐ Processing Claude action results..." 305 306# Check if Claude action succeeded 307if [ "${{ steps.claude-action.outcome }}" = "success" ]; then 308echo "โ Claude Code action completed successfully" 309elif [ "${{ steps.claude-action.outcome }}" = "failure" ]; then 310echo "โ Claude Code action failed" 311 312# Create error summary 313echo "" >> $GITHUB_STEP_SUMMARY 314echo "### โ Claude Execution Failed" >> $GITHUB_STEP_SUMMARY 315echo "" >> $GITHUB_STEP_SUMMARY 316echo "The Claude Code action encountered an error. Common causes:" >> $GITHUB_STEP_SUMMARY 317echo "- Authentication issues" >> $GITHUB_STEP_SUMMARY 318echo "- Network connectivity problems" >> $GITHUB_STEP_SUMMARY 319echo "- Model availability issues" >> $GITHUB_STEP_SUMMARY 320echo "- Rate limiting" >> $GITHUB_STEP_SUMMARY 321echo "" >> $GITHUB_STEP_SUMMARY 322echo "Please check the workflow logs for detailed error information." >> $GITHUB_STEP_SUMMARY 323else 324echo "โ ๏ธ Claude Code action was cancelled or skipped" 325fi 326 327# Add execution summary 328- name : Add Claude Execution Summary 329if : always() 330shell : bash 331run : | 332 echo "" >> $GITHUB_STEP_SUMMARY 333 echo "### Claude Execution Details" >> $GITHUB_STEP_SUMMARY 334 echo "" >> $GITHUB_STEP_SUMMARY 335 336 # Event information 337 echo "#### Event Information" >> $GITHUB_STEP_SUMMARY 338 echo "- **Trigger**: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY 339 echo "- **Repository**: ${{ github.repository }}" >> $GITHUB_STEP_SUMMARY 340 echo "- **Actor**: @${{ github.actor }}" >> $GITHUB_STEP_SUMMARY 341 echo "" >> $GITHUB_STEP_SUMMARY 342 343 # Execution status 344 echo "#### Execution Status" >> $GITHUB_STEP_SUMMARY 345 if [ "${{ steps.claude-action.outcome }}" = "success" ]; then 346 echo "- **Claude Action**: โ Success" >> $GITHUB_STEP_SUMMARY 347 elif [ "${{ steps.claude-action.outcome }}" = "failure" ]; then 348 echo "- **Claude Action**: โ Failed" >> $GITHUB_STEP_SUMMARY 349 else 350 echo "- **Claude Action**: โ ๏ธ ${{ steps.claude-action.outcome }}" >> $GITHUB_STEP_SUMMARY 351 fi 352 echo "- **Model Used**: ${{ inputs.model }}" >> $GITHUB_STEP_SUMMARY 353 echo "- **Max Turns**: ${{ inputs.max-turns }}" >> $GITHUB_STEP_SUMMARY 354 echo "- **Workflow Status**: ${{ job.status }}" >> $GITHUB_STEP_SUMMARY 355 356 # Add timestamp 357 echo "" >> $GITHUB_STEP_SUMMARY 358 echo "#### Timestamp" >> $GITHUB_STEP_SUMMARY 359 echo "- **Completed at**: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY