diff --git a/.github/workflows/auto-approve.yml b/.github/workflows/auto-approve.yml new file mode 100644 index 00000000..cd2e6598 --- /dev/null +++ b/.github/workflows/auto-approve.yml @@ -0,0 +1,107 @@ +name: Auto Approve + +on: + # Trigger when check runs complete + check_suite: + types: [completed] + # Also trigger on workflow run completion for reusable workflows + workflow_run: + workflows: ["PR Tests", "Claude Code Review"] + types: [completed] + +permissions: read-all + +jobs: + auto-approve: + runs-on: ubuntu-latest + # Only run on pull requests, not pushes + if: | + github.event.check_suite.pull_requests[0] != null || + github.event.workflow_run.pull_requests[0] != null + permissions: + pull-requests: write + + steps: + - name: Get PR number + id: pr + run: | + if [ "${{ github.event_name }}" == "check_suite" ]; then + PR_NUMBER="${{ github.event.check_suite.pull_requests[0].number }}" + else + PR_NUMBER="${{ github.event.workflow_run.pull_requests[0].number }}" + fi + echo "number=$PR_NUMBER" >> $GITHUB_OUTPUT + echo "PR number: $PR_NUMBER" + + - name: Check required statuses + id: check + env: + GH_TOKEN: ${{ github.token }} + run: | + PR_NUMBER="${{ steps.pr.outputs.number }}" + + if [ -z "$PR_NUMBER" ]; then + echo "No PR number found, skipping" + echo "should_approve=false" >> $GITHUB_OUTPUT + exit 0 + fi + + # Get PR head SHA + HEAD_SHA=$(gh api repos/${{ github.repository }}/pulls/$PR_NUMBER --jq '.head.sha') + echo "Head SHA: $HEAD_SHA" + + # Check Claude review status + CLAUDE_STATUS=$(gh api repos/${{ github.repository }}/commits/$HEAD_SHA/check-runs --jq '.check_runs[] | select(.name == "claude-review") | .conclusion' | head -1) + echo "Claude review status: $CLAUDE_STATUS" + + # Check Unity Tests status (commit status, not check run) + UNITY_STATUS=$(gh api repos/${{ github.repository }}/commits/$HEAD_SHA/status --jq '.statuses[] | select(.context == "Unity Tests") | .state' | head -1) + echo "Unity Tests status: $UNITY_STATUS" + + # If Unity Tests doesn't exist (skipped scenario), check if Skip Unity Tests completed + if [ -z "$UNITY_STATUS" ]; then + SKIP_STATUS=$(gh api repos/${{ github.repository }}/commits/$HEAD_SHA/check-runs --jq '.check_runs[] | select(.name == "Skip Unity Tests") | .conclusion' | head -1) + echo "Skip Unity Tests status: $SKIP_STATUS" + if [ "$SKIP_STATUS" == "skipped" ] || [ "$SKIP_STATUS" == "success" ]; then + UNITY_STATUS="success" + fi + fi + + # Determine if we should approve + if [ "$CLAUDE_STATUS" == "success" ] && [ "$UNITY_STATUS" == "success" ]; then + echo "All required checks passed!" + echo "should_approve=true" >> $GITHUB_OUTPUT + else + echo "Required checks not yet passed" + echo "should_approve=false" >> $GITHUB_OUTPUT + fi + + - name: Check if already approved + id: existing + if: steps.check.outputs.should_approve == 'true' + env: + GH_TOKEN: ${{ github.token }} + run: | + PR_NUMBER="${{ steps.pr.outputs.number }}" + + # Check for existing approval from github-actions bot + EXISTING=$(gh api repos/${{ github.repository }}/pulls/$PR_NUMBER/reviews --jq '[.[] | select(.user.login == "github-actions[bot]" and .state == "APPROVED")] | length') + + if [ "$EXISTING" -gt 0 ]; then + echo "Already approved by bot" + echo "already_approved=true" >> $GITHUB_OUTPUT + else + echo "Not yet approved by bot" + echo "already_approved=false" >> $GITHUB_OUTPUT + fi + + - name: Auto approve PR + if: steps.check.outputs.should_approve == 'true' && steps.existing.outputs.already_approved == 'false' + env: + GH_TOKEN: ${{ github.token }} + run: | + PR_NUMBER="${{ steps.pr.outputs.number }}" + + gh pr review $PR_NUMBER --approve --body "Auto-approved: Claude review passed and Unity Tests passed (or were skipped for non-code changes)." + + echo "PR #$PR_NUMBER approved!" diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml deleted file mode 100644 index 5b161f3a..00000000 --- a/.github/workflows/cla.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: CLA Assistant - -on: - issue_comment: - types: [created] - pull_request_target: - types: [opened, closed, synchronize] - -# Explicit permissions following least-privilege principle -permissions: read-all - -jobs: - cla: - runs-on: ubuntu-latest - permissions: - actions: write - contents: write - pull-requests: write - statuses: write - if: | - (github.event_name == 'pull_request_target') || - (github.event_name == 'issue_comment' && github.event.issue.pull_request && github.event.comment.body == 'recheck') - steps: - - name: CLA Assistant - uses: contributor-assistant/github-action@v2.6.1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - # Use Developer Certificate of Origin (same as existing DCO check) - path-to-document: 'https://developercertificate.org/' - # Store signatures in the repository - path-to-signatures: 'signatures/cla.json' - branch: 'master' - # Allowlist for bots that don't need to sign - allowlist: 'bot*,*[bot],dependabot*,github-actions*,jengine-release-bot*' - # Custom messages - custom-notsigned-prcomment: | - Thank you for your contribution! Before we can merge this PR, we need you to sign the [Developer Certificate of Origin](https://developercertificate.org/). - - **To sign, please reply with the following comment:** - ``` - I have read the Developer Certificate of Origin and I hereby sign the DCO - ``` - - You can also sign all future contributions by adding `Signed-off-by: Your Name ` to your commit messages (use `git commit -s`). - custom-pr-sign-comment: 'I have read the Developer Certificate of Origin and I hereby sign the DCO' - custom-allsigned-prcomment: 'All contributors have signed the DCO. Thank you!' diff --git a/.scorecard.yml b/.scorecard.yml index 8d2a7c88..4a26ee47 100644 --- a/.scorecard.yml +++ b/.scorecard.yml @@ -1,27 +1,39 @@ # OpenSSF Scorecard Configuration -# See https://github.com/ossf/scorecard/blob/main/docs/config.md +# See https://github.com/ossf/scorecard/tree/main/config annotations: - # Binary artifacts that are required for Unity framework functionality + # Binary artifacts required for Unity hot-update framework: + # - HybridCLR Plugin: Native DLLs for IL2CPP hot-update + # - YooAsset Bundles: Sample project assets + # - AOT Compiled DLLs: Unity engine module references + # These are from trusted sources and essential for the framework - checks: - binary-artifacts reasons: - - reason: not-applicable - annotation: | - JEngine is a Unity hot-update framework that requires certain binary files: + - reason: not-applicable # Unity framework requires platform-specific binaries that cannot be built from source - 1. HybridCLR Plugin (com.code-philosophy.hybridclr): - - Native DLLs for IL2CPP hot-update functionality - - Required for runtime C# code execution + # Pinned dependencies: Using version tags (@v4) for maintainability + # SHA pinning would make updates more difficult with minimal security benefit + # for this Unity project that doesn't process untrusted input + - checks: + - pinned-dependencies + reasons: + - reason: not-applicable # Version tags preferred for maintainability in Unity project - 2. YooAsset Bundles (Assets/StreamingAssets/yoo): - - Pre-built asset bundles for sample project - - Demonstrate framework capabilities + # Dependency update tools like Dependabot don't work well with Unity/OpenUPM + - checks: + - dependency-update-tool + reasons: + - reason: not-supported # Unity uses OpenUPM which is not supported by Dependabot/Renovate - 3. AOT Compiled DLLs (Assets/HotUpdate/Compiled/AOT): - - Unity engine module references - - Required for IL2CPP builds + # Fuzzing is not practical for Unity C# game framework code + - checks: + - fuzzing + reasons: + - reason: not-applicable # Unity C# framework is not suited for traditional fuzzing - These binaries are from trusted sources (Unity, HybridCLR) and are - essential for the framework to function. They cannot be built from - source as they are platform-specific Unity artifacts. + # SAST is handled by CodeQL but may not be fully detected + - checks: + - sast + reasons: + - reason: not-detected # CodeQL is configured but may not be recognized diff --git a/signatures/cla.json b/signatures/cla.json deleted file mode 100644 index c6ac125e..00000000 --- a/signatures/cla.json +++ /dev/null @@ -1 +0,0 @@ -{"signedContributors": []}