Skip to content
Draft
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
32 changes: 26 additions & 6 deletions .github/workflows/github-issue-autosolve.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,16 @@ jobs:
ref: ${{ steps.actions_ref.outputs.ref }}
path: .actions

# Install Claude CLI BEFORE authentication so that npm install does
# not run with cloud credentials in the environment. The credentials
# file written by google-github-actions/auth contains a live OIDC
# bearer token, and npm post-install scripts could exfiltrate it.
- name: Install Claude CLI
shell: bash
run: |
npm install --global "@anthropic-ai/claude-code@2.1.79"
echo "Claude CLI installed: $(claude --version)"

- name: Authenticate to Google Cloud (Vertex)
if: inputs.auth_mode == 'vertex' && inputs.vertex_workload_identity_provider != ''
uses: google-github-actions/auth@v3
Expand All @@ -203,6 +213,22 @@ jobs:
service_account: ${{ inputs.vertex_service_account }}
workload_identity_provider: ${{ inputs.vertex_workload_identity_provider }}

# Move the credentials file out of $GITHUB_WORKSPACE so that Claude
# cannot read or accidentally commit it.
- name: Move credentials out of workspace
if: inputs.auth_mode == 'vertex' && inputs.vertex_workload_identity_provider != ''
shell: bash
run: |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2129:style:6:3: Consider using { cmd1; cmd2; } >> file instead of individual redirects [shellcheck]

for f in gha-creds-*.json; do
[ -f "$f" ] && mv "$f" "$RUNNER_TEMP/" && echo "Moved $f to RUNNER_TEMP"
done
if [ -n "$GOOGLE_APPLICATION_CREDENTIALS" ] && [[ "$GOOGLE_APPLICATION_CREDENTIALS" == "$GITHUB_WORKSPACE"* ]]; then
new_path="$RUNNER_TEMP/$(basename "$GOOGLE_APPLICATION_CREDENTIALS")"
echo "GOOGLE_APPLICATION_CREDENTIALS=$new_path" >> "$GITHUB_ENV"
echo "CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=$new_path" >> "$GITHUB_ENV"
echo "GOOGLE_GHA_CREDS_PATH=$new_path" >> "$GITHUB_ENV"
fi

# --- Build prompt ---
- name: Build prompt
id: build_prompt
Expand Down Expand Up @@ -231,12 +257,6 @@ jobs:
ANTHROPIC_VERTEX_PROJECT_ID: ${{ inputs.auth_mode == 'vertex' && inputs.vertex_project_id || '' }}
CLOUD_ML_REGION: ${{ inputs.auth_mode == 'vertex' && inputs.vertex_region || '' }}

- name: Install Claude CLI
shell: bash
run: ${{ env.ACTIONS_DIR }}/run_step.sh shared install_claude
env:
CLAUDE_CLI_VERSION: "2.1.79"

- name: Build assessment prompt
id: assess_prompt
shell: bash
Expand Down
13 changes: 13 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,16 @@ scripts that set up temporary git repos and validate behavior.
return code is checked automatically.
- In workflow YAML files, always use the latest major version of built-in
GitHub Actions (e.g., `actions/checkout@v5`, `actions/upload-artifact@v4`).
- In autosolve workflows, install the Claude CLI (npm) BEFORE any cloud
authentication step, and move credential files out of the workspace
immediately after authentication. npm post-install scripts run with the
job's full environment, so installing after auth exposes credentials
(e.g., the OIDC bearer token in `gha-creds-*.json`) to arbitrary code.
The correct step order is: checkout → install CLI → authenticate →
move credentials → run autosolve action.
- Do not silently swallow errors. In shell scripts, avoid `|| return 0`,
`|| true`, or `|| :` to suppress failures without logging — use
`log_warning` to surface what went wrong. In Go code, avoid `return nil`
on error paths without logging or returning the error. If ignoring an
error is genuinely correct (e.g., best-effort cleanup), add a comment
explaining why it's safe to ignore.
2 changes: 2 additions & 0 deletions autosolve-go/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Built binary (lives at repo root of autosolve-go/)
/autosolve
10 changes: 10 additions & 0 deletions autosolve-go/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.PHONY: build test clean

build:
go build -o autosolve ./cmd/autosolve

test:
go test ./... -count=1

clean:
rm -f autosolve
64 changes: 64 additions & 0 deletions autosolve-go/assess/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Autosolve Assess (Go)
description: Run Claude in read-only mode to assess whether a task is suitable for automated resolution.

# Prerequisites:
# The calling workflow must install the Claude CLI BEFORE authenticating
# to any cloud provider. npm post-install scripts run with the job's
# full environment, so installing after auth would expose credentials
# (e.g. the OIDC bearer token in gha-creds-*.json) to arbitrary code.

inputs:
prompt:
description: The task to assess. Plain text instructions describing what needs to be done.
required: false
default: ""
skill:
description: Path to a skill/prompt file relative to the repo root.
required: false
default: ""
additional_instructions:
description: Extra context appended after the task prompt but before the assessment footer.
required: false
default: ""
assessment_criteria:
description: Custom criteria for the assessment. If not provided, uses default criteria.
required: false
default: ""
model:
description: Claude model ID.
required: false
default: "claude-opus-4-6"
blocked_paths:
description: Comma-separated path prefixes that cannot be modified (injected into security preamble).
required: false
default: ".github/workflows/"

outputs:
assessment:
description: PROCEED or SKIP
value: ${{ steps.assess.outputs.assessment }}
summary:
description: Human-readable assessment reasoning.
value: ${{ steps.assess.outputs.summary }}
result:
description: Full Claude result text.
value: ${{ steps.assess.outputs.result }}

runs:
using: "composite"
steps:
- name: Build autosolve
shell: bash
run: cd "${{ github.action_path }}/.." && go build -o /tmp/autosolve ./cmd/autosolve

- name: Run assessment
id: assess
shell: bash
run: /tmp/autosolve assess
env:
INPUT_PROMPT: ${{ inputs.prompt }}
INPUT_SKILL: ${{ inputs.skill }}
INPUT_ADDITIONAL_INSTRUCTIONS: ${{ inputs.additional_instructions }}
INPUT_ASSESSMENT_CRITERIA: ${{ inputs.assessment_criteria }}
INPUT_MODEL: ${{ inputs.model }}
INPUT_BLOCKED_PATHS: ${{ inputs.blocked_paths }}
Loading