name: OpenHands Build & Test on: workflow_dispatch: inputs: task: description: 'Build task to execute' required: true type: string repo_name: description: 'Repository name' required: true type: string commit_sha: description: 'Commit SHA' required: true type: string retry_count: description: 'Retry attempt number' required: false type: string default: '0' previous_errors: description: 'Previous build errors (for retry)' required: false type: string default: '' jobs: build: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python 3.12 uses: actions/setup-python@v5 with: python-version: '3.12' - name: Install uv uses: astral-sh/setup-uv@v6 with: cache: true - name: Install OpenHands SDK run: | uv pip install --system "openhands-sdk @ git+https://github.com/OpenHands/agent-sdk.git@main#subdirectory=openhands-sdk" uv pip install --system "openhands-tools @ git+https://github.com/OpenHands/agent-sdk.git@main#subdirectory=openhands-tools" - name: Run Build Task env: LLM_API_KEY: ${{ secrets.OPENHANDS_API_KEY }} TASK: ${{ github.event.inputs.task }} REPO_NAME: ${{ github.event.inputs.repo_name }} COMMIT_SHA: ${{ github.event.inputs.commit_sha }} RETRY_COUNT: ${{ github.event.inputs.retry_count }} PREVIOUS_ERRORS: ${{ github.event.inputs.previous_errors }} LLM_MODEL: ${{ vars.LLM_MODEL || 'anthropic/claude-sonnet-4-5-20250929' }} LLM_BASE_URL: ${{ vars.LLM_BASE_URL || '' }} GITEA_API_URL: ${{ vars.GITEA_API_URL || 'https://git.oky.sh' }} GITEA_API_TOKEN: ${{ secrets.GITEA_API_TOKEN }} GITEA_REPO_OWNER: ${{ github.event.inputs.repo_owner || 'gitadmin' }} run: | python .github/scripts/agent_build.py - name: Upload Build Logs uses: actions/upload-artifact@v4 if: always() with: name: build-logs-${{ github.run_number }} path: | *.log output/ retention-days: 7 - name: Update Gitea Status if: always() && env.GITEA_API_TOKEN != '' run: | STATUS="${{ job.status }}" if [ "$STATUS" = "success" ]; then STATE="success" DESCRIPTION="Build passed ✅" else STATE="failure" DESCRIPTION="Build failed ❌ (attempt ${{ github.event.inputs.retry_count || 0 }})" fi echo "Updating Gitea status: $STATE" curl -X POST \ "$GITEA_API_URL/api/v1/repos/$GITEA_REPO_OWNER/$REPO_NAME/statuses/$COMMIT_SHA" \ -H "Authorization: token $GITEA_API_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"state\": \"$STATE\", \"description\": \"$DESCRIPTION\", \"context\": \"openhands/build\", \"target_url\": \"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID\"}" - name: Comment on Commit (if PR exists) if: always() uses: actions/github-script@v7 with: script: | const { data: commits } = await github.rest.repos.listPullRequestsAssociatedWithCommit({ owner: context.repo.owner, repo: context.repo.repo, commit_sha: process.env.COMMIT_SHA }); if (commits.length > 0) { const pr = commits[0]; const status = '${{ job.status }}' === 'success' ? '✅ Passed' : '❌ Failed'; const comment = `## OpenHands Build ${status} **Repository:** ${process.env.REPO_NAME} **Commit:** \`${process.env.COMMIT_SHA.substring(0, 8)}\` **Attempt:** ${process.env.RETRY_COUNT || 0} [View Build Logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) `; await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: pr.number, body: comment }); } - name: Notify on Failure if: failure() && env.GITEA_API_TOKEN != '' run: | echo "Build failed after ${{ github.event.inputs.retry_count || 0 }} attempts" echo "Please check the logs for details" echo "Gitea status has been updated to 'failure'"